Exemplo n.º 1
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}
        )
        try:
            script_in_db = Script.objects.get(name=script.name)
        except Script.DoesNotExist:
            form = ScriptForm(
                data={
                    "script": script_content,
                    "comment": "Created by maas-%s" % get_running_version(),
                }
            )
            # 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.
            if not form.is_valid():
                raise Exception("%s: %s" % (script.name, form.errors))
            script_in_db = form.save(commit=False)
            script_in_db.default = True
            script_in_db.save()
        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.
                no_update = False
                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
                        no_update = True
                        break
                if no_update:
                    continue
                form = ScriptForm(
                    instance=script_in_db,
                    data={
                        "script": script_content,
                        "comment": "Updated by maas-%s"
                        % get_running_version(),
                    },
                    edit_default=True,
                )
                # 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.
                if not form.is_valid():
                    raise Exception("%s: %s" % (script.name, form.errors))
                script_in_db = form.save(commit=False)
                script_in_db.default = True
                script_in_db.save()
Exemplo n.º 2
0
 def test_uses_snappy_get_snap_version(self):
     self.patch(snappy, "running_in_snap").return_value = True
     self.patch(snappy,
                "get_snap_version").return_value = "2.10.0-456-g.deadbeef"
     maas_version = get_running_version()
     self.assertEqual(maas_version.short_version, "2.10.0")
     self.assertEqual(maas_version.extended_info, "456-g.deadbeef")
Exemplo n.º 3
0
 def register(
     self,
     system_id,
     hostname,
     interfaces,
     url,
     nodegroup_uuid=None,
     beacon_support=False,
     version=None,
 ):
     # Hold off on fabric creation if the remote controller
     # supports beacons; it will happen later when UpdateInterfaces is
     # called.
     create_fabrics = False if beacon_support else True
     result = yield self._register(
         system_id,
         hostname,
         interfaces,
         url,
         nodegroup_uuid=nodegroup_uuid,
         create_fabrics=create_fabrics,
         version=version,
     )
     if beacon_support:
         # The remote supports beaconing, so acknowledge that.
         result["beacon_support"] = True
     if version:
         # The remote supports version checking, so reply to that.
         result["version"] = str(get_running_version())
     return result
Exemplo n.º 4
0
    def test_method_is_cached(self):
        self.patch(snap, "running_in_snap").return_value = True
        mock_get_snap_versions = self.patch(snap, "get_snap_version")
        mock_get_snap_versions.return_value = snap.SnapVersion(
            version="2.10.0-456-g.deadbeef",
            revision="1234",
        )
        version.get_running_version.cache_clear()

        first_return_value = version.get_running_version()
        second_return_value = version.get_running_version()
        # The return value is not empty (full unit tests have been performed
        # earlier).
        self.assertNotIn(first_return_value, [b"", "", None])
        self.assertEqual(first_return_value, second_return_value)
        mock_get_snap_versions.assert_called_once()
Exemplo n.º 5
0
 def register(
     self,
     system_id,
     hostname,
     interfaces,
     url,
     nodegroup_uuid=None,
     beacon_support=False,
     version=None,
 ):
     result = yield self._register(
         system_id,
         hostname,
         interfaces,
         url,
         nodegroup_uuid=nodegroup_uuid,
         version=version,
     )
     if beacon_support:
         # The remote supports beaconing, so acknowledge that.
         result["beacon_support"] = True
     if version:
         # The remote supports version checking, so reply to that.
         result["version"] = str(get_running_version())
     return result
Exemplo n.º 6
0
 def test_uses_get_deb_versions_info(self):
     self.patch(version.deb,
                "get_deb_versions_info").return_value = deb.DebVersionsInfo(
                    current=deb.DebVersion(
                        version="2.10.0-456-g.deadbeef-0ubuntu1", ))
     maas_version = get_running_version()
     self.assertEqual(maas_version.short_version, "2.10.0")
     self.assertEqual(maas_version.extended_info, "456-g.deadbeef")
