Example #1
0
def parseKickstart(handler, f, strict_mode=False, pass_to_boss=False):
    # preprocessing the kickstart file has already been handled in initramfs.

    ksparser = AnacondaKSParser(handler)
    kswarnings = []
    showwarning = warnings.showwarning

    def ksshowwarning(message, category, filename, lineno, file=None, line=None):
        # Print the warning with default function.
        showwarning(message, category, filename, lineno, file, line)
        # Collect pykickstart warnings.
        if issubclass(category, KickstartParseWarning):
            kswarnings.append(message)

    try:
        # Process warnings differently in this part.
        with warnings.catch_warnings():

            # Set up the warnings module.
            warnings.showwarning = ksshowwarning
            warnings.simplefilter("always", category=KickstartParseWarning)

            # Parse the kickstart file in DBus modules.
            if pass_to_boss:
                boss = BOSS.get_proxy()
                report = KickstartReport.from_structure(
                    boss.ReadKickstartFile(f)
                )
                for warn in report.warning_messages:
                    warnings.warn(warn.message, KickstartParseWarning)
                if not report.is_valid():
                    message = "\n\n".join(map(str, report.error_messages))
                    raise KickstartError(message)

            # Parse the kickstart file in anaconda.
            ksparser.readKickstart(f)

            # Process pykickstart warnings in the strict mode:
            if strict_mode and kswarnings:
                raise KickstartError("Please modify your kickstart file to fix the warnings "
                                     "or remove the `ksstrict` option.")

    except KickstartError as e:
        # We do not have an interface here yet, so we cannot use our error
        # handling callback.
        parsing_log.error(e)

        # Print kickstart warnings in the strict mode.
        if strict_mode and kswarnings:
            print(_("\nSome warnings occurred during reading the kickstart file:"))
            for w in kswarnings:
                print(str(w).strip())

        # Print an error and terminate.
        print(_("\nAn error occurred during reading the kickstart file:"
                "\n%s\n\nThe installer will now terminate.") % str(e).strip())

        util.ipmi_report(IPMI_ABORTED)
        time.sleep(10)
        sys.exit(1)
Example #2
0
    def read_kickstart(self, s):
        """Read the given kickstart string.

        The kickstart string should contain only commands and
        sections that are defined by the kickstart specification.

        :param s: a kickstart string
        :return: a kickstart report
        """
        log.debug("Reading kickstart...")
        report = KickstartReport()

        try:
            handler = self.get_kickstart_handler()
            parser = self.get_kickstart_parser(handler)

            with warnings.catch_warnings(record=True) as warns:
                warnings.simplefilter(action="always",
                                      category=KickstartParseWarning)

                parser.readKickstartFromString(s)
                self.process_kickstart(handler)

                for warn in warns:
                    if issubclass(warn.category, KickstartParseWarning):
                        data = KickstartMessage.for_warning(str(warn))
                        report.warning_messages.append(data)

        except KickstartError as e:
            data = KickstartMessage.for_error(e)
            report.error_messages.append(data)
        else:
            self.kickstarted = True

        return report
    def ReadKickstart(self, kickstart):
        """Mock parsing for now.

        Returns parse error if PARSE_ERROR string is found in kickstart.
        """
        self.kickstart = kickstart
        report = KickstartReport()

        for lnum, line in enumerate(kickstart.splitlines(), 1):
            if "PARSE_ERROR" in line:
                data = KickstartMessage()
                data.message = "Mocked parse error: \"PARSE_ERROR\" found"
                data.line_number = lnum
                report.error_messages.append(data)

        return KickstartReport.to_structure(report)
    def ReadKickstart(self, kickstart: Str) -> Structure:
        """Read the kickstart string.

        :param kickstart: a kickstart string
        :returns: a structure with a kickstart report
        """
        return KickstartReport.to_structure(
            self.implementation.read_kickstart(kickstart))
