Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
 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
Beispiel #7
0
 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
Beispiel #8
0
 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
Beispiel #9
0
    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
Beispiel #10
0
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])
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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
Beispiel #14
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
Beispiel #16
0
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))
Beispiel #17
0
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])
Beispiel #18
0
##
## 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)