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)
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)
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
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)
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