Exemplo n.º 7
0
 def test_uses_version_from_python(self):
     self.patch(version, "_get_version_from_apt").return_value = None
     self.patch(version,
                "DISTRIBUTION").parsed_version = parse_version("2.10.0b1")
     self.patch(version, "_get_maas_repo_hash").return_value = None
     maas_version = get_running_version()
     self.assertEqual(maas_version.short_version, "2.10.0~beta1")
     self.assertEqual(maas_version.extended_info, "")
Exemplo n.º 8
0
def notification_available(notification_version):
    current_version = version.get_running_version()
    notification_version = version.MAASVersion.from_string(
        notification_version
    )
    log.debug(f"Current MAAS version: {current_version}")
    log.debug(f"Notification version: {notification_version}")
    return notification_version > current_version
Exemplo n.º 9
0
    def test_method_is_cached(self):
        mock_apt = self.patch(version, "_get_version_from_apt")
        mock_apt.return_value = "1.8.0~alpha4+bzr356-0ubuntu1"
        version.get_running_version.cache_clear()

        first_return_value = version.get_running_version()
        second_return_value = version.get_running_version()
        # The return value is not empty (full unit tests have been performed
        # earlier).
        self.assertNotIn(first_return_value, [b"", "", None])
        self.assertEqual(first_return_value, second_return_value)
        # Apt has only been called once.
        self.expectThat(
            mock_apt,
            MockCalledOnceWith(version.RACK_PACKAGE_NAME,
                               version.REGION_PACKAGE_NAME),
        )
Exemplo n.º 10
0
def get_maas_user_agent():
    from maasserver.models import Config

    version = get_running_version()
    user_agent = f"maas/{version.short_version}/{version.extended_info}"
    uuid = Config.objects.get_config("uuid")
    if uuid:
        user_agent += f"/{uuid}"
    return user_agent
Exemplo n.º 11
0
def inner_start_up(master=False):
    """Startup jobs that must run serialized w.r.t. other starting servers."""
    # Register our MAC data type with psycopg.
    register_mac_type(connection.cursor())

    # All commissioning and testing scripts are stored in the database. For
    # a commissioning ScriptSet to be created Scripts must exist first. Call
    # this early, only on the master process, to ensure they exist and are
    # only created once. If get_or_create_running_controller() is called before
    # this it will fail on first run.
    if master:
        load_builtin_scripts()

    # Ensure the this region is represented in the database. The first regiond
    # to pass through inner_start_up on this host can do this; it should NOT
    # be restricted to masters only. This also ensures that the MAAS ID is set
    # on the filesystem; it will be done in a post-commit hook and will thus
    # happen before `locks.startup` is released.
    node = RegionController.objects.get_or_create_running_controller()
    # Update region version
    ControllerInfo.objects.set_version(node, get_running_version())
    # Ensure that uuid is created after creating
    RegionController.objects.get_or_create_uuid()

    # Only perform the following if the master process for the
    # region controller.
    if master:
        # Freshen the kms SRV records.
        dns_kms_setting_changed()

        # Make sure the commissioning distro series is still a supported LTS.
        commissioning_distro_series = Config.objects.get_config(
            name="commissioning_distro_series"
        )
        ubuntu = UbuntuOS()
        if commissioning_distro_series not in (
            ubuntu.get_supported_commissioning_releases()
        ):
            Config.objects.set_config(
                "commissioning_distro_series",
                ubuntu.get_default_commissioning_release(),
            )
            Notification.objects.create_info_for_admins(
                "Ubuntu %s is no longer a supported commissioning "
                "series. Ubuntu %s has been automatically selected."
                % (
                    commissioning_distro_series,
                    ubuntu.get_default_commissioning_release(),
                ),
                ident="commissioning_release_deprecated",
            )

        with RegionConfiguration.open() as config:
            Config.objects.set_config("maas_url", config.maas_url)

        # Update deprecation notifications if needed
        sync_deprecation_notifications()
