Ejemplo n.º 1
0
    def parse(self, args):
        """Parse the command."""
        retval = super().parse(args)

        # Check the file system type.
        fmt = get_format("btrfs")

        if not fmt.supported or not fmt.formattable:
            msg = _("Btrfs file system is not supported.")
            raise KickstartParseError(msg, lineno=self.lineno)

        return retval
Ejemplo n.º 2
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") %
                    "zerombr"))

        self.zerombr = True
        return self
Ejemplo n.º 3
0
def get_device_names(specs, disks_only=False, msg="{}", lineno=None):
    """Get device names from device specifications."""
    drives = []

    for spec in specs:
        matched = device_matches(spec, disks_only=disks_only)
        if not matched:
            raise KickstartParseError(msg.format(spec), lineno=lineno)
        else:
            drives.extend(matched)

    return drives
Ejemplo n.º 4
0
    def parse(self, args):
        retval = super().parse(args)

        if self.fstype:
            fmt = get_format(self.fstype)

            if not fmt or fmt.type is None:
                raise KickstartParseError(_(
                    "File system type \"{}\" given in autopart command is "
                    "invalid.").format(self.fstype),
                                          lineno=self.lineno)
        return retval
Ejemplo n.º 5
0
    def _check_boot_drive(self, storage, boot_drive, usable_disks):
        """Check the specified boot drive."""
        # Resolve the disk identifier.
        matched_disks = device_matches(boot_drive,
                                       devicetree=storage.devicetree,
                                       disks_only=True)

        if not matched_disks:
            raise KickstartParseError(
                _("No match found for given boot drive "
                  "\"{}\".").format(boot_drive))

        if len(matched_disks) > 1:
            raise KickstartParseError(
                _("More than one match found for given boot drive "
                  "\"{}\".").format(boot_drive))

        if matched_disks[0] not in usable_disks:
            raise KickstartParseError(
                _("Requested boot drive \"{}\" doesn't exist or cannot "
                  "be used.").format(boot_drive))
Ejemplo n.º 6
0
 def parse(self, args):
     # first call the overriden command
     retval = F12_Partition.parse(self, args)
     # the part 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 part/partition and autopart commands can't be used at the same time"
         )
         raise KickstartParseError(formatErrorMsg(self.lineno,
                                                  msg=errorMsg))
     return retval
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    def parse(self, args):
        if len(args) > 0:
            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % self.currentCmd))

        if self.currentCmd == "cmdline":
            self.displayMode = DISPLAY_MODE_CMDLINE
        elif self.currentCmd == "graphical":
            self.displayMode = DISPLAY_MODE_GRAPHICAL
        elif self.currentCmd == "text":
            self.displayMode = DISPLAY_MODE_TEXT

        return self
Ejemplo n.º 9
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

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

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

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

        ddd = self.dataClass()  # pylint: disable=not-callable
        self.set_to_obj(ns, ddd)
        ddd.lineno = self.lineno
        if len(ns.partition) == 1:
            ddd.partition = ns.partition[0]

        return ddd
Ejemplo n.º 10
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) == 0:
            msg = _("Snapshot origin must be specified!")
            raise KickstartParseError(msg, lineno=self.lineno)
        elif len(extra) > 1:
            msg = _("Snapshot origin can be specified only once!")
            raise KickstartParseError(msg, lineno=self.lineno)

        snap_data = self.dataClass()   # pylint: disable=not-callable
        self.set_to_obj(ns, snap_data)
        snap_data.lineno = self.lineno
        snap_data.origin = extra[0]

        # 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
Ejemplo n.º 11
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(
                formatErrorMsg(self.lineno, msg=error_message))

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

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

        return retval
Ejemplo n.º 12
0
    def parse(self, args):
        (_ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)
        assert len(_ns.iqn) == 1

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

        self.iscsiname = _ns.iqn[0]
        return self
Ejemplo n.º 13
0
    def parse(self, args):
        # first call the overriden command
        retval = F18_Partition.parse(self, args)
        # the part 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 part/partition and autopart commands can't be used at the same time"
            )
            raise KickstartParseError(formatErrorMsg(self.lineno,
                                                     msg=errorMsg))

        # when using tmpfs, grow is not suported
        if retval.fstype == "tmpfs":
            if retval.grow or retval.maxSizeMB != 0:
                errorMsg = _(
                    "The --fstype=tmpfs option can't be used together with --grow or --maxsize"
                )
                raise KickstartParseError(
                    formatErrorMsg(self.lineno, msg=errorMsg))

        return retval
