Esempio n. 1
0
def stringToVersion(s):
    """Convert string into one of the provided version constants.  Raises
       KickstartVersionError if string does not match anything.
    """
    # First try these short forms.
    try:
        return versionMap[s.upper()]
    except KeyError:
        pass

    # Now try the Fedora versions.
    m = re.match(r"^fedora.* (\d+)$", s, re.I)

    if m and m.group(1):
        if "FC" + m.group(1) in versionMap:
            return versionMap["FC" + m.group(1)]
        elif "F" + m.group(1) in versionMap:
            return versionMap["F" + m.group(1)]
        else:
            raise KickstartVersionError(_("Unsupported version specified: %s") % s)

    # Now try the RHEL versions.
    m = re.match(r"^red hat enterprise linux.* (\d+)([\.\d]*)$", s, re.I)

    if m and m.group(1):
        if "RHEL" + m.group(1) in versionMap:
            return versionMap["RHEL" + m.group(1)]
        else:
            raise KickstartVersionError(_("Unsupported version specified: %s") % s)

    # If nothing else worked, we're out of options.
    raise KickstartVersionError(_("Unsupported version specified: %s") % s)
Esempio n. 2
0
    def handleHeader(self, lineno, args):
        """Process the arguments to the %packages header and set attributes
           on the Version's Packages instance appropriate.  This method may be
           overridden in a subclass if necessary.
        """
        Section.handleHeader(self, lineno, args)
        op = self._getParser()
        ns = op.parse_args(args=args[1:], lineno=lineno)

        if ns.defaultPackages and ns.nobase:
            raise KickstartParseError(formatErrorMsg(lineno, msg=_("--default and --nobase cannot be used together")), lineno=lineno)
        elif ns.defaultPackages and ns.nocore:
            raise KickstartParseError(formatErrorMsg(lineno, msg=_("--default and --nocore cannot be used together")), lineno=lineno)

        self.handler.packages.excludeDocs = ns.excludedocs
        self.handler.packages.addBase = not ns.nobase
        if ns.ignoremissing:
            self.handler.packages.handleMissing = KS_MISSING_IGNORE
        else:
            self.handler.packages.handleMissing = KS_MISSING_PROMPT

        if ns.defaultPackages:
            self.handler.packages.default = True

        if ns.instLangs is not None:
            self.handler.packages.instLangs = ns.instLangs

        self.handler.packages.nocore = ns.nocore
        self.handler.packages.multiLib = ns.multiLib
        self.handler.packages.excludeWeakdeps = ns.excludeWeakdeps
        self.handler.packages.timeout = ns.timeout
        self.handler.packages.retries = ns.retries
        self.handler.packages.seen = True
Esempio n. 3
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if not ns.format:
            ns.preexist = True

        vg = self.handler.VolGroupData()
        self.set_to_obj(ns, vg)
        vg.lineno = self.lineno

        if len(extra) == 0:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("volgroup must be given a VG name")))
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "volgroup", "options": extra}
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))

        if len(extra) == 1 and not ns.preexist:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("volgroup must be given a list of partitions")))
        elif len(extra) > 1 and ns.preexist:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Members may not be specified for preexisting volgroup")))

        vg.vgname = extra[0]

        if len(extra) > 1:
            vg.physvols = extra[1:]

        # Check for duplicates in the data list.
        if vg in self.dataList():
            warnings.warn(_("A volgroup with the name %s has already been defined.") % vg.vgname)

        return vg
Esempio n. 4
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)

        snap_data = self.dataClass()   # pylint: disable=not-callable
        self.set_to_obj(ns, snap_data)
        snap_data.lineno = self.lineno

        # Check for duplicates
        if snap_data.name in [snap.name for snap in self.dataList()]:
            msg = (_("Snapshot with the name %s has been already defined!") % snap_data.name)
            raise KickstartParseError(msg, lineno=self.lineno)

        if snap_data.when is None:
            msg = _("Snapshot \"when\" parameter must be specified!")
            raise KickstartParseError(msg, lineno=self.lineno)

        groups = snap_data.origin.split('/')
        if len(groups) != 2 or len(groups[0]) == 0 or len(groups[1]) == 0:
            msg = (_("Snapshot origin %s must be specified by VG/LV!") % snap_data.origin)
            raise KickstartParseError(msg, lineno=self.lineno)

        # Check if value in a '--when' param is valid
        if snap_data.when != "" and snap_data.when not in self.whenMap.values():
            msg = (_("Snapshot when param must have one of these values %s!") %
                   self.whenMap.keys())
            raise KickstartParseError(msg, lineno=self.lineno)

        return snap_data
