livemedia-creator: Use qemu instead of virt-install

Switching to using qemu directly allows lmc to be more flexible. It can
now run from inside a mock chroot for creation of all image types,
inculding disk images, and can take advantage of KVM on the host system
if /dev/kvm device is present inside the mock.

It should also be possible to create cross-arch images, but without kvm
available this is likely to be a very slow option.
This commit is contained in:
Brian C. Lane 2016-01-05 16:49:40 -08:00
parent 8e47b8a96a
commit f8316a7b89
3 changed files with 277 additions and 174 deletions

View File

@ -226,7 +226,7 @@ Passed to --vcpus command
.TP
\fB\-\-vnc VNC\fR
Passed to --graphics command
Passed to qemu -display command. eg. vnc=127.0.0.1:5, default is to choose the first unused vnc port.
.TP
\fB\-\-arch ARCH\fR

View File

@ -12,8 +12,8 @@ isos, bootable (partitioned) disk images, tarfiles, and filesystem images for
use with virtualization and container solutions like libvirt, docker, and
OpenStack.
The general idea is to use virt-install with kickstart and an Anaconda boot.iso
to install into a disk image and then use the disk image to create the bootable
The general idea is to use qemu with kickstart and an Anaconda boot.iso to
install into a disk image and then use the disk image to create the bootable
media.
livemedia-creator --help will describe all of the options available. At the
@ -21,19 +21,14 @@ minimum you need:
``--make-iso`` to create a final bootable .iso or one of the other ``--make-*`` options.
``--iso`` to specify the Anaconda install media to use with virt-install
``--iso`` to specify the Anaconda install media to use with qemu.
``--ks`` to select the kickstart file describing what to install.
To use livemedia-creator with virt-install you will need to install the
following packages, as well as have libvirtd setup correctly.
* ``virt-install``
* ``libvirt-python``
To use livemedia-creator with virtualization you will need to have qemu installed.
If you are going to be using Anaconda directly, with ``--no-virt`` mode, make sure
you have the anaconda package installed. You can use the anaconda-tui package
to save a bit of space on the build system.
you have the anaconda-tui package installed.
Conventions used in this document:
@ -58,8 +53,8 @@ You can run it directly from the lorax git repo like this::
--make-iso --iso=/extra/iso/boot.iso \
--ks=./docs/fedora-livemedia.ks --lorax-templates=./share/
If you want to watch the install you can pass ``--vnc vnc`` and use a vnc client
to connect to localhost:0
You can observe the installation using vnc. The logs will show what port was
chosen, or you can use a specific port by passing it. eg. ``--vnc vnc:127.0.0.1:5``
This is usually a good idea when testing changes to the kickstart. lmc tries
to monitor the logs for fatal errors, but may not catch everything.
@ -74,7 +69,7 @@ Normally you would run both stages, but it is possible to stop after the
install stage, by using ``--image-only``, or to skip the install stage and use
a previously created disk image by passing ``--disk-image`` or ``--fs-image``
When creating an iso virt-install boots using the passed Anaconda installer iso
When creating an iso qemu boots using the passed Anaconda installer iso
and installs the system based on the kickstart. The ``%post`` section of the
kickstart is used to customize the installed system in the same way that
current spin-kickstarts do.
@ -82,24 +77,22 @@ current spin-kickstarts do.
livemedia-creator monitors the install process for problems by watching the
install logs. They are written to the current directory or to the base
directory specified by the --logfile command. You can also monitor the install
by passing ``--vnc vnc`` and using a vnc client. This is recommended when first
modifying a kickstart, since there are still places where Anaconda may get
stuck without the log monitor catching it.
by using a vnc client. This is recommended when first modifying a kickstart,
since there are still places where Anaconda may get stuck without the log
monitor catching it.
The output from this process is a partitioned disk image. kpartx can be used
to mount and examine it when there is a problem with the install. It can also
be booted using kvm.
When creating an iso the disk image's / partition is copied into a formatted
disk image which is then used as the input to lorax for creation of the final
media.
filesystem image which is then used as the input to lorax for creation of the
final media.
The final image is created by lorax, using the templates in /usr/share/lorax/
or the directory specified by ``--lorax-templates``
Currently the standard lorax templates are used to make a bootable iso, but
it should be possible to modify them to output other results. They are
written using the Mako template system which is very flexible.
The final image is created by lorax, using the templates in /usr/share/lorax/live/
or the live directory below the directory specified by ``--lorax-templates``. The
templates are written using the Mako template system with some extra commands
added by lorax.
.. note::
The output from --make-iso includes the artifacts used to create the boot.iso;
@ -163,10 +156,10 @@ changes. Here are the steps I used to convert the Fedora XFCE spin.
memtest86+
syslinux
One drawback to using virt-install is that it pulls the packages from
the repo each time you run it. To speed things up you either need a local
mirror of the packages, or you can use a caching proxy. When using a proxy
you pass it to livemedia-creator like this:
One drawback to using qemu is that it pulls the packages from the repo each
time you run it. To speed things up you either need a local mirror of the
packages, or you can use a caching proxy. When using a proxy you pass it to
livemedia-creator like this:
``--proxy=http://proxy.yourdomain.com:3128``
@ -175,16 +168,16 @@ packages will get cached, so your kickstart url would look like:
``url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"``
You can also add an update repo, but don't name it updates. Add --proxy to
it as well.
You can also add an update repo, but don't name it updates. Add --proxy to it
as well.
Anaconda image install (no-virt)
--------------------------------
You can create images without using virt-install by passing ``--no-virt`` on the
cmdline. This will use Anaconda's directory install feature to handle the install.
There are a couple of things to keep in mind when doing this:
You can create images without using qemu by passing ``--no-virt`` on the
cmdline. This will use Anaconda's directory install feature to handle the
install. There are a couple of things to keep in mind when doing this:
1. It will be most reliable when building images for the same release that the
host is running. Because Anaconda has expectations about the system it is
@ -302,9 +295,9 @@ You can also create qcow2 appliance images using ``--image-type=qcow2``, for exa
Filesystem Image Creation
-------------------------
livemedia-creator can be used to create un-partitined filesystem images using the
``--make-fsimage`` option. As of version 21.8 this works with both virt-install and no-virt modes
of operation. Previously it was only available with no-virt.
livemedia-creator can be used to create un-partitined filesystem images using
the ``--make-fsimage`` option. As of version 21.8 this works with both qemu and
no-virt modes of operation. Previously it was only available with no-virt.
Kickstarts should have a single / partition with no extra mountpoints.
@ -347,8 +340,8 @@ using Atomic installer iso with local repo included in the image can be found
in docs/rhel-atomic-pxe-live.ks.
Using Mock to Create Images
---------------------------
Using Mock and --no-virt to Create Images
-----------------------------------------
As of lorax version 22.2 you can use livemedia-creator and anaconda version
22.15 inside of a mock chroot with --make-iso and --make-fsimage.
@ -404,6 +397,66 @@ located at ~/results/try-1/images/boot.iso, and the ~/results/try-1/
directory tree will also contain the vmlinuz, initrd, etc.
Using Mock and qemu to Create Images
------------------------------------
Version 25.0 of livemedia-creator switches to using qemu for virtualization.
This allows creation of all image types, and use of the KVM on the host if
/dev/kvm is present in the mock environment.
On the host system:
1. yum install -y mock
2. Add a user to the mock group to use for running mock. eg. builder
3. Create a new /etc/mock/ config file based on the rawhide one, or modify the
existing one so that the following options are setup::
config_opts['chroot_setup_cmd'] = 'install @buildsys-build lorax qemu'
# build results go into /home/builder/results/
config_opts['plugin_conf']['bind_mount_opts']['dirs'].append(('/home/builder/results','/results/'))
If you are creating images for a branched release of Fedora you should also enable
the updates-testing repository so that you get the latest builds in your mock chroot.
The following steps are run as the builder user who is a member of the mock
group.
4. Make a directory for results matching the bind mount above
``mkdir ~/results/``
5. Copy the example kickstarts
``cp /usr/share/docs/lorax/*ks .``
6. Make sure tar and dracut-network are in the %packages section and that the
``url points to the correct repo``
7. Init the mock
``mock -r fedora-rawhide-x86_64 --init``
8. Copy the kickstart inside the mock
``mock -r fedora-rawhide-x86_64 --copyin ./fedora-minimal.ks /root/``
9. Copy the Anaconda boot.iso inside the mock
``mock -r fedora-rawhide-x86_64 --copyin ./boot.iso /root/``
10. Make a minimal iso::
mock -r fedora-rawhide-x86_64 --chroot -- livemedia-creator \
--resultdir=/results/try-1 --logfile=/results/logs/try-1/try-1.log \
--make-iso --ks /root/fedora-minimal.ks --iso /root/boot.iso
Results will be in ./results/try-1 and logs under /results/logs/try-1/
including anaconda logs and livemedia-creator logs. The new iso will be
located at ~/results/try-1/images/boot.iso, and the ~/results/try-1/
directory tree will also contain the vmlinuz, initrd, etc.
This will run qemu without kvm support, which is going to be very slow. You can
add ``mknod /dev/kvm c 10 232;`` to create the device node before running lmc.
OpenStack Image Creation
------------------------
@ -528,29 +581,27 @@ Make sure that the kickstart you are using creates a /boot/efi partition by incl
Debugging problems
------------------
Sometimes an installation will get stuck. When using virt-install the logs will
Sometimes an installation will get stuck. When using qemu the logs will
be written to ./virt-install.log and most of the time any problems that happen
will be near the end of the file. lmc tries to detect common errors and will
cancel the installation when they happen. But not everything can be caught.
When creating a new kickstart it is helpful to use the ``--vnc vnc`` command so
that you can monitor the installation as it happens, and if it gets stuck
without lmc detecting the problem you can switch to tty1 and examine the system
directly.
When creating a new kickstart it is helpful to use vnc so that you can monitor
the installation as it happens, and if it gets stuck without lmc detecting the
problem you can switch to tty1 and examine the system directly.
If it does get stuck the best way to cancel is to use virsh to destroy the domain.
1. Use ``sudo virsh list`` to show the name of the virt. It will start with LiveOS and contain a UUID.
2. Run ``sudo virsh destroy <name>`` to destroy the domain.
3. Wait 20 seconds or so for lmc to detect that the domain vanished. It should handle cleanup.
If it does get stuck the best way to cancel is to use kill -9 on the qemu pid,
lmc will detect that the process died and cleanup.
If lmc didn't handle the cleanup for some reason you can do this:
1. ``sudo virsh undefine <name>``
2. ``sudo umount /tmp/tmpXXXX`` to unmount the iso from its mountpoint.
3. ``sudo rm -rf /tmp/tmpXXXX``
4. ``sudo rm /var/tmp/diskXXXXX`` to remove the disk image.
1. ``sudo umount /tmp/lmc-XXXX`` to unmount the iso from its mountpoint.
2. ``sudo rm -rf /tmp/lmc-XXXX``
3. ``sudo rm /var/tmp/lmc-disk-XXXXX`` to remove the disk image.
The logs from the virt-install run are stored in virt-install.log,
logs from livemedia-creator are in livemedia.log and program.log
Note that lmc uses the lmc- prefix for all of its temporary files and
directories to make it easier to find and clean up leftovers.
The logs from the qemu run are stored in virt-install.log, logs from
livemedia-creator are in livemedia.log and program.log
You can add ``--image-only`` to skip the .iso creation and examine the resulting
disk image. Or you can pass ``--keep-image`` to keep it around after the iso has

View File

@ -24,16 +24,15 @@ log = logging.getLogger("livemedia-creator")
import os
import sys
import uuid
import tempfile
import subprocess
from time import sleep
import shutil
import argparse
import hashlib
import glob
import json
from math import ceil
import socket
# Use pykickstart to calculate disk image size
from pykickstart.parser import KickstartParser
@ -53,17 +52,11 @@ from pylorax.sysutils import joinpaths, remove
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 mksquashfs, mkqemu_img, mktar, mkrootfsimg
from pylorax.imgutils import copytree
from pylorax.imgutils import copytree, mkcpio
from pylorax.executils import execWithRedirect, execReadlines, runcmd
from pylorax.monitor import LogMonitor
from pylorax.mount import IsoMountpoint
# no-virt mode doesn't need libvirt, so make it optional
try:
import libvirt
except ImportError:
libvirt = None
# Default parameters for rebuilding initramfs, override with --dracut-args
DRACUT_DEFAULT = ["--xz", "--add", "livenet dmsquash-live convertfs pollcdrom qemu qemu-net",
"--omit", "plymouth", "--no-hostonly", "--debug", "--no-early-microcode"]
@ -92,11 +85,76 @@ class FakeDNF(object):
pass
class VirtualInstall(object):
def find_free_port(start=5900, end=5999, host="127.0.0.1"):
""" Return first free port in range.
:param int start: Starting port number
:param int end: Ending port number
:param str host: Host IP to search
:returns: First free port or -1 if none found
:rtype: int
"""
Run virt-install using an iso and a kickstart
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for port in range(start, end+1):
try:
s.bind((host, port))
s.close()
return port
except OSError:
pass
return -1
def append_initrd(initrd, files):
""" Append files to an initrd.
:param str initrd: Path to initrd
:param list files: list of file paths to add
:returns: Path to a new initrd
:rtype: str
The files are added to the initrd by creating a cpio image
of the files (stored at /) and writing the cpio to the end of a
copy of the initrd.
The initrd is not changed, a copy is made before appending the
cpio archive.
"""
def __init__(self, iso, ks_paths, disk_img, img_size=2048,
qemu_initrd = tempfile.mktemp(prefix="lmc-initrd-", suffix=".img")
shutil.copy2(initrd, qemu_initrd)
ks_dir = tempfile.mkdtemp(prefix="lmc-ksdir-")
for ks in files:
shutil.copy2(ks, ks_dir)
ks_initrd = tempfile.mktemp(prefix="lmc-ks-", suffix=".img")
mkcpio(ks_dir, ks_initrd)
shutil.rmtree(ks_dir)
with open(qemu_initrd, "ab") as initrd_fp:
with open(ks_initrd, "rb") as ks_fp:
while True:
data = ks_fp.read(1024**2)
if not data:
break
initrd_fp.write(data)
os.unlink(ks_initrd)
return qemu_initrd
class QEMUInstall(object):
"""
Run qemu using an iso and a kickstart
"""
# Mapping of arch to qemu command
QEMU_CMDS = {"x86_64": "qemu-system-x86_64",
"i386": "qemu-system-i386",
"arm": "qemu-system-arm",
"aarch64": "qemu-system-aarch64",
"ppc": "qemu-system-ppc",
"ppc64": "qemu-system-ppc64"
}
def __init__(self, opts, iso, ks_paths, disk_img, img_size=2048,
kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None,
log_check=None, virtio_host="127.0.0.1", virtio_port=6080,
image_type=None, boot_uefi=False, ovmf_path=None):
@ -112,7 +170,7 @@ class VirtualInstall(object):
:param str kernel_args: Extra kernel arguments to pass on the kernel cmdline
:param int memory: Amount of RAM to assign to the virt, in MiB
:param int vcpus: Number of virtual cpus
:param str vnc: Arguments to pass to virt-install --graphics
:param str vnc: Arguments to pass to qemu -display
:param str arch: Optional architecture to use in the virt
:param log_check: Method that returns True if the installation fails
:type log_check: method
@ -122,102 +180,97 @@ class VirtualInstall(object):
:param bool boot_uefi: Use OVMF to boot the VM in UEFI mode
:param str ovmf_path: Path to the OVMF firmware
"""
self.virt_name = "LiveOS-"+str(uuid.uuid4())
# add --graphics none later
# add whatever serial cmds are needed later
args = ["-n", self.virt_name,
"-r", str(memory),
"--noreboot",
"--noautoconsole"]
# Lookup qemu-system- for arch if passed, or try to guess using host arch
qemu_cmd = [self.QEMU_CMDS.get(arch or os.uname().machine, "qemu-system-"+os.uname().machine)]
if not os.path.exists("/usr/bin/"+qemu_cmd[0]):
raise InstallError("%s does not exist, cannot run qemu" % qemu_cmd[0])
args.append("--graphics")
if vnc:
args.append(vnc)
else:
args.append("none")
qemu_cmd += ["-nodefconfig"]
qemu_cmd += ["-m", str(memory)]
if vcpus:
qemu_cmd += ["-smp", str(vcpus)]
for ks in ks_paths:
args.append("--initrd-inject")
args.append(ks)
if not opts.no_kvm and os.path.exists("/dev/kvm"):
qemu_cmd += ["--machine", "accel=kvm"]
disk_opts = "path={0}".format(disk_img)
disk_opts += ",cache=unsafe,discard=unmap"
if image_type:
disk_opts += ",format={0}".format(image_type)
else:
disk_opts += ",format=raw"
# Copy the initrd from the iso, create a cpio archive of the kickstart files
# and append it to the temporary initrd.
qemu_initrd = append_initrd(iso.initrd, ks_paths)
qemu_cmd += ["-kernel", iso.kernel]
qemu_cmd += ["-initrd", qemu_initrd]
# Add the disk and cdrom
if not os.path.isfile(disk_img):
mksparse(disk_img, img_size * 1024**2)
args.append("--disk")
args.append(disk_opts)
drive_args = "file=%s" % disk_img
drive_args += ",cache=unsafe,discard=unmap"
if image_type:
drive_args += ",format=%s" % image_type
else:
drive_args += ",format=raw"
qemu_cmd += ["-drive", drive_args]
if iso.stage2:
disk_opts = "path={0},device=cdrom,readonly=on,shareable=on".format(iso.iso_path)
args.append("--disk")
args.append(disk_opts)
drive_args = "file=%s,media=cdrom,readonly=on" % iso.iso_path
qemu_cmd += ["-drive", drive_args]
extra_args = "ks=file:/{0}".format(os.path.basename(ks_paths[0]))
if not vnc:
extra_args += " inst.cmdline"
# Setup the cmdline args
# ======================
cmdline_args = "ks=file:/%s" % os.path.basename(ks_paths[0])
cmdline_args += " inst.stage2=hd:LABEL=%s" % udev_escape(iso.label)
if opts.proxy:
cmdline_args += " inst.proxy=%s" % opts.proxy
if kernel_args:
extra_args += " "+kernel_args
if iso.stage2:
extra_args += " stage2=hd:LABEL={0}".format(udev_escape(iso.label))
args.append("--extra-args")
args.append(extra_args)
cmdline_args += " "+kernel_args
cmdline_args += " inst.text inst.cmdline"
args.append("--location")
args.append(iso.mount_dir)
qemu_cmd += ["-append", cmdline_args]
channel_args = "tcp,host={0}:{1},mode=connect,target_type=virtio" \
",name=org.fedoraproject.anaconda.log.0".format(
virtio_host, virtio_port)
args.append("--channel")
args.append(channel_args)
if not opts.vnc:
vnc_port = find_free_port()
if vnc_port == -1:
raise InstallError("No free VNC ports")
display_args = "vnc=127.0.0.1:%d" % (vnc_port - 5900)
else:
display_args = opts.vnc
log.info("qemu %s", display_args)
qemu_cmd += ["-nographic", "-display", display_args ]
if arch:
args.append("--arch")
args.append(arch)
# Setup the virtio log port
qemu_cmd += ["-device", "virtio-serial-pci,id=virtio-serial0"]
qemu_cmd += ["-device", "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0"
",id=channel0,name=org.fedoraproject.anaconda.log.0"]
qemu_cmd += ["-chardev", "socket,id=charchannel0,host=%s,port=%s" % (virtio_host, virtio_port)]
if vcpus:
args.append("--vcpus")
args.append(str(vcpus))
# PAss through rng from host
qemu_cmd += ["-object", "rng-random,id=virtio-rng0,filename=/dev/random"]
qemu_cmd += ["-device", "virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pci.0,addr=0x9"]
if boot_uefi and ovmf_path:
args.append("--boot")
args.append(UEFI_FIRMWARE.format(ovmf_path))
qemu_cmd += ["-drive", "file=%s/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on" % ovmf_path]
qemu_cmd += ["-drive", "file=%sOVMF_VARS.fd,if=pflash,format=raw,unit=1" % ovmf_path]
log.info("Running virt-install.")
log.info("Running qemu")
log.debug(qemu_cmd)
try:
execWithRedirect("virt-install", args, raise_err=True)
execWithRedirect(qemu_cmd[0], qemu_cmd[1:], reset_lang=False, raise_err=True,
callback=lambda p: not log_check())
except subprocess.CalledProcessError as e:
raise InstallError("Problem starting virtual install: %s" % e)
conn = libvirt.openReadOnly(None)
dom = conn.lookupByName(self.virt_name)
# TODO: If vnc has been passed, we should look up the port and print that
# for the user at this point
while dom.isActive() and not log_check():
sys.stdout.write(".")
sys.stdout.flush()
sleep(10)
print()
log.error("Running qemu failed:")
log.error("cmd: %s", " ".join(e.cmd))
log.error("output: %s", e.output or "")
raise InstallError("QEMUInstall failed")
except (OSError, KeyboardInterrupt) as e:
log.error("Running qemu failed: %s", str(e))
raise InstallError("QEMUInstall failed")
finally:
os.unlink(qemu_initrd)
if log_check():
log.info("Installation error detected. See logfile.")
log.error("Installation error detected. See logfile for details.")
raise InstallError("QEMUInstall failed")
else:
log.info("Install finished. Or at least virt shut down.")
log.info("Installation finished without errors.")
def destroy(self):
"""
Make sure the virt has been shut down and destroyed
Could use libvirt for this instead.
"""
log.info("Shutting down %s", self.virt_name)
subprocess.call(["virsh", "destroy", self.virt_name])
subprocess.call(["virsh", "undefine", self.virt_name])
def is_image_mounted(disk_img):
"""
@ -775,18 +828,22 @@ def novirt_install(opts, disk_img, disk_size):
def virt_install(opts, install_log, disk_img, disk_size):
"""
Use virt-install to install to a disk image
Use qemu to install to a disk image
:param opts: options passed to livemedia-creator
:type opts: argparse options
:param str install_log: The path to write the log from virt-install
:param str install_log: The path to write the log from qemu
:param str disk_img: The full path to the disk image to be created
:param int disk_size: The size of the disk_img in MiB
This uses virt-install with a boot.iso and a kickstart to create a disk
This uses qemu with a boot.iso and a kickstart to create a disk
image and then optionally, based on the opts passed, creates tarfile.
"""
iso_mount = IsoMountpoint(opts.iso, opts.location)
if not iso_mount.stage2:
iso_mount.umount()
raise InstallError("ISO is missing stage2, cannot continue")
log_monitor = LogMonitor(install_log, timeout=opts.timeout)
kernel_args = ""
@ -796,7 +853,6 @@ def virt_install(opts, install_log, disk_img, disk_size):
kernel_args += " proxy="+opts.proxy
if opts.image_type and not opts.make_fsimage:
# virt-install can't take all the qcow2 options so create the image first
qemu_args = []
for arg in opts.qemu_args:
qemu_args += arg.split(" ", 1)
@ -811,15 +867,13 @@ def virt_install(opts, install_log, disk_img, disk_size):
diskimg_path = disk_img
try:
virt = VirtualInstall(iso_mount, opts.ks, diskimg_path, disk_size,
kernel_args, opts.ram, opts.vcpus, opts.vnc, opts.arch,
log_check = log_monitor.server.log_check,
virtio_host = log_monitor.host,
virtio_port = log_monitor.port,
image_type=opts.image_type, boot_uefi=opts.virt_uefi,
ovmf_path=opts.ovmf_path)
virt.destroy()
QEMUInstall(opts, iso_mount, opts.ks, diskimg_path, disk_size,
kernel_args, opts.ram, opts.vcpus, opts.vnc, opts.arch,
log_check = log_monitor.server.log_check,
virtio_host = log_monitor.host,
virtio_port = log_monitor.port,
image_type=opts.image_type, boot_uefi=opts.virt_uefi,
ovmf_path=opts.ovmf_path)
log_monitor.shutdown()
except InstallError as e:
log.error("VirtualInstall failed: %s", e)
@ -931,7 +985,7 @@ def make_image(opts, ks):
:returns: Path of the image created
:rtype: str
Use virt-install or anaconda to install to a disk image.
Use qemu+boot.iso or anaconda to install to a disk image.
"""
# Disk size for a filesystem image should only be the size of /
# to prevent surprises when using the same kickstart for different installations.
@ -1049,7 +1103,7 @@ def main():
help="Build a Vagrant Box image")
parser.add_argument("--iso", type=os.path.abspath,
help="Anaconda installation .iso path to use for virt-install")
help="Anaconda installation .iso path to use for qemu")
parser.add_argument("--iso-only", action="store_true",
help="Remove all iso creation artifacts except the boot.iso, "
"combine with --iso-name to rename the boot.iso")
@ -1061,7 +1115,7 @@ def main():
help="Exit after creating fs/disk image.")
parser.add_argument("--no-virt", action="store_true",
help="Use Anaconda's image install instead of virt-install")
help="Run anaconda directly on host instead of using qemu")
parser.add_argument("--proxy",
help="proxy URL to use for the install")
parser.add_argument("--anaconda-arg", action="append", dest="anaconda_args",
@ -1072,8 +1126,8 @@ def main():
"i.e., highbank, mvebu, omap, tegra, etc.")
parser.add_argument("--location", default=None, type=os.path.abspath,
help="location of iso directory tree with initrd.img "
"and vmlinuz. Used to run virt-install with a "
"newer initrd than the iso.")
"and vmlinuz. Used to run qemu with a newer initrd "
"than the iso.")
parser.add_argument("--logfile", default="./livemedia.log",
type=os.path.abspath,
@ -1126,25 +1180,26 @@ def main():
app_group.add_argument("--app-file", default="appliance.xml",
help="Appliance template results file.")
# Group of arguments to pass to virt-install
if not libvirt:
virt_group = parser.add_argument_group("virt-install arguments (DISABLED -- no libvirt)")
else:
virt_group = parser.add_argument_group("virt-install arguments")
# Group of arguments to pass to qemu
virt_group = parser.add_argument_group("qemu arguments")
virt_group.add_argument("--ram", metavar="MEMORY", type=int, default=1024,
help="Memory to allocate for installer in megabytes.")
virt_group.add_argument("--vcpus", type=int, default=None,
help="Passed to --vcpus command")
help="Passed to qemu -smp command")
virt_group.add_argument("--vnc",
help="Passed to --graphics command")
help="Passed to qemu -display command. eg. vnc=127.0.0.1:5, default is to "
"choose the first unused vnc port.")
virt_group.add_argument("--arch", default=None,
help="Passed to --arch command")
help="System arch to build for. Used to select qemu-system-* command. "
"Defaults to qemu-system-<arch>")
virt_group.add_argument("--kernel-args",
help="Additional argument to pass to the installation kernel")
virt_group.add_argument("--ovmf-path", default="/usr/share/OVMF/",
help="Path to OVMF firmware")
virt_group.add_argument("--virt-uefi", action="store_true", default=False,
help="Use OVMF firmware to boot the VM in UEFI mode")
virt_group.add_argument("--no-kvm", action="store_true", default=False,
help="Skip using kvm with qemu even if it is available.")
# dracut arguments
dracut_group = parser.add_argument_group("dracut arguments")
@ -1232,12 +1287,9 @@ def main():
if opts.volid and len(opts.volid) > 32:
errors.append("the volume id cannot be longer than 32 characters")
if is_install and not opts.no_virt and not libvirt:
errors.append("virt install requires libvirt-python3 to be installed.")
if is_install and not opts.no_virt \
and not os.path.exists("/usr/bin/virt-install"):
errors.append("virt-install needs to be installed.")
and not any(glob.glob("/usr/bin/qemu-system-*")):
errors.append("qemu needs to be installed.")
if is_install and opts.no_virt \
and not os.path.exists("/usr/sbin/anaconda"):