work in progress - passes simple tests
[plcapi.git] / PLC / ConfFiles.py
1 #
2 # Functions for interacting with the conf_files table in the database
3 #
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
6 #
7 # $Id$
8 #
9
10 from PLC.Faults import *
11 from PLC.Parameter import Parameter
12 from PLC.Filter import Filter
13 from PLC.Table import Row, Table
14 from PLC.Nodes import Node, Nodes
15 from PLC.NodeGroups import NodeGroup, NodeGroups
16
17 class ConfFile(Row):
18     """
19     Representation of a row in the conf_files table. To use,
20     instantiate with a dict of values.
21     """
22
23     table_name = 'conf_files'
24     primary_key = 'conf_file_id'
25     join_tables = ['conf_file_node', 'conf_file_nodegroup']
26     fields = {
27         'conf_file_id': Parameter(int, "Configuration file identifier"),
28         'enabled': Parameter(bool, "Configuration file is active"),
29         'source': Parameter(str, "Relative path on the boot server where file can be downloaded", max = 255),
30         'dest': Parameter(str, "Absolute path where file should be installed", max = 255),
31         'file_permissions': Parameter(str, "chmod(1) permissions", max = 20),
32         'file_owner': Parameter(str, "chown(1) owner", max = 50),
33         'file_group': Parameter(str, "chgrp(1) owner", max = 50),
34         'preinstall_cmd': Parameter(str, "Shell command to execute prior to installing", max = 1024, nullok = True),
35         'postinstall_cmd': Parameter(str, "Shell command to execute after installing", max = 1024, nullok = True),
36         'error_cmd': Parameter(str, "Shell command to execute if any error occurs", max = 1024, nullok = True),
37         'ignore_cmd_errors': Parameter(bool, "Install file anyway even if an error occurs"),
38         'always_update': Parameter(bool, "Always attempt to install file even if unchanged"),
39         'node_ids': Parameter(int, "List of nodes linked to this file"),
40         'nodegroup_ids': Parameter(int, "List of node groups linked to this file"),
41         }
42
43     def add_node(self, node, commit = True):
44         """
45         Add configuration file to node.
46         """
47
48         assert 'conf_file_id' in self
49         assert isinstance(node, Node)
50         assert 'node_id' in node
51
52         conf_file_id = self['conf_file_id']
53         node_id = node['node_id']
54
55         if node_id not in self['node_ids']:
56             self.api.db.do("INSERT INTO conf_file_node (conf_file_id, node_id)" \
57                            " VALUES(%(conf_file_id)d, %(node_id)d)",
58                            locals())
59
60             if commit:
61                 self.api.db.commit()
62
63             self['node_ids'].append(node_id)
64             node['conf_file_ids'].append(conf_file_id)
65
66     def remove_node(self, node, commit = True):
67         """
68         Remove configuration file from node.
69         """
70
71         assert 'conf_file_id' in self
72         assert isinstance(node, Node)
73         assert 'node_id' in node
74
75         conf_file_id = self['conf_file_id']
76         node_id = node['node_id']
77
78         if node_id in self['node_ids']:
79             self.api.db.do("DELETE FROM conf_file_node" \
80                            " WHERE conf_file_id = %(conf_file_id)d" \
81                            " AND node_id = %(node_id)d",
82                            locals())
83
84             if commit:
85                 self.api.db.commit()
86
87             self['node_ids'].remove(node_id)
88             node['conf_file_ids'].remove(conf_file_id)
89
90     def add_nodegroup(self, nodegroup, commit = True):
91         """
92         Add configuration file to node group.
93         """
94
95         assert 'conf_file_id' in self
96         assert isinstance(nodegroup, NodeGroup)
97         assert 'nodegroup_id' in nodegroup
98
99         conf_file_id = self['conf_file_id']
100         nodegroup_id = nodegroup['nodegroup_id']
101
102         if nodegroup_id not in self['nodegroup_ids']:
103             self.api.db.do("INSERT INTO conf_file_nodegroup (conf_file_id, nodegroup_id)" \
104                            " VALUES(%(conf_file_id)d, %(nodegroup_id)d)",
105                            locals())
106
107             if commit:
108                 self.api.db.commit()
109
110             self['nodegroup_ids'].append(nodegroup_id)
111             nodegroup['conf_file_ids'].append(conf_file_id)
112
113     def remove_nodegroup(self, nodegroup, commit = True):
114         """
115         Remove configuration file from node group.
116         """
117
118         assert 'conf_file_id' in self
119         assert isinstance(nodegroup, NodeGroup)
120         assert 'nodegroup_id' in nodegroup
121
122         conf_file_id = self['conf_file_id']
123         nodegroup_id = nodegroup['nodegroup_id']
124
125         if nodegroup_id in self['nodegroup_ids']:
126             self.api.db.do("DELETE FROM conf_file_nodegroup" \
127                            " WHERE conf_file_id = %(conf_file_id)d" \
128                            " AND nodegroup_id = %(nodegroup_id)d",
129                            locals())
130
131             if commit:
132                 self.api.db.commit()
133
134             self['nodegroup_ids'].remove(nodegroup_id)
135             nodegroup['conf_file_ids'].remove(conf_file_id)
136
137 class ConfFiles(Table):
138     """
139     Representation of the conf_files table in the database.
140     """
141
142     def __init__(self, api, conf_file_filter = None, columns = None):
143         Table.__init__(self, api, ConfFile, columns)
144
145         sql = "SELECT %s FROM view_conf_files WHERE True" % \
146               ", ".join(self.columns)
147
148         if conf_file_filter is not None:
149             if isinstance(conf_file_filter, (list, tuple, set)):
150                 conf_file_filter = Filter(ConfFile.fields, {'conf_file_id': conf_file_filter})
151             elif isinstance(conf_file_filter, dict):
152                 conf_file_filter = Filter(ConfFile.fields, conf_file_filter)
153             sql += " AND (%s) %s" % conf_file_filter.sql(api)
154
155         self.selectall(sql)