Esempio n. 5
0
def main(argv=None):
    opts = parse_args(argv)
    if not opts.kscfg:
        return (1, _("Need to specify a config to flatten"))

    try:
        ksversion = makeVersion(opts.version)
    except KickstartVersionError:
        print(_("The version %s is not supported by pykickstart") % opts.version)
        sys.exit(1)

    ksparser = pykickstart.parser.KickstartParser(ksversion)
    try:
        ksparser.readKickstart(opts.kscfg)
    except IOError as msg:
        return (1, _("Failed to read kickstart file '%(filename)s' : %(error_msg)s") % {"filename": opts.kscfg, "error_msg": msg})
    except pykickstart.errors.KickstartError as e:
        return (1, _("Failed to parse kickstart file '%(filename)s' : %(error_msg)s") % {"filename": opts.kscfg, "error_msg": e})

    if opts.output:
        try:
            f = open(opts.output, 'w')
        except IOError as msg:
            return (1, _("Failed to open output file '%(filename)s' : %(error_msg)s") % {"filename": opts.output, "error_msg": msg})
    else:
        f = sys.stdout

    f.write("%s" % ksparser.handler)

    if opts.output:
        f.close()

    return (0, '')
Esempio n. 6
0
    def check_values (self, values, args):
        def seen(option):
            return option in self.option_seen

        def usedTooNew(option):
            return option.introduced and option.introduced > self.version

        def usedDeprecated(option):
            return option.deprecated

        def usedRemoved(option):
            return option.removed and option.removed <= self.version

        for option in [o for o in self.option_list if isinstance(o, Option)]:
            if option.required and not seen(option):
                raise KickstartValueError(formatErrorMsg(self.lineno, _("Option %s is required") % option))
            elif seen(option) and usedTooNew(option):
                mapping = {"option": option, "intro": versionToString(option.introduced),
                           "version": versionToString(self.version)}
                self.error(_("The %(option)s option was introduced in version %(intro)s, but you are using kickstart syntax version %(version)s.") % mapping)
            elif seen(option) and usedRemoved(option):
                mapping = {"option": option, "removed": versionToString(option.removed),
                           "version": versionToString(self.version)}

                if option.removed == self.version:
                    self.error(_("The %(option)s option is no longer supported.") % mapping)
                else:
                    self.error(_("The %(option)s option was removed in version %(removed)s, but you are using kickstart syntax version %(version)s.") % mapping)
            elif seen(option) and usedDeprecated(option) and self.version >= option.deprecated:
                mapping = {"lineno": self.lineno, "option": option}
                warnings.warn(_("Ignoring deprecated option on line %(lineno)s:  The %(option)s option has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this option.") % mapping, DeprecationWarning)

        return (values, args)
Esempio n. 7
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) > 1:
            raise KickstartParseError(
                formatErrorMsg(self.lineno, msg=_("Only one partition may be specified for driverdisk command."))
            )
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "driverdisk", "options": extra}
            raise KickstartParseError(
                formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
            )

        if len(extra) == 1 and ns.source:
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno, msg=_("Only one of --source and partition may be specified for driverdisk command.")
                )
            )

        if not extra and not ns.source:
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno, msg=_("One of --source or partition must be specified for driverdisk command.")
                )
            )

        ddd = self.handler.DriverDiskData()
        self.set_to_obj(ns, ddd)
        ddd.lineno = self.lineno
        if len(extra) == 1:
            ddd.partition = extra[0]

        return ddd
Esempio n. 8
0
    def parse(self, args):
        # call the overridden command to do it's job first
        retval = F21_Network.parse(self, args)

        # validate the network interface name
        error_message = validate_network_interface_name(retval.interfacename)
        # something is wrong with the interface name
        if error_message:
            raise KickstartParseError(error_message, lineno=self.lineno)

        if retval.bridgeopts:
            if not retval.bridgeslaves:
                msg = _("Option --bridgeopts requires --bridgeslaves to be specified")
                raise KickstartParseError(msg, lineno=self.lineno)
            opts = retval.bridgeopts.split(",")
            for opt in opts:
                _key, _sep, value = opt.partition("=")
                if not value or "=" in value:
                    msg = _("Bad format of --bridgeopts, expecting key=value options separated by ','")
                    raise KickstartParseError(msg, lineno=self.lineno)

        if retval.bindto == BIND_TO_MAC:
            if retval.vlanid and not retval.bondopts:
                msg = _("--bindto=%s is not supported for this type of device") % BIND_TO_MAC
                raise KickstartParseError(msg, lineno=self.lineno)

        return retval
Esempio n. 9
0
def formatErrorMsg(lineno, msg=""):
    """Properly format the error message msg for inclusion in an exception."""
    if msg != "":
        mapping = {"lineno": lineno, "msg": msg}
        return _("The following problem occurred on line %(lineno)s of the kickstart file:\n\n%(msg)s\n") % mapping
    else:
        return _("There was a problem reading from line %s of the kickstart file") % lineno
Esempio n. 10
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)
        self.set_to_self(ns)

        # just "timezone" without any arguments and timezone specification doesn't really make sense,
        # so throw an error when we see it (it might even be an indication of an incorrect machine generated kickstart)
        if not args:
            error_message = _("At least one option and/or an argument are expected for the  %s command") % "timezone"
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=error_message))

        # To be able to support the timezone command being used without
        # a timezone specification:
        # - we don't call the parse() method of the ancestors
        # -> due to the FC3 parse() method that would be eventually called,
        #    which throws an exception if no timezone specification is provided
        # - we implement the relevant functionality of the ancestor methods here

        if len(ns.timezone) == 1:
            self.timezone = ns.timezone[0]
        elif len(ns.timezone) > 1:
            error_message = _("One or zero arguments are expected for the %s command") % "timezone"
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=error_message))

        if self.ntpservers and self.nontp:
            msg = formatErrorMsg(self.lineno, msg=_("Options --nontp and --ntpservers are mutually exclusive"))
            raise KickstartParseError(msg)

        return self
