示例#1
0
 def test_dbus_name(self):
     """Test DBus path."""
     self.assertEqual(get_dbus_name(), "")
     self.assertEqual(get_dbus_name("a"), "a")
     self.assertEqual(get_dbus_name("a", "b"), "a.b")
     self.assertEqual(get_dbus_name("a", "b", "c"), "a.b.c")
     self.assertEqual(get_dbus_name("org", "freedesktop", "DBus"),
                      "org.freedesktop.DBus")
示例#2
0
文件: error.py 项目: yurchor/dasbus
    def decorator(error_name, namespace=()):
        error_name = get_dbus_name(*namespace, error_name)

        def decorated(cls):
            error_mapper.add_rule(
                ErrorRule(exception_type=cls, error_name=error_name))
            return cls

        return decorated
示例#3
0
    def __init__(self, message_bus, service_name):
        """Creates a module observer.

        :param message_bus: a message bus
        :param service_name: a DBus name of a service
        """
        super().__init__(message_bus, service_name)
        self._proxy = None
        self._is_addon = service_name.startswith(get_dbus_name(*ADDONS_NAMESPACE))
        self._namespace = get_namespace_from_name(service_name)
        self._object_path = get_dbus_path(*self._namespace)
示例#4
0
    def __init__(self, namespace, basename=None):
        """Create an identifier.

        :param namespace: a sequence of strings
        :param basename: a string with the base name or None
        """
        if basename:
            namespace = (*namespace, basename)

        self._namespace = namespace
        self._name = get_dbus_name(*namespace)
        self._path = get_dbus_path(*namespace)
示例#5
0
文件: error.py 项目: dhodovsk/dasbus
def dbus_error(error_name, namespace=()):
    """Define decorated class as a DBus error.

    The decorated exception class will be mapped to a DBus error.

    :param error_name: a DBus name of the error
    :param namespace: a sequence of strings
    :return: a decorator
    """
    error_name = get_dbus_name(*namespace, error_name)

    def decorated(cls):
        register.map_exception_to_name(cls, error_name)
        return cls

    return decorated
示例#6
0
    def _find_addons(self):
        """Find additional modules."""
        modules = []

        if not self._addons_enabled:
            return modules

        dbus = self._message_bus.proxy
        names = dbus.ListActivatableNames()
        prefix = get_dbus_name(*ADDONS_NAMESPACE)

        for service_name in names:
            if not service_name.startswith(prefix):
                continue

            log.debug("Found %s.", service_name)
            modules.append(
                ModuleObserver(self._message_bus, service_name, is_addon=True))

        return modules
示例#7
0
 def decorated(cls):
     name = get_dbus_name(*namespace, interface_name)
     xml = DBusSpecificationGenerator.generate_specification(cls, name)
     setattr(cls, DBUS_XML_ATTRIBUTE, xml)
     return cls
