fixed bug introduced when porting to py3
[plcapi.git] / PLC / Nodes.py
index ce2cbad..6af9ee9 100644 (file)
@@ -5,7 +5,6 @@
 # Copyright (C) 2006 The Trustees of Princeton University
 #
 
 # Copyright (C) 2006 The Trustees of Princeton University
 #
 
-from types import StringTypes
 import re
 
 from PLC.Faults import *
 import re
 
 from PLC.Faults import *
@@ -16,6 +15,7 @@ from PLC.Table import Row, Table
 from PLC.NodeTypes import NodeTypes
 from PLC.BootStates import BootStates
 from PLC.Interfaces import Interface, Interfaces
 from PLC.NodeTypes import NodeTypes
 from PLC.BootStates import BootStates
 from PLC.Interfaces import Interface, Interfaces
+from PLC.TagTypes import TagType, TagTypes
 
 def valid_hostname(hostname):
     # 1. Each part begins and ends with a letter or number.
 
 def valid_hostname(hostname):
     # 1. Each part begins and ends with a letter or number.
@@ -58,6 +58,8 @@ class Node(Row):
         'last_download': Parameter(int, "Date and time when node boot image was created", ro = True),
         'last_pcu_reboot': Parameter(int, "Date and time when PCU reboot was attempted", ro = True),
         'last_pcu_confirmation': Parameter(int, "Date and time when PCU reboot was confirmed", ro = True),
         'last_download': Parameter(int, "Date and time when node boot image was created", ro = True),
         'last_pcu_reboot': Parameter(int, "Date and time when PCU reboot was attempted", ro = True),
         'last_pcu_confirmation': Parameter(int, "Date and time when PCU reboot was confirmed", ro = True),
+        'last_time_spent_online': Parameter(int, "Length of time the node was last online before shutdown/failure", ro = True),
+        'last_time_spent_offline': Parameter(int, "Length of time the node was last offline after failure and before reboot", ro = True),
         'verified': Parameter(bool, "Whether the node configuration is verified correct", ro=False),
         'key': Parameter(str, "(Admin only) Node key", max = 256),
         'session': Parameter(str, "(Admin only) Node session value", max = 256, ro = True),
         'verified': Parameter(bool, "Whether the node configuration is verified correct", ro=False),
         'key': Parameter(str, "(Admin only) Node key", max = 256),
         'session': Parameter(str, "(Admin only) Node session value", max = 256, ro = True),
@@ -91,25 +93,25 @@ class Node(Row):
     def validate_hostname(self, hostname):
         hostname = hostname.lower()
         if not valid_hostname(hostname):
     def validate_hostname(self, hostname):
         hostname = hostname.lower()
         if not valid_hostname(hostname):
-            raise PLCInvalidArgument, "Invalid hostname"
+            raise PLCInvalidArgument("Invalid hostname")
 
         conflicts = Nodes(self.api, [hostname])
         for node in conflicts:
             if 'node_id' not in self or self['node_id'] != node['node_id']:
 
         conflicts = Nodes(self.api, [hostname])
         for node in conflicts:
             if 'node_id' not in self or self['node_id'] != node['node_id']:
-                raise PLCInvalidArgument, "Hostname already in use"
+                raise PLCInvalidArgument("Hostname already in use")
 
         return hostname
 
     def validate_node_type(self, node_type):
         node_types = [row['node_type'] for row in NodeTypes(self.api)]
         if node_type not in node_types:
 
         return hostname
 
     def validate_node_type(self, node_type):
         node_types = [row['node_type'] for row in NodeTypes(self.api)]
         if node_type not in node_types:
-            raise PLCInvalidArgument, "Invalid node type %r"%node_type
+            raise PLCInvalidArgument("Invalid node type %r"%node_type)
         return node_type
 
     def validate_boot_state(self, boot_state):
         boot_states = [row['boot_state'] for row in BootStates(self.api)]
         if boot_state not in boot_states:
         return node_type
 
     def validate_boot_state(self, boot_state):
         boot_states = [row['boot_state'] for row in BootStates(self.api)]
         if boot_state not in boot_states:
-            raise PLCInvalidArgument, "Invalid boot state %r"%boot_state
+            raise PLCInvalidArgument("Invalid boot state %r"%boot_state)
         return boot_state
 
     validate_date_created = Row.validate_timestamp
         return boot_state
 
     validate_date_created = Row.validate_timestamp
@@ -120,6 +122,15 @@ class Node(Row):
     validate_last_pcu_reboot = Row.validate_timestamp
     validate_last_pcu_confirmation = Row.validate_timestamp
 
     validate_last_pcu_reboot = Row.validate_timestamp
     validate_last_pcu_confirmation = Row.validate_timestamp
 
+    def update_readonly_int(self, col_name, commit = True):
+
+        assert 'node_id' in self
+        assert self.table_name
+
+        self.api.db.do("UPDATE %s SET %s = %s" % (self.table_name, col_name, self[col_name]) + \
+                        " where node_id = %d" % (self['node_id']) )
+        self.sync(commit)
+
     def update_timestamp(self, col_name, commit = True):
         """
         Update col_name field with current time
     def update_timestamp(self, col_name, commit = True):
         """
         Update col_name field with current time