Esempio n. 11
0
    def parse(self, args):
        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
        data = self.handler.BTRFSData()
        self._setToObj(self.op, opts, data)
        data.lineno = self.lineno

        if len(extra) == 0:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("btrfs must be given a mountpoint")))

        if len(extra) == 1 and not data.subvol:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("btrfs must be given a list of partitions")))
        elif len(extra) == 1:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("btrfs subvol requires specification of parent volume")))

        if data.subvol and not data.name:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("btrfs subvolume requires a name")))

        data.mountpoint = extra[0]
        data.devices = extra[1:]

        # Check for duplicates in the data list.
        if data in self.dataList():
            warnings.warn(_("A btrfs volume with the mountpoint %s has already been defined.") % data.label)

        return data
Esempio n. 12
0
    def _parseJoin(self, args):
        try:
            # We only support these args
            opts, remaining = getopt.getopt(args, "", ("client-software=",
                                                       "server-software=",
                                                       "membership-software=",
                                                       "one-time-password="******"no-password",
                                                       "computer-ou="))
        except getopt.GetoptError as ex:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_(
                "Invalid realm arguments: %s") % ex))

        if len(remaining) != 1:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_(
                "Specify only one realm to join")))

        # Parse successful, just use this as the join command
        self.join_realm = remaining[0]
        self.join_args = args

        # Build a discovery command
        self.discover_options = []
        supported_discover_options = ("--client-software",
                                      "--server-software",
                                      "--membership-software")
        for (o, a) in opts:
            if o in supported_discover_options:
                self.discover_options.append("%s=%s" % (o, a))
Esempio n. 13
0
    def parse(self, args):
        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
        vg = self.handler.VolGroupData()
        self._setToObj(self.op, opts, vg)
        vg.lineno = self.lineno

        if len(extra) == 0:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("volgroup must be given a VG name")))

        if len(extra) == 1 and not opts.preexist:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("volgroup must be given a list of partitions")))
        elif len(extra) > 1 and opts.preexist:
            raise KickstartValueError(
                formatErrorMsg(self.lineno, msg=_("Members may not be specified for preexisting volgroup"))
            )

        vg.vgname = extra[0]

        if len(extra) > 1:
            vg.physvols = extra[1:]

        # Check for duplicates in the data list.
        if vg in self.dataList():
            warnings.warn(_("A volgroup with the name %s has already been defined.") % vg.vgname)

        return vg
Esempio n. 14
0
def main():
    opts = parse_args()
    if not opts.kscfg:
        print(_("Need to specify a config to flatten"), file=sys.stderr)
        sys.exit(1)

    ksversion = makeVersion(opts.version)
    ksparser = pykickstart.parser.KickstartParser(ksversion)
    try:
        ksparser.readKickstart(opts.kscfg)
    except IOError as msg:
        print(_("Failed to read kickstart file '%(filename)s' : %(error_msg)s") % {"filename": opts.kscfg, "error_msg": msg}, file=sys.stderr)
        sys.exit(1)
    except pykickstart.errors.KickstartError as e:
        print(_("Failed to parse kickstart file '%(filename)s' : %(error_msg)s") % {"filename": opts.kscfg, "error_msg": e}, file=sys.stderr)
        sys.exit(1)

    if opts.output:
        try:
            f = open(opts.output, 'w')
        except IOError as msg:
            print(_("Failed to open output file '%(filename)s' : %(error_msg)s") % {"filename": opts.output, "error_msg": msg}, file=sys.stderr)
            sys.exit(1)
    else:
        f = sys.stdout

    f.write("%s" % ksparser.handler)
    f.close()
Esempio n. 15
0
    def _parse_optional(self, arg_string):
        def usedTooNew(action):
            return action.introduced and action.introduced > self.version

        def usedRemoved(action):
            return action.removed and action.removed <= self.version

        option_tuple = ArgumentParser._parse_optional(self, arg_string)
        if option_tuple is None or option_tuple[0] is None:
            return option_tuple

        action = option_tuple[0]

        if usedTooNew(action):
            mapping = {"option": action.option_strings[0], "intro": versionToString(action.introduced),
                       "version": versionToString(self.version)}
            self.error(_("The %(option)s option was introduced in version %(intro)s, but you are using kickstart syntax version %(version)s.") % mapping)
        elif usedRemoved(action):
            mapping = {"option": action.option_strings[0], "removed": versionToString(action.removed),
                       "version": versionToString(self.version)}

            if action.removed == self.version:
                self.error(_("The %(option)s option is no longer supported.") % mapping)
            else:
                self.error(_("The %(option)s option was removed in version %(removed)s, but you are using kickstart syntax version %(version)s.") % mapping)
        elif action.deprecated == True or (self.version and self.version >= action.deprecated):
            mapping = {"lineno": self.lineno, "option": action.option_strings[0]}
            warnings.warn(_("Ignoring deprecated option on line %(lineno)s:  The %(option)s option has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this option.") % mapping, DeprecationWarning)

        return option_tuple
