[PATCH][pykickstart] Add support for lvm thin provisioning.

David Lehman dlehman at redhat.com
Tue Jun 25 20:41:05 UTC 2013


This adds a new autopart type and options to the logvol command.
---
 pykickstart/commands/autopart.py | 18 ++++++++------
 pykickstart/commands/logvol.py   | 54 ++++++++++++++++++++++++++++++++++++++++
 pykickstart/constants.py         |  1 +
 pykickstart/handlers/control.py  | 10 ++++----
 tests/commands/autopart.py       |  2 ++
 tests/commands/logvol.py         | 34 +++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 12 deletions(-)

diff --git a/pykickstart/commands/autopart.py b/pykickstart/commands/autopart.py
index c31e014..308ff25 100644
--- a/pykickstart/commands/autopart.py
+++ b/pykickstart/commands/autopart.py
@@ -184,7 +184,8 @@ class F17_AutoPart(F16_AutoPart):
         self.typeMap = { "lvm": AUTOPART_TYPE_LVM,
                          "btrfs": AUTOPART_TYPE_BTRFS,
                          "plain": AUTOPART_TYPE_PLAIN,
-                         "partition": AUTOPART_TYPE_PLAIN }
+                         "partition": AUTOPART_TYPE_PLAIN,
+                         "thinp": AUTOPART_TYPE_LVM_THINP }
 
     def __str__(self):
         retval = F16_AutoPart.__str__(self)
@@ -195,12 +196,10 @@ class F17_AutoPart(F16_AutoPart):
             # remove any trailing newline
             retval = retval.strip()
             retval += " --type="
-            if self.type == AUTOPART_TYPE_LVM:
-                retval += "lvm"
-            elif self.type == AUTOPART_TYPE_BTRFS:
-                retval += "btrfs"
-            else:
-                retval += "plain"
+            for s, n in self.typeMap.items():
+                if self.type == n:
+                    retval += s
+                    break
             retval += "\n"
 
         return retval
@@ -259,3 +258,8 @@ class F18_AutoPart(F17_AutoPart):
         op = F17_AutoPart._getParser(self)
         op.add_option("--cipher")
         return op
+
+class F19_AutoPart(F18_AutoPart):
+    def __init__(self, writePriority=100, *args, **kwargs):
+        F18_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
+        self.typeMap["thinp"] = AUTOPART_TYPE_LVM_THINP
diff --git a/pykickstart/commands/logvol.py b/pykickstart/commands/logvol.py
index 9a7b54c..28b8b50 100644
--- a/pykickstart/commands/logvol.py
+++ b/pykickstart/commands/logvol.py
@@ -233,6 +233,34 @@ class F18_LogVolData(F17_LogVolData):
 
         return retval
 
+class F19_LogVolData(F18_LogVolData):
+    def __init__(self, *args, **kwargs):
+        F18_LogVolData.__init__(self, *args, **kwargs)
+        self.thin_pool = kwargs.get("thin_pool", False)
+        self.thin_volume = kwargs.get("thin_volume", False)
+        self.pool_name = kwargs.get("pool_name", "")
+
+        # these are only for thin pools
+        self.chunk_size = kwargs.get("chunk_size", None)        # kilobytes
+        self.metadata_size = kwargs.get("metadata_size", None)  # megabytes
+
+    def _getArgsAsStr(self):
+        retval = F18_LogVolData._getArgsAsStr(self)
+
+        if self.thin_pool:
+            retval += " --thinpool"
+
+            if self.metadata_size:
+                retval += " --metadatasize=%d" % self.metadata_size
+
+            if self.chunk_size:
+                retval += " --chunksize=%d" % self.chunk_size
+
+        if self.thin_volume:
+            retval += " --thin --poolname=%s" % self.pool_name
+
+        return retval
+
 class FC3_LogVol(KickstartCommand):
     removedKeywords = KickstartCommand.removedKeywords
     removedAttrs = KickstartCommand.removedAttrs
@@ -394,3 +422,29 @@ class F18_LogVol(F17_LogVol):
         op.add_option("--cipher")
         return op
 
+class F19_LogVol(F18_LogVol):
+    def _getParser(self):
+        op = F18_LogVol._getParser(self)
+        op.add_option("--thinpool", action="store_true", dest="thin_pool",
+                      default=False)
+        op.add_option("--thin", action="store_true", dest="thin_volume",
+                      default=False)
+        op.add_option("--poolname", dest="pool_name")
+        op.add_option("--chunksize", type="int", dest="chunk_size")
+        op.add_option("--metadatasize", type="int", dest="metadata_size")
+        return op
+
+    def parse(self, args):
+        retval = F18_LogVol.parse(self, args)
+
+        if retval.thin_volume and retval.thin_pool:
+            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--thin and --thinpool cannot both be specified for the same logvol")))
+
+        if retval.thin_volume and not retval.pool_name:
+            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--thin requires --poolname to specify pool name")))
+
+        if (retval.chunk_size or retval.metadata_size) and \
+           not retval.thin_pool:
+            raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--chunksize and --metadatasize are for thin pools only")))
+
+        return retval
diff --git a/pykickstart/constants.py b/pykickstart/constants.py
index d476c49..7a19a00 100644
--- a/pykickstart/constants.py
+++ b/pykickstart/constants.py
@@ -25,6 +25,7 @@ CLEARPART_TYPE_LIST = 3
 AUTOPART_TYPE_PLAIN = 0
 AUTOPART_TYPE_BTRFS = 1
 AUTOPART_TYPE_LVM = 2
