+ build_sh_options=""
+ if "cramfs" in build_sh_spec:
+ type += "_cramfs"
+ if "serial" in build_sh_spec:
+ build_sh_options += " -s {}".format(build_sh_spec['serial'])
+ if "variant" in build_sh_spec:
+ build_sh_options += " -V {}".format(build_sh_spec['variant'])
+
+ for karg in build_sh_spec['kargs']:
+ build_sh_options += ' -k "{}"'.format(karg)
+
+ import time
+ date = time.strftime('%Y-%m-%d-%H-%M', time.gmtime())
+ if not os.path.isdir(self.LOGDIR):
+ os.makedirs(self.LOGDIR)
+ log_file = "{}/{}-{}.log".format(self.LOGDIR, date, nodename)
+
+ command = '{} -f "{}" -o "{}" -t "{}" {} > {} 2>&1'\
+ .format(self.BOOTCDBUILD,
+ floppy_file,
+ node_image,
+ type,
+ build_sh_options,
+ log_file)
+
+ print >> log, "The build command line is {}".format(command)
+
+ return command, log_file
+
+ def call(self, auth, node_id_or_hostname, action, filename, options = []):
+
+ self.trash=[]
+
+ ### compute file suffix and type
+ if action.find("-iso") >= 0 :
+ suffix = ".iso"
+ type = "iso"
+ elif action.find("-usb") >= 0:
+ suffix = ".usb"
+ type = "usb"
+ else:
+ suffix = ".txt"
+ type = "txt"
+
+ # check for node existence and get node_type
+ nodes = Nodes(self.api, [node_id_or_hostname])
+ if not nodes:
+ raise PLCInvalidArgument("No such node {}".format(node_id_or_hostname))
+ node = nodes[0]
+
+ print >> log, "GetBootMedium: {} requested on node {}. Node type is: {}"\
+ .format(action, node['node_id'], node['node_type'])
+
+ # check the required action against the node type
+ node_type = node['node_type']
+ if action not in allowed_actions[node_type]:
+ raise PLCInvalidArgument("Action {} not valid for {} nodes, valid actions are {}"\
+ .format(action, node_type, "|".join(allowed_actions[node_type])))
+
+ # handle / canonicalize options
+ if type == "txt":
+ if options:
+ raise PLCInvalidArgument("Options are not supported for node configs")
+ else:
+ # create a dict for build.sh
+ build_sh_spec={'kargs':[]}
+ # use node tags as defaults
+ # check for node tag equivalents
+ tags = NodeTags(self.api,
+ {'node_id': node['node_id'],
+ 'tagname': ['serial', 'cramfs', 'kvariant', 'kargs',
+ 'no-hangcheck', 'systemd-debug' ]},
+ ['tagname', 'value'])
+ if tags:
+ for tag in tags:
+ if tag['tagname'] == 'serial':
+ build_sh_spec['serial'] = tag['value']
+ elif tag['tagname'] == 'cramfs':
+ build_sh_spec['cramfs'] = True
+ elif tag['tagname'] == 'kvariant':
+ build_sh_spec['variant'] = tag['value']
+ elif tag['tagname'] == 'kargs':
+ build_sh_spec['kargs'] += tag['value'].split()
+ elif tag['tagname'] == 'no-hangcheck':
+ build_sh_spec['kargs'].append('hcheck_reboot0')
+ elif tag['tagname'] == 'systemd-debug':
+ build_sh_spec['kargs'].append('systemd.log_level=debug')
+ build_sh_spec['kargs'].append('systemd.log_target=console')
+ # then options can override tags
+ for option in options:
+ if option == "cramfs":
+ 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":
+ build_sh_spec['serial']='default'
+ elif option.find("serial:") == 0:
+ build_sh_spec['serial']=option.replace("serial:","")
+ elif option.find("variant:") == 0:
+ build_sh_spec['variant']=option.replace("variant:","")
+ elif option == "no-hangcheck":
+ build_sh_spec['kargs'].append('hcheck_reboot0')
+ elif option == "systemd-debug":
+ build_sh_spec['kargs'].append('systemd.log_level=debug')
+ else:
+ raise PLCInvalidArgument("unknown option {}".format(option))
+
+ # compute nodename according the action
+ if action.find("node-") == 0:
+ nodename = node['hostname']
+ else:
+ node = None
+ # compute a 8 bytes random number
+ tempbytes = random.sample (xrange(0,256), 8);
+ def hexa2 (c): return chr((c>>4)+65) + chr ((c&16)+65)
+ nodename = "".join(map(hexa2,tempbytes))
+
+ # get nodefamily
+ (pldistro,fcdistro,arch) = self.get_nodefamily(node, auth)
+ self.nodefamily="{}-{}-{}".format(pldistro, fcdistro, arch)
+
+ # apply on globals
+ for attr in [ "BOOTCDDIR", "BOOTCDBUILD", "GENERICDIR" ]:
+ setattr(self,attr,getattr(self,attr).replace("@NODEFAMILY@",self.nodefamily))
+
+ filename = self.handle_filename(filename, nodename, suffix, arch)
+
+ # log call
+ if node:
+ self.message='GetBootMedium on node {} - action={}'.format(nodename, action)
+ self.event_objects={'Node': [ node ['node_id'] ]}
+ else:
+ self.message='GetBootMedium - generic - action={}'.format(action)
+