livemedia-creator: Add --image-type and --qemu-args options

Also alias --qcow2 to --image-type=qcow2

This allows --make-disk to be used to create any disk image that
qemu-img supports, not just raw or qcow2. See qemu-img --help for a list
of the supported image types.
This commit is contained in:
Brian C. Lane 2015-12-18 15:30:51 -08:00
parent 3d343aace8
commit be685b51ac

View File

@ -52,7 +52,7 @@ from pylorax.treebuilder import findkernels
from pylorax.sysutils import joinpaths, remove from pylorax.sysutils import joinpaths, remove
from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach
from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount from pylorax.imgutils import get_loop_name, dm_detach, mount, umount, Mount
from pylorax.imgutils import mksquashfs, mkqcow2, mktar, mkrootfsimg from pylorax.imgutils import mksquashfs, mkqemu_img, mktar, mkrootfsimg
from pylorax.imgutils import copytree from pylorax.imgutils import copytree
from pylorax.executils import execWithRedirect, execReadlines, runcmd from pylorax.executils import execWithRedirect, execReadlines, runcmd
from pylorax.monitor import LogMonitor from pylorax.monitor import LogMonitor
@ -99,7 +99,7 @@ class VirtualInstall(object):
def __init__(self, iso, ks_paths, disk_img, img_size=2048, def __init__(self, iso, ks_paths, disk_img, img_size=2048,
kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None,
log_check=None, virtio_host="127.0.0.1", virtio_port=6080, log_check=None, virtio_host="127.0.0.1", virtio_port=6080,
qcow2=False, boot_uefi=False, ovmf_path=None): image_type=None, boot_uefi=False, ovmf_path=None):
""" """
Start the installation Start the installation
@ -118,7 +118,7 @@ class VirtualInstall(object):
:type log_check: method :type log_check: method
:param str virtio_host: Hostname to connect virtio log to :param str virtio_host: Hostname to connect virtio log to
:param int virtio_port: Port to connect virtio log to :param int virtio_port: Port to connect virtio log to
:param bool qcow2: Set to True if disk_img is a qcow2 :param str image_type: Type of qemu-img disk to create, or None.
:param bool boot_uefi: Use OVMF to boot the VM in UEFI mode :param bool boot_uefi: Use OVMF to boot the VM in UEFI mode
:param str ovmf_path: Path to the OVMF firmware :param str ovmf_path: Path to the OVMF firmware
""" """
@ -142,8 +142,8 @@ class VirtualInstall(object):
disk_opts = "path={0}".format(disk_img) disk_opts = "path={0}".format(disk_img)
disk_opts += ",cache=unsafe,discard=unmap" disk_opts += ",cache=unsafe,discard=unmap"
if qcow2: if image_type:
disk_opts += ",format=qcow2" disk_opts += ",format={0}".format(image_type)
else: else:
disk_opts += ",format=raw" disk_opts += ",format=raw"
if not os.path.isfile(disk_img): if not os.path.isfile(disk_img):
@ -611,7 +611,7 @@ def novirt_install(opts, disk_img, disk_size, repo_url):
:param str repo_url: The url of the repository to use for the installation :param str repo_url: The url of the repository to use for the installation
This method makes sure SELinux is permissive during the install, runs anaconda This method makes sure SELinux is permissive during the install, runs anaconda
to create the image and then based on the opts passed create a qcow2 image to create the image and then based on the opts passed create a qemu disk image
or tarfile. or tarfile.
""" """
import selinux import selinux
@ -713,20 +713,20 @@ def novirt_install(opts, disk_img, disk_size, repo_url):
if selinux_enforcing: if selinux_enforcing:
selinux.security_setenforce(1) selinux.security_setenforce(1)
# qcow2 is used by bare qcow2 images and by Vagrant # qemu disk image is used by bare qcow2 images and by Vagrant
if opts.qcow2: if opts.image_type:
log.info("Converting %s to qcow2", disk_img) log.info("Converting %s to %s", disk_img, opts.image_type)
qcow2_args = [] qemu_args = []
for arg in opts.qcow2_args: for arg in opts.qemu_args:
qcow2_args += arg.split(" ", 1) qemu_args += arg.split(" ", 1)
# convert the image to qcow2 format # convert the image to the selected format
if "-O" not in qcow2_args: if "-O" not in qemu_args:
qcow2_args.extend(["-O", "qcow2"]) qemu_args.extend(["-O", opts.image_type])
qcow2_img = tempfile.mktemp(prefix="disk", suffix=".img") qemu_img = tempfile.mktemp(prefix="disk", suffix=".img")
execWithRedirect("qemu-img", ["convert"] + qcow2_args + [disk_img, qcow2_img], raise_err=True) execWithRedirect("qemu-img", ["convert"] + qemu_args + [disk_img, qemu_img], raise_err=True)
if not opts.make_vagrant: if not opts.make_vagrant:
execWithRedirect("mv", ["-f", qcow2_img, disk_img], raise_err=True) execWithRedirect("mv", ["-f", qemu_img, disk_img], raise_err=True)
else: else:
# Take the new qcow2 image and package it up for Vagrant # Take the new qcow2 image and package it up for Vagrant
compress_args = [] compress_args = []
@ -735,7 +735,7 @@ def novirt_install(opts, disk_img, disk_size, repo_url):
vagrant_dir = tempfile.mkdtemp() vagrant_dir = tempfile.mkdtemp()
metadata_path = joinpaths(vagrant_dir, "metadata.json") metadata_path = joinpaths(vagrant_dir, "metadata.json")
execWithRedirect("mv", ["-f", qcow2_img, joinpaths(vagrant_dir, "box.img")], raise_err=True) execWithRedirect("mv", ["-f", qemu_img, joinpaths(vagrant_dir, "box.img")], raise_err=True)
if opts.vagrant_metadata: if opts.vagrant_metadata:
shutil.copy2(opts.vagrant_metadata, metadata_path) shutil.copy2(opts.vagrant_metadata, metadata_path)
else: else:
@ -796,13 +796,15 @@ def virt_install(opts, install_log, disk_img, disk_size):
if opts.proxy: if opts.proxy:
kernel_args += " proxy="+opts.proxy kernel_args += " proxy="+opts.proxy
if opts.qcow2 and not opts.make_fsimage: if opts.image_type and not opts.make_fsimage:
# virt-install can't take all the qcow2 options so create the image first # virt-install can't take all the qcow2 options so create the image first
qcow2_args = [] qemu_args = []
for arg in opts.qcow2_args: for arg in opts.qemu_args:
qcow2_args += arg.split(" ", 1) qemu_args += arg.split(" ", 1)
if "-f" not in qemu_args:
qemu_args += ["-f", opts.image_type]
mkqcow2(disk_img, disk_size*1024**2, qcow2_args) mkqemu_img(disk_img, disk_size*1024**2, qemu_args)
if opts.make_fsimage or opts.make_tar or opts.make_oci: if opts.make_fsimage or opts.make_tar or opts.make_oci:
diskimg_path = tempfile.mktemp(prefix="disk", suffix=".img") diskimg_path = tempfile.mktemp(prefix="disk", suffix=".img")
@ -815,7 +817,7 @@ def virt_install(opts, install_log, disk_img, disk_size):
log_check = log_monitor.server.log_check, log_check = log_monitor.server.log_check,
virtio_host = log_monitor.host, virtio_host = log_monitor.host,
virtio_port = log_monitor.port, virtio_port = log_monitor.port,
qcow2=opts.qcow2, boot_uefi=opts.virt_uefi, image_type=opts.image_type, boot_uefi=opts.virt_uefi,
ovmf_path=opts.ovmf_path) ovmf_path=opts.ovmf_path)
virt.destroy() virt.destroy()
@ -1098,10 +1100,14 @@ def main():
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-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=[],
help="Arguments to pass to qemu-img. Pass once for each argument, they will be used for ALL calls to qemu-img.")
image_group.add_argument("--qcow2", action="store_true", image_group.add_argument("--qcow2", action="store_true",
help="Create qcow2 image instead of raw sparse image when making disk images.") help="Create qcow2 image instead of raw sparse image when making disk images.")
image_group.add_argument("--qcow2-arg", action="append", dest="qcow2_args", default=[], image_group.add_argument("--qcow2-arg", action="append", dest="qemu_args", default=[],
help="Arguments to pass to qemu-img. Pass once for each argument") help="Arguments to pass to qemu-img. Pass once for each argument, they will be used for ALL calls to qemu-img.")
image_group.add_argument("--compression", default="xz", image_group.add_argument("--compression", default="xz",
help="Compression binary for make-tar. xz, lzma, gzip, and bzip2 are supported. xz is the default.") help="Compression binary for make-tar. xz, lzma, gzip, and bzip2 are supported. xz is the default.")
image_group.add_argument("--compress-arg", action="append", dest="compress_args", default=[], image_group.add_argument("--compress-arg", action="append", dest="compress_args", default=[],
@ -1238,19 +1244,23 @@ def main():
# Vagrant creates a qcow2 inside a tar, turn on qcow2 # Vagrant creates a qcow2 inside a tar, turn on qcow2
if opts.make_vagrant: if opts.make_vagrant:
opts.qcow2 = True opts.image_type = "qcow2"
if opts.qcow2 and not os.path.exists("/usr/bin/qemu-img"): # Alias --qcow2 to --image-type=qcow2
errors.append("qcow2 requires the qemu-img utility to be installed.") if opts.qcow2:
opts.image_type = "qcow2"
if opts.qcow2 and opts.make_iso: if opts.image_type and not os.path.exists("/usr/bin/qemu-img"):
errors.append("qcow2 cannot be used to make a bootable iso.") errors.append("image-type requires the qemu-img utility to be installed." % opts.image_type)
if opts.make_fsimage and opts.qcow2: if opts.image_type and opts.make_iso:
errors.append("qcow2 cannot be used to make filesystem images.") errors.append("image-type cannot be used to make a bootable iso.")
if opts.make_tar and opts.qcow2: if opts.image_type and opts.make_fsimage:
errors.append("qcow2 cannot be used to make a tar.") errors.append("image-type cannot be used to make filesystem images.")
if opts.image_type and opts.make_tar:
errors.append("image-type cannot be used to make a tar.")
if opts.make_oci and not (opts.oci_config and opts.oci_runtime): if opts.make_oci and not (opts.oci_config and opts.oci_runtime):
errors.append("--make-oci requires --oci-config and --oci-runtime") errors.append("--make-oci requires --oci-config and --oci-runtime")