+AUTOPART_TYPE_LVM_THINP = 3
 
 DISPLAY_MODE_CMDLINE = 0
 DISPLAY_MODE_GRAPHICAL = 1
diff --git a/pykickstart/handlers/control.py b/pykickstart/handlers/control.py
index 82a2139..f01a052 100644
--- a/pykickstart/handlers/control.py
+++ b/pykickstart/handlers/control.py
@@ -948,7 +948,7 @@ commandMap = {
     F19: {
         "auth": authconfig.FC3_Authconfig,
         "authconfig": authconfig.FC3_Authconfig,
-        "autopart": autopart.F18_AutoPart,
+        "autopart": autopart.F19_AutoPart,
         "autostep": autostep.FC3_AutoStep,
         "bootloader": bootloader.F19_Bootloader,
         "btrfs": btrfs.F17_BTRFS,
@@ -974,7 +974,7 @@ commandMap = {
         "lang": lang.F19_Lang,
         "liveimg": method.F19_Method,
         "logging": logging.FC6_Logging,
-        "logvol": logvol.F18_LogVol,
+        "logvol": logvol.F19_LogVol,
         "mediacheck": mediacheck.FC4_MediaCheck,
         "multipath": multipath.FC6_MultiPath,
         "network": network.F19_Network,
@@ -1257,7 +1257,7 @@ commandMap = {
         "lang": lang.F19_Lang,
         "liveimg": method.F19_Method,
         "logging": logging.FC6_Logging,
-        "logvol": logvol.F18_LogVol,
+        "logvol": logvol.F19_LogVol,
         "mediacheck": mediacheck.FC4_MediaCheck,
         "multipath": multipath.FC6_MultiPath,
         "network": network.F19_Network,
@@ -1547,7 +1547,7 @@ dataMap = {
         "FcoeData": fcoe.F13_FcoeData,
         "GroupData": group.F12_GroupData,
         "IscsiData": iscsi.F17_IscsiData,
-        "LogVolData": logvol.F18_LogVolData,
+        "LogVolData": logvol.F19_LogVolData,
         "MultiPathData": multipath.FC6_MultiPathData,
         "NetworkData": network.F19_NetworkData,
         "PartData": partition.F18_PartData,
@@ -1616,7 +1616,7 @@ dataMap = {
         "FcoeData": fcoe.F13_FcoeData,
         "GroupData": group.F12_GroupData,
         "IscsiData": iscsi.F17_IscsiData,
-        "LogVolData": logvol.F18_LogVolData,
+        "LogVolData": logvol.F19_LogVolData,
         "MultiPathData": multipath.FC6_MultiPathData,
         "NetworkData": network.F19_NetworkData,
         "PartData": partition.F18_PartData,
diff --git a/tests/commands/autopart.py b/tests/commands/autopart.py
index 39dbb8f..c298b7c 100644
--- a/tests/commands/autopart.py
+++ b/tests/commands/autopart.py
@@ -119,6 +119,8 @@ class F17_TestCase(F16_TestCase):
                           "autopart --type=lvm\n")
         self.assert_parse("autopart --type=btrfs",
                           "autopart --type=btrfs\n")
+        self.assert_parse("autopart --type=thinp",
+                          "autopart --type=thinp\n")
 
         self.assert_parse("autopart --nolvm",
                           "autopart --type=plain\n")
diff --git a/tests/commands/logvol.py b/tests/commands/logvol.py
index cd868fd..5eb0361 100644
--- a/tests/commands/logvol.py
+++ b/tests/commands/logvol.py
@@ -243,5 +243,39 @@ class F18_TestCase(F17_TestCase):
 
         self.assert_parse_error("logvol / --cipher --name=NAME --vgname=VGNAME")
 
+class F19_TestCase(F18_TestCase):
+    def runTest(self):
+        F18_TestCase.runTest(self)
+
+        self.assert_parse("logvol none --name=pool1 --vgname=vg --thinpool",
+                          "logvol none  --thinpool --name=pool1 --vgname=vg\n")
+        self.assert_parse("logvol none --name=pool1 --vgname=vg --thinpool "
+                          "--chunksize=512",
+                          "logvol none  --thinpool --chunksize=512 "
+                          "--name=pool1 --vgname=vg\n")
+        self.assert_parse("logvol none --name=pool1 --vgname=vg --thinpool "
+                          "--metadatasize=4 --chunksize=1024",
+                          "logvol none  --thinpool --metadatasize=4 "
+                          "--chunksize=1024 --name=pool1 --vgname=vg\n")
+        self.assert_parse("logvol /home --name=home --vgname=vg "
+                          "--thin --poolname=pool1",
+                          "logvol /home  --thin --poolname=pool1 "
+                          "--name=home --vgname=vg\n")
+
+        # missing pool name
+        self.assert_parse_error("logvol /home --name=home --vgname=vg --thin")
+
+        # chunksize is an int
+        self.assert_parse_error("logvol none --name=pool1 --vgname=vg "
+                                "--thinpool --chunksize=foo")
+
+        # both --thin and --thinpool
+        self.assert_parse_error("logvol /home --name=home --thin --thinpool --vgname=vg --size=10000")
+
+        # chunksize and/or metadata size and not thinpool
+        self.assert_parse_error("logvol none --name=pool1 --vgname=vg "
+                                "--chunksize=512")
+
+
 if __name__ == "__main__":
     unittest.main()
-- 
1.8.1.4



More information about the anaconda-patches mailing list