Add an option to align the image size to a multiplier.

If provided, round the disk image size up to a multiple of the value.
This allows for image formats with specific size-alignment requirements
(e.g., disk size must be in GiB).
This commit is contained in:
David Shea 2019-03-28 11:04:51 -04:00
parent 3d3dda1400
commit 8ef4f431d8
4 changed files with 30 additions and 5 deletions

View File

@ -604,6 +604,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": False, # False instead of None because of TOML "image_type": False, # False instead of None because of TOML
"qemu_args": [], "qemu_args": [],
"image_name": default_image_name("xz", "root.tar"), "image_name": default_image_name("xz", "root.tar"),
@ -625,6 +626,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": False, # False instead of None because of TOML "image_type": False, # False instead of None because of TOML
"qemu_args": [], "qemu_args": [],
"image_name": "live.iso", "image_name": "live.iso",
@ -649,6 +651,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": False, # False instead of None because of TOML "image_type": False, # False instead of None because of TOML
"qemu_args": [], "qemu_args": [],
"image_name": "disk.img", "image_name": "disk.img",
@ -671,6 +674,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": "qcow2", "image_type": "qcow2",
"qemu_args": [], "qemu_args": [],
"image_name": "disk.qcow2", "image_name": "disk.qcow2",
@ -693,6 +697,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": False, # False instead of None because of TOML "image_type": False, # False instead of None because of TOML
"qemu_args": [], "qemu_args": [],
"image_name": "filesystem.img", "image_name": "filesystem.img",
@ -715,6 +720,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": False, "image_type": False,
"qemu_args": [], "qemu_args": [],
"image_name": "disk.ami", "image_name": "disk.ami",
@ -737,6 +743,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": "vpc", "image_type": "vpc",
"qemu_args": ["-o", "subformat=fixed,force_size"], "qemu_args": ["-o", "subformat=fixed,force_size"],
"image_name": "disk.vhd", "image_name": "disk.vhd",
@ -759,6 +766,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": "vmdk", "image_type": "vmdk",
"qemu_args": [], "qemu_args": [],
"image_name": "disk.vmdk", "image_name": "disk.vmdk",
@ -781,6 +789,7 @@ def compose_args(compose_type):
"ostree": False, "ostree": False,
"live_rootfs_keep_size": False, "live_rootfs_keep_size": False,
"live_rootfs_size": 0, "live_rootfs_size": 0,
"image_size_align": 0,
"image_type": "qcow2", "image_type": "qcow2",
"qemu_args": [], "qemu_args": [],
"image_name": "disk.qcow2", "image_name": "disk.qcow2",

View File

@ -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.") 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", image_group.add_argument("--fs-label", default="Anaconda",
help="Label to set on fsimage, default is '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, image_group.add_argument("--image-type", default=None,
help="Create an image with qemu-img. See qemu-img --help for supported formats.") 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=[], image_group.add_argument("--qemu-arg", action="append", dest="qemu_args", default=[],

View File

@ -467,6 +467,9 @@ def calculate_disk_size(opts, ks):
log.info("Adding 1024M for reqpart --addboot") log.info("Adding 1024M for reqpart --addboot")
disk_size += 1024 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) log.info("Using disk size of %sMiB", disk_size)
return disk_size return disk_size

View File

@ -246,7 +246,7 @@ class CreatorTest(unittest.TestCase):
def disk_size_simple_test(self): def disk_size_simple_test(self):
"""Test calculating the disk size with a simple / partition""" """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_version = makeVersion()
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n"
@ -258,7 +258,7 @@ class CreatorTest(unittest.TestCase):
def disk_size_boot_test(self): def disk_size_boot_test(self):
"""Test calculating the disk size with / and /boot partitions""" """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_version = makeVersion()
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n"
@ -271,7 +271,7 @@ class CreatorTest(unittest.TestCase):
def disk_size_boot_fsimage_test(self): def disk_size_boot_fsimage_test(self):
"""Test calculating the disk size with / and /boot partitions on a fsimage""" """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_version = makeVersion()
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n"
@ -284,7 +284,7 @@ class CreatorTest(unittest.TestCase):
def disk_size_reqpart_test(self): def disk_size_reqpart_test(self):
"""Test calculating the disk size with reqpart and a / partition""" """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_version = makeVersion()
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n"
@ -297,7 +297,7 @@ class CreatorTest(unittest.TestCase):
def disk_size_reqpart_boot_test(self): def disk_size_reqpart_boot_test(self):
"""Test calculating the disk size with reqpart --add-boot and a / partition""" """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_version = makeVersion()
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n" ks.readKickstartFromString("url --url=http://dl.fedoraproject.com\n"
@ -308,6 +308,17 @@ class CreatorTest(unittest.TestCase):
"shutdown\n") "shutdown\n")
self.assertEqual(calculate_disk_size(opts, ks), 5622) 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") @unittest.skipUnless(os.geteuid() == 0 and not os.path.exists("/.in-container"), "requires root privileges, and no containers")
def boot_over_root_test(self): def boot_over_root_test(self):