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