2 # Functions for interacting with the nodegroups table in the database
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
7 # $Id: NodeGroups.py,v 1.13 2006/10/20 17:50:33 mlhuang Exp $
10 from types import StringTypes
12 from PLC.Faults import *
13 from PLC.Parameter import Parameter
14 from PLC.Debug import profile
15 from PLC.Table import Row, Table
16 from PLC.Nodes import Node, Nodes
20 Representation of a row in the nodegroups table. To use, optionally
21 instantiate with a dict of values. Update as you would a
22 dict. Commit to the database with sync().
25 table_name = 'nodegroups'
26 primary_key = 'nodegroup_id'
27 join_tables = ['nodegroup_node', 'conf_file_nodegroup']
29 'nodegroup_id': Parameter(int, "Node group identifier"),
30 'name': Parameter(str, "Node group name", max = 50, optional = False),
31 'description': Parameter(str, "Node group description", max = 200),
32 'node_ids': Parameter([int], "List of nodes in this node group"),
33 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
36 def validate_name(self, name):
37 # Make sure name is not blank
39 raise PLCInvalidArgument, "Invalid node group name"
41 # Make sure node group does not alredy exist
42 conflicts = NodeGroups(self.api, [name])
43 for nodegroup_id in conflicts:
44 if 'nodegroup_id' not in self or self['nodegroup_id'] != nodegroup_id:
45 raise PLCInvalidArgument, "Node group name already in use"
49 def add_node(self, node, commit = True):
51 Add node to existing nodegroup.
54 assert 'nodegroup_id' in self
55 assert isinstance(node, Node)
56 assert 'node_id' in node
58 node_id = node['node_id']
59 nodegroup_id = self['nodegroup_id']
61 if node_id not in self['node_ids']:
62 assert nodegroup_id not in node['nodegroup_ids']
64 self.api.db.do("INSERT INTO nodegroup_node (nodegroup_id, node_id)" \
65 " VALUES(%(nodegroup_id)d, %(node_id)d)",
71 self['node_ids'].append(node_id)
72 node['nodegroup_ids'].append(nodegroup_id)
74 def remove_node(self, node, commit = True):
76 Remove node from existing nodegroup.
79 assert 'nodegroup_id' in self
80 assert isinstance(node, Node)
81 assert 'node_id' in node
83 node_id = node['node_id']
84 nodegroup_id = self['nodegroup_id']
86 if node_id in self['node_ids']:
87 assert nodegroup_id in node['nodegroup_ids']
89 self.api.db.do("DELETE FROM nodegroup_node" \
90 " WHERE nodegroup_id = %(nodegroup_id)d" \
91 " AND node_id = %(node_id)d",
97 self['node_ids'].remove(node_id)
98 node['nodegroup_ids'].remove(nodegroup_id)
100 class NodeGroups(Table):
102 Representation of row(s) from the nodegroups table in the
106 def __init__(self, api, nodegroup_id_or_name_list = None):
109 sql = "SELECT %s FROM view_nodegroups" % \
110 ", ".join(NodeGroup.fields)
112 if nodegroup_id_or_name_list:
113 # Separate the list into integers and strings
114 nodegroup_ids = filter(lambda nodegroup_id: isinstance(nodegroup_id, (int, long)),
115 nodegroup_id_or_name_list)
116 names = filter(lambda name: isinstance(name, StringTypes),
117 nodegroup_id_or_name_list)
118 sql += " WHERE (False"
120 sql += " OR nodegroup_id IN (%s)" % ", ".join(map(str, nodegroup_ids))
122 sql += " OR name IN (%s)" % ", ".join(api.db.quote(names))
125 rows = self.api.db.selectall(sql)
128 self[row['nodegroup_id']] = nodegroup = NodeGroup(api, row)
129 for aggregate in ['node_ids', 'conf_file_ids']:
130 if not nodegroup.has_key(aggregate) or nodegroup[aggregate] is None:
131 nodegroup[aggregate] = []
133 nodegroup[aggregate] = map(int, nodegroup[aggregate].split(','))