Esempio n. 16
0
    def parse(self, args):
        # the 'mount' command can't be used together with any other
        # partitioning-related command
        conflicting_command = None

        # seen indicates that the corresponding
        # command has been seen in kickstart
        if self.handler.autopart.seen:
            conflicting_command = "autopart"
        if self.handler.partition.seen:
            conflicting_command = "part/partition"
        elif self.handler.raid.seen:
            conflicting_command = "raid"
        elif self.handler.volgroup.seen:
            conflicting_command = "volgroup"
        elif self.handler.logvol.seen:
            conflicting_command = "logvol"
        elif hasattr(self.handler, "reqpart") and self.handler.reqpart.seen:
            conflicting_command = "reqpart"

        if conflicting_command:
            # allow for translation of the error message
            errorMsg = _("The '%s' and 'mount' commands can't be used at the same time") % \
                         conflicting_command
            raise KickstartParseError(errorMsg, lineno=self.lineno)

        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if extra:
            mapping = {"command": "mount", "options": extra}
            raise KickstartParseError(_("Unexpected arguments to %(command)s command: %(options)s") % mapping, lineno=self.lineno)

        md = self.dataClass()  # pylint: disable=not-callable
        self.set_to_obj(ns, md)
        md.lineno = self.lineno
        md.device = ns.device[0]
        md.mount_point = ns.mntpoint[0]

        if md.mount_point.lower() != "none" and not md.mount_point.startswith("/"):
            raise KickstartParseError(_("Invalid mount point '%s' given") % md.mount_point, lineno=self.lineno)

        if md.reformat is False and md.mkfs_opts:
            raise KickstartParseError(_("'--mkfsoptions' requires --reformat"), lineno=self.lineno)

        # The semantics is as follows:
        #   --reformat          -> just reformat with the same format as existing
        #   --reformat=SOME_FMT -> reformat to given format
        #   no '--reformat'     -> don't reformat
        #
        # md.reformat can either be 'False' (not specified), 'True' (just
        # '--reformat') or a non-empty string ('--reformat=FORMAT'). Only the
        # last case requires special treatment.
        if md.reformat and md.reformat is not True:
            # a new format given
            md.format = md.reformat
            md.reformat = True

        return md
Esempio n. 17
0
def _format_error_message(lineno, msg=""):
    """Properly format the error message msg in an exception.
       This function should be called only in exceptions to format the error messages.
    """
    if msg:
        return _("The following problem occurred on line %(lineno)s of the kickstart file:"
                 "\n\n%(msg)s\n") % {"lineno": lineno, "msg": msg}

    return _("There was a problem reading from line %s of the kickstart file") % lineno
Esempio n. 18
0
    def parse(self, args):
        retval = F14_Url.parse(self, args)

        if self.url and self.mirrorlist:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Only one of --url and --mirrorlist may be specified for url command.")))

        if not self.url and not self.mirrorlist:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("One of --url or --mirrorlist must be specified for url command.")))

        return retval
Esempio n. 19
0
    def parse(self, args):
        retval = F21_LogVol.parse(self, args)

        if not retval.format and retval.mkfsopts:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("--mkfsoptions with --noformat has no effect.")))

        if retval.fsprofile and retval.mkfsopts:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("--mkfsoptions and --fsprofile cannot be used together.")))

        return retval
Esempio n. 20
0
    def parse(self, args):
        retval = F14_Partition.parse(self, args)

        if retval.resize and not retval.onPart:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize can only be used in conjunction with --onpart")))

        if retval.resize and not retval.size:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize requires --size to specify new size")))

        return retval
Esempio n. 21
0
def ksboolean(value):
    try:
        if value.lower() in ("on", "yes", "true", "1"):
            return True
        elif value.lower() in ("off", "no", "false", "0"):
            return False
        else:
            raise ArgumentTypeError(_("invalid boolean value: %r") % value)
    except AttributeError:
        raise ArgumentTypeError(_("invalid boolean value: %r") % value)
Esempio n. 22
0
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config", dest="kscfg", required=True,
                        help=_("Path to kickstart config file"))
    parser.add_argument("-v", "--version", dest="version", default=DEVEL,
                        help=_("Kickstart version to use for interpreting config"))
    parser.add_argument("-o", "--output", dest="output",
                        help=_("Write flattened config to OUTPUT"))

    return parser.parse_args()
Esempio n. 23
0
    def parse(self, args):
        retval = F15_LogVol.parse(self, args)

        if retval.resize and not retval.preexist:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize can only be used in conjunction with --useexisting")))

        if retval.resize and not retval.size:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize requires --size to indicate new size")))

        return retval
Esempio n. 24
0
    def parse(self, args):
        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
        self._setToSelf(self.op, opts)

        if len(extra) != 0:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "eula"))

        if not self.agreed:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("Kickstart command eula expects the --agreed option")))

        return self
Esempio n. 25
0
    def parse(self, args):
        (_ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) != 1:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "iscsiname"))
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "iscsiname", "options": extra}
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))

        self.iscsiname = extra[0]
        return self