Ejemplo n.º 14
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")))
        elif ns.defaultPackages and ns.nocore:
            raise KickstartParseError(
                formatErrorMsg(
                    lineno,
                    msg=_("--default and --nocore cannot be used together")))

        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
Ejemplo n.º 15
0
    def parse(self, args):
        retval = FC3_IgnoreDisk.parse(self, args)

        howmany = 0
        if self.ignoredisk:
            howmany += 1
        if self.onlyuse:
            howmany += 1
        if howmany != 1:
            raise KickstartParseError(_("One of --drives or --only-use must be specified "
                                        "for ignoredisk command."), lineno=self.lineno)

        return retval
Ejemplo n.º 16
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)
        self.set_to_self(ns)
        if not self.remote:
            self.remote = self.osname

        if not self.url.startswith(("file:", "http:", "https:")):
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg="ostree repos must use file, HTTP or HTTPS protocol."))

        return self
Ejemplo n.º 17
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) > 0:
            msg = _(
                "The enable module command does not take position arguments!")
            raise KickstartParseError(msg, lineno=self.lineno)

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

        return enable_module_data
Ejemplo n.º 18
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)

        # Check that just one of exclusive required options is specified
        used_options = [opt for attr, opt in self.exclusive_required_options
                        if getattr(ns, attr, None)]
        if self.urlRequired and not used_options:
            mapping = {"options_list": ", ".join((opt for attr, opt in self.exclusive_required_options))}
            raise KickstartParseError(_("One of -%(options_list)s options must be specified for repo command.") % mapping, lineno=self.lineno)
        if len(used_options) > 1:
            mapping = {"options_list": ", ".join((opt for opt in used_options))}
            raise KickstartParseError(_("Only one of %(options_list)s options may be specified for repo command.") % mapping, lineno=self.lineno)

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

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

        return rd
Ejemplo n.º 19
0
    def _validate_grub2_configuration(self, data):
        """Validate the GRUB2 configuration.

        :raise: KickstartParseError if not valid
        """
        # Skip other types of the boot loader.
        if not issubclass(BootLoaderFactory.get_class(), GRUB2):
            return

        # Check the location support.
        if self.preferred_location == BOOTLOADER_LOCATION_PARTITION:
            raise KickstartParseError(
                _("GRUB2 does not support installation to a partition."),
                lineno=data.bootloader.lineno)

        # Check the password format.
        if self.password_is_set \
                and self.password_is_encrypted \
                and not self.password.startswith("grub.pbkdf2."):
            raise KickstartParseError(
                _("GRUB2 encrypted password must be in grub.pbkdf2 format."),
                lineno=data.bootloader.lineno)
Ejemplo n.º 20
0
    def parse(self, args):
        ns = self.op.parse_args(args=args, lineno=self.lineno)
        self.set_to_self(ns)

        if self.biospart is None and self.partition is None or \
           self.biospart is not None and self.partition is not None:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=_("One of biospart or partition options must be specified."
                      )),
                                      lineno=self.lineno)

        return self
Ejemplo n.º 21
0
    def handleHeader(self, lineno, args):
        """Process packages section header.

        Add checks based on configuration settings.
        """
        super().handleHeader(lineno, args)

        if not conf.payload.enable_ignore_broken_packages \
           and self.handler.packages.handleBroken == KS_BROKEN_IGNORE:
            raise KickstartParseError(_(
                "The %packages --ignorebroken feature is not supported on your product!"
            ),
                                      lineno=lineno)
Ejemplo n.º 22
0
    def parse(self, args):
        # first call the overriden method
        retval = FC3_VolGroup.parse(self, args)

        # Check that any reserved space options are in their valid ranges.
        if getattr(retval, "reserved_space",
                   None) and retval.reserved_space < 0:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg="Volume group reserved space must be a positive integer."),
                                      lineno=self.lineno)

        if getattr(retval, "reserved_percent",
                   None) is not None and not 0 < retval.reserved_percent < 100:
            raise KickstartParseError(formatErrorMsg(
                self.lineno,
                msg=
                "Volume group reserved space percentage must be between 1 and 99."
            ),
                                      lineno=self.lineno)

        # the volgroup 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 volgroup and autopart commands can't be used at the same time"
            )
            raise KickstartParseError(formatErrorMsg(self.lineno,
                                                     msg=errorMsg),
                                      lineno=self.lineno)
        # the same applies to the 'mount' command
        if hasattr(self.handler, "mount") and self.handler.mount.seen:
            errorMsg = _(
                "The volgroup and mount commands can't be used at the same time"
            )
            raise KickstartParseError(formatErrorMsg(self.lineno,
                                                     msg=errorMsg),
                                      lineno=self.lineno)
        return retval