Exemplo n.º 12
0
 def test_uses_version_from_python_with_git_info(self):
     self.patch(version, "_get_version_from_apt").return_value = None
     self.patch(version,
                "DISTRIBUTION").parsed_version = parse_version("2.10.0b1")
     self.patch(version, "_get_maas_repo_commit_count").return_value = 1234
     self.patch(version, "_get_maas_repo_hash").return_value = "deadbeef"
     maas_version = get_running_version()
     self.assertEqual(maas_version.short_version, "2.10.0~beta1")
     self.assertEqual(maas_version.extended_info, "1234-g.deadbeef")
Exemplo n.º 13
0
 def test_calls__get_version_from_apt(self):
     mock_apt = self.patch(version, "_get_version_from_apt")
     mock_apt.return_value = "2.10.0-456-g.deadbeef-0ubuntu1"
     maas_version = get_running_version()
     self.assertEqual(maas_version.short_version, "2.10.0")
     self.assertEqual(maas_version.extended_info, "456-g.deadbeef")
     self.expectThat(
         mock_apt,
         MockCalledOnceWith(version.RACK_PACKAGE_NAME,
                            version.REGION_PACKAGE_NAME),
     )
Exemplo n.º 14
0
    def test_update_script(self):
        load_builtin_scripts()
        update_script_values = random.choice(BUILTIN_SCRIPTS)
        script = Script.objects.get(name=update_script_values.name)

        # Fields which we can update
        orig_title = script.title
        orig_description = script.description
        orig_script_type = script.script_type
        orig_results = script.results
        orig_parameters = script.parameters

        script.title = factory.make_string()
        script.description = factory.make_string()
        script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES)
        script.results = [factory.make_name("result")]
        script.script.parameters = {
            factory.make_name("param"): {
                "type": "storage"
            }
        }

        # Put fake old data in to simulate updating a script.
        old_script = VersionedTextFile.objects.create(
            data=factory.make_string())
        script.script = old_script

        # User changeable fields.
        user_tags = [factory.make_name("tag") for _ in range(3)]
        script.tags = copy.deepcopy(user_tags)
        user_timeout = timedelta(random.randint(0, 1000))
        script.timeout = user_timeout
        script.save()

        load_builtin_scripts()
        script = reload_object(script)

        self.assertEqual(orig_title, script.title, script.name)
        self.assertEqual(orig_description, script.description, script.name)
        self.assertEqual(orig_script_type, script.script_type, script.name)
        self.assertDictEqual(orig_results, script.results, script.name)
        self.assertDictEqual(orig_parameters, script.parameters, script.name)

        self.assertThat(script.tags, ContainsAll(user_tags))
        self.assertEqual(user_timeout, script.timeout)

        self.assertEqual(old_script, script.script.previous_version)
        self.assertEqual("Updated by maas-%s" % get_running_version(),
                         script.script.comment)
        self.assertTrue(script.default)
Exemplo n.º 15
0
 def test_register_acks_version(self):
     yield self.installFakeRegion()
     rack_controller = yield deferToDatabase(factory.make_RackController)
     protocol = self.make_Region()
     protocol.transport = MagicMock()
     response = yield call_responder(
         protocol,
         RegisterRackController,
         {
             "system_id": rack_controller.system_id,
             "hostname": rack_controller.hostname,
             "interfaces": {},
             "version": "2.3.0",
         },
     )
     self.assertEqual(response["version"], str(get_running_version()))