Esempio n. 26
0
def _load_url(location):
    '''Load a location (URL or filename) and return contents as string'''

    try:
        request = requests.get(location, verify=SSL_VERIFY)
    except SSLError as e:
        raise KickstartError(_('Error securely accessing URL "%s"') % location + ': {e}'.format(e=str(e)))
    except RequestException as e:
        raise KickstartError(_('Error accessing URL "%s"') % location + ': {e}'.format(e=str(e)))

    return request.content
Esempio n. 27
0
    def parse(self, args):
        (_ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(_ns.kbd) != 1:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "keyboard"))
        elif extra:
            mapping = {"command": "keyboard", "options": extra}
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping))

        self.keyboard = _ns.kbd[0]
        return self
Esempio n. 28
0
 def _parseArguments(self, string):
     if self.join_realm:
         raise KickstartParseError(_("The realm command 'join' should only be specified once"), lineno=self.lineno)
     args = shlex.split(string)
     if not args:
         raise KickstartParseError(_("Missing realm command arguments"), lineno=self.lineno)
     command = args.pop(0)
     if command == "join":
         self._parseJoin(args)
     else:
         raise KickstartParseError(_("Unsupported realm '%s' command") % command, lineno=self.lineno)
Esempio n. 29
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if not ns.password:
            raise KickstartParseError(_("A single argument is expected for the %s command") % "rootpw", lineno=self.lineno)
        elif extra:
            mapping = {"command": "rootpw", "options": extra}
            raise KickstartParseError(_("Unexpected arguments to %(command)s command: %(options)s") % mapping, lineno=self.lineno)

        self.set_to_self(ns)
        return self
Esempio n. 30
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        self.set_to_self(ns)

        if extra:
            raise KickstartParseError(_("Kickstart command %s does not take any arguments") % "eula", lineno=self.lineno)

        if not self.agreed:
            raise KickstartParseError(_("Kickstart command eula expects the --agreed option"), lineno=self.lineno)

        return self
Esempio n. 31
0
 def _when_cb(self, value):
     if value.lower() in self.whenMap:
         return self.whenMap[value.lower()]
     else:
         msg = _("Invalid snapshot when parameter: %s") % value
         raise KickstartParseError(formatErrorMsg(self.lineno, msg=msg),
                                   lineno=self.lineno)
Esempio n. 32
0
    def parse(self, args):
        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)

        if len(extra) == 0:
            raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol"))

        lvd = self.handler.LogVolData()
        self._setToObj(self.op, opts, lvd)
        lvd.lineno = self.lineno
        lvd.mountpoint=extra[0]

        # Check for duplicates in the data list.
        if lvd in self.dataList():
            warnings.warn(_("A logical volume with the name %s has already been defined in volume group %s.") % (lvd.name, lvd.vgname))

        return lvd
Esempio n. 33
0
    def dispatcher(self, args, lineno):
        """Call the appropriate KickstartCommand handler for the current line
           in the kickstart file.  A handler for the current command should
           be registered, though a handler of None is not an error.  Returns
           the data object returned by KickstartCommand.parse.

           args    -- A list of arguments to the current command
           lineno  -- The line number in the file, for error reporting
        """
        cmd = args[0]

        if cmd not in self.commands:
            raise KickstartParseError(_("Unknown command: %s") % cmd,
                                      lineno=lineno)
        elif self.commands[cmd] is not None:
            self.commands[cmd].currentCmd = cmd
            self.commands[cmd].currentLine = self.currentLine
            self.commands[cmd].lineno = lineno
            self.commands[cmd].seen = True

            # The parser returns the data object that was modified.  This is either
            # the command handler object itself (a KickstartCommand object), or it's
            # a BaseData subclass instance that should be put into the command's
            # dataList.  The latter is done via side effects.
            #
            # Regardless, return the object that was given to us by the parser.
            obj = self.commands[cmd].parse(args[1:])

            # Here's the side effect part - don't worry about lst not being returned.
            lst = self.commands[cmd].dataList()
            if isinstance(obj, BaseData) and lst is not None:
                lst.append(obj)

            return obj
Esempio n. 34
0
    def parse(self, args):
        retval = F15_Bootloader.parse(self, args)

        if "," in retval.bootDrive:     # pylint: disable=no-member
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--boot-drive accepts only one argument")))

        return retval
Esempio n. 35
0
    def _processGroup(self, line):
        op = KSOptionParser(prog="", description="", version=version.DEVEL)
        op.add_argument("--nodefaults", action="store_true", default=False,
                        help="", version=version.DEVEL)
        op.add_argument("--optional", action="store_true", default=False,
                        help="", version=version.DEVEL)

        (ns, extra) = op.parse_known_args(args=line.split())

        if ns.nodefaults and ns.optional:
            raise KickstartParseError(_("Group cannot specify both --nodefaults and --optional"))

        # If the group name has spaces in it, we have to put it back together
        # now.
        grp = " ".join(extra)

        if grp in [g.name for g in self.groupList]:
            return

        if ns.nodefaults:
            self.groupList.append(Group(name=grp, include=constants.GROUP_REQUIRED))
        elif ns.optional:
            self.groupList.append(Group(name=grp, include=constants.GROUP_ALL))
        else:
            self.groupList.append(Group(name=grp, include=constants.GROUP_DEFAULT))