Example #5
0
    def ReadKickstartFile(self, path: Str) -> Structure:
        """Read the specified kickstart file.

        :param path: a path to a file
        :returns: a structure with a kickstart report
        """
        return KickstartReport.to_structure(
            self.implementation.read_kickstart_file(path))
Example #6
0
 def deprecated_warnings_test(self):
     response = self.timezone_interface.ReadKickstart(
         "timezone --isUtc Europe/Bratislava")
     report = KickstartReport.from_structure(response)
     self.assertIn(
         "The option --isUtc will be deprecated in future releases",
         str(report.warning_messages[0]))
     self.assertEqual(len(report.warning_messages), 1)
    def deprecated_warnings_test(self):
        response = self.timezone_interface.ReadKickstart("timezone --isUtc Europe/Bratislava")
        report = KickstartReport.from_structure(response)

        warning = "The option --isUtc will be deprecated in future releases. " \
                  "Please modify your kickstart file to replace this option with " \
                  "its preferred alias --utc."

        self.assertEqual(len(report.warning_messages), 1)
        self.assertEqual(report.warning_messages[0].message, warning)
Example #8
0
def check_kickstart_interface(test,
                              interface,
                              ks_in,
                              ks_out=None,
                              ks_valid=True,
                              ks_tmp=None):
    """Test the parsing and generating of a kickstart module.

    :param test: instance of TestCase
    :param interface: instance of KickstartModuleInterface
    :param ks_in: string with the input kickstart
    :param ks_out: string with the output kickstart
    :param ks_valid: True if the input kickstart is valid, otherwise False
    :param ks_tmp: string with the temporary output kickstart
    """
    callback = PropertiesChangedCallback()
    interface.PropertiesChanged.connect(callback)

    result = None

    # Read a kickstart,
    if ks_in is not None:
        ks_in = dedent(ks_in).strip()
        result = KickstartReport.from_structure(interface.ReadKickstart(ks_in))
        test.assertEqual(ks_valid, result.is_valid())

    if not ks_valid:
        return result

    if ks_out is None:
        return result

    # Generate a kickstart
    ks_out = dedent(ks_out).strip()
    ks_generated = clear_version_from_kickstart_string(
        interface.GenerateKickstart()).strip()
    test.assertEqual(ks_out, ks_generated)

    # Test the properties changed callback.
    if ks_in is not None:
        callback.assert_any_call(KICKSTART_MODULE.interface_name,
                                 {'Kickstarted': True}, [])
    else:
        test.assertEqual(interface.Kickstarted, False)
        callback.assert_not_called()

    # Test the temporary kickstart.
    if ks_tmp is None:
        return

    ks_tmp = dedent(ks_tmp).strip()
    test.assertEqual(ks_tmp, interface.GenerateTemporaryKickstart().strip())

    return result
    def _distribute_to_modules(self, elements):
        """Distribute split kickstart to modules synchronously.

        :returns: list of (Line number, Message) errors reported by modules when
                  distributing kickstart
        :rtype: list of kickstart reports
        """
        reports = []

        for observer in self._module_observers:
            if not observer.is_service_available:
                log.warning("Module %s not available!", observer.service_name)
                continue

            commands = observer.proxy.KickstartCommands
            sections = observer.proxy.KickstartSections
            addons = observer.proxy.KickstartAddons

            log.info("%s handles commands %s sections %s addons %s.",
                     observer.service_name, commands, sections, addons)

            module_elements = elements.get_and_process_elements(
                commands=commands,
                sections=sections,
                addons=addons
            )

            module_kickstart = elements.get_kickstart_from_elements(
                module_elements
            )

            if not module_kickstart:
                log.info("There are no kickstart data for %s.", observer.service_name)
                continue

            module_report = KickstartReport.from_structure(
                observer.proxy.ReadKickstart(module_kickstart)
            )

            line_references = elements.get_references_from_elements(
                module_elements
            )

            for message in module_report.get_messages():
                line_number, file_name = line_references[message.line_number]
                message.line_number = line_number
                message.file_name = file_name
                message.module_name = observer.service_name

            reports.append(module_report)

        return reports
