diff --git a/src/pylorax/api/compose.py b/src/pylorax/api/compose.py index 3ac3061c..08d37e54 100644 --- a/src/pylorax/api/compose.py +++ b/src/pylorax/api/compose.py @@ -604,6 +604,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": False, # False instead of None because of TOML "qemu_args": [], "image_name": default_image_name("xz", "root.tar"), @@ -625,6 +626,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": False, # False instead of None because of TOML "qemu_args": [], "image_name": "live.iso", @@ -649,6 +651,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": False, # False instead of None because of TOML "qemu_args": [], "image_name": "disk.img", @@ -671,6 +674,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": "qcow2", "qemu_args": [], "image_name": "disk.qcow2", @@ -693,6 +697,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": False, # False instead of None because of TOML "qemu_args": [], "image_name": "filesystem.img", @@ -715,6 +720,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": False, "qemu_args": [], "image_name": "disk.ami", @@ -737,6 +743,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": "vpc", "qemu_args": ["-o", "subformat=fixed,force_size"], "image_name": "disk.vhd", @@ -759,6 +766,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": "vmdk", "qemu_args": [], "image_name": "disk.vmdk", @@ -781,6 +789,7 @@ def compose_args(compose_type): "ostree": False, "live_rootfs_keep_size": False, "live_rootfs_size": 0, + "image_size_align": 0, "image_type": "qcow2", "qemu_args": [], "image_name": "disk.qcow2", diff --git a/src/pylorax/cmdline.py b/src/pylorax/cmdline.py index 163af0a1..c409b47e 100644 --- a/src/pylorax/cmdline.py +++ b/src/pylorax/cmdline.py @@ -217,6 +217,8 @@ def lmc_parser(dracut_default=""): help="Name of output file to create. Used for tar, fs and disk image. Default is a random name.") image_group.add_argument("--fs-label", default="Anaconda", help="Label to set on fsimage, default is 'Anaconda'") + image_group.add_argument("--image-size-align", type=int, default=0, + help="Create a disk image with a size that is a multiple of this value in MiB.") image_group.add_argument("--image-type", default=None, help="Create an image with qemu-img. See qemu-img --help for supported formats.") image_group.add_argument("--qemu-arg", action="append", dest="qemu_args", default=[], diff --git a/src/pylorax/creator.py b/src/pylorax/creator.py index eda6fea0..a968b687 100644 --- a/src/pylorax/creator.py +++ b/src/pylorax/creator.py @@ -467,6 +467,9 @@ def calculate_disk_size(opts, ks): log.info("Adding 1024M for reqpart --addboot") disk_size += 1024 + if opts.image_size_align: + disk_size += opts.image_size_align - (disk_size % opts.image_size_align) + log.info("Using disk size of %sMiB", disk_size) return disk_size diff --git a/tests/pylorax/test_creator.py b/tests/pylorax/test_creator.py index 8edb5a61..cadcc589 100644 --- a/tests/pylorax/test_creator.py +++ b/tests/pylorax/test_creator.py @@ -246,7 +246,7 @@ class CreatorTest(unittest.TestCase): def disk_size_simple_test(self): """Test calculating the disk size with a simple / partition""" - opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False) + opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False, image_size_align=0) ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" @@ -258,7 +258,7 @@ class CreatorTest(unittest.TestCase): def disk_size_boot_test(self): """Test calculating the disk size with / and /boot partitions""" - opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False) + opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False, image_size_align=0) ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" @@ -271,7 +271,7 @@ class CreatorTest(unittest.TestCase): def disk_size_boot_fsimage_test(self): """Test calculating the disk size with / and /boot partitions on a fsimage""" - opts = DataHolder(no_virt=True, make_fsimage=True, make_iso=False, make_pxe_live=False) + opts = DataHolder(no_virt=True, make_fsimage=True, make_iso=False, make_pxe_live=False, image_size_align=0) ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" @@ -284,7 +284,7 @@ class CreatorTest(unittest.TestCase): def disk_size_reqpart_test(self): """Test calculating the disk size with reqpart and a / partition""" - opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False) + opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False, image_size_align=0) ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" @@ -297,7 +297,7 @@ class CreatorTest(unittest.TestCase): def disk_size_reqpart_boot_test(self): """Test calculating the disk size with reqpart --add-boot and a / partition""" - opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False) + opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False, image_size_align=0) ks_version = makeVersion() ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" @@ -308,6 +308,17 @@ class CreatorTest(unittest.TestCase): "shutdown\n") self.assertEqual(calculate_disk_size(opts, ks), 5622) + def disk_size_align_test(self): + """Test aligning the disk size""" + opts = DataHolder(no_virt=True, make_fsimage=False, make_iso=False, make_pxe_live=False, image_size_align=1024) + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" + "network --bootproto=dhcp --activate\n" + "repo --name=other --baseurl=http://dl.fedoraproject.com\n" + "part / --size=4096\n" + "shutdown\n") + self.assertEqual(calculate_disk_size(opts, ks), 5120) @unittest.skipUnless(os.geteuid() == 0 and not os.path.exists("/.in-container"), "requires root privileges, and no containers") def boot_over_root_test(self):