Esempio n. 36
0
def returnClassForVersion(version=DEVEL):
    """Return the class of the syntax handler for version.  version can be
       either a string or the matching constant.  Raises KickstartVersionError
       if version does not match anything.
    """
    try:
        version = int(version)
        module = "%s" % versionToString(version, skipDevel=True)
    except ValueError:
        module = "%s" % version
        version = stringToVersion(version)

    module = module.lower()

    try:
        _path = os.path.join(os.path.dirname(__file__), "handlers/")
        sys.path.extend([_path])
        loaded = importlib.import_module(module)

        for (k, v) in list(loaded.__dict__.items()):
            if k.lower().endswith("%shandler" % module):
                return v
    except:
        raise KickstartVersionError(
            _("Unsupported version specified: %s") % version)
Esempio n. 37
0
 def methodToRepo(self):
     if not self.handler.method.url:
         raise KickstartError(formatErrorMsg(self.handler.method.lineno, msg=_("Method must be a url to be added to the repo list.")))
     reponame = "ks-method-url"
     repourl = self.handler.method.url
     rd = self.handler.RepoData(name=reponame, baseurl=repourl)
     return rd
Esempio n. 38
0
 def _type_cb(self, value):
     if value.lower() in self.typeMap:
         return self.typeMap[value.lower()]
     else:
         raise KickstartParseError(
             formatErrorMsg(self.lineno,
                            msg=_("Invalid autopart type: %s") % value))
Esempio n. 39
0
    def parse(self, args):
        # call the overriden command to do its job first
        retval = F18_AutoPart.parse(self, args)

        # Using autopart together with other partitioning command such as
        # part/partition, raid, logvol or volgroup can lead to hard to debug
        # behavior that might among other result into an unbootable system.
        #
        # Therefore if any of those commands is detected in the same kickstart
        # together with autopart, an error is raised and installation is
        # aborted.
        conflicting_command = ""

        # seen indicates that the corresponding
        # command has been seen in kickstart
        if self.handler.partition.seen:
            conflicting_command = "part/partition"
        elif self.handler.raid.seen:
            conflicting_command = "raid"
        elif self.handler.volgroup.seen:
            conflicting_command = "volgroup"
        elif self.handler.logvol.seen:
            conflicting_command = "logvol"

        if conflicting_command:
            # allow for translation of the error message
            errorMsg = _(
                "The %s and autopart commands can't be used at the same time"
            ) % conflicting_command
            raise KickstartParseError(formatErrorMsg(self.lineno,
                                                     msg=errorMsg))
        return retval
Esempio n. 40
0
    def parse(self, args):
        # call the overridden command to do it's job first
        retval = F21_Network.parse(self, args)

        if retval.bridgeopts:
            if not retval.bridgeslaves:
                msg = _("Option --bridgeopts requires --bridgeslaves to be specified")
                raise KickstartParseError(msg, lineno=self.lineno)
            opts = retval.bridgeopts.split(",")
            for opt in opts:
                _key, _sep, value = opt.partition("=")
                if not value or "=" in value:
                    msg = _("Bad format of --bridgeopts, expecting key=value options separated by ','")
                    raise KickstartParseError(msg, lineno=self.lineno)

        return retval
Esempio n. 41
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)
        dd = FC6_MpPathData()
        self.set_to_obj(ns, dd)
        dd.lineno = self.lineno
        dd.mpdev = dd.name.split('/')[-1]

        parent = None
        for x in range(0, len(self.mpaths)):
            mpath = self.mpaths[x]
            for path in mpath.paths:
                if path.device == dd.device:
                    mapping = {
                        "device": path.device,
                        "multipathdev": path.mpdev
                    }
                    raise KickstartParseError(
                        formatErrorMsg(
                            self.lineno,
                            msg=
                            _("Device '%(device)s' is already used in multipath '%(multipathdev)s'"
                              ) % mapping))
            if mpath.name == dd.mpdev:
                parent = x

        if parent is None:
            mpath = self.dataClass(name=dd.name)  # pylint: disable=not-callable
            mpath.paths.append(dd)
            return mpath
        else:
            mpath = self.mpaths[parent]
            mpath.paths.append(dd)
            return dd
Esempio n. 42
0
def load_to_file(location, destination):
    '''Load a destination URL or file into a file name.
    Type of input is inferred automatically.

    Arguments:
    location -- URL or file name to load
    destination -- destination file name to write to

    Returns: file name with contents
    Raises: KickstartError on error reading or writing'''

    if _is_url(location):
        contents = _load_url(location)

        # Write to file
        try:
            with open(destination, 'w') as fh:
                fh.write(contents)
        except IOError as e:
            raise KickstartError(
                _('Error writing file "%s":') % location +
                ': {e}'.format(e=str(e)))

        return destination
    else:
        _copy_file(location, destination)
        return destination
Esempio n. 43
0
 def _parseArguments(self, string):
     if self.join_realm:
         raise KickstartParseError(
             _("The realm command 'join' should only be specified once"),
             lineno=self.lineno)
     args = shlex.split(string)
     if not args:
         raise KickstartParseError(_("Missing realm command arguments"),
                                   lineno=self.lineno)
     command = args.pop(0)
     if command == "join":
         self._parseJoin(args)
     else:
         raise KickstartParseError(_("Unsupported realm '%s' command") %
                                   command,
                                   lineno=self.lineno)