Example #10
0
def distribute_kickstart(ks_path):
    tmpfile = tempfile.mktemp(suffix=".run_boss_locally.ks")
    shutil.copyfile(ks_path, tmpfile)
    print(RED + "distributing kickstart {}".format(tmpfile) + RESET)
    boss_object = test_dbus_connection.get_proxy(BOSS.service_name,
                                                 BOSS.object_path)
    try:
        report = KickstartReport.from_structure(
            boss_object.ReadKickstartFile(tmpfile))
        print("distribute_kickstart: ReadKickstartFile() errors: {}".format(
            str(report)))
    finally:
        os.unlink(tmpfile)
Example #11
0
    def _load_kickstart(self):
        """Load the kickstart"""
        from pyanaconda import kickstart

        # Construct a commandMap with only the supported Anaconda's commands
        commandMap = dict(
            (k, kickstart.commandMap[k]) for k in SUPPORTED_KICKSTART_COMMANDS)

        # Prepare new data object
        self.data = kickstart.AnacondaKSHandler(self._addon_module_paths["ks"],
                                                commandUpdates=commandMap)

        kickstart_path = INPUT_KICKSTART_PATH
        if os.path.exists(OUTPUT_KICKSTART_PATH):
            log.info("using kickstart from previous run for input")
            kickstart_path = OUTPUT_KICKSTART_PATH

        log.info("parsing input kickstart %s", kickstart_path)
        try:
            # Read the installed kickstart
            parser = kickstart.AnacondaKSParser(self.data)
            parser.readKickstart(kickstart_path)
            log.info("kickstart parsing done")
        except pykickstart.errors.KickstartError as kserr:
            log.critical("kickstart parsing failed: %s", kserr)
            log.critical(
                "Initial Setup startup failed due to invalid kickstart file")
            raise InitialSetupError

        # if we got this far the kickstart should be valid, so send it to Boss as well
        boss = BOSS.get_proxy()
        report = KickstartReport.from_structure(
            boss.ReadKickstartFile(kickstart_path))

        if not report.is_valid():
            message = "\n\n".join(map(str, report.error_messages))
            raise InitialSetupError(message)

        if self.external_reconfig:
            # set the reconfig flag in kickstart so that
            # relevant spokes show up
            services_proxy = SERVICES.get_proxy()
            services_proxy.SetSetupOnBoot(SETUP_ON_BOOT_RECONFIG)

        # Record if groups, users or root password has been set before Initial Setup
        # has been started, so that we don't trample over existing configuration.
        users_proxy = USERS.get_proxy()
        self._groups_already_configured = bool(users_proxy.Groups)
        self._users_already_configured = bool(users_proxy.Users)
        self._root_password_already_configured = users_proxy.IsRootPasswordSet
    def read_kickstart_file(self, path):
        """Read the specified kickstart file.

        :param path: a path to a file
        :returns: a kickstart report
        """
        report = KickstartReport()

        try:
            elements = self._split_to_elements(path)
            reports = self._distribute_to_modules(elements)
        except KickstartError as e:
            data = KickstartMessage.for_error(e)
            data.module_name = BOSS.service_name
            data.file_name = path
            report.error_messages.append(data)
        else:
            self._merge_module_reports(report, reports)

        return report
Example #13
0
    def read_kickstart(self, s):
        """Read the given kickstart string.

        The kickstart string should contain only commands and
        sections that are defined by the kickstart specification.

        :param s: a kickstart string
        :return: a kickstart report
        """
        log.debug("Reading kickstart...")
        report = KickstartReport()

        try:
            handler = self.get_kickstart_handler()
            parser = self.get_kickstart_parser(handler)
            parser.readKickstartFromString(s)
            self.process_kickstart(handler)
        except KickstartError as e:
            data = KickstartMessage.for_error(e)
            report.error_messages.append(data)
        else:
            self.kickstarted = True

        return report