oops
[plcapi.git] / PLC / Methods / GetBootMedium.py
index 7449e4f..f7f0c4b 100644 (file)
@@ -3,6 +3,7 @@ import random
 import base64
 import os
 import os.path
+import time
 
 from PLC.Faults import *
 from PLC.Method import Method
@@ -12,7 +13,7 @@ from PLC.Auth import Auth
 from PLC.Nodes import Node, Nodes
 from PLC.Interfaces import Interface, Interfaces
 from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings
-from PLC.NodeGroups import NodeGroup, NodeGroups
+from PLC.NodeTags import NodeTags
 
 # could not define this in the class..
 boot_medium_actions = [ 'node-preview',
@@ -92,6 +93,7 @@ class GetBootMedium(Method):
         - 'partition' - for USB actions only
         - 'cramfs'
         - 'serial' or 'serial:<console_spec>'
+        - 'no-hangcheck'
         console_spec (or 'default') is passed as-is to bootcd/build.sh
         it is expected to be a colon separated string denoting
         tty - baudrate - parity - bits
@@ -174,6 +176,8 @@ class GetBootMedium(Method):
         if renew_key:
             file += 'NODE_ID="%d"\n' % node['node_id']
             file += 'NODE_KEY="%s"\n' % node['key']
+            # not used anywhere, just a note for operations people
+            file += 'KEY_RENEWAL_DATE="%s"\n' % time.strftime('%Y-%m-%d at %H:%M:%S +0000',time.gmtime())
 
         if primary['mac']:
             file += 'NET_DEVICE="%s"\n' % primary['mac'].lower()
@@ -219,32 +223,27 @@ class GetBootMedium(Method):
 
     # see also InstallBootstrapFS in bootmanager that does similar things
     def get_nodefamily (self, node):
+        # get defaults from the myplc build
         try:
             (pldistro,arch) = file("/etc/planetlab/nodefamily").read().strip().split("-")
         except:
             (pldistro,arch) = ("planetlab","i386")
             
+        # with no valid argument, return system-wide defaults
         if not node:
             return (pldistro,arch)
 
-        known_archs = [ 'i386', 'x86_64' ]
-        nodegroupnames = [ ng['groupname'] for ng in NodeGroups (self.api, node['nodegroup_ids'],['groupname'])]
-        # (1) if groupname == arch, nodefamily becomes pldistro-groupname
-        # (2) else if groupname looks like pldistro-arch, it is taken as a nodefamily
-        # (3) otherwise groupname is taken as an extension
-        for nodegroupname in nodegroupnames:
-            if nodegroupname in known_archs:
-                arch = nodegroupname
-            else:
-                for known_arch in known_archs:
-                    try:
-                        (api_pldistro,api_arch)=nodegroupname.split("-")
-                        # sanity check
-                        if api_arch != known_arch: raise Exception,"mismatch"
-                        (pldistro,arch) = (api_pldistro, api_arch)
-                        break
-                    except:
-                        pass
+        node_id=node['node_id']
+        # cannot use accessors in the API itself
+        # the 'arch' tag type is assumed to exist, see db-config
+        arch_tags = NodeTags (self.api, {'tagname':'arch','node_id':node_id},['tagvalue'])
+        if arch_tags:
+            arch=arch_tags[0]['tagvalue']
+        # ditto
+        pldistro_tags = NodeTags (self.api, {'tagname':'pldistro','node_id':node_id},['tagvalue'])
+        if pldistro_tags:
+            pldistro=pldistro_tags[0]['tagvalue']
+
         return (pldistro,arch)
 
     def bootcd_version (self):
@@ -284,19 +283,21 @@ class GetBootMedium(Method):
                 raise PLCInvalidArgument, "Options are not supported for node configs"
         else:
             # create a dict for build.sh 
-            optdict={}
+            build_sh_spec={'-k':[]}
             for option in options:
                 if option == "cramfs":
-                    optdict['cramfs']=True
+                    build_sh_spec['cramfs']=True
                 elif option == 'partition':
                     if type != "usb":
                         raise PLCInvalidArgument, "option 'partition' is for USB images only"
                     else:
                         type="usb_partition"
                 elif option == "serial":
-                    optdict['serial']='default'
+                    build_sh_spec['serial']='default'
                 elif option.find("serial:") == 0:
-                    optdict['serial']=option.replace("serial:","")
+                    build_sh_spec['serial']=option.replace("serial:","")
+                elif option == "no-hangcheck":
+                    build_sh_spec['-k'].append('hangcheck_reboot=0')
                 else:
                     raise PLCInvalidArgument, "unknown option %s"%option
 
@@ -354,9 +355,9 @@ class GetBootMedium(Method):
             if filedir:
                 if not os.path.exists(filedir):
                     try:
-                        os.makedirs (dirname,0777)
+                        os.makedirs (filedir,0777)
                     except:
-                        raise PLCPermissionDenied, "Could not create dir %s"%dirname
+                        raise PLCPermissionDenied, "Could not create dir %s"%filedir
 
         
         ### generic media
@@ -425,9 +426,15 @@ class GetBootMedium(Method):
                 node_image = "%s/%s%s"%(self.WORKDIR,nodename,suffix)
 
                 # make build's arguments
-                serial_arg=""
-                if "cramfs" in optdict: type += "_cramfs"
-                if "serial" in optdict: serial_arg = "-s %s"%optdict['serial']
+                build_sh_options=""
+                if "cramfs" in build_sh_spec: 
+                    type += "_cramfs"
+                if "serial" in build_sh_spec: 
+                    build_sh_options += " -s %s"%build_sh_spec['serial']
+                
+                for k_option in build_sh_spec['-k']:
+                    build_sh_options += " -k %s"%k_option
+
                 log_file="%s.log"%node_image
                 # invoke build.sh
                 build_command = '%s -f "%s" -o "%s" -t "%s" %s &> %s' % (self.BOOTCDBUILD,