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