示例#8
0
class AnacondaConfigurationTestCase(unittest.TestCase):
    """Test the Anaconda configuration."""

    # Full names of the Anaconda modules.
    MODULE_NAMES = set(
        map(lambda s: s.service_name, (
            services.TIMEZONE,
            services.NETWORK,
            services.LOCALIZATION,
            services.SECURITY,
            services.USERS,
            services.PAYLOADS,
            services.STORAGE,
            services.SERVICES,
            services.SUBSCRIPTION,
        )))

    # Known namespaces of the Anaconda modules.
    MODULE_NAMESPACES = set(
        map(lambda n: get_dbus_name(*n), (
            namespaces.MODULES_NAMESPACE,
            namespaces.ADDONS_NAMESPACE,
        )))

    def test_default_configuration(self):
        # Make sure that we are able to import conf.
        from pyanaconda.core.configuration.anaconda import conf
        self.assertEqual(conf.anaconda.debug, False)

    def test_source(self):
        conf = AnacondaConfiguration()
        sources = conf.get_sources()
        self.assertEqual(sources, [])

    def test_default_source(self):
        conf = AnacondaConfiguration.from_defaults()
        sources = conf.get_sources()
        self.assertEqual(len(sources), 1)
        self.assertEqual(sources[0], os.environ.get("ANACONDA_CONFIG_TMP"))

    def test_default_validation(self):
        conf = AnacondaConfiguration.from_defaults()
        conf.validate()

        # Set invalid value.
        parser = conf.get_parser()
        parser["Anaconda"]["debug"] = "string"
        with self.assertRaises(ConfigurationError):
            conf.validate()

        # Remove a required option.
        parser.remove_option("Anaconda", "debug")
        with self.assertRaises(ConfigurationError):
            conf.validate()

        # Remove a required section.
        parser.remove_section("Anaconda")
        with self.assertRaises(ConfigurationError):
            conf.validate()

    def test_read(self):
        conf = AnacondaConfiguration()

        with tempfile.NamedTemporaryFile("w") as f:
            conf.read(f.name)
            self.assertEqual(len(conf.get_sources()), 1)
            self.assertEqual(conf.get_sources()[0], f.name)

    def test_default_read(self):
        AnacondaConfiguration.from_defaults()

    def test_write(self):
        conf = AnacondaConfiguration()

        with tempfile.NamedTemporaryFile("r+") as f:
            conf.write(f.name)
            f.flush()
            self.assertFalse(f.read(), "The file should be empty.")

    def test_default_write(self):
        conf = AnacondaConfiguration.from_defaults()

        with tempfile.NamedTemporaryFile("r+") as f:
            conf.write(f.name)
            f.flush()
            self.assertTrue(f.read(), "The file shouldn't be empty.")

    def test_set_from_files(self):
        conf = AnacondaConfiguration.from_defaults()
        paths = []

        with tempfile.TemporaryDirectory() as d:
            # Add nonexistent file.
            nonexistent = os.path.join(d, "nonexistent")
            paths.append(nonexistent)

            # Add empty directory.
            empty_dir = os.path.join(d, "empty")
            os.mkdir(empty_dir)
            paths.append(empty_dir)

            # Add existing file.
            existing = os.path.join(d, "a.conf")
            paths.append(existing)

            with open(existing, mode="w") as f:
                f.write("")

            # Add non-empty directory.
            conf_dir = os.path.join(d, "conf.d")
            os.mkdir(conf_dir)
            paths.append(conf_dir)

            for name in ["b.conf", "c.conf", "d"]:
                with open(os.path.join(conf_dir, name), mode="w") as f:
                    f.write("")

            # Check the paths.
            self.assertEqual([os.path.relpath(path, d) for path in paths],
                             ["nonexistent", "empty", "a.conf", "conf.d"])

            conf._sources = []
            conf.set_from_files(paths)

            # Check the loaded files.
            self.assertEqual(
                [os.path.relpath(path, d) for path in conf.get_sources()],
                ["a.conf", "conf.d/b.conf", "conf.d/c.conf"])

    def _check_configuration_sources(self, conf, file_names):
        """Check the loaded configuration sources."""
        file_paths = [os.path.join(CONFIG_DIR, path) for path in file_names]
        self.assertEqual(file_paths, conf.get_sources())

    @patch("pyanaconda.core.configuration.anaconda.ANACONDA_CONFIG_DIR",
           CONFIG_DIR)
    def test_set_from_requested_profile(self):
        conf = AnacondaConfiguration.from_defaults()

        # Test an unknown requested profile.
        with self.assertRaises(ConfigurationError) as cm:
            conf.set_from_profile("unknown-profile")

        expected = "Unable to find any suitable configuration files " \
                   "for the 'unknown-profile' profile."

        self.assertEqual(str(cm.exception), expected)

        # Test a known requested profile.
        conf.set_from_profile("fedora-workstation")

        self._check_configuration_sources(conf, [
            "anaconda.conf", "profile.d/fedora.conf",
            "profile.d/fedora-workstation.conf"
        ])

    @patch("pyanaconda.core.configuration.anaconda.ANACONDA_CONFIG_DIR",
           CONFIG_DIR)
    def test_set_from_detected_profile(self):
        conf = AnacondaConfiguration.from_defaults()

        # Test unknown os-release values.
        with self.assertLogs(level="WARNING") as cm:
            conf.set_from_detected_profile("unknown-os", "unknown-variant")

        expected = \
            "Unable to find any suitable configuration files for the detected " \
            "os-release values. No profile configuration will be used."

        self.assertIn(expected, "\n".join(cm.output))

        # Test known os-release values.
        conf.set_from_detected_profile("fedora", "workstation")

        self._check_configuration_sources(conf, [
            "anaconda.conf", "profile.d/fedora.conf",
            "profile.d/fedora-workstation.conf"
        ])

    def _check_pattern(self, pattern):
        """Check the specified module pattern."""
        if pattern.endswith(".*"):
            self.assertIn(pattern[:-2], self.MODULE_NAMESPACES)
        else:
            self.assertIn(pattern, self.MODULE_NAMES)

    def test_activatable_modules(self):
        """Test the activatable_modules option."""
        conf = AnacondaConfiguration.from_defaults()

        for pattern in conf.anaconda.activatable_modules:
            self._check_pattern(pattern)

    def test_kickstart_modules(self):
        """Test the kickstart_modules option."""
        conf = AnacondaConfiguration.from_defaults()
        self.assertEqual(conf.anaconda.activatable_modules, [
            "org.fedoraproject.Anaconda.Modules.*",
            "org.fedoraproject.Anaconda.Addons.*"
        ])

        parser = conf.get_parser()
        parser.read_string(
            dedent("""

        [Anaconda]
        kickstart_modules =
            org.fedoraproject.Anaconda.Modules.Timezone
            org.fedoraproject.Anaconda.Modules.Localization
            org.fedoraproject.Anaconda.Modules.Security

        """))

        self.assertEqual(conf.anaconda.activatable_modules, [
            "org.fedoraproject.Anaconda.Modules.Timezone",
            "org.fedoraproject.Anaconda.Modules.Localization",
            "org.fedoraproject.Anaconda.Modules.Security",
            "org.fedoraproject.Anaconda.Addons.*"
        ])

        for pattern in conf.anaconda.activatable_modules:
            self._check_pattern(pattern)

    def test_forbidden_modules(self):
        """Test the forbidden_modules option."""
        conf = AnacondaConfiguration.from_defaults()

        for pattern in conf.anaconda.forbidden_modules:
            self._check_pattern(pattern)

    def test_addons_enabled_modules(self):
        """Test the addons_enabled option."""
        conf = AnacondaConfiguration.from_defaults()
        self.assertEqual(conf.anaconda.forbidden_modules, [])

        parser = conf.get_parser()
        parser.read_string(
            dedent("""

        [Anaconda]
        forbidden_modules =
            org.fedoraproject.Anaconda.Modules.Timezone
            org.fedoraproject.Anaconda.Modules.Localization
            org.fedoraproject.Anaconda.Modules.Security

        """))

        self.assertEqual(conf.anaconda.forbidden_modules, [
            "org.fedoraproject.Anaconda.Modules.Timezone",
            "org.fedoraproject.Anaconda.Modules.Localization",
            "org.fedoraproject.Anaconda.Modules.Security",
        ])

        parser.read_string(
            dedent("""

        [Anaconda]
        addons_enabled = True

        """))

        self.assertEqual(conf.anaconda.forbidden_modules, [
            "org.fedoraproject.Anaconda.Modules.Timezone",
            "org.fedoraproject.Anaconda.Modules.Localization",
            "org.fedoraproject.Anaconda.Modules.Security",
        ])

        parser.read_string(
            dedent("""

        [Anaconda]
        addons_enabled = False

        """))

        self.assertEqual(conf.anaconda.forbidden_modules, [
            "org.fedoraproject.Anaconda.Addons.*",
            "org.fedoraproject.Anaconda.Modules.Timezone",
            "org.fedoraproject.Anaconda.Modules.Localization",
            "org.fedoraproject.Anaconda.Modules.Security",
        ])

        for pattern in conf.anaconda.forbidden_modules:
            self._check_pattern(pattern)

    def test_optional_modules(self):
        """Test the optional_modules option."""
        conf = AnacondaConfiguration.from_defaults()

        for pattern in conf.anaconda.optional_modules:
            self._check_pattern(pattern)

    def test_bootloader(self):
        conf = AnacondaConfiguration.from_defaults()
        self.assertIn("selinux", conf.bootloader.preserved_arguments)

    def test_default_partitioning(self):
        conf = AnacondaConfiguration.from_defaults()
        self.assertEqual(conf.storage.default_partitioning,
                         [{
                             'name': '/',
                             'min': Size("1024 MiB"),
                             'max': Size("70 GiB"),
                         }, {
                             'name': '/home',
                             'min': Size("500 MiB"),
                             'free': Size("50 GiB"),
                         }])

    def test_convert_partitioning(self):
        convert_line = StorageSection._convert_partitioning_line

        self.assertEqual(
            convert_line("/ (min 1 GiB, max 2 GiB, free 20 GiB)"), {
                "name": "/",
                "min": Size("1 GiB"),
                "max": Size("2 GiB"),
                "free": Size("20 GiB")
            })

        self.assertEqual(convert_line("/home (size 1 GiB)"), {
            "name": "/home",
            "size": Size("1 GiB")
        })

        self.assertEqual(convert_line("swap"), {"name": "swap"})

        with self.assertRaises(ValueError):
            convert_line("")

        with self.assertRaises(ValueError):
            convert_line("(size 1 GiB)")

        with self.assertRaises(ValueError):
            convert_line("/home (size)")

        with self.assertRaises(ValueError):
            convert_line("/home (invalid 1 GiB)")

        with self.assertRaises(ValueError):
            convert_line("/home  (size 1 GiB, min 2 GiB)")

        with self.assertRaises(ValueError):
            convert_line("/home  (max 2 GiB)")

    def test_default_installation_source(self):
        conf = AnacondaConfiguration.from_defaults()
        self.assertEqual(conf.payload.default_source,
                         SOURCE_TYPE_CLOSEST_MIRROR)

    def test_default_password_policies(self):
        conf = AnacondaConfiguration.from_defaults()
        self.assertEqual(conf.ui.password_policies, [
            {
                'name': 'root',
                "quality": 1,
                "length": 6,
            },
            {
                'name': 'user',
                "quality": 1,
                "length": 6,
                "empty": True,
            },
            {
                'name': 'luks',
                "quality": 1,
                "length": 6,
            },
        ])

    def test_convert_password_policy(self):
        convert_line = UserInterfaceSection._convert_policy_line

        self.assertEqual(
            convert_line("root (quality 100, length 10, empty, strict)"), {
                "name": "root",
                "quality": 100,
                "length": 10,
                "empty": True,
                "strict": True,
            })

        self.assertEqual(convert_line("luks (quality 100, length 10)"), {
            "name": "luks",
            "quality": 100,
            "length": 10,
        })

        with self.assertRaises(ValueError):
            convert_line("")

        with self.assertRaises(ValueError):
            convert_line("(empty)")

        with self.assertRaises(ValueError):
            convert_line("user (quality)")

        with self.assertRaises(ValueError):
            convert_line("user (invalid 100)")

        # Missing length.
        with self.assertRaises(ValueError):
            convert_line("user (quality 100)")

        # Missing quality.
        with self.assertRaises(ValueError):
            convert_line("user (length 10)")
示例#9
0
文件: error.py 项目: yurchor/dasbus
 def get_name(self, exception_type):
     """Get a DBus name for the given exception type."""
     return get_dbus_name(*self._default_namespace, exception_type.__name__)