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 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