@@ -152,10 +163,10 @@ class Node(Row):
         from PLC.Methods.AddNodeTag import AddNodeTag
         from PLC.Methods.UpdateNodeTag import UpdateNodeTag
         shell = Shell()
         from PLC.Methods.AddNodeTag import AddNodeTag
         from PLC.Methods.UpdateNodeTag import UpdateNodeTag
         shell = Shell()
-        for (tagname,value) in tags.iteritems():
+        for (tagname,value) in tags.items():
             # the tagtype instance is assumed to exist, just check that
             if not TagTypes(self.api,{'tagname':tagname}):
             # the tagtype instance is assumed to exist, just check that
             if not TagTypes(self.api,{'tagname':tagname}):
-                raise PLCInvalidArgument,"No such TagType %s"%tagname
+                raise PLCInvalidArgument("No such TagType %s"%tagname)
             node_tags=NodeTags(self.api,{'tagname':tagname,'node_id':node['node_id']})
             if not node_tags:
                 AddNodeTag(self.api).__call__(shell.auth,node['node_id'],tagname,value)
             node_tags=NodeTags(self.api,{'tagname':tagname,'node_id':node['node_id']})
             if not node_tags:
                 AddNodeTag(self.api).__call__(shell.auth,node['node_id'],tagname,value)
@@ -222,7 +233,7 @@ class Node(Row):
 
         if slice_names:
             slices = Slices(self.api, slice_names, ['slice_id']).dict('slice_id')
 
         if slice_names:
             slices = Slices(self.api, slice_names, ['slice_id']).dict('slice_id')
-            slice_ids += slices.keys()
+            slice_ids += list(slices.keys())
 
         if self['slice_ids'] != slice_ids:
             from PLC.Methods.AddSliceToNodes import AddSliceToNodes
 
         if self['slice_ids'] != slice_ids:
             from PLC.Methods.AddSliceToNodes import AddSliceToNodes
@@ -251,7 +262,7 @@ class Node(Row):
 
         if slice_names:
             slices = Slices(self.api, slice_names, ['slice_id']).dict('slice_id')
 
         if slice_names:
             slices = Slices(self.api, slice_names, ['slice_id']).dict('slice_id')
-            slice_ids += slices.keys()
+            slice_ids += list(slices.keys())
 
         if self['slice_ids_whitelist'] != slice_ids:
             from PLC.Methods.AddSliceToNodesWhitelist import AddSliceToNodesWhitelist
 
         if self['slice_ids_whitelist'] != slice_ids:
             from PLC.Methods.AddSliceToNodesWhitelist import AddSliceToNodesWhitelist
@@ -290,7 +301,6 @@ class Node(Row):
         self['deleted'] = True
         self.sync(commit)
 
         self['deleted'] = True
         self.sync(commit)
 
-
 class Nodes(Table):
     """
     Representation of row(s) from the nodes table in the
 class Nodes(Table):
     """
     Representation of row(s) from the nodes table in the
@@ -308,26 +318,26 @@ class Nodes(Table):
                                                 Node.primary_key)
 
         sql = "SELECT %s FROM %s WHERE deleted IS False" % \
                                                 Node.primary_key)
 
         sql = "SELECT %s FROM %s WHERE deleted IS False" % \
-              (", ".join(self.columns.keys()+self.tag_columns.keys()),view)
+              (", ".join(list(self.columns.keys())+list(self.tag_columns.keys())),view)
 
         if node_filter is not None:
             if isinstance(node_filter, (list, tuple, set)):
                 # Separate the list into integers and strings
 
         if node_filter is not None:
             if isinstance(node_filter, (list, tuple, set)):
                 # Separate the list into integers and strings
-                ints = filter(lambda x: isinstance(x, (int, long)), node_filter)
-                strs = filter(lambda x: isinstance(x, StringTypes), node_filter)
+                ints = [x for x in node_filter if isinstance(x, int)]
+                strs = [x for x in node_filter if isinstance(x, str)]
                 node_filter = Filter(Node.fields, {'node_id': ints, 'hostname': strs})
                 sql += " AND (%s) %s" % node_filter.sql(api, "OR")
             elif isinstance(node_filter, dict):
                 node_filter = Filter(Node.fields, {'node_id': ints, 'hostname': strs})
                 sql += " AND (%s) %s" % node_filter.sql(api, "OR")
             elif isinstance(node_filter, dict):
-                allowed_fields=dict(Node.fields.items()+Node.tags.items())
+                allowed_fields=dict(list(Node.fields.items())+list(Node.tags.items()))
                 node_filter = Filter(allowed_fields, node_filter)
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
                 node_filter = Filter(allowed_fields, node_filter)
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
-            elif isinstance (node_filter, StringTypes):
+            elif isinstance (node_filter, str):
                 node_filter = Filter(Node.fields, {'hostname':node_filter})
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
                 node_filter = Filter(Node.fields, {'hostname':node_filter})
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
-            elif isinstance (node_filter, (int, long)):
+            elif isinstance (node_filter, int):
                 node_filter = Filter(Node.fields, {'node_id':node_filter})
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
             else:
                 node_filter = Filter(Node.fields, {'node_id':node_filter})
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
             else:
-                raise PLCInvalidArgument, "Wrong node filter %r"%node_filter
+                raise PLCInvalidArgument("Wrong node filter %r"%node_filter)
 
         self.selectall(sql)
 
         self.selectall(sql)