Esempio n. 44
0
    def readKickstart(self, f, reset=True):
        """Process a kickstart file, given by the filename f."""
        if reset:
            self._reset()

        # an %include might not specify a full path.  if we don't try to figure
        # out what the path should have been, then we're unable to find it
        # requiring full path specification, though, sucks.  so let's make
        # the reading "smart" by keeping track of what the path is at each
        # include depth.
        if not os.path.exists(f):
            if self._includeDepth - 1 in self.currentdir:
                if os.path.exists(os.path.join(self.currentdir[self._includeDepth - 1], f)):
                    f = os.path.join(self.currentdir[self._includeDepth - 1], f)

        cd = os.path.dirname(f)
        if not cd.startswith("/"):
            cd = os.path.abspath(cd)
        self.currentdir[self._includeDepth] = cd

        try:
            s = load_to_str(f)
        except KickstartError as e:
            raise KickstartError(_("Unable to open input kickstart file: %s") % str(e), lineno=0)

        self.readKickstartFromString(s, reset=False)
Esempio n. 45
0
def returnClassForVersion(version=DEVEL):
    """Return the class of the syntax handler for version.  version can be
       either a string or the matching constant.  Raises KickstartValueError
       if version does not match anything.
    """
    try:
        version = int(version)
        module = "%s" % versionToString(version, skipDevel=True)
    except ValueError:
        module = "%s" % version
        version = stringToVersion(version)

    module = module.lower()

    try:
        import pykickstart.handlers
        sys.path.extend(pykickstart.handlers.__path__)
        found = imp.find_module(module)
        loaded = imp.load_module(module, found[0], found[1], found[2])

        for (k, v) in list(loaded.__dict__.items()):
            if k.lower().endswith("%shandler" % module):
                return v
    except:
        found = None
        raise KickstartVersionError(
            _("Unsupported version specified: %s") % version)
    finally:  # Closing opened files in imp.load_module
        if found and len(found) > 0:
            found[0].close()
Esempio n. 46
0
def _copy_file(filename, destination):
    '''Copy file to destination'''

    try:
        shutil.copyfile(filename, destination)
    except OSError as e:
        raise KickstartError(_('Error copying file: %s') % str(e))
Esempio n. 47
0
 def parse(self, args):
     # first call the overriden method
     retval = F19_Raid.parse(self, args)
     # the raid command can't be used together with the autopart command
     # due to the hard to debug behavior their combination introduces
     if self.handler.autopart.seen:
         errorMsg = _(
             "The raid and autopart commands can't be used at the same time"
         )
         raise KickstartParseError(errorMsg, lineno=self.lineno)
     # the same applies to the 'mount' command
     if hasattr(self.handler, "mount") and self.handler.mount.seen:
         errorMsg = _(
             "The raid and mount commands can't be used at the same time")
         raise KickstartParseError(errorMsg, lineno=self.lineno)
     return retval
Esempio n. 48
0
    def parse(self, args):
        (_ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(_ns.kbd) != 1:
            raise KickstartParseError(
                _("Kickstart command %s requires one argument") % "keyboard",
                lineno=self.lineno)
        elif extra:
            mapping = {"command": "keyboard", "options": extra}
            raise KickstartParseError(
                _("Unexpected arguments to %(command)s command: %(options)s") %
                mapping,
                lineno=self.lineno)

        self.keyboard = _ns.kbd[0]
        return self
Esempio n. 49
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)
        # because positional arguments with variable number of values
        # don't parse very well
        if not ns.partitions:
            if extra:
                ns.partitions = extra
                extra = []
            elif len(ns.name) > 1:
                ns.partitions = ns.name[1:]
                ns.name = [ns.name[0]]

        if not ns.format:
            ns.preexist = True

        vg = self.dataClass()  # pylint: disable=not-callable
        self.set_to_obj(ns, vg)
        vg.lineno = self.lineno

        if not ns.name:
            raise KickstartParseError(formatErrorMsg(
                self.lineno, msg=_("volgroup must be given a VG name")),
                                      lineno=self.lineno)

        if not any([ns.partitions, ns.preexist]):
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=_("volgroup must be given a list of partitions")),
                                      lineno=self.lineno)
        elif ns.partitions and ns.preexist:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=_(
                    "Members may not be specified for preexisting volgroup")),
                                      lineno=self.lineno)
        vg.vgname = ns.name[0]

        if ns.partitions:
            vg.physvols = ns.partitions

        # Check for duplicates in the data list.
        if vg in self.dataList():
            warnings.warn(
                _("A volgroup with the name %s has already been defined.") %
                vg.vgname)

        return vg
Esempio n. 50
0
    def parse(self, args):
        (opts, _extra) = self.op.parse_args(args=args, lineno=self.lineno)
        self._setToSelf(self.op, opts)

        if len(self.disabled) == 0 and len(self.enabled) == 0:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("One of --disabled or --enabled must be provided.")))

        return self
Esempio n. 51
0
    def parse(self, args):
        if args:
            msg = _("Kickstart command %s does not take any arguments"
                    ) % self.currentCmd
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=msg),
                                      lineno=self.lineno)

        return self
