class RevisorKickstart: def __init__(self, cfg=None): self.cfg = cfg def create_parser(self): self.handler = makeVersion() self.parser = KickstartParser(self.handler) def read_file(self, url): if not hasattr(self, "parser"): self.create_parser() self.parser.readKickstart(url) def _reset(self): self.parser._reset() def __str__(self): return "%s" % self.handler.__str__() def _get(self, item=None, val=None): if not item == None: if hasattr(self.handler, item): if not val is None: if hasattr(getattr(self.handler, item), val): return getattr(getattr(self.handler, item), val) elif isinstance(getattr(self.handler, item), dict): return getattr(self.handler, item)[val] else: return None else: return getattr(self.handler, item) elif hasattr(self.handler, val): return getattr(self.handler, val) else: return self.handler
def get_kickstart_reqs(kickstart_path): # gather all of the reqs listed in the %packages sections reqs = set() ksparser = KickstartParser(makeVersion()) ksparser.readKickstart(kickstart_path) reqs.update(ksparser.handler.packages.packageList) return reqs
def process_kickstart(ksfile): # pykickstart refs # https://jlaska.fedorapeople.org/pykickstart-doc/pykickstart.commands.html ksparser = KickstartParser(makeVersion()) try: ksparser.readKickstart(ksfile) except KickstartError as e: sys.stderr.write(str(e)) sys.exit(1) user_data = '#!/bin/bash' # repo for repo in ksparser.handler.repo.repoList: if repo.mirrorlist: repo_url = 'metalink=%s' % repo.mirrorlist else: repo_url = 'baseurl=%s' % repo.baseurl user_data += """ cat <<"EOF" >/etc/yum.repos.d/%s.repo [%s] name=%s %s enabled=1 gpgcheck=0 EOF """ % (repo.name, repo.name, repo.name, repo_url) # rootpw if ksparser.handler.rootpw.isCrypted: user_data += 'echo "root:%s" | chpasswd -e\n' % ksparser.handler.rootpw.password else: user_data += 'echo "root:%s" | chpasswd\n' % ksparser.handler.rootpw.password # selinux if ksparser.handler.selinux.selinux is 0: selinux_status = 'disabled' elif ksparser.handler.selinux.selinux is 2: selinux_status = 'enforcing' else: selinux_status = 'enforcing' user_data += "sed -i 's/SELINUX=.*/SELINUX=%s/' /etc/selinux/config\n" % selinux_status # %packages packages = [] for group in ksparser.handler.packages.groupList: packages.append("@%s" % group.name) for package in ksparser.handler.packages.packageList: packages.append(package) if packages: user_data += "yum -y install %s\n" % ' '.join(packages) # skip %prep # %post user_data += ksparser.handler.scripts[1].script # remove cloud-init package and reboot user_data += 'yum -y remove cloud-init\nreboot' print user_data
def _blueprint_to_ks(blueprint_data): recipe_obj = recipes.recipe_from_toml(blueprint_data) ks = KickstartParser(makeVersion()) # write out the customization data, and parse the resulting kickstart with tempfile.NamedTemporaryFile(prefix="lorax.test.customizations", mode="w") as f: add_customizations(f, recipe_obj) f.flush() ks.readKickstart(f.name) return ks
def load_or_default(system_ks_path, ks_template): """ load system ks or default ks """ ksparser = KickstartParser(makeVersion()) try: ksparser.readKickstart(system_ks_path) except (KickstartError, IOError): log_message("Cannot read the system Kickstart at %s." % system_ks_path) try: ksparser.readKickstart(ks_template) except AttributeError: log_message("There is no KS_POSTSCRIPT_TEMPLATE specified in settings.py.", level=logging.DEBUG) except IOError: log_message("Cannot read the Kickstart template %s." % ks_template) return None return ksparser
def load_or_default(system_ks_path): """load system ks or default ks""" ksparser = KickstartParser(makeVersion()) try: ksparser.readKickstart(system_ks_path) except (KickstartError, IOError): log_message("Can't read system kickstart at {0}".format(system_ks_path)) try: ksparser.readKickstart(settings.KS_TEMPLATE) except AttributeError: log_message("There is no KS_TEMPLATE_POSTSCRIPT specified in settings.py") except IOError: log_message("Can't read kickstart template {0}".format(settings.KS_TEMPLATE)) return None return ksparser
def load_or_default(system_ks_path): """load system ks or default ks""" ksparser = KickstartParser(makeVersion()) try: ksparser.readKickstart(system_ks_path) except (KickstartError, IOError): log_message( "Can't read system kickstart at {0}".format(system_ks_path)) try: ksparser.readKickstart(settings.KS_TEMPLATE) except AttributeError: log_message( "There is no KS_TEMPLATE_POSTSCRIPT specified in settings.py" ) except IOError: log_message("Can't read kickstart template {0}".format( settings.KS_TEMPLATE)) return None return ksparser
def load_or_default(system_ks_path, ks_template): """ load system ks or default ks """ ksparser = KickstartParser(makeVersion()) try: ksparser.readKickstart(system_ks_path) except (KickstartError, IOError): log_message("Cannot read the system Kickstart at %s." % system_ks_path) try: ksparser.readKickstart(ks_template) except AttributeError: log_message( "There is no KS_POSTSCRIPT_TEMPLATE specified in settings.py.", level=logging.DEBUG) except IOError: log_message("Cannot read the Kickstart template %s." % ks_template) return None return ksparser
def add_repo(self, ksfile, siderepo): """ Add a repository to an existing KS file """ # read ksparser = KickstartParser(makeVersion()) ksparser.readKickstart(ksfile) #obtain the handler dump kshandlers = ksparser.handler # add a repository kshandlers.repo.repoList.extend(['repo --name="siderepo" --baseurl={0:s}\n'.format(siderepo)]) # Write a new ks file outfile = open(ksfile, 'w') outfile.write(kshandlers.__str__()) outfile.close() return
def main(argv): op = argparse.ArgumentParser(usage="%(prog)s [options] ksfile", add_help=False) op.add_argument("ksfile", nargs="?", help=_("filename or URL to read from")) op.add_argument("-e", "--firsterror", dest="firsterror", action="store_true", default=False, help=_("halt after the first error or warning")) op.add_argument("-i", "--followincludes", dest="followincludes", action="store_true", default=False, help=_("parse include files when %%include is seen")) op.add_argument("-l", "--listversions", dest="listversions", action="store_true", default=False, help=_("list the available versions of kickstart syntax")) op.add_argument("-v", "--version", dest="version", default=DEVEL, help=_("version of kickstart syntax to validate against")) op.add_argument("-h", "--help", dest="help", action="store_true", default=False, help=_("show this help message and exit")) opts = op.parse_args(argv) # parse --help manually b/c we don't want to sys.exit before the # tests have finished if opts.help: return (0, op.format_help().split("\n")) if opts.listversions: versions = [] for key in sorted(versionMap.keys()): versions.append(key) return (0, versions) if not opts.ksfile: return (1, op.format_usage().split("\n")) destdir = tempfile.mkdtemp("", "ksvalidator-tmp-", "/tmp") try: f = load_to_file(opts.ksfile, "%s/ks.cfg" % destdir) except KickstartError as e: return (cleanup(destdir), [_("Error reading %(filename)s:\n%(version)s") % {"filename": opts.ksfile, "version": e}]) try: handler = makeVersion(opts.version) except KickstartVersionError: return (cleanup(destdir), [_("The version %s is not supported by pykickstart") % opts.version]) ksparser = KickstartParser(handler, followIncludes=opts.followincludes, errorsAreFatal=opts.firsterror) # turn kickstart parse warnings into errors warnings.filterwarnings(action="error", category=KickstartParseWarning) processedFile = None try: processedFile = preprocessKickstart(f) ksparser.readKickstart(processedFile) return (cleanup(destdir, processedFile, exitval=ksparser.errorsCount), []) except KickstartDeprecationWarning as err: return (cleanup(destdir, processedFile), [_("File uses a deprecated option or command.\n%s") % err]) except KickstartParseError as err: return (cleanup(destdir, processedFile), [str(err)]) except KickstartError: return (cleanup(destdir, processedFile), [_("General kickstart error in input file")]) except Exception as e: return (cleanup(destdir, processedFile), [_("General error in input file: %s") % e])
def run_creator(opts, cancel_func=None): """Run the image creator process :param opts: Commandline options to control the process :type opts: Either a DataHolder or ArgumentParser :param cancel_func: Function that returns True to cancel build :type cancel_func: function :returns: The result directory and the disk image path. :rtype: Tuple of str This function takes the opts arguments and creates the selected output image. See the cmdline --help for livemedia-creator for the possible options (Yes, this is not ideal, but we can fix that later) """ result_dir = None # Parse the kickstart if opts.ks: ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstart(opts.ks[0]) # live iso usually needs dracut-live so warn the user if it is missing if opts.ks and opts.make_iso: if "dracut-live" not in ks.handler.packages.packageList: log.error("dracut-live package is missing from the kickstart.") raise RuntimeError( "dracut-live package is missing from the kickstart.") # Make the disk or filesystem image if not opts.disk_image and not opts.fs_image: if not opts.ks: raise RuntimeError("Image creation requires a kickstart file") # Check the kickstart for problems errors = check_kickstart(ks, opts) if errors: list(log.error(e) for e in errors) raise RuntimeError("\n".join(errors)) # Make the image. Output of this is either a partitioned disk image or a fsimage try: disk_img = make_image(opts, ks, cancel_func=cancel_func) except InstallError as e: log.error("ERROR: Image creation failed: %s", e) raise RuntimeError("Image creation failed: %s" % e) if opts.image_only: return (result_dir, disk_img) if opts.make_iso: work_dir = tempfile.mkdtemp(prefix="lmc-work-") log.info("working dir is %s", work_dir) if (opts.fs_image or opts.no_virt) and not opts.disk_image: # Create iso from a filesystem image disk_img = opts.fs_image or disk_img if not make_squashfs(opts, disk_img, work_dir): log.error("squashfs.img creation failed") raise RuntimeError("squashfs.img creation failed") if cancel_func and cancel_func(): raise RuntimeError("ISO creation canceled") with Mount(disk_img, opts="loop") as mount_dir: result_dir = make_livecd(opts, mount_dir, work_dir) else: # Create iso from a partitioned disk image disk_img = opts.disk_image or disk_img with PartitionMount(disk_img) as img_mount: if img_mount and img_mount.mount_dir: make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks) / 1024.0) result_dir = make_livecd(opts, img_mount.mount_dir, work_dir) # --iso-only removes the extra build artifacts, keeping only the boot.iso if opts.iso_only and result_dir: boot_iso = joinpaths(result_dir, "images/boot.iso") if not os.path.exists(boot_iso): log.error("%s is missing, skipping --iso-only.", boot_iso) else: iso_dir = tempfile.mkdtemp(prefix="lmc-result-") dest_file = joinpaths(iso_dir, opts.iso_name or "boot.iso") shutil.move(boot_iso, dest_file) shutil.rmtree(result_dir) result_dir = iso_dir # cleanup the mess # cleanup work_dir? if disk_img and not (opts.keep_image or opts.disk_image or opts.fs_image): os.unlink(disk_img) log.info("Disk image erased") disk_img = None elif opts.make_appliance: if not opts.ks: networks = [] else: networks = ks.handler.network.network make_appliance(opts.disk_image or disk_img, opts.app_name, opts.app_template, opts.app_file, networks, opts.ram, opts.vcpus or 1, opts.arch, opts.title, opts.project, opts.releasever) elif opts.make_pxe_live: work_dir = tempfile.mkdtemp(prefix="lmc-work-") log.info("working dir is %s", work_dir) disk_img = opts.fs_image or opts.disk_image or disk_img log.debug("disk image is %s", disk_img) result_dir = make_live_images(opts, work_dir, disk_img) if result_dir is None: log.error("Creating PXE live image failed.") raise RuntimeError("Creating PXE live image failed.") if opts.result_dir != opts.tmp and result_dir: copytree(result_dir, opts.result_dir, preserve=False) shutil.rmtree(result_dir) result_dir = None return (result_dir, disk_img)
def run_creator(opts, callback_func=None): """Run the image creator process :param opts: Commandline options to control the process :type opts: Either a DataHolder or ArgumentParser :returns: The result directory and the disk image path. :rtype: Tuple of str This function takes the opts arguments and creates the selected output image. See the cmdline --help for livemedia-creator for the possible options (Yes, this is not ideal, but we can fix that later) """ result_dir = None # Parse the kickstart if opts.ks: ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstart(opts.ks[0]) # live iso usually needs dracut-live so warn the user if it is missing if opts.ks and opts.make_iso: if "dracut-live" not in ks.handler.packages.packageList: log.error("dracut-live package is missing from the kickstart.") raise RuntimeError("dracut-live package is missing from the kickstart.") # Make the disk or filesystem image if not opts.disk_image and not opts.fs_image: if not opts.ks: raise RuntimeError("Image creation requires a kickstart file") errors = [] if opts.no_virt and ks.handler.method.method not in ("url", "nfs") \ and not ks.handler.ostreesetup.seen: errors.append("Only url, nfs and ostreesetup install methods are currently supported." "Please fix your kickstart file." ) if ks.handler.method.method in ("url", "nfs") and not ks.handler.network.seen: errors.append("The kickstart must activate networking if " "the url or nfs install method is used.") if ks.handler.displaymode.displayMode is not None: errors.append("The kickstart must not set a display mode (text, cmdline, " "graphical), this will interfere with livemedia-creator.") if opts.make_fsimage or (opts.make_pxe_live and opts.no_virt): # Make sure the kickstart isn't using autopart and only has a / mountpoint part_ok = not any(p for p in ks.handler.partition.partitions if p.mountpoint not in ["/", "swap"]) if not part_ok or ks.handler.autopart.seen: errors.append("Filesystem images must use a single / part, not autopart or " "multiple partitions. swap is allowed but not used.") if not opts.no_virt and ks.handler.reboot.action != KS_SHUTDOWN: errors.append("The kickstart must include shutdown when using virt installation.") if errors: list(log.error(e) for e in errors) raise RuntimeError("\n".join(errors)) # Make the image. Output of this is either a partitioned disk image or a fsimage try: disk_img = make_image(opts, ks) except InstallError as e: log.error("ERROR: Image creation failed: %s", e) raise RuntimeError("Image creation failed: %s" % e) if opts.image_only: return (result_dir, disk_img) if opts.make_iso: work_dir = tempfile.mkdtemp(prefix="lmc-work-") log.info("working dir is %s", work_dir) if (opts.fs_image or opts.no_virt) and not opts.disk_image: # Create iso from a filesystem image disk_img = opts.fs_image or disk_img if not make_squashfs(opts, disk_img, work_dir): log.error("squashfs.img creation failed") raise RuntimeError("squashfs.img creation failed") with Mount(disk_img, opts="loop") as mount_dir: result_dir = make_livecd(opts, mount_dir, work_dir) else: # Create iso from a partitioned disk image disk_img = opts.disk_image or disk_img with PartitionMount(disk_img) as img_mount: if img_mount and img_mount.mount_dir: make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) result_dir = make_livecd(opts, img_mount.mount_dir, work_dir) # --iso-only removes the extra build artifacts, keeping only the boot.iso if opts.iso_only and result_dir: boot_iso = joinpaths(result_dir, "images/boot.iso") if not os.path.exists(boot_iso): log.error("%s is missing, skipping --iso-only.", boot_iso) else: iso_dir = tempfile.mkdtemp(prefix="lmc-result-") dest_file = joinpaths(iso_dir, opts.iso_name or "boot.iso") shutil.move(boot_iso, dest_file) shutil.rmtree(result_dir) result_dir = iso_dir # cleanup the mess # cleanup work_dir? if disk_img and not (opts.keep_image or opts.disk_image or opts.fs_image): os.unlink(disk_img) log.info("Disk image erased") disk_img = None elif opts.make_appliance: if not opts.ks: networks = [] else: networks = ks.handler.network.network make_appliance(opts.disk_image or disk_img, opts.app_name, opts.app_template, opts.app_file, networks, opts.ram, opts.vcpus or 1, opts.arch, opts.title, opts.project, opts.releasever) elif opts.make_pxe_live: work_dir = tempfile.mkdtemp(prefix="lmc-work-") log.info("working dir is %s", work_dir) disk_img = opts.fs_image or opts.disk_image or disk_img log.debug("disk image is %s", disk_img) result_dir = make_live_images(opts, work_dir, disk_img) if result_dir is None: log.error("Creating PXE live image failed.") raise RuntimeError("Creating PXE live image failed.") if opts.result_dir != opts.tmp and result_dir: copytree(result_dir, opts.result_dir, preserve=False) shutil.rmtree(result_dir) result_dir = None return (result_dir, disk_img)
def main(argv=None): ## ## OPTION PROCESSING ## op = argparse.ArgumentParser() op.add_argument("-i", "--input", dest="input", help=_("a basis file to use for seeding the kickstart data (optional)")) op.add_argument("-o", "--output", dest="output", help=_("the location to write the finished kickstart file, or stdout if not given")) op.add_argument("-v", "--version", dest="version", default=DEVEL, help=_("version of kickstart syntax to validate against")) opts = op.parse_args(argv) ## ## SETTING UP PYKICKSTART ## try: kshandler = makeVersion(opts.version) except KickstartVersionError: print(_("The version %s is not supported by pykickstart") % opts.version) return 1 ksparser = KickstartParser(kshandler, followIncludes=True, errorsAreFatal=False) if opts.input: try: processedFile = preprocessKickstart(opts.input) ksparser.readKickstart(processedFile) os.remove(processedFile) except KickstartError as e: # Errors should just dump you to the prompt anyway. print(_("Warning: The following error occurred when processing the input file:\n%s\n") % e) internalCommands = {".clear": ClearCommand(), ".show": ShowCommand(), ".quit": QuitCommand()} ## ## SETTING UP READLINE ## readline.parse_and_bind("tab: complete") readline.set_completer(KickstartCompleter(kshandler, internalCommands).complete) # Since everything in kickstart looks like a command line arg, we need to # remove '-' from the delimiter string. delims = readline.get_completer_delims() readline.set_completer_delims(delims.replace('-', '')) ## ## REPL ## print("Press ^D to exit.") while True: try: line = six.moves.input("ks> ") # pylint: disable=no-member except EOFError: # ^D was hit, time to quit. break except KeyboardInterrupt: # ^C was hit, time to quit. Don't be like other programs. break # All internal commands start with a ., so if that's the beginning of the # line, we need to dispatch ourselves. if line.startswith("."): words = line.split() if words[0] in internalCommands: try: internalCommands[words[0]].execute(ksparser) except EOFError: # ".quit" was typed, time to quit. break else: print(_("Internal command %s not recognized.") % words[0]) continue # Now process the line of input as if it were a kickstart file - just an # extremely short one. try: ksparser.readKickstartFromString(line) except KickstartError as e: print(e) # And finally, print the output kickstart file. if opts.output: with open(opts.output, "w") as fd: fd.write(str(ksparser.handler)) else: print("\n" + str(ksparser.handler)) return 0
handler = makeVersion(opts.version) except KickstartVersionError: print(_("The version %s is not supported by pykickstart") % opts.version) cleanup(destdir) ksparser = KickstartParser(handler, followIncludes=opts.followincludes, errorsAreFatal=opts.firsterror) # turn DeprecationWarnings into errors warnings.filterwarnings("error") processedFile = None try: processedFile = preprocessKickstart(f) ksparser.readKickstart(processedFile) cleanup(destdir, processedFile, exitval=0) except DeprecationWarning as msg: print(_("File uses a deprecated option or command.\n%s") % msg) cleanup(destdir, processedFile) except KickstartParseError as msg: print(msg) cleanup(destdir, processedFile) except KickstartError: print(_("General kickstart error in input file")) cleanup(destdir, processedFile) except Exception as e: print(_("General error in input file: %s") % e) cleanup(destdir, processedFile)
def main(argv): op = argparse.ArgumentParser(usage="%(prog)s [options] ksfile [ksfile...]", add_help=False) op.add_argument("ksfile", nargs="*", help=_("filename or URL to read from")) op.add_argument("-e", "--firsterror", dest="firsterror", action="store_true", default=False, help=_("halt after the first error or warning")) op.add_argument("-i", "--followincludes", dest="followincludes", action="store_true", default=False, help=_("parse include files when %%include is seen")) op.add_argument("-l", "--listversions", dest="listversions", action="store_true", default=False, help=_("list the available versions of kickstart syntax")) op.add_argument("-v", "--version", dest="version", default=DEVEL, help=_("version of kickstart syntax to validate against")) op.add_argument("-h", "--help", dest="help", action="store_true", default=False, help=_("show this help message and exit")) opts = op.parse_args(argv) # parse --help manually b/c we don't want to sys.exit before the # tests have finished if opts.help: return (0, op.format_help().split("\n")) if opts.listversions: versions = [] for key in sorted(versionMap.keys()): versions.append(key) return (0, versions) if not opts.ksfile: return (1, op.format_usage().split("\n")) rc = 0 retmsg = [] # unpack any globs ksfiles = [] for inksfile in opts.ksfile: if is_url(inksfile): ksfiles.append(inksfile) else: ksfiles.extend(glob.glob(inksfile)) # check if there are any files to check if not ksfiles: return (1, ["No files match the patterns."]) # iterate over files to check them with tempfile.TemporaryDirectory(prefix="ksvalidator-tmp-") as destdir: for ksfile in ksfiles: print( _("\nChecking kickstart file %(filename)s\n" % {"filename": ksfile})) try: f = load_to_file(ksfile, os.path.join(destdir, "ks.cfg")) except KickstartError as e: rc += 1 retmsg.append( _("Error reading %(filename)s:\n%(version)s") % { "filename": ksfile, "version": e }) try: handler = makeVersion(opts.version) except KickstartVersionError: # return immediately because bad version is fatal for all files return (1, [ _("The version %s is not supported by pykickstart") % opts.version ]) # turn kickstart parse warnings into errors warnings.filterwarnings(action="error", category=KickstartParseWarning) ksparser = KickstartParser(handler, followIncludes=opts.followincludes, errorsAreFatal=opts.firsterror) try: processedFile = preprocessKickstart(f) if processedFile is None: raise RuntimeError("Empty file") ksparser.readKickstart(processedFile) rc += ksparser.errorsCount except KickstartDeprecationWarning as err: rc += 1 retmsg.append( _("File uses a deprecated option or command.\n%s") % err) except KickstartParseError as err: rc += 1 retmsg.append(str(err)) except KickstartError: rc += 1 retmsg.append(_("General kickstart error in input file")) except Exception as e: # pylint: disable=broad-except rc += 1 retmsg.append(_("General error in input file: %s") % e) return rc, retmsg
def main(): ## ## OPTION PROCESSING ## op = argparse.ArgumentParser() op.add_argument("-i", "--input", dest="input", help=_("a basis file to use for seeding the kickstart data (optional)")) op.add_argument("-o", "--output", dest="output", help=_("the location to write the finished kickstart file, or stdout if not given")) op.add_argument("-v", "--version", dest="version", default=DEVEL, help=_("version of kickstart syntax to validate against")) opts = op.parse_args(sys.argv[1:]) ## ## SETTING UP PYKICKSTART ## try: kshandler = makeVersion(opts.version) except KickstartVersionError: print(_("The version %s is not supported by pykickstart") % opts.version) sys.exit(1) ksparser = KickstartParser(kshandler, followIncludes=True, errorsAreFatal=False) if opts.input: try: processedFile = preprocessKickstart(opts.input) ksparser.readKickstart(processedFile) os.remove(processedFile) except KickstartError as e: # Errors should just dump you to the prompt anyway. print(_("Warning: The following error occurred when processing the input file:\n%s\n") % e) internalCommands = {".clear": ClearCommand(), ".show": ShowCommand(), ".quit": QuitCommand()} ## ## SETTING UP READLINE ## readline.parse_and_bind("tab: complete") readline.set_completer(KickstartCompleter(kshandler, internalCommands).complete) # Since everything in kickstart looks like a command line arg, we need to # remove '-' from the delimiter string. delims = readline.get_completer_delims() readline.set_completer_delims(delims.replace('-', '')) ## ## REPL ## print("Press ^D to exit.") while True: try: line = six.moves.input("ks> ") # pylint: disable=no-member except EOFError: # ^D was hit, time to quit. break except KeyboardInterrupt: # ^C was hit, time to quit. Don't be like other programs. break # All internal commands start with a ., so if that's the beginning of the # line, we need to dispatch ourselves. if line.startswith("."): words = line.split() if words[0] in internalCommands: try: internalCommands[words[0]].execute(ksparser) except EOFError: # ".quit" was typed, time to quit. break else: print(_("Internal command %s not recognized.") % words[0]) continue # Now process the line of input as if it were a kickstart file - just an # extremely short one. try: ksparser.readKickstartFromString(line) except KickstartError as e: print(e) # And finally, print the output kickstart file. if opts.output: with open(opts.output, "w") as fd: fd.write(str(ksparser.handler)) else: print("\n" + str(ksparser.handler))
def main(argv): op = argparse.ArgumentParser(usage="%(prog)s [options] ksfile", add_help=False) op.add_argument("ksfile", nargs="?", help=_("filename or URL to read from")) op.add_argument("-e", "--firsterror", dest="firsterror", action="store_true", default=False, help=_("halt after the first error or warning")) op.add_argument("-i", "--followincludes", dest="followincludes", action="store_true", default=False, help=_("parse include files when %%include is seen")) op.add_argument("-l", "--listversions", dest="listversions", action="store_true", default=False, help=_("list the available versions of kickstart syntax")) op.add_argument("-v", "--version", dest="version", default=DEVEL, help=_("version of kickstart syntax to validate against")) op.add_argument("-h", "--help", dest="help", action="store_true", default=False, help=_("show this help message and exit")) opts = op.parse_args(argv) # parse --help manually b/c we don't want to sys.exit before the # tests have finished if opts.help: return (0, op.format_help().split("\n")) if opts.listversions: versions = [] for key in sorted(versionMap.keys()): versions.append(key) return (0, versions) if not opts.ksfile: return (1, op.format_usage().split("\n")) destdir = tempfile.mkdtemp("", "ksvalidator-tmp-", "/tmp") try: f = load_to_file(opts.ksfile, "%s/ks.cfg" % destdir) except KickstartError as e: return (cleanup(destdir), [_("Error reading %(filename)s:\n%(version)s") % {"filename": opts.ksfile, "version": e}]) try: handler = makeVersion(opts.version) except KickstartVersionError: return (cleanup(destdir), [_("The version %s is not supported by pykickstart") % opts.version]) ksparser = KickstartParser(handler, followIncludes=opts.followincludes, errorsAreFatal=opts.firsterror) # turn DeprecationWarnings into errors warnings.filterwarnings("error") processedFile = None try: processedFile = preprocessKickstart(f) ksparser.readKickstart(processedFile) return (cleanup(destdir, processedFile, exitval=ksparser.errorsCount), []) except DeprecationWarning as err: return (cleanup(destdir, processedFile), [_("File uses a deprecated option or command.\n%s") % err]) except KickstartParseError as err: return (cleanup(destdir, processedFile), [str(err)]) except KickstartError: return (cleanup(destdir, processedFile), [_("General kickstart error in input file")]) except Exception as e: return (cleanup(destdir, processedFile), [_("General error in input file: %s") % e])
## ## SETTING UP PYKICKSTART ## try: kshandler = makeVersion(opts.version) except KickstartVersionError: print(_("The version %s is not supported by pykickstart") % opts.version) sys.exit(1) ksparser = KickstartParser(kshandler, followIncludes=True, errorsAreFatal=False) if opts.input: try: processedFile = preprocessKickstart(opts.input) ksparser.readKickstart(processedFile) os.remove(processedFile) except KickstartError as e: # Errors should just dump you to the prompt anyway. print(_("Warning: The following error occurred when processing the input file:\n%s\n") % e) internalCommands = {".clear": ClearCommand(), ".show": ShowCommand(), ".quit": QuitCommand()} ## ## SETTING UP READLINE ## readline.parse_and_bind("tab: complete") readline.set_completer(KickstartCompleter(kshandler, internalCommands).complete)