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.12 2006/10/06 19:05:31 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),
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 # Remove leading and trailing spaces
40 # Make sure name is not blank after we removed the spaces
42 raise PLCInvalidArgument, "Invalid node group name"
44 # Make sure node group does not alredy exist
45 conflicts = NodeGroups(self.api, [name])
46 for nodegroup_id in conflicts:
47 if 'nodegroup_id' not in self or self['nodegroup_id'] != nodegroup_id:
48 raise PLCInvalidArgument, "Node group name already in use"
52 def add_node(self, node, commit = True):
54 Add node to existing nodegroup.
57 assert 'nodegroup_id' in self
58 assert isinstance(node, Node)
59 assert 'node_id' in node
61 node_id = node['node_id']
62 nodegroup_id = self['nodegroup_id']
64 if node_id not in self['node_ids']:
65 assert nodegroup_id not in node['nodegroup_ids']
67 self.api.db.do("INSERT INTO nodegroup_node (nodegroup_id, node_id)" \
68 " VALUES(%(nodegroup_id)d, %(node_id)d)",
74 self['node_ids'].append(node_id)
75 node['nodegroup_ids'].append(nodegroup_id)
77 def remove_node(self, node, commit = True):
79 Remove node from existing nodegroup.
82 assert 'nodegroup_id' in self
83 assert isinstance(node, Node)
84 assert 'node_id' in node
86 node_id = node['node_id']
87 nodegroup_id = self['nodegroup_id']
89 if node_id in self['node_ids']:
90 assert nodegroup_id in node['nodegroup_ids']
92 self.api.db.do("DELETE FROM nodegroup_node" \
93 " WHERE nodegroup_id = %(nodegroup_id)d" \
94 " AND node_id = %(node_id)d",
100 self['node_ids'].remove(node_id)
101 node['nodegroup_ids'].remove(nodegroup_id)
103 class NodeGroups(Table):
105 Representation of row(s) from the nodegroups table in the
109 def __init__(self, api, nodegroup_id_or_name_list = None):
112 sql = "SELECT %s FROM view_nodegroups" % \
113 ", ".join(NodeGroup.fields)
115 if nodegroup_id_or_name_list:
116 # Separate the list into integers and strings
117 nodegroup_ids = filter(lambda nodegroup_id: isinstance(nodegroup_id, (int, long)),
118 nodegroup_id_or_name_list)
119 names = filter(lambda name: isinstance(name, StringTypes),
120 nodegroup_id_or_name_list)
121 sql += " WHERE (False"
123 sql += " OR nodegroup_id IN (%s)" % ", ".join(map(str, nodegroup_ids))
125 sql += " OR name IN (%s)" % ", ".join(api.db.quote(names))
128 rows = self.api.db.selectall(sql)
131 self[row['nodegroup_id']] = nodegroup = NodeGroup(api, row)
132 for aggregate in ['node_ids', 'conf_file_ids']:
133 if not nodegroup.has_key(aggregate) or nodegroup[aggregate] is None:
134 nodegroup[aggregate] = []
136 nodegroup[aggregate] = map(int, nodegroup[aggregate].split(','))