====
[plcapi.git] / PLC / Nodes.py
index 9cf0edf..7e27ed4 100644 (file)
@@ -4,9 +4,6 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id$
-# $URL$
-#
 
 from types import StringTypes
 import re
 
 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.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.
@@ -57,6 +55,12 @@ class Node(Row):
         'date_created': Parameter(int, "Date and time when node entry was created", ro = True),
         'last_updated': Parameter(int, "Date and time when node entry was created", ro = True),
         'last_contact': Parameter(int, "Date and time when node last contacted plc", ro = True),
         'date_created': Parameter(int, "Date and time when node entry was created", ro = True),
         'last_updated': Parameter(int, "Date and time when node entry was created", ro = True),
         'last_contact': Parameter(int, "Date and time when node last contacted plc", ro = True),
+        'last_boot': Parameter(int, "Date and time when node last booted", 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),
@@ -88,6 +92,7 @@ class Node(Row):
     tags = { }
 
     def validate_hostname(self, hostname):
     tags = { }
 
     def validate_hostname(self, hostname):
+        hostname = hostname.lower()
         if not valid_hostname(hostname):
             raise PLCInvalidArgument, "Invalid hostname"
 
         if not valid_hostname(hostname):
             raise PLCInvalidArgument, "Invalid hostname"
 
@@ -113,32 +118,46 @@ class Node(Row):
     validate_date_created = Row.validate_timestamp
     validate_last_updated = Row.validate_timestamp
     validate_last_contact = Row.validate_timestamp
     validate_date_created = Row.validate_timestamp
     validate_last_updated = Row.validate_timestamp
     validate_last_contact = Row.validate_timestamp
+    validate_last_boot = Row.validate_timestamp
+    validate_last_download = Row.validate_timestamp
+    validate_last_pcu_reboot = Row.validate_timestamp
+    validate_last_pcu_confirmation = Row.validate_timestamp
 
 
-    def update_last_contact(self, commit = True):
-        """
-        Update last_contact field with current time
-        """
+    def update_readonly_int(self, col_name, commit = True):
 
         assert 'node_id' in self
         assert self.table_name
 
 
         assert 'node_id' in self
         assert self.table_name
 
-        self.api.db.do("UPDATE %s SET last_contact = CURRENT_TIMESTAMP " % (self.table_name) + \
-                       " where node_id = %d" % ( self['node_id']) )
+        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)
 
         self.sync(commit)
 
-
-    def update_last_updated(self, commit = True):
+    def update_timestamp(self, col_name, commit = True):
         """
         """
-        Update last_updated field with current time
+        Update col_name field with current time
         """
 
         assert 'node_id' in self
         assert self.table_name
 
         """
 
         assert 'node_id' in self
         assert self.table_name
 
-        self.api.db.do("UPDATE %s SET last_updated = CURRENT_TIMESTAMP " % (self.table_name) + \
+        self.api.db.do("UPDATE %s SET %s = CURRENT_TIMESTAMP " % (self.table_name, col_name) + \
                        " where node_id = %d" % (self['node_id']) )
         self.sync(commit)
 
                        " where node_id = %d" % (self['node_id']) )
         self.sync(commit)
 
+    def update_last_boot(self, commit = True):
+        self.update_timestamp('last_boot', commit)
+    def update_last_download(self, commit = True):
+        self.update_timestamp('last_download', commit)
+    def update_last_pcu_reboot(self, commit = True):
+        self.update_timestamp('last_pcu_reboot', commit)
+    def update_last_pcu_confirmation(self, commit = True):
+        self.update_timestamp('last_pcu_confirmation', commit)
+
+    def update_last_contact(self, commit = True):
+        self.update_timestamp('last_contact', commit)
+    def update_last_updated(self, commit = True):
+        self.update_timestamp('last_updated', commit)
+
     def update_tags(self, tags):
         from PLC.Shell import Shell
         from PLC.NodeTags import NodeTags
     def update_tags(self, tags):
         from PLC.Shell import Shell
         from PLC.NodeTags import NodeTags
@@ -283,7 +302,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
@@ -315,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(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")
                 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
                 sql += " AND (%s) %s" % node_filter.sql(api, "AND")
             else:
                 raise PLCInvalidArgument, "Wrong node filter %r"%node_filter