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