Beispiel #1
0
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)
Beispiel #2
0
 def setUp(self):
     self.command = BeakerWorkflow(None)
Beispiel #3
0
 def setUp(self):
     self.command = BeakerWorkflow(None)
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #7
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
    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