예제 #1
0
    def create_commissioning_script_set(
        self,
        node,
        scripts=None,
        script_input=None,
        enlisting=False,
    ):
        """Create a new commissioning ScriptSet with ScriptResults

        ScriptResults will be created for all builtin commissioning scripts.
        Optionally a list of user scripts and tags can be given to create
        ScriptResults for. If None all user scripts will be assumed. Scripts
        may also have paramaters passed to them.
        """
        if node.is_controller:
            # Controllers can only run the builtin scripts for them.
            scripts = [
                script["name"] for script in NODE_INFO_SCRIPTS.values()
                if script["run_on_controller"]
            ]
        elif enlisting:
            if Config.objects.get_config("enlist_commissioning"):
                scripts = list(NODE_INFO_SCRIPTS.keys()) + ["enlisting"]
            else:
                scripts = ["bmc-config"]
        elif not scripts:
            # No user selected scripts, select all scripts below.
            pass
        elif "none" in scripts:
            # Don't add any scripts besides the ones that come with MAAS.
            scripts = list(NODE_INFO_SCRIPTS.keys())
        else:
            scripts = list(NODE_INFO_SCRIPTS.keys()) + scripts

        script_set = self.create(
            node=node,
            result_type=RESULT_TYPE.COMMISSIONING,
            power_state_before_transition=node.power_state,
            requested_scripts=scripts if scripts else [],
        )

        if not scripts:
            # If the user hasn't selected any commissioning Scripts select
            # all by default excluding for_hardware scripts.
            qs = Script.objects.filter(
                script_type=SCRIPT_TYPE.COMMISSIONING,
                for_hardware=[]).exclude(tags__contains=["noauto"])
            for script in qs:
                script_set.add_pending_script(script, script_input)
        else:
            self._add_user_selected_scripts(script_set, scripts, script_input)

        self._clean_old(node, RESULT_TYPE.COMMISSIONING, script_set)
        return script_set
예제 #2
0
파일: __init__.py 프로젝트: kcns008/maas
def refresh(system_id, consumer_key, token_key, token_secret, maas_url=None):
    """Run all builtin commissioning scripts and report results to region."""
    maaslog.info("Refreshing rack controller hardware information.")

    if maas_url is None:
        maas_url = 'http://127.0.0.1:5240/MAAS'
    url = "%s/metadata/%s/" % (maas_url, MD_VERSION)

    creds = {
        'consumer_key': consumer_key,
        'token_key': token_key,
        'token_secret': token_secret,
        'consumer_secret': '',
    }

    scripts = {
        name: config
        for name, config in NODE_INFO_SCRIPTS.items()
        if config['run_on_controller']
    }

    with tempfile.TemporaryDirectory(prefix='maas-commission-') as tmpdir:
        failed_scripts = runscripts(scripts, url, creds, tmpdir=tmpdir)

    if len(failed_scripts) == 0:
        signal_wrapper(url, creds, 'OK', 'Finished refreshing %s' % system_id)
    else:
        signal_wrapper(url, creds, 'FAILED',
                       'Failed refreshing %s' % system_id)
예제 #3
0
    def create_commissioning_script_set(self,
                                        node,
                                        scripts=None,
                                        script_input=None):
        """Create a new commissioning ScriptSet with ScriptResults

        ScriptResults will be created for all builtin commissioning scripts.
        Optionally a list of user scripts and tags can be given to create
        ScriptResults for. If None all user scripts will be assumed. Scripts
        may also have paramaters passed to them.
        """
        # Avoid circular dependencies.
        from metadataserver.models import ScriptResult

        if scripts is None:
            scripts = []
        else:
            scripts = [str(i) for i in scripts]

        script_set = self.create(
            node=node,
            result_type=RESULT_TYPE.COMMISSIONING,
            power_state_before_transition=node.power_state,
            requested_scripts=scripts,
        )

        # Add all builtin commissioning scripts.
        for script_name, data in NODE_INFO_SCRIPTS.items():
            if node.is_controller and not data["run_on_controller"]:
                continue
            ScriptResult.objects.create(
                script_set=script_set,
                status=SCRIPT_STATUS.PENDING,
                script_name=script_name,
            )

        if node.is_controller:
            # MAAS doesn't run custom commissioning scripts during controller
            # refresh.
            return script_set
        elif not scripts:
            # If the user hasn't selected any commissioning Scripts select
            # all by default excluding for_hardware scripts.
            qs = Script.objects.filter(
                script_type=SCRIPT_TYPE.COMMISSIONING,
                for_hardware=[]).exclude(tags__contains=["noauto"])
            for script in qs:
                script_set.add_pending_script(script, script_input)
        elif "none" in scripts:
            # Don't add any scripts besides the ones that come with MAAS but
            # do perform cleanup below.
            pass
        else:
            self._add_user_selected_scripts(script_set, scripts, script_input)

        self._clean_old(node, RESULT_TYPE.COMMISSIONING, script_set)
        return script_set
