class WorkflowTest(unittest.TestCase): def setUp(self): self.command = BeakerWorkflow(None) 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_processTemplate_minimal_recipe(self): recipeTemplate = BeakerRecipe() recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{ 'name': '/example', 'arches': [] }], family='RedHatEnterpriseLinux6') 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>') # https://bugzilla.redhat.com/show_bug.cgi?id=723789 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) # https://bugzilla.redhat.com/show_bug.cgi?id=1200427 def test_distro_wildcard(self): recipeTemplate = BeakerRecipe() recipeTemplate.addBaseRequires(distro='RHEL-7.1%', family='RedHatEnterpriseLinux7') recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{ 'name': '/example', 'arches': [] }], family='RedHatEnterpriseLinux7') xml = recipe.toxml(prettyxml=True) self.assertIn('<distro_name op="like" value="RHEL-7.1%"/>', xml) # https://bugzilla.redhat.com/show_bug.cgi?id=1010355 def test_hostrequire_accepts_like_operator(self): recipeTemplate = BeakerRecipe() recipeTemplate.addBaseRequires(hostrequire=['hostname like %.khw.%']) recipe = self.command.processTemplate(recipeTemplate, requestedTasks=[{ 'name': '/example', 'arches': [] }], family='RedHatEnterpriseLinux7') xml = recipe.toxml() self.assertIn('<hostname op="like" value="%.khw.%"/>', xml)
def setUp(self): self.command = BeakerWorkflow(None)
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
class WorkflowTest(unittest.TestCase): def setUp(self): self.command = BeakerWorkflow(None) 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_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>') # https://bugzilla.redhat.com/show_bug.cgi?id=723789 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>') 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>') 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': []}]) xml = recipe.toxml(prettyxml=True) self.assertEquals(len(re.findall('<distro_name', xml)), 1, xml) self.assertEquals(len(re.findall('<hostname', xml)), 1, xml) # https://bugzilla.redhat.com/show_bug.cgi?id=1200427 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) # https://bugzilla.redhat.com/show_bug.cgi?id=1010355 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 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
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 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 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