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.18 2006/11/09 03:07:42 mlhuang Exp $
10 from types import StringTypes
12 from PLC.Faults import *
13 from PLC.Parameter import Parameter
14 from PLC.Filter import Filter
15 from PLC.Debug import profile
16 from PLC.Table import Row, Table
17 from PLC.Nodes import Node, Nodes
21 Representation of a row in the nodegroups table. To use, optionally
22 instantiate with a dict of values. Update as you would a
23 dict. Commit to the database with sync().
26 table_name = 'nodegroups'
27 primary_key = 'nodegroup_id'
28 join_tables = ['nodegroup_node', 'conf_file_nodegroup']
30 'nodegroup_id': Parameter(int, "Node group identifier"),
31 'name': Parameter(str, "Node group name", max = 50),
32 'description': Parameter(str, "Node group description", max = 200, nullok = True),
33 'node_ids': Parameter([int], "List of nodes in this node group"),
34 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
37 def validate_name(self, name):
38 # Make sure name is not blank
40 raise PLCInvalidArgument, "Invalid node group name"
42 # Make sure node group does not alredy exist
43 conflicts = NodeGroups(self.api, [name])
44 for nodegroup_id in conflicts:
45 if 'nodegroup_id' not in self or self['nodegroup_id'] != nodegroup_id:
46 raise PLCInvalidArgument, "Node group name already in use"
50 def add_node(self, node, commit = True):
52 Add node to existing nodegroup.
55 assert 'nodegroup_id' in self
56 assert isinstance(node, Node)
57 assert 'node_id' in node
59 node_id = node['node_id']
60 nodegroup_id = self['nodegroup_id']
62 if node_id not in self['node_ids']:
63 assert nodegroup_id not in node['nodegroup_ids']
65 self.api.db.do("INSERT INTO nodegroup_node (nodegroup_id, node_id)" \
66 " VALUES(%(nodegroup_id)d, %(node_id)d)",
72 self['node_ids'].append(node_id)
73 node['nodegroup_ids'].append(nodegroup_id)
75 def remove_node(self, node, commit = True):
77 Remove node from existing nodegroup.
80 assert 'nodegroup_id' in self
81 assert isinstance(node, Node)
82 assert 'node_id' in node
84 node_id = node['node_id']
85 nodegroup_id = self['nodegroup_id']
87 if node_id in self['node_ids']:
88 assert nodegroup_id in node['nodegroup_ids']
90 self.api.db.do("DELETE FROM nodegroup_node" \
91 " WHERE nodegroup_id = %(nodegroup_id)d" \
92 " AND node_id = %(node_id)d",
98 self['node_ids'].remove(node_id)
99 node['nodegroup_ids'].remove(nodegroup_id)
101 class NodeGroups(Table):
103 Representation of row(s) from the nodegroups table in the
107 def __init__(self, api, nodegroup_filter = None, columns = None):
108 Table.__init__(self, api, NodeGroup, columns)
110 sql = "SELECT %s FROM view_nodegroups WHERE True" % \
111 ", ".join(self.columns)
113 if nodegroup_filter is not None:
114 if isinstance(nodegroup_filter, (list, tuple, set)):
115 # Separate the list into integers and strings
116 ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter)
117 strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter)
118 nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'name': strs})
119 sql += " AND (%s)" % nodegroup_filter.sql(api, "OR")
120 elif isinstance(nodegroup_filter, dict):
121 nodegroup_filter = Filter(NodeGroup.fields, nodegroup_filter)
122 sql += " AND (%s)" % nodegroup_filter.sql(api, "AND")