Esempio n. 52
0
def main():
    opts = parse_args()
    if not opts.kscfg:
        print(_("Need to specify a config to flatten"), file=sys.stderr)
        sys.exit(1)

    ksversion = makeVersion(opts.version)
    ksparser = pykickstart.parser.KickstartParser(ksversion)
    try:
        ksparser.readKickstart(opts.kscfg)
    except IOError as msg:
        print(
            _("Failed to read kickstart file '%(filename)s' : %(error_msg)s") %
            {
                "filename": opts.kscfg,
                "error_msg": msg
            },
            file=sys.stderr)
        sys.exit(1)
    except pykickstart.errors.KickstartError as e:
        print(
            _("Failed to parse kickstart file '%(filename)s' : %(error_msg)s")
            % {
                "filename": opts.kscfg,
                "error_msg": e
            },
            file=sys.stderr)
        sys.exit(1)

    if opts.output:
        try:
            f = open(opts.output, 'w')
        except IOError as msg:
            print(
                _("Failed to open output file '%(filename)s' : %(error_msg)s")
                % {
                    "filename": opts.output,
                    "error_msg": msg
                },
                file=sys.stderr)
            sys.exit(1)
    else:
        f = sys.stdout

    f.write("%s" % ksparser.handler)
    f.close()
Esempio n. 53
0
    def parse(self, args):
        ud = self.dataClass()   # pylint: disable=not-callable
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)
        assert len(ns.sshkey) == 1

        if extra:
            mapping = {"command": "sshkey", "options": extra}
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping), lineno=self.lineno)

        self.set_to_obj(ns, ud)
        ud.key = ns.sshkey[0]
        ud.lineno = self.lineno

        if ud in self.dataList():
            warnings.warn(_("An ssh user with the name %s has already been defined.") % ud.username)

        return ud
Esempio n. 54
0
    def parse(self, args):
        (_opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)

        if len(extra) > 0:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % self.currentCmd))

        self.unsupported_hardware = True
        return self
Esempio n. 55
0
    def parse(self, args):
        # call the overriden command to do its job first
        retval = F20_AutoPart.parse(self, args)

        # btrfs is not a valid filesystem type
        if self.fstype == "btrfs":
            raise KickstartParseError(_(
                "autopart --fstype=btrfs is not valid fstype, use --type=btrfs instead"
            ),
                                      lineno=self.lineno)

        if self._typeAsStr() == "btrfs" and self.fstype:
            raise KickstartParseError(
                _("autopart --fstype cannot be used with --type=btrfs"),
                lineno=self.lineno)

        return retval
Esempio n. 56
0
def _check_ksboolean(_option, opt, value):
    if value.lower() in ("on", "yes", "true", "1"):
        return True
    elif value.lower() in ("off", "no", "false", "0"):
        return False
    else:
        mapping = {"opt": opt, "value": value}
        raise OptionValueError(_("Option %(opt)s: invalid boolean value: %(value)r") % mapping)
Esempio n. 57
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) != 1:
            raise KickstartParseError(
                _("Kickstart command %s requires one argument") % "mouse",
                lineno=self.lineno)
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "mouse", "options": extra}
            raise KickstartParseError(
                _("Unexpected arguments to %(command)s command: %(options)s") %
                mapping,
                lineno=self.lineno)

        self.set_to_self(ns)
        self.mouse = extra[0]
        return self
Esempio n. 58
0
def _preprocessStateMachine (lineIter):
    l = None
    lineno = 0
    retval = ""

    if six.PY3:
        retval = retval.encode(sys.getdefaultencoding())

    while True:
        try:
            l = next(lineIter)
        except StopIteration:
            break

        # At the end of the file?
        if l == "":
            break

        lineno += 1
        ksurl = None

        ll = l.strip()
        if not ll.startswith("%ksappend"):
            if six.PY3:
                l = l.encode(sys.getdefaultencoding())
            retval += l
            continue

        # Try to pull down the remote file.
        try:
            ksurl = ll.split(' ')[1]
        except:
            raise KickstartParseError(formatErrorMsg(lineno, msg=_("Illegal url for %%ksappend: %s") % ll))

        try:
            contents = load_to_str(ksurl)
        except KickstartError as e:
            raise KickstartError(formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file: %s") % str(e)))

        # If that worked, write the remote file to the output kickstart
        # file in one burst.  This allows multiple %ksappend lines to
        # exist.
        if contents is not None:
            retval += contents.encode(sys.getdefaultencoding())

    return retval
Esempio n. 59
0
    def parse(self, args):
        retval = F20_Raid.parse(self, args)

        if not retval.format and retval.mkfsopts:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=_("--mkfsoptions with --noformat has no effect.")),
                                      lineno=self.lineno)

        if retval.fsprofile and retval.mkfsopts:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=_(
                    "--mkfsoptions and --fsprofile cannot be used together.")),
                                      lineno=self.lineno)

        return retval
Esempio n. 60
0
    def parse(self, args):
        FC6_Timezone.parse(self, args)

        if self.ntpservers and self.nontp:
            msg = _("Options --nontp and --ntpservers are mutually exclusive")
            raise KickstartParseError(msg, lineno=self.lineno)

        return self