#
# Chris Lumens <clumens@redhat.com>
#
# Copyright 2005, 2006, 2007, 2008, 2012 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use, modify,
# copy, or redistribute it subject to the terms and conditions of the GNU
# General Public License v.2. This program is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
# trademarks that are incorporated in the source code or documentation are not
# subject to the GNU General Public License and may only be used or replicated
# with the express permission of Red Hat, Inc.
#
from pykickstart.base import KickstartCommand
from pykickstart.version import versionToLongString, RHEL6, RHEL7, RHEL8
from pykickstart.version import FC3, F9, F12, F16, F17, F18, F20, F21, F26, F29, F38
from pykickstart.constants import AUTOPART_TYPE_BTRFS, AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP, AUTOPART_TYPE_PLAIN
from pykickstart.errors import KickstartParseError
from pykickstart.options import KSOptionParser
from pykickstart.i18n import _
[docs]class FC3_AutoPart(KickstartCommand):
removedKeywords = KickstartCommand.removedKeywords
removedAttrs = KickstartCommand.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
KickstartCommand.__init__(self, writePriority, *args, **kwargs)
self.autopart = kwargs.get("autopart", False)
def __str__(self):
retval = KickstartCommand.__str__(self)
if self.autopart:
retval += "autopart\n"
return retval
[docs] def parse(self, args):
if len(args) > 0:
raise KickstartParseError(_("Kickstart command %s does not take any arguments") % "autopart", lineno=self.lineno)
self.autopart = True
return self
def _getParser(self):
return KSOptionParser(prog="autopart", description="""
Automatically create partitions -- a root (``/``) partition,
a swap partition, and an appropriate boot partition
for the architecture. On large enough drives, this
will also create a /home partition.""",
version=FC3, conflicts=self.conflictingCommands)
[docs]class F9_AutoPart(FC3_AutoPart):
removedKeywords = FC3_AutoPart.removedKeywords
removedAttrs = FC3_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
FC3_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.encrypted = kwargs.get("encrypted", False)
self.passphrase = kwargs.get("passphrase", "")
self.op = self._getParser()
def __str__(self):
retval = KickstartCommand.__str__(self)
if not self.autopart:
return retval
retval += "autopart"
if self.encrypted:
retval += " --encrypted"
if self.passphrase:
retval += " --passphrase=\"%s\""% self.passphrase
retval += "\n"
return retval
def _getParser(self):
op = FC3_AutoPart._getParser(self)
op.add_argument("--encrypted", action="store_true", default=False,
version=F9, help="""
Should all devices with support be encrypted by default?
This is equivalent to checking the "Encrypt" checkbox on
the initial partitioning screen.""")
op.add_argument("--passphrase", version=F9, help="""
Only relevant if ``--encrypted`` is specified. Provide
a default system-wide passphrase for all encrypted
devices.""")
return op
[docs] def parse(self, args):
ns = self.op.parse_args(args=args, lineno=self.lineno)
self.set_to_self(ns)
self.autopart = True
return self
[docs]class F12_AutoPart(F9_AutoPart):
removedKeywords = F9_AutoPart.removedKeywords
removedAttrs = F9_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F9_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.escrowcert = kwargs.get("escrowcert", "")
self.backuppassphrase = kwargs.get("backuppassphrase", False)
def __str__(self):
retval = F9_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.encrypted and self.escrowcert:
retval = retval.strip()
retval += " --escrowcert=\"%s\"" % self.escrowcert
if self.backuppassphrase:
retval += " --backuppassphrase"
retval += "\n"
return retval
def _getParser(self):
op = F9_AutoPart._getParser(self)
op.add_argument("--escrowcert", metavar="<url>", version=F12, help="""
Only relevant if ``--encrypted`` is specified. Load an
X.509 certificate from ``<url>``. Store the data
encryption keys of all encrypted volumes created during
installation, encrypted using the certificate, as files
in ``/root``.""")
op.add_argument("--backuppassphrase", action="store_true",
default=False, version=F12, help="""
Only relevant if ``--escrowcert`` is specified. In
addition to storing the data encryption keys, generate
a random passphrase and add it to all encrypted volumes
created during installation. Then store the passphrase,
encrypted using the certificate specified by
``--escrowcert``, as files in ``/root`` (one file for
each encrypted volume).""")
return op
[docs]class RHEL6_AutoPart(F12_AutoPart):
removedKeywords = F12_AutoPart.removedKeywords
removedAttrs = F12_AutoPart.removedAttrs
conflictingCommands = ["partition", "raid", "volgroup", "logvol"]
def __init__(self, writePriority=100, *args, **kwargs):
F12_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.cipher = kwargs.get("cipher", "")
def __str__(self):
retval = F12_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.encrypted and self.cipher:
# remove any trailing newline
retval = retval.strip()
retval += " --cipher=\"%s\"" % self.cipher
retval += "\n"
return retval
def _getParser(self):
op = F12_AutoPart._getParser(self)
op.add_argument("--cipher", version=RHEL6, help="""
Only relevant if ``--encrypted`` is specified. Specifies
which encryption algorithm should be used to encrypt the
filesystem.""")
return op
[docs]class F16_AutoPart(F12_AutoPart):
removedKeywords = F12_AutoPart.removedKeywords
removedAttrs = F12_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F12_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.lvm = kwargs.get("lvm", True)
def __str__(self):
retval = F12_AutoPart.__str__(self)
if not self.autopart:
return retval
# If requested, disable LVM autopart
if not self.lvm:
# remove any trailing newline
retval = retval.strip()
retval += " --nolvm"
retval += "\n"
return retval
def _getParser(self):
op = F12_AutoPart._getParser(self)
op.add_argument("--nolvm", action="store_false", dest="lvm",
default=True, version=F16,
help="Don't use LVM when partitioning.")
return op
[docs]class F17_AutoPart(F16_AutoPart):
def __init__(self, writePriority=100, *args, **kwargs):
self.typeMap = {"lvm": AUTOPART_TYPE_LVM,
"btrfs": AUTOPART_TYPE_BTRFS,
"plain": AUTOPART_TYPE_PLAIN,
"partition": AUTOPART_TYPE_PLAIN}
F16_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.type = kwargs.get("type", None)
def _typeAsStr(self):
retval = None
for (key, value) in list(self.typeMap.items()):
if value == self.type:
retval = key
break
if retval == "partition":
retval = "plain"
return retval
def __str__(self):
retval = F16_AutoPart.__str__(self)
if not self.autopart:
return retval
ty = self._typeAsStr()
if ty:
# remove any trailing newline
retval = retval.strip()
retval += " --type=%s\n" % ty
return retval
def _type_cb(self, value):
if value.lower() in self.typeMap:
return self.typeMap[value.lower()]
else:
raise KickstartParseError(_("Invalid autopart type: %s") % value, lineno=self.lineno)
def _getParser(self):
op = F16_AutoPart._getParser(self)
op.add_argument("--nolvm", action="store_const", version=F17,
const=AUTOPART_TYPE_PLAIN, dest="type",
help="The same as ``--type=plain``")
op.add_argument("--type", type=self._type_cb, version=F17, help="""
Select automatic partitioning scheme. Must be one of the
following: %s. Plain means regular
partitions with no btrfs or lvm.""" % list(self.typeMap.keys()))
return op
[docs] def parse(self, args):
retval = F16_AutoPart.parse(self, args)
# make this always True to avoid writing --nolvm
self.lvm = True
return retval
[docs]class F18_AutoPart(F17_AutoPart):
removedKeywords = F17_AutoPart.removedKeywords
removedAttrs = F17_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F17_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.cipher = kwargs.get("cipher", "")
def __str__(self):
retval = F17_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.encrypted and self.cipher:
# remove any trailing newline
retval = retval.strip()
retval += " --cipher=\"%s\"" % self.cipher
retval += "\n"
return retval
def _getParser(self):
op = F17_AutoPart._getParser(self)
op.add_argument("--cipher", version=F18, help="""
Only relevant if ``--encrypted`` is specified. Specifies
which encryption algorithm should be used to encrypt the
filesystem.""")
return op
[docs]class F20_AutoPart(F18_AutoPart):
conflictingCommands = ["partition", "raid", "volgroup", "logvol"]
def __init__(self, writePriority=100, *args, **kwargs):
F18_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.typeMap["thinp"] = AUTOPART_TYPE_LVM_THINP
def _getParser(self):
"Only necessary for the type change documentation"
op = F18_AutoPart._getParser(self)
for action in op._actions:
if "--type" in action.option_strings:
action.help += """
.. versionchanged:: %s
Partitioning scheme 'thinp' was added.""" % versionToLongString(F20)
return op
[docs]class F21_AutoPart(F20_AutoPart):
removedKeywords = F20_AutoPart.removedKeywords
removedAttrs = F20_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F20_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.fstype = kwargs.get("fstype", "")
def __str__(self):
retval = F20_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.fstype:
# remove any trailing newline
retval = retval.strip()
retval += " --fstype=%s" % self.fstype
retval += "\n"
return retval
def _getParser(self):
op = F20_AutoPart._getParser(self)
op.add_argument("--fstype", version=F21, help="""
Use the specified filesystem type on the partitions.
Note that it cannot be used with ``--type=btrfs`` since
btrfs is both a partition scheme and a filesystem. eg.
``--fstype=ext4``.""")
return op
[docs] 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
[docs]class F23_AutoPart(F21_AutoPart):
conflictingCommands = ["partition", "raid", "volgroup", "logvol", "reqpart"]
[docs]class RHEL7_AutoPart(F21_AutoPart):
conflictingCommands = ["partition", "raid", "volgroup", "logvol", "reqpart"]
def __init__(self, writePriority=100, *args, **kwargs):
F21_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.nohome = kwargs.get("nohome", False)
def __str__(self):
retval = F21_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.nohome:
# remove any trailing newline
retval = retval.strip()
retval += " --nohome"
retval += "\n"
return retval
def _getParser(self):
op = F21_AutoPart._getParser(self)
op.add_argument("--nohome", action="store_true", default=False,
version=RHEL7, help="""
Do not create a /home partition.""")
return op
[docs]class F26_AutoPart(F23_AutoPart):
removedKeywords = F23_AutoPart.removedKeywords
removedAttrs = F23_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F23_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.nohome = kwargs.get("nohome", False)
self.noboot = kwargs.get("noboot", False)
self.noswap = kwargs.get("noswap", False)
def __str__(self):
retval = F23_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.nohome:
# remove any trailing newline
retval = retval.strip()
retval += " --nohome"
retval += "\n"
if self.noboot:
# remove any trailing newline
retval = retval.strip()
retval += " --noboot"
retval += "\n"
if self.noswap:
# remove any trailing newline
retval = retval.strip()
retval += " --noswap"
retval += "\n"
return retval
def _getParser(self):
op = F23_AutoPart._getParser(self)
op.add_argument("--nohome", action="store_true", default=False,
version=F26, help="""
Do not create a /home partition.""")
op.add_argument("--noboot", action="store_true", default=False,
version=F26, help="""
Do not create a /boot partition.""")
op.add_argument("--noswap", action="store_true", default=False,
version=F26, help="""
Do not create a swap partition. Only one of ``--noswap``
and ``--hibernation`` can be specified.""")
return op
[docs]class F29_AutoPart(F26_AutoPart):
removedKeywords = F26_AutoPart.removedKeywords
removedAttrs = F26_AutoPart.removedAttrs
def __init__(self, writePriority=100, *args, **kwargs):
F26_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
self.luks_version = kwargs.get("luks_version", "")
self.pbkdf = kwargs.get("pbkdf", "")
self.pbkdf_memory = kwargs.get("pbkdf_memory", 0)
self.pbkdf_time = kwargs.get("pbkdf_time", 0)
self.pbkdf_iterations = kwargs.get("pbkdf_iterations", 0)
def __str__(self):
retval = F26_AutoPart.__str__(self)
if not self.autopart:
return retval
if self.encrypted and self.luks_version:
retval = retval.strip()
retval += " --luks-version=%s" % self.luks_version
retval += "\n"
if self.encrypted and self.pbkdf:
retval = retval.strip()
retval += " --pbkdf=%s" % self.pbkdf
retval += "\n"
if self.encrypted and self.pbkdf_memory:
retval = retval.strip()
retval += " --pbkdf-memory=%s" % self.pbkdf_memory
retval += "\n"
if self.encrypted and self.pbkdf_time:
retval = retval.strip()
retval += " --pbkdf-time=%s" % self.pbkdf_time
retval += "\n"
if self.encrypted and self.pbkdf_iterations:
retval = retval.strip()
retval += " --pbkdf-iterations=%s" % self.pbkdf_iterations
retval += "\n"
return retval
def _getParser(self):
op = F26_AutoPart._getParser(self)
op.add_argument("--luks-version", dest="luks_version", version=F29, default="",
help="""
Only relevant if ``--encrypted`` is specified. Specifies
which version of LUKS format should be used to encrypt
the filesystem.""")
op.add_argument("--pbkdf", version=F29, default="", help="""
Only relevant if ``--encrypted`` is specified. Sets
Password-Based Key Derivation Function (PBKDF) algorithm
for LUKS keyslot. See ``man cryptsetup``.""")
op.add_argument("--pbkdf-memory", dest="pbkdf_memory", type=int, default=0,
version=F29, help="""
Only relevant if ``--encrypted`` is specified. Sets
the memory cost for PBKDF. See ``man cryptsetup``.""")
op.add_argument("--pbkdf-time", dest="pbkdf_time", type=int, default=0,
version=F29, help="""
Only relevant if ``--encrypted`` is specified. Sets
the number of milliseconds to spend with PBKDF passphrase
processing. See ``--iter-time`` in ``man cryptsetup``.
Only one of ``--pbkdf-time`` and ``--pbkdf-iterations``
can be specified.
""")
op.add_argument("--pbkdf-iterations", dest="pbkdf_iterations", type=int, default=0,
version=F29, help="""
Only relevant if ``--encrypted`` is specified. Sets
the number of iterations directly and avoids PBKDF benchmark.
See ``--pbkdf-force-iterations`` in ``man cryptsetup``.
Only one of ``--pbkdf-time`` and ``--pbkdf-iterations``
can be specified.
""")
return op
[docs] def parse(self, args):
retval = F26_AutoPart.parse(self, args)
if self.pbkdf_time and self.pbkdf_iterations:
msg = _("Only one of --pbkdf-time and --pbkdf-iterations can be specified.")
raise KickstartParseError(msg, lineno=self.lineno)
return retval
[docs]class RHEL8_AutoPart(F29_AutoPart):
removedKeywords = F29_AutoPart.removedKeywords
removedAttrs = F29_AutoPart.removedAttrs
[docs] def parse(self, args):
# call the overriden command to do it's job first
retval = F29_AutoPart.parse(self, args)
# btrfs is no more supported
if self._typeAsStr() == "btrfs":
raise KickstartParseError(_("autopart --type=btrfs is not supported"),
lineno=self.lineno)
return retval
def _getParser(self):
"Only necessary for the type change documentation"
op = F29_AutoPart._getParser(self)
for action in op._actions:
if "--type" in action.option_strings:
action.help += """
.. versionchanged:: %s
Partitioning scheme 'btrfs' was removed.""" % versionToLongString(RHEL8)
if "--fstype" in action.option_strings:
action.help += """
.. versionchanged:: %s
Partitioning scheme 'btrfs' was removed.""" % versionToLongString(RHEL8)
return op
[docs]class RHEL9_AutoPart(RHEL8_AutoPart):
pass
[docs]class F38_AutoPart(F29_AutoPart):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.hibernation = kwargs.get("hibernation", False)
def __str__(self):
retval = super().__str__()
if self.autopart and self.hibernation:
# remove any trailing newline
retval = retval.strip()
retval += " --hibernation"
retval += "\n"
return retval
def _getParser(self):
op = super()._getParser()
op.add_argument("--hibernation", action="store_true", default=False,
version=F38, help="""
Create a swap partition with an automatically determined
size that's big enough for hibernation. Only one of
``--noswap`` and ``--hibernation`` can be specified.""")
return op
[docs] def parse(self, args):
retval = super().parse(args)
if self.hibernation and self.noswap:
msg = _("Only one of --noswap and --hibernation can be specified.")
raise KickstartParseError(msg, lineno=self.lineno)
return retval