====
[plcapi.git] / PLC / Nodes.py
index 6b799c1..7e27ed4 100644 (file)
@@ -4,9 +4,6 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id$
-# $URL$
-#
 
 from types import StringTypes
 import re
@@ -19,6 +16,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.TagTypes import TagType, TagTypes
 
 def valid_hostname(hostname):
     # 1. Each part begins and ends with a letter or number.
@@ -61,6 +59,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_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),
@@ -92,6 +92,7 @@ class Node(Row):
     tags = { }
 
     def validate_hostname(self, hostname):
+        hostname = hostname.lower()
         if not valid_hostname(hostname):
             raise PLCInvalidArgument, "Invalid hostname"
 
@@ -122,6 +123,15 @@ class Node(Row):
     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
@@ -292,7 +302,6 @@ class Node(Row):
         self['deleted'] = True
         self.sync(commit)
 
-
 class Nodes(Table):
     """
     Representation of row(s) from the nodes table in the
@@ -324,10 +333,10 @@ class Nodes(Table):
                 node_filter = Filter(allowed_fields, node_filter)
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
             elif isinstance (node_filter, StringTypes):
-                node_filter = Filter(Node.fields, {'hostname':[node_filter]})
+                node_filter = Filter(Node.fields, {'hostname':node_filter})
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
-            elif isinstance (node_filter, int):
-                node_filter = Filter(Node.fields, {'node_id':[node_filter]})
+            elif isinstance (node_filter, (int, long)):
+                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