Ejemplo n.º 23
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
Ejemplo n.º 24
0
    def parse(self, args):
        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
        self._setToSelf(self.op, opts)

        # 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(extra) > 1:
            error_message = _(
                "One or zero arguments are expected for the %s command"
            ) % "timezone"
            raise KickstartValueError(
                formatErrorMsg(self.lineno, msg=error_message))

        if len(extra) > 0:
            self.timezone = extra[0]

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

        return self
Ejemplo n.º 25
0
def get_snapshot_device(request, devicetree):
    """Get the ThinLV snapshot device.

    :param request: a snapshot request
    :param devicetree: a device tree to look up devices
    :return: a model of the ThinLV snapshot
    """
    snap_name = request.name.replace('-', '--')
    origin = request.origin.replace('-', '--').replace('/', '-')
    origin_dev = devicetree.get_device_by_name(origin)
    log.debug("Snapshot: name %s has origin %s", request.name, origin_dev)

    if origin_dev is None:
        raise KickstartParseError(_("Snapshot: origin \"%s\" doesn't exist!") %
                                  request.origin,
                                  lineno=request.lineno)

    if not origin_dev.is_thin_lv:
        raise KickstartParseError(
            _("Snapshot: origin \"%(origin)s\" of snapshot "
              "\"%(name)s\" is not a valid thin LV device.") % {
                  "origin": request.origin,
                  "name": request.name
              },
            lineno=request.lineno)

    if devicetree.get_device_by_name("%s-%s" %
                                     (origin_dev.vg.name, snap_name)):
        raise KickstartParseError(_("Snapshot %s already exists.") %
                                  request.name,
                                  lineno=request.lineno)
    try:
        return LVMLogicalVolumeDevice(name=request.name,
                                      parents=[origin_dev.pool],
                                      seg_type="thin",
                                      origin=origin_dev)
    except ValueError as e:
        raise KickstartParseError(str(e), lineno=request.lineno) from e
Ejemplo n.º 26
0
    def parse(self, args):
        (_ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(_ns.updates) > 1:
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=_("Kickstart command %s only takes one argument") %
                    "updates"))
        elif extra:
            mapping = {"command": "updates", "options": extra}
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=
                    _("Unexpected arguments to %(command)s command: %(options)s"
                      ) % mapping))
        elif not _ns.updates:
            self.url = "floppy"
        else:
            self.url = _ns.updates[0]

        return self
Ejemplo n.º 27
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)

        if len(extra) != 2:
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=
                    _("device command requires two arguments: module type and name"
                      )))
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "device", "options": extra}
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=
                    _("Unexpected arguments to %(command)s command: %(options)s"
                      ) % mapping))

        self.moduleOpts = ns.moduleOpts
        self.type = extra[0]
        self.moduleName = extra[1]
        return self
Ejemplo n.º 28
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)
        self.set_to_self(ns)
        assert len(ns.timezone) == 1

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

        self.timezone = ns.timezone[0]
        return self
Ejemplo n.º 29
0
    def parse(self, args):
        (ns, extra) = self.op.parse_known_args(args=args, lineno=self.lineno)
        self.set_to_self(ns)

        if len(extra) != 1 and not self.lock:
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=_("A single argument is expected for the %s command") %
                    "rootpw"))
        elif any(arg for arg in extra if arg.startswith("-")):
            mapping = {"command": "rootpw", "options": extra}
            raise KickstartParseError(
                formatErrorMsg(
                    self.lineno,
                    msg=
                    _("Unexpected arguments to %(command)s command: %(options)s"
                      ) % mapping))

        if len(extra) == 1:
            self.password = extra[0]

        return self
Ejemplo n.º 30
0
def _preprocessStateMachine (lineIter):
    l = None
    lineno = 0

    # Now open an output kickstart file that we are going to write to one
    # line at a time.
    (outF, outName) = tempfile.mkstemp("-ks.cfg", "", "/tmp")

    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:
                import sys
                l = l.encode(sys.getdefaultencoding())
            os.write(outF, 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.  Then close everything up to get ready to
        # read ahead in the input file.  This allows multiple %ksappend
        # lines to exist.
        if contents is not None:
            os.write(outF, contents)

    # All done - close the temp file and return its location.
    os.close(outF)
    return outName