예제 #4
0
def load_builtin_scripts():
    for script in BUILTIN_SCRIPTS:
        if script.inject_file:
            with open(script.inject_path, "r") as f:
                script.substitutes["inject_file"] = f.read()
        script_content = tempita.Template.from_filename(script.script_path,
                                                        encoding="utf-8")
        script_content = script_content.substitute({
            "name": script.name,
            **script.substitutes
        })
        form = None
        try:
            script_in_db = Script.objects.get(name=script.name)
        except Script.DoesNotExist:
            form = ScriptForm(
                data={
                    "script": script_content,
                    "comment": f"Created by maas-{get_maas_version()}",
                })
        else:
            if script_in_db.script.data != script_content:
                # Don't add back old versions of a script. This prevents two
                # connected regions with different versions of a script from
                # fighting with eachother.
                for vtf in script_in_db.script.previous_versions():
                    if vtf.data == script_content:
                        # Don't update anything if we detect we have an old
                        # version of the builtin scripts
                        break
                else:
                    form = ScriptForm(
                        instance=script_in_db,
                        data={
                            "script": script_content,
                            "comment": f"Updated by maas-{get_maas_version()}",
                        },
                        edit_default=True,
                    )

        if form is not None:
            # Form validation should never fail as these are the scripts
            # which ship with MAAS. If they ever do this will be cause by
            # unit tests.
            assert (
                form.is_valid()
            ), f"Builtin script {script.name} caused these errors: {form.errors}"
            script_in_db = form.save(commit=False)
        if NODE_INFO_SCRIPTS.get(script.name, {}).get("run_on_controller"):
            script_in_db.add_tag("deploy-info")
        else:
            script_in_db.remove_tag("deploy-info")
        script_in_db.default = True
        script_in_db.save()
예제 #5
0
    def create_commissioning_script_set(self, node, scripts=[], input={}):
        """Create a new commissioning ScriptSet with ScriptResults

        ScriptResults will be created for all builtin commissioning scripts.
        Optionally a list of user scripts and tags can be given to create
        ScriptResults for. If None all user scripts will be assumed. Scripts
        may also have paramaters passed to them.
        """
        # Avoid circular dependencies.
        from metadataserver.models import ScriptResult

        script_set = self.create(
            node=node,
            result_type=RESULT_TYPE.COMMISSIONING,
            power_state_before_transition=node.power_state)
        self._clean_old(node, RESULT_TYPE.COMMISSIONING, script_set)

        for script_name, data in NODE_INFO_SCRIPTS.items():
            if node.is_controller and not data['run_on_controller']:
                continue
            ScriptResult.objects.create(script_set=script_set,
                                        status=SCRIPT_STATUS.PENDING,
                                        script_name=script_name)

        # MAAS doesn't run custom commissioning scripts during controller
        # refresh.
        if node.is_controller:
            return script_set

        if scripts == []:
            qs = Script.objects.filter(script_type=SCRIPT_TYPE.COMMISSIONING)
        else:
            ids = [
                int(id) for id in scripts
                if isinstance(id, int) or id.isdigit()
            ]
            qs = Script.objects.filter(
                Q(name__in=scripts) | Q(tags__overlap=scripts) | Q(id__in=ids),
                script_type=SCRIPT_TYPE.COMMISSIONING)
        for script in qs:
            form = ParametersForm(data=input.get(script.name, {}),
                                  script=script,
                                  node=node)
            if not form.is_valid():
                script_set.delete()
                raise ValidationError(form.errors)
            for param in form.cleaned_data['input']:
                ScriptResult.objects.create(script_set=script_set,
                                            status=SCRIPT_STATUS.PENDING,
                                            script=script,
                                            script_name=script.name,
                                            parameters=param)

        return script_set
예제 #6
0
def refresh(
    system_id,
    consumer_key,
    token_key,
    token_secret,
    maas_url=None,
    post_process_hook=None,
):
    """Run all builtin commissioning scripts and report results to region."""
    maaslog.info("Refreshing rack controller hardware information.")

    if maas_url is None:
        maas_url = "http://127.0.0.1:5240/MAAS"
    url = "%s/metadata/%s/" % (maas_url, MD_VERSION)

    creds = {
        "consumer_key": consumer_key,
        "token_key": token_key,
        "token_secret": token_secret,
        "consumer_secret": "",
    }

    scripts = {
        name: config
        for name, config in NODE_INFO_SCRIPTS.items()
        if config["run_on_controller"]
    }

    with tempfile.TemporaryDirectory(prefix="maas-commission-") as tmpdir:
        failed_scripts = runscripts(
            scripts,
            url,
            creds,
            tmpdir=tmpdir,
            post_process_hook=post_process_hook,
        )

    if len(failed_scripts) == 0:
        signal_wrapper(url, creds, "OK", "Finished refreshing %s" % system_id)
    else:
        signal_wrapper(
            url, creds, "FAILED", "Failed refreshing %s" % system_id
        )
예제 #7
0
    def test_create_commissioning_script_set_for_controller(self):
        for _ in range(3):
            factory.make_Script(script_type=SCRIPT_TYPE.COMMISSIONING)
        node = factory.make_Node(node_type=random.choice([
            NODE_TYPE.RACK_CONTROLLER, NODE_TYPE.REGION_CONTROLLER,
            NODE_TYPE.REGION_AND_RACK_CONTROLLER
        ]), )

        script_set = ScriptSet.objects.create_commissioning_script_set(node)

        expected_scripts = [
            script_name for script_name, data in NODE_INFO_SCRIPTS.items()
            if data['run_on_controller']
        ]
        self.assertItemsEqual(
            expected_scripts,
            [script_result.name for script_result in script_set])
        self.assertEquals(RESULT_TYPE.COMMISSIONING, script_set.result_type)
        self.assertEquals(node.power_state,
                          script_set.power_state_before_transition)