Exemplo n.º 16
0
    def read(self, request):
        """@description-title MAAS version information
        @description Read version and capabilities of this MAAS instance.

        @success (http-status-code) "server-success" 200
        @success (json) "success-json" A JSON object containing MAAS version
        and capabilities information.
        @success-example "success-json" [exkey=version] placeholder text
        """
        version = get_running_version()
        version_info = {
            "capabilities": API_CAPABILITIES_LIST,
            "version": version.short_version,
            "subversion": version.extended_info,
        }
        return HttpResponse(
            json.dumps(version_info),
            content_type="application/json; charset=utf-8",
            status=int(http.client.OK),
        )
Exemplo n.º 17
0
    def test_creates_scripts(self):
        load_builtin_scripts()

        for script in BUILTIN_SCRIPTS:
            script_in_db = Script.objects.get(name=script.name)

            # While MAAS allows user scripts to leave these fields blank,
            # builtin scripts should always have values.
            self.assertTrue(script_in_db.title, script.name)
            self.assertTrue(script_in_db.description, script.name)
            self.assertTrue(script_in_db.script.data, script.name)
            self.assertThat(script_in_db.tags, Not(Equals([])), script.name)

            # These values should always be set by the script loader.
            self.assertEqual(
                "Created by maas-%s" % get_running_version(),
                script_in_db.script.comment,
                script.name,
            )
            self.assertTrue(script_in_db.default, script.name)
Exemplo n.º 18
0
 def test_updates_version(self):
     with post_commit_hooks:
         start_up.inner_start_up()
     region = RegionController.objects.first()
     self.assertEqual(region.version, str(get_running_version()))
Exemplo n.º 19
0
 def version(self, params):
     """Return the MAAS version."""
     version = get_running_version()
     if version.extended_info:
         return f"{version.short_version} ({version.extended_info})"
     return version.short_version
Exemplo n.º 20
0
    def test_update_doesnt_revert_script(self):
        load_builtin_scripts()
        update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2)
        update_script_values = BUILTIN_SCRIPTS[update_script_index]
        script = Script.objects.get(name=update_script_values.name)
        # Put fake new data in to simulate another MAAS region updating
        # to a newer version.
        new_script = factory.make_string()
        script.script = script.script.update(new_script)

        # Fake user updates
        user_tags = [factory.make_name("tag") for _ in range(3)]
        script.tags = user_tags
        user_timeout = timedelta(random.randint(0, 1000))
        script.timeout = user_timeout
        script.save()

        # Test that subsequent scripts still get updated
        second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1]
        second_script = Script.objects.get(
            name=second_update_script_values.name)
        # Put fake old data in to simulate updating a script.
        orig_title = second_script.title
        orig_description = second_script.description
        orig_script_type = second_script.script_type
        orig_results = second_script.results
        orig_parameters = second_script.parameters

        second_script.title = factory.make_string()
        second_script.description = factory.make_string()
        second_script.script_type = factory.pick_choice(SCRIPT_TYPE_CHOICES)
        second_script.results = [factory.make_name("result")]
        second_script.script.parameters = {
            factory.make_name("param"): {
                "type": "storage"
            }
        }

        # Put fake old data in to simulate updating a script.
        old_script = VersionedTextFile.objects.create(
            data=factory.make_string())
        second_script.script = old_script

        second_script.save()

        load_builtin_scripts()

        script = reload_object(script)
        self.assertEqual(update_script_values.name, script.name)
        self.assertEqual(new_script, script.script.data)
        self.assertTrue(min([tag in script.tags for tag in user_tags]))
        self.assertEqual(user_timeout, script.timeout)
        self.assertTrue(script.default)

        second_script = reload_object(second_script)
        self.assertEqual(orig_title, second_script.title)
        self.assertEqual(orig_description, second_script.description)
        self.assertEqual(orig_script_type, second_script.script_type)
        self.assertDictEqual(orig_results, second_script.results)
        self.assertDictEqual(orig_parameters, second_script.parameters)
        self.assertEqual(old_script, second_script.script.previous_version)
        self.assertEqual(
            "Updated by maas-%s" % get_running_version(),
            second_script.script.comment,
        )
        self.assertTrue(second_script.default)