def test_processTemplate_does_not_produce_duplicates(self): recipeTemplate = BeakerRecipe() # with passed-in distroRequires XML recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{'name': '/example', 'arches': []}], distroRequires='<distroRequires><distro_name op="=" value="RHEL99-U1" /></distroRequires>', family='RedHatEnterpriseLinux99') xml = recipe.toxml(prettyxml=True) self.assertEquals(len(re.findall('<distro_name', xml)), 1, xml) # with passed-in hostRequires XML recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{'name': '/example', 'arches': []}], hostRequires='<hostRequires><hostname op="=" value="lolcat.example.invalid" /></hostRequires>', family='RedHatEnterpriseLinux99') xml = recipe.toxml(prettyxml=True) self.assertEquals(len(re.findall('<hostname', xml)), 1, xml) # with distroRequires and hostRequires in the template recipeTemplate.addBaseRequires(distro='RHEL99-U1', machine='lolcat.example.invalid') recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{'name': '/example', 'arches': []}], family='RedHatEnterpriseLinux99') xml = recipe.toxml(prettyxml=True) self.assertEquals(len(re.findall('<distro_name', xml)), 1, xml) self.assertEquals(len(re.findall('<hostname', xml)), 1, xml)
def test_distro_wildcard(self): recipeTemplate = BeakerRecipe() recipeTemplate.addBaseRequires(distro='RHEL-7.1%') recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{'name': '/example', 'arches': []}]) xml = recipe.toxml(prettyxml=True) self.assertIn('<distro_name op="like" value="RHEL-7.1%"/>', xml)
def test_hostrequire_accepts_like_operator(self): recipeTemplate = BeakerRecipe() recipeTemplate.addBaseRequires(hostrequire=['hostname like %.khw.%']) recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{'name': '/example', 'arches': []}]) xml = recipe.toxml() self.assertIn('<hostname op="like" value="%.khw.%"/>', xml)
def run(self, *args, **kwargs): self.set_hub(**kwargs) debug = kwargs.pop('debug', False) dryrun = kwargs.pop('dryrun', False) wait = kwargs.pop('wait', False) taskParams = kwargs.pop('taskparam', []) families = kwargs.pop('family', []) kwargs.pop('variant', None) kwargs.pop('arch', None) if not kwargs.get('whiteboard'): kwargs['whiteboard'] = 'Test harness installation' if not families: families = self.getOsMajors(**kwargs) # filter out any junky old distros with no family families = [f for f in families if f] fva = set() # all family-variant-arch combinations for family in families: dts = self.hub.distrotrees.filter({'family': family}) for dt in dts: fva.add((family, dt['variant'] or '', dt['arch'])) # if this family has any variants, discard combinations which have blank variant if any(f == family and v for f, v, a in fva): fva.difference_update([(f, v, a) for f, v, a in fva if f == family and not v]) job = BeakerJob(**kwargs) for family, variant, arch in sorted(fva): requestedTasks = self.getTasks(family=family, **kwargs) recipe = BeakerRecipe() recipe.addBaseRequires(family=family, variant=variant, arch=arch, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe = self.processTemplate(recipe, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, family=family, allow_empty_recipe=True, **kwargs) recipe.whiteboard = ' '.join([family, variant, arch]) recipeset = BeakerRecipeSet(**kwargs) recipeset.addRecipe(recipe) job.addRecipeSet(recipeset) jobxml = job.toxml(**kwargs) if debug: print jobxml submitted_jobs = [] failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) except Exception, ex: failed = True print >>sys.stderr, ex
def _req_to_bkr_job(self, req): """Transform requirement to beaker job xml.""" specs = deepcopy(req) # work with own copy, do not modify the input # Job attributes: specs.update({"retention_tag": "audit"}) specs.update({"product": "[internal]"}) specs.update({"whiteboard": "This job has been created using mrack."}) # RecipeSet attributes specs.update({"priority": "Normal"}) # Add allowed keys specs.update({"ks_append": self._allow_ssh_key(self.pubkey)}) # Use ks_meta specs.update({"ks_meta": "harness='restraint-rhts beakerlib-redhat'"}) # Recipe task definition specs.update( { # we use dummy task because beaker reuire a task in recipe "tasks": [{ "name": "/distribution/dummy", "role": "STANDALONE" }] }) # Create recipe with the specifications recipe = BeakerRecipe(**specs) recipe.addBaseRequires(**specs) # Specify the architecture arch_node = xml_doc().createElement("distro_arch") arch_node.setAttribute("op", "=") arch_node.setAttribute("value", specs["arch"]) recipe.addDistroRequires(arch_node) # Add ReserveSys element to reserve system after provisioning recipe.addReservesys(duration=str(self.reserve_duration)) for task in specs["tasks"]: recipe.addTask(task=task["name"], role=task["role"]) # Create RecipeSet and add our Recipe to it. recipe_set = BeakerRecipeSet(**specs) recipe_set.addRecipe(recipe) # Create job instance and inject created RecipeSet to it job = BeakerJob(**specs) job.addRecipeSet(recipe_set) return job
def test_processPartitions(self): recipe = BeakerRecipe() recipe.addPartition(name='/mnt/block1',type='part', fs='ext3', size=1024) xml = recipe.toxml() self.assertEquals(xml, '<recipe whiteboard="">' '<distroRequires>' '<and/>' '</distroRequires>' '<hostRequires/>' '<repos/>' '<partitions>' '<partition fs="ext3" name="/mnt/block1" size="1024" type="part"/>' '</partitions>' '</recipe>')
def test_processPartitions(self): recipe = BeakerRecipe() recipe.addPartition(name='/mnt/block1',type='part', fs='ext3', size=1024) xml = recipe.toxml(prettyxml=True) self.assertEquals(xml.strip(), """ <recipe whiteboard=""> <distroRequires> <and/> </distroRequires> <hostRequires> <and/> </hostRequires> <repos/> <partitions> <partition fs="ext3" name="/mnt/block1" size="1024" type="part"/> </partitions> </recipe> """.strip())
def recipe(self, harness, distro, variant, arch, task_names, role='STANDALONE', **kwargs): ks_meta = kwargs.pop('ks_meta') or '' extra_whiteboard = '' if 'Fedora' in distro: ks_meta += ' no_updates_repos' if harness: extra_whiteboard = '(harness=%s)' % harness ks_meta += ' harness=%s' % harness recipe = BeakerRecipe(**kwargs) recipe.addBaseRequires(distro=distro, variant=variant, ks_meta=ks_meta, **kwargs) arch_require = self.doc.createElement('distro_arch') arch_require.setAttribute('op', '=') arch_require.setAttribute('value', arch) return self.processTemplate(recipe, requestedTasks=[{'name': task_name, 'arches': []} for task_name in task_names], distroRequires=[arch_require], whiteboard='%s %s %s %s %s' % (distro, variant, arch, role, extra_whiteboard), role=role, **kwargs)
def test_processTemplate_minimal_recipe(self): recipeTemplate = BeakerRecipe() recipe = self.command.processTemplate(recipeTemplate, [{'name': '/example', 'arches': []}]) xml = recipe.toxml() self.assertEquals(xml, '<recipe whiteboard="">' '<distroRequires>' '<and/>' '</distroRequires>' '<hostRequires/>' '<repos/>' '<partitions/>' '<task name="/distribution/install" role="STANDALONE">' '<params/>' '</task>' '<task name="/example" role="STANDALONE">' '<params/>' '</task>' '</recipe>')
def run(self, *args, **kwargs): self.set_hub(**kwargs) debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) machine = kwargs.get("machine", None) families = kwargs.get("family", []) taskParams = kwargs.get("taskparam", []) # Add in Inventory if requested if kwargs.get("inventory"): kwargs['task'].append('/distribution/inventory') if not machine: self.parser.error('Use --machine to specify machine to be tested') if not kwargs.get("whiteboard"): kwargs["whiteboard"] = "Test %s" % machine # If family is specified on command line just do it. if kwargs['family']: if not kwargs['arches']: self.parser.error("If family is specified you must specify arches as well") families = dict((family, [arch for arch in kwargs['arches']]) for family in kwargs['family']) else: families = self.getSystemOsMajorArches(*args, **kwargs) # Exit early if not families: print >>sys.stderr, 'Could not find an appropriate distro to provision system with.' sys.exit(1) # Create Job job = BeakerJob(*args, **kwargs) for family, arches in families.items(): kwargs['family'] = family # Start with install task requestedTasks = [dict(name='/distribution/install', arches=[])] # get all tasks requested requestedTasks.extend(self.getTasks(*args, **kwargs)) # If arch is specified on command line limit to just those. (if they match) if kwargs['arches']: arches = set(kwargs['arches']).intersection(set(arches)) for arch in arches: recipeTemplate = BeakerRecipe() # Add Distro Requirements temp = dict(kwargs) temp['family'] = family recipeTemplate.addBaseRequires(*args, **temp) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, **temp)) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml submitted_jobs = [] failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) except Exception, ex: failed = True print >>sys.stderr, ex
def run(self, *args, **kwargs): debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) family = kwargs.get("family", None) distro = kwargs.get("distro", None) arches = kwargs.get("arches", []) taskParams = kwargs.get("taskparam", []) ksTemplate = kwargs.get("template", None) # todo: fetch family mapping based on distro from the server if not family and not distro: sys.stderr.write("No Family or Distro specified\n") sys.exit(1) if not arches: sys.stderr.write( "No arches specified, you must specify at least one\n") sys.exit(1) if not ksTemplate: sys.stderr.write( "You must specify kickstart template to run this workflow\n") sys.exit(1) if family: kwargs['os_major'] = int(self._get_os_major_version(family)) else: # get family data based on distro if not hasattr(self, 'hub'): self.set_hub(**kwargs) # this will return info about all arches and variants # but the family string is the same so break after the first iteration for distro in self.hub.distrotrees.filter({ 'name': distro, 'family': family }): family = distro[ "distro_osmajor"] # e.g. RedHatEnterpriseLinux6 os_version = distro[ "distro_osversion"] # e.g. RedHatEnterpriseLinux6.3 kwargs["os_major"] = int(self._get_os_major_version(family)) kwargs["family"] = family kwargs["os_minor"] = int( os_version.replace(family, "").replace(".", "")) break # Add kickstart and kernel options ks_args = {} # make ksmeta from command line options and taskParams for parameter in [ "distro", "family", "variant", "os_major", "os_minor" ]: if kwargs.get(parameter, None): ks_args[parameter.upper()] = kwargs.get(parameter) # allow taskParams to override existing values try: for param in taskParams: (name, value) = param.split('=', 1) # use both upper case and regular case variable names ks_args[name.upper()] = value ks_args[name] = value except: print >> sys.stderr, "Every task param has to have a value." sys.exit(1) if kwargs['kernel_options'] is None: kwargs['kernel_options'] = "" pristine_kernel_options = kwargs['kernel_options'] # get all tasks requested requestedTasks = self.getTasks(*args, **kwargs) # Create Job job = BeakerJob(*args, **kwargs) # Add Host Requirements for arch in arches: ks_args["ARCH"] = arch # Create Base Recipe recipeTemplate = BeakerRecipe() # get kickstart and add it to recipes kickstart = generateKickstart(ksTemplate, ks_args) kernel_options = generateKernelOptions(ksTemplate, ks_args) kwargs[ 'kernel_options'] = pristine_kernel_options + " " + kernel_options kwargs['kernel_options'] = kwargs['kernel_options'].strip() recipeTemplate.addKickstart(kickstart) # Add Distro Requirements recipeTemplate.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) if self.multi_host: for i in range(self.n_servers): recipeSet.addRecipe( self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='SERVERS', arch=arch, **kwargs)) for i in range(self.n_clients): recipeSet.addRecipe( self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='CLIENTS', arch=arch, **kwargs)) job.addRecipeSet(recipeSet) else: recipe = self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, **kwargs) recipeSet.addRecipe(recipe) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml if not dryrun: if not hasattr(self, 'hub'): self.set_hub(**kwargs) try: job = self.hub.jobs.upload(jobxml) except Exception, ex: print >> sys.stderr, unicode(ex) sys.exit(1) else: print "Submitted: %s" % job
def run(self, *args, **kwargs): self.set_hub(**kwargs) debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) machine = kwargs.get("machine", None) family = kwargs.get("family", []) taskParams = kwargs.get("taskparam", []) # Add in Inventory if requested if kwargs.get("inventory"): kwargs['task'].append('/distribution/inventory') if not machine: self.parser.error('Use --machine to specify machine to be tested') if not kwargs.get("whiteboard"): kwargs["whiteboard"] = "Test %s" % machine # If family is specified on command line just do it. if family: if not kwargs['arches']: self.parser.error( "If family is specified you must specify arches as well") families = dict((family, [arch for arch in kwargs['arches']]) for family in family) else: families = self.get_system_os_major_arches(*args, **kwargs) # Exit early if not families: sys.stderr.write( 'Could not find an appropriate distro to provision system with.' ) sys.exit(1) # Create Job job = BeakerJob(*args, **kwargs) for family, arches in families.items(): kwargs['family'] = family # get all tasks requested requestedTasks = self.get_tasks(*args, **kwargs) # If arch is specified on command line limit to just those. (if they match) if kwargs['arches']: arches = set(kwargs['arches']).intersection(set(arches)) for arch in arches: recipeTemplate = BeakerRecipe() # Add Distro Requirements temp = dict(kwargs) temp['family'] = family recipeTemplate.add_base_requires(*args, **temp) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) recipe_set.add_recipe( self.process_template(recipeTemplate, requestedTasks, taskParams=taskParams, allow_empty_recipe=True, distroRequires=arch_node, **temp)) job.add_recipe_set(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: print(jobxml) submitted_jobs = [] failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) except Exception as ex: failed = True sys.stderr.write(ex) if not dryrun: print("Submitted: %s" % submitted_jobs) if wait: watch_tasks(self.hub, submitted_jobs) if failed: sys.exit(1)
def run(self, *args, **kwargs): self.set_hub(**kwargs) # get all tasks requested requestedTasks = self.getTasks(*args, **kwargs) debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) family = kwargs.get("family", None) distro = kwargs.get("distro", None) arches = kwargs.get("arches", []) taskParams = kwargs.get("taskparam", []) if not family and not distro: sys.stderr.write("No Family or Distro specified\n") sys.exit(1) if not arches: # Get default arches that apply for this distro/family arches = self.getArches(*args, **kwargs) if not requestedTasks: sys.stderr.write("You must specify a package, type or task to run\n") sys.exit(1) # Create Job job = BeakerJob(*args, **kwargs) # Create Base Recipe recipeTemplate = BeakerRecipe() # Add Distro Requirements recipeTemplate.addBaseRequires(*args, **kwargs) # Add Host Requirements for arch in arches: arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) if self.multi_host: for i in range(self.n_servers): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='SERVERS', arch=arch, **kwargs)) for i in range(self.n_clients): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='CLIENTS', arch=arch, **kwargs)) else: recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, **kwargs)) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml submitted_jobs = [] is_failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) print "Submitted: %s" % submitted_jobs except (KeyboardInterrupt, SystemExit): raise except Exception, ex: is_failed = True sys.stderr.write('Exception: %s\n' % ex) if wait: is_failed |= watch_tasks(self.hub, submitted_jobs)
def provision(self, *args, **kwargs): """ provision resources in Beaker """ # Break down kwargs for debug, dryrun, recipesets, and whiteboard debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) recipesets = kwargs.get("recipesets", []) keys_path = kwargs.get('ssh_keys_path', '') # Create Job job = BeakerJob(*args, **kwargs) # Add All Host Requirements for recipeset in recipesets: kwargs = self.create_recipesets(recipeset, **kwargs) family = kwargs.get("family", None) distro = kwargs.get("distro", None) task_params = kwargs.get("taskparam", []) # tasks are list of dictionaries which follows format # for beaker in a box # tasks = [ {arches:[], 'name': '/distribution/utils/dummy'}] # for beaker production # tasks = [ {arches:[], 'name': '/distribution/dummy'}] tasks = kwargs.get("tasks", [{ 'arches': [], 'name': '/distribution/dummy' }]) arch = kwargs.get("arch", "x86_64") ks_meta = kwargs.get("ks_meta", "") method = kwargs.get("method", "nfs") priority = kwargs.get("priority", "Normal") hostrequires = kwargs.get("hostrequires", []) reserve_duration = kwargs.get("reserve_duration", None) if reserve_duration: kwargs.update({"reserve_duration": "%s" % reserve_duration}) tags = kwargs.get("tags", []) if tags: kwargs.update({"tag": tags}) repos = kwargs.get("repos", []) baseurls = [] for repo in repos: if "baseurl" in repo: baseurls.append(repo.get("baseurl")) else: kwargs.update({"repo": baseurls}) ks_append = kwargs.get("ks_append", []) ssh_key = kwargs.get("ssh_key", []) for key_file in kwargs.get("ssh_key_file", []): file_path = os.path.join(keys_path, key_file) try: with open(file_path, "r") as f: ssh_key.append(f.read()) except (OSError, IOError): LOG.info("Unable to read from ssh key file: %s" % file_path) if ssh_key: ks_append.append("""%%post mkdir -p /root/.ssh cat >>/root/.ssh/authorized_keys << "__EOF__" %s __EOF__ restorecon -R /root/.ssh chmod go-w /root /root/.ssh /root/.ssh/authorized_keys %%end""" % '\n'.join(ssh_key)) kwargs.update({"ks_append": ks_append}) requested_tasks = [] # adding arches=[] to every task definition for task in tasks: if not ('arches' in list(task.keys())): task['arches'] = [] requested_tasks.append(task) # Tasks and harnesses if 'harness' in ks_meta: # Disable report plugins task_params.append("RSTRNT_DISABLED=01_dmesg_check " "10_avc_check") # Reserve the system after its installed kwargs.update({"reserve": True}) else: requested_tasks.append({ 'arches': [], 'name': '/distribution/reservesys' }) if reserve_duration: task_params.append("RESERVETIME=%s" % reserve_duration) # Update defaults kwargs.update({"suppress_install_task": True}) kwargs.update({"method": method}) kwargs.update({"priority": priority}) # Must have family or distro if not family and not distro and not arch: sys.stderr.write("No Family or Distro and arch specified\n") sys.exit(1) if not requested_tasks: sys.stderr.write("You must specify a task to run\n") sys.exit(1) # Create Workflow wrkflow = BeakerWorkflow('BeakerWorkflow') # Create Base Recipe recipe_template = BeakerRecipe(*args, **kwargs) # Add Host Requirements for requirement in hostrequires: if 'force' in requirement: # hostRequires element is created by BeakerRecipe, use it hostrequires_node = recipe_template.node.getElementsByTagName( 'hostRequires')[0] # noqa E501 # all other filters are ignored if the hostname is forced, # so the use of 'force' is mutually exclusive with the use # of any other 'hostRequires' filters hostrequires_node.setAttribute('force', requirement['force']) elif 'rawxml' in requirement: requirement_node = xml.dom.minidom.parseString( requirement['rawxml']).documentElement recipe_template.addHostRequires(requirement_node) else: # If force is not used, a requirement can be any number # of differently formatted XML elements, each with their # own combination of element name and valid attrs. So, # the best we can do is generate XML based on the input, # and only the "tag" key is required. tag_name = requirement['tag'] requirement_node = self.doc.createElement(tag_name) for attr, value in requirement.items(): # Force all values to str, which the XML writer expects. requirement_node.setAttribute(attr, str(value)) # use the BeakerRecipe API to add the element recipe_template.addHostRequires(requirement_node) # Add Distro Requirements recipe_template.addBaseRequires(*args, **kwargs) for partition in kwargs.get("partitions", []): recipe_template.addPartition(**partition) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) if wrkflow.multi_host: for i in range(self.n_servers): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='SERVERS', **kwargs)) for i in range(self.n_clients): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='CLIENTS', **kwargs)) else: recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: LOG.debug(jobxml) self.submitted_jobs = [] if not dryrun: self.submitted_jobs.append(self.hub.jobs.upload(jobxml)) LOG.info("Submitted: %s" % self.submitted_jobs) return self.submitted_jobs
def run(self, *args, **kwargs): self.set_hub(**kwargs) debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) family = kwargs.get("family", None) distro = kwargs.get("distro", None) machine = kwargs.get("machine", None) arches = kwargs.get("arches", []) if machine: kwargs['ignore_system_status'] = True if not arches: arches = [self.default_distro_tree(machine)['arch']] if not family and not distro: kwargs['distro'] = self.default_distro_tree( machine)['distro']['name'] else: if not family and not distro: sys.stderr.write("No Family or Distro specified\n") sys.exit(1) # defaults to 'x86_64' instead of all the known arches if not arches: arches = ['x86_64'] kwargs['reserve'] = True # Create Job job = BeakerJob(*args, **kwargs) # Create Base Recipe recipeTemplate = BeakerRecipe() # Add Distro Requirements recipeTemplate.addBaseRequires(*args, **kwargs) for arch in arches: arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) recipeSet.addRecipe( self.processTemplate(recipeTemplate, [], distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml if not dryrun: try: job = self.hub.jobs.upload(jobxml) print "Submitted: %s" % job except (KeyboardInterrupt, SystemExit): raise except Exception, ex: sys.stderr.write('Exception: %s\n' % ex) sys.exit(1) if wait: sys.exit(watch_tasks(self.hub, [job]))
def provision(self, *args, **kwargs): """ provision resources in Beaker """ # Break down kwargs for debug, dryrun, recipesets, and whiteboard debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) recipesets = kwargs.get("recipesets", []) # Create Job job = BeakerJob(*args, **kwargs) # Add All Host Requirements for recipeset in recipesets: kwargs = self.create_recipesets(recipeset, **kwargs) family = kwargs.get("family", None) distro = kwargs.get("distro", None) task_params = kwargs.get("taskparam", []) # tasks are list of dictionaries which follows format # for beaker in a box # tasks = [ {arches:[], 'name': '/distribution/utils/dummy'}] # for beaker production # tasks = [ {arches:[], 'name': '/distribution/dummy'}] tasks = kwargs.get("tasks", [{ 'arches': [], 'name': '/distribution/dummy' }]) arch = kwargs.get("arch", "x86_64") ks_meta = kwargs.get("ks_meta", "") method = kwargs.get("method", "nfs") priority = kwargs.get("priority", "Normal") hostrequires = kwargs.get("hostrequires", []) reserve_duration = kwargs.get("reserve_duration", None) if reserve_duration: kwargs.update({"reserve_duration": "%s" % reserve_duration}) tags = kwargs.get("tags", []) if tags: kwargs.update({"tag": tags}) requested_tasks = [] # adding arches=[] to every task definition for task in tasks: if not ('arches' in task.keys()): task['arches'] = [] requested_tasks.append(task) # Tasks and harnesses if 'harness' in ks_meta: # Disable report plugins task_params.append("RSTRNT_DISABLED=01_dmesg_check " "10_avc_check") # Reserve the system after its installed kwargs.update({"reserve": True}) # We don't need to run a task but beaker needs one. # therefore its defaulted to # [{arches:[], 'name': '/distribution/dummy'}] # if no repos are defined but with no value use default repo # This default will not work for Fedora repos = kwargs.get("repos", [ "http://file.bos.redhat.com/~bpeck/restraint/rhel" "$releasever" ]) kwargs.update({'repo': repos}) else: requested_tasks.append({ 'arches': [], 'name': '/distribution/reservesys' }) # Update defaults kwargs.update({"suppress_install_task": True}) kwargs.update({"method": method}) kwargs.update({"priority": priority}) # Must have family or distro if not family and not distro and not arch: sys.stderr.write("No Family or Distro and arch specified\n") sys.exit(1) if not requested_tasks: sys.stderr.write("You must specify a task to run\n") sys.exit(1) # Create Workflow wrkflow = BeakerWorkflow('BeakerWorkflow') # Create Base Recipe recipe_template = BeakerRecipe(*args, **kwargs) # Add Host Requirements for requirement in hostrequires: if 'force' in requirement: # hostRequires element is created by BeakerRecipe, use it hostrequires_node = recipe_template.node.getElementsByTagName( 'hostRequires')[0] # noqa E501 # all other filters are ignored if the hostname is forced, # so the use of 'force' is mutually exclusive with the use # of any other 'hostRequires' filters hostrequires_node.setAttribute('force', requirement['force']) elif 'rawxml' in requirement: requirement_node = xml.dom.minidom.parseString( requirement['rawxml']).documentElement recipe_template.addHostRequires(requirement_node) else: # If force is not used, a requirement can be any number # of differently formatted XML elements, each with their # own combination of element name and valid attrs. So, # the best we can do is generate XML based on the input, # and only the "tag" key is required. tag_name = requirement['tag'] requirement_node = self.doc.createElement(tag_name) for attr, value in requirement.items(): # Force all values to str, which the XML writer expects. requirement_node.setAttribute(attr, str(value)) # use the BeakerRecipe API to add the element recipe_template.addHostRequires(requirement_node) # Add Distro Requirements recipe_template.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) if wrkflow.multi_host: for i in range(self.n_servers): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='SERVERS', **kwargs)) for i in range(self.n_clients): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='CLIENTS', **kwargs)) else: recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: LOG.debug(jobxml) self.submitted_jobs = [] if not dryrun: self.submitted_jobs.append(self.hub.jobs.upload(jobxml)) LOG.info("Submitted: %s" % self.submitted_jobs) return self.submitted_jobs
def provision(self, *args, **kwargs): """ provision resources in Beaker """ # Break down kwargs for debug, dryrun, wait, and recipesets debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) recipesets = kwargs.get("recipesets", []) # Create Job job = BeakerJob(*args, **kwargs) # Add All Host Requirements for recipeset in recipesets: kwargs = self.create_recipesets(recipeset, **kwargs) family = kwargs.get("family", None) distro = kwargs.get("distro", None) task_params = kwargs.get("taskparam", []) arch = kwargs.get("arch", None) ks_meta = kwargs.get("ks_meta", "") method = kwargs.get("method", "nfs") priority = kwargs.get("priority", "Normal") # Tasks and harnesses if 'harness' in ks_meta: # Disable report plugins task_params.append("RSTRNT_DISABLED=01_dmesg_check " "10_avc_check") # Reserve the system after its installed kwargs.update({"reserve": True}) # We don't need to run a task but beaker needs one. requested_tasks = \ [{'arches': [], 'name': '/distribution/dummy'}] # if no repos are defined but with no value use default repo # This default will not work for Fedora repos = kwargs.get("repos", [ "http://file.bos.redhat.com/~bpeck/restraint/rhel" "$releasever" ]) kwargs.update({'repo': repos}) else: requested_tasks = \ [{'arches': [], 'name': '/distribution/dummy'}, {'arches': [], 'name': '/distribution/reservesys'}] # Update defaults kwargs.update({"suppress_install_task": True}) kwargs.update({"method": method}) kwargs.update({"priority": priority}) # Must have family or distro if not family and not distro and not arch: sys.stderr.write("No Family or Distro and arch specified\n") sys.exit(1) if not requested_tasks: sys.stderr.write("You must specify a task to run\n") sys.exit(1) # Create Workflow wrkflow = BeakerWorkflow('BeakerWorkflow') # Create Base Recipe recipe_template = BeakerRecipe(*args, **kwargs) # Add Distro Requirements recipe_template.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) if wrkflow.multi_host: for i in range(self.n_servers): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='SERVERS', **kwargs)) for i in range(self.n_clients): recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='CLIENTS', **kwargs)) else: recipe_set.addRecipe( wrkflow.processTemplate(recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: LOG.debug(jobxml) self.submitted_jobs = [] is_failed = False if not dryrun: try: self.submitted_jobs.append(self.hub.jobs.upload(jobxml)) LOG.info("Submitted: %s" % self.submitted_jobs) return self.submitted_jobs except (KeyboardInterrupt, SystemExit): raise except Exception, ex: is_failed = True sys.stderr.write('Exception: %s\n' % ex) if wait: is_failed |= watch_tasks(self.hub, self.submitted_jobs)
def run(self, *args, **kwargs): sys.stderr.write('workflow-installer-test is deprecated, use --kickstart with workflow-simple or any other workflow command') debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) family = kwargs.get("family", None) distro = kwargs.get("distro", None) arches = kwargs.get("arches", []) taskParams = kwargs.get("taskparam", []) ksTemplate = kwargs.get("template", None) # todo: fetch family mapping based on distro from the server if not family and not distro: sys.stderr.write("No Family or Distro specified\n") sys.exit(1) if not arches: sys.stderr.write("No arches specified, you must specify at least one\n") sys.exit(1) if not ksTemplate: sys.stderr.write("You must specify kickstart template to run this workflow\n") sys.exit(1) if family: kwargs['os_major'] = int(self._get_os_major_version(family)) else: # get family data based on distro if not hasattr(self,'hub'): self.set_hub(**kwargs) # this will return info about all arches and variants # but the family string is the same so break after the first iteration for distro in self.hub.distrotrees.filter({'name': distro, 'family': family}): family = distro["distro_osmajor"] # e.g. RedHatEnterpriseLinux6 os_version = distro["distro_osversion"] # e.g. RedHatEnterpriseLinux6.3 kwargs["os_major"] = int(self._get_os_major_version(family)) kwargs["family"] = family kwargs["os_minor"] = int(os_version.replace(family, "").replace(".", "")) break # Add kickstart and kernel options ks_args = {} # make ksmeta from command line options and taskParams for parameter in ["distro", "family", "variant", "os_major", "os_minor"]: if kwargs.get(parameter, None): ks_args[parameter.upper()] = kwargs.get(parameter) # allow taskParams to override existing values try: for param in taskParams: (name, value) = param.split('=', 1) # use both upper case and regular case variable names ks_args[name.upper()] = value ks_args[name] = value except: print >>sys.stderr, "Every task param has to have a value." sys.exit(1) if kwargs['kernel_options'] is None: kwargs['kernel_options'] = "" pristine_kernel_options = kwargs['kernel_options'] # get all tasks requested requestedTasks = self.getTasks(*args, **kwargs) # Create Job job = BeakerJob(*args, **kwargs) # Add Host Requirements for arch in arches: ks_args["ARCH"] = arch # Create Base Recipe recipeTemplate = BeakerRecipe() # get kickstart and add it to recipes kickstart = generateKickstart(ksTemplate, ks_args) kernel_options = generateKernelOptions(ksTemplate, ks_args) kwargs['kernel_options'] = pristine_kernel_options + " " + kernel_options kwargs['kernel_options'] = kwargs['kernel_options'].strip() recipeTemplate.addKickstart(kickstart) # Add Distro Requirements recipeTemplate.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) if self.multi_host: for i in range(self.n_servers): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='SERVERS', arch=arch, **kwargs)) for i in range(self.n_clients): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='CLIENTS', arch=arch, **kwargs)) job.addRecipeSet(recipeSet) else: recipe = self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, **kwargs) recipeSet.addRecipe(recipe) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml if not dryrun: if not hasattr(self,'hub'): self.set_hub(**kwargs) try: job = self.hub.jobs.upload(jobxml) except Exception, ex: print >>sys.stderr, unicode(ex) sys.exit(1) else: print "Submitted: %s" % job
def provision(self, *args, **kwargs): """ provision resources in Beaker """ # Break down kwargs for debug, dryrun, wait, and recipesets debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) recipesets = kwargs.get("recipesets", []) # Create Job job = BeakerJob(*args, **kwargs) # Add All Host Requirements for recipeset in recipesets: kwargs = self.create_recipesets(recipeset, **kwargs) family = kwargs.get("family", None) distro = kwargs.get("distro", None) task_params = kwargs.get("taskparam", []) arch = kwargs.get("arch", None) ks_meta = kwargs.get("ks_meta", "") method = kwargs.get("method", "nfs") priority = kwargs.get("priority", "Normal") # Tasks and harnesses if 'harness' in ks_meta: # Disable report plugins task_params.append("RSTRNT_DISABLED=01_dmesg_check " "10_avc_check") # Reserve the system after its installed kwargs.update({"reserve": True}) # We don't need to run a task but beaker needs one. requested_tasks = \ [{'arches': [], 'name': '/distribution/dummy'}] # if no repos are defined but with no value use default repo # This default will not work for Fedora repos = kwargs.get( "repos", ["http://file.bos.redhat.com/~bpeck/restraint/rhel" "$releasever"] ) kwargs.update({'repo': repos}) else: requested_tasks = \ [{'arches': [], 'name': '/distribution/dummy'}, {'arches': [], 'name': '/distribution/reservesys'}] # Update defaults kwargs.update({"suppress_install_task": True}) kwargs.update({"method": method}) kwargs.update({"priority": priority}) # Must have family or distro if not family and not distro and not arch: sys.stderr.write("No Family or Distro and arch specified\n") sys.exit(1) if not requested_tasks: sys.stderr.write("You must specify a task to run\n") sys.exit(1) # Create Workflow wrkflow = BeakerWorkflow('BeakerWorkflow') # Create Base Recipe recipe_template = BeakerRecipe(*args, **kwargs) # Add Distro Requirements recipe_template.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) if wrkflow.multi_host: for i in range(self.n_servers): recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='SERVERS', **kwargs)) for i in range(self.n_clients): recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='CLIENTS', **kwargs)) else: recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: LOG.debug(jobxml) self.submitted_jobs = [] is_failed = False if not dryrun: try: self.submitted_jobs.append(self.hub.jobs.upload(jobxml)) LOG.info("Submitted: %s" % self.submitted_jobs) return self.submitted_jobs except (KeyboardInterrupt, SystemExit): raise except Exception, ex: is_failed = True sys.stderr.write('Exception: %s\n' % ex) if wait: is_failed |= watch_tasks(self.hub, self.submitted_jobs)
def run(self, *args, **kwargs): self.set_hub(**kwargs) debug = kwargs.pop('debug', False) dryrun = kwargs.pop('dryrun', False) wait = kwargs.pop('wait', False) taskParams = kwargs.pop('taskparam', []) families = kwargs.pop('family', []) kwargs.pop('variant', None) kwargs.pop('arch', None) if not kwargs.get('whiteboard'): kwargs['whiteboard'] = 'Test harness installation' if not families: families = self.get_os_majors(**kwargs) # filter out any junky old distros with no family families = [f for f in families if f] fva = set() # all family-variant-arch combinations for family in families: dts = self.hub.distrotrees.filter({'family': family}) for dt in dts: fva.add((family, dt['variant'] or '', dt['arch'])) # if this family has any variants, discard combinations which have blank variant if any(f == family and v for f, v, a in fva): fva.difference_update([(f, v, a) for f, v, a in fva if f == family and not v]) job = BeakerJob(**kwargs) for family, variant, arch in sorted(fva): requestedTasks = self.get_tasks(family=family, **kwargs) recipe = BeakerRecipe() recipe.add_base_requires(family=family, variant=variant, arch=arch, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe = self.process_template(recipe, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, family=family, allow_empty_recipe=True, **kwargs) recipe.whiteboard = ' '.join([family, variant, arch]) recipeset = BeakerRecipeSet(**kwargs) recipeset.add_recipe(recipe) job.add_recipe_set(recipeset) jobxml = job.toxml(**kwargs) if debug: print(jobxml) submitted_jobs = [] failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) print("Submitted: %s" % submitted_jobs) except (KeyboardInterrupt, SystemError): raise except Exception as ex: failed = True sys.stderr.write('Exception: %s\n' % ex) if wait: failed |= watch_tasks(self.hub, submitted_jobs) sys.exit(failed)
def run(self, *args, **kwargs): if not kwargs.get("package", []) and not kwargs.get("task", []) \ and not kwargs.get("taskfile", []) and not kwargs.get("type", []): self.parser.error('No tasks specified to be run\nHint: ' 'Use --task, --package, --taskfile or --task-type to select tasks\n') self.set_hub(**kwargs) debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) wait = kwargs.get("wait", False) family = kwargs.get("family", None) distro = kwargs.get("distro", None) arches = kwargs.get("arches", []) taskParams = kwargs.get("taskparam", []) if not family and not distro: sys.stderr.write("No Family or Distro specified\n") sys.exit(1) if not arches: # Get default arches that apply for this distro/family arches = self.getArches(*args, **kwargs) # get all tasks requested try: requestedTasks = self.getTasks(*args, **kwargs) except xmlrpclib.Fault: requestedTasks = None if not requestedTasks: sys.stderr.write("No tasks match the specified option(s)\n") sys.exit(1) # Create Job job = BeakerJob(*args, **kwargs) # Create Base Recipe recipeTemplate = BeakerRecipe() # Add Distro Requirements recipeTemplate.addBaseRequires(*args, **kwargs) # Add Host Requirements for arch in arches: arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipeSet = BeakerRecipeSet(**kwargs) if self.multi_host: for i in range(self.n_servers): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='SERVERS', arch=arch, **kwargs)) for i in range(self.n_clients): recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, role='CLIENTS', arch=arch, **kwargs)) else: recipeSet.addRecipe(self.processTemplate(recipeTemplate, requestedTasks, taskParams=taskParams, distroRequires=arch_node, arch=arch, **kwargs)) job.addRecipeSet(recipeSet) # jobxml jobxml = job.toxml(**kwargs) if debug: print jobxml submitted_jobs = [] is_failed = False if not dryrun: try: submitted_jobs.append(self.hub.jobs.upload(jobxml)) print "Submitted: %s" % submitted_jobs except (KeyboardInterrupt, SystemExit): raise except Exception, ex: is_failed = True sys.stderr.write('Exception: %s\n' % ex) if wait: is_failed |= watch_tasks(self.hub, submitted_jobs)
def provision(self, *args, **kwargs): """ provision resources in Beaker """ # Break down kwargs for debug, dryrun, recipesets, and whiteboard debug = kwargs.get("debug", False) dryrun = kwargs.get("dryrun", False) recipesets = kwargs.get("recipesets", []) keys_path = kwargs.get('ssh_keys_path', '') # Create Job job = BeakerJob(*args, **kwargs) # Add All Host Requirements for recipeset in recipesets: kwargs = self.create_recipesets(recipeset, **kwargs) family = kwargs.get("family", None) distro = kwargs.get("distro", None) task_params = kwargs.get("taskparam", []) # tasks are list of dictionaries which follows format # for beaker in a box # tasks = [ {arches:[], 'name': '/distribution/utils/dummy'}] # for beaker production # tasks = [ {arches:[], 'name': '/distribution/dummy'}] tasks = kwargs.get("tasks", [{'arches': [], 'name': '/distribution/dummy'}]) arch = kwargs.get("arch", "x86_64") ks_meta = kwargs.get("ks_meta", "") method = kwargs.get("method", "nfs") priority = kwargs.get("priority", "Normal") hostrequires = kwargs.get("hostrequires", []) reserve_duration = kwargs.get("reserve_duration", None) if reserve_duration: kwargs.update({"reserve_duration": "%s" % reserve_duration}) tags = kwargs.get("tags", []) if tags: kwargs.update({"tag": tags}) repos = kwargs.get("repos", []) baseurls = [] for repo in repos: if "baseurl" in repo: baseurls.append(repo.get("baseurl")) else: kwargs.update({"repo": baseurls}) ks_append = kwargs.get("ks_append", []) ssh_key = kwargs.get("ssh_key", []) for key_file in kwargs.get("ssh_key_file", []): file_path = os.path.join(keys_path, key_file) try: with open(file_path, "r") as f: ssh_key.append(f.read()) except: LOG.info("Unable to read from ssh key file: %s" % file_path) if ssh_key: ks_append.append("""%%post mkdir -p /root/.ssh cat >>/root/.ssh/authorized_keys << "__EOF__" %s __EOF__ restorecon -R /root/.ssh chmod go-w /root /root/.ssh /root/.ssh/authorized_keys %%end""" % '\n'.join(ssh_key)) kwargs.update({"ks_append": ks_append}) requested_tasks = [] # adding arches=[] to every task definition for task in tasks: if not('arches' in task.keys()): task['arches'] = [] requested_tasks.append(task) # Tasks and harnesses if 'harness' in ks_meta: # Disable report plugins task_params.append("RSTRNT_DISABLED=01_dmesg_check " "10_avc_check") # Reserve the system after its installed kwargs.update({"reserve": True}) else: requested_tasks.append({'arches': [], 'name': '/distribution/reservesys'}) if reserve_duration: task_params.append("RESERVETIME=%s" % reserve_duration) # Update defaults kwargs.update({"suppress_install_task": True}) kwargs.update({"method": method}) kwargs.update({"priority": priority}) # Must have family or distro if not family and not distro and not arch: sys.stderr.write("No Family or Distro and arch specified\n") sys.exit(1) if not requested_tasks: sys.stderr.write("You must specify a task to run\n") sys.exit(1) # Create Workflow wrkflow = BeakerWorkflow('BeakerWorkflow') # Create Base Recipe recipe_template = BeakerRecipe(*args, **kwargs) # Add Host Requirements for requirement in hostrequires: if 'force' in requirement: # hostRequires element is created by BeakerRecipe, use it hostrequires_node = recipe_template.node.getElementsByTagName('hostRequires')[0] # noqa E501 # all other filters are ignored if the hostname is forced, # so the use of 'force' is mutually exclusive with the use # of any other 'hostRequires' filters hostrequires_node.setAttribute('force', requirement['force']) elif 'rawxml' in requirement: requirement_node = xml.dom.minidom.parseString( requirement['rawxml']).documentElement recipe_template.addHostRequires(requirement_node) else: # If force is not used, a requirement can be any number # of differently formatted XML elements, each with their # own combination of element name and valid attrs. So, # the best we can do is generate XML based on the input, # and only the "tag" key is required. tag_name = requirement['tag'] requirement_node = self.doc.createElement(tag_name) for attr, value in requirement.items(): # Force all values to str, which the XML writer expects. requirement_node.setAttribute(attr, str(value)) # use the BeakerRecipe API to add the element recipe_template.addHostRequires(requirement_node) # Add Distro Requirements recipe_template.addBaseRequires(*args, **kwargs) arch_node = self.doc.createElement('distro_arch') arch_node.setAttribute('op', '=') arch_node.setAttribute('value', arch) recipe_set = BeakerRecipeSet(**kwargs) if wrkflow.multi_host: for i in range(self.n_servers): recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='SERVERS', **kwargs)) for i in range(self.n_clients): recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, role='CLIENTS', **kwargs)) else: recipe_set.addRecipe(wrkflow.processTemplate( recipe_template, requested_tasks, taskParams=task_params, distroRequires=arch_node, **kwargs)) job.addRecipeSet(recipe_set) # jobxml jobxml = job.toxml(**kwargs) if debug: LOG.debug(jobxml) self.submitted_jobs = [] if not dryrun: self.submitted_jobs.append(self.hub.jobs.upload(jobxml)) LOG.info("Submitted: %s" % self.submitted_jobs) return self.submitted_jobs