From e5c0c634b03881bed825dbac3fad1a92fce695f0 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Tue, 3 Nov 2015 18:03:09 -0800 Subject: [PATCH] Add --virt-uefi to boot the VM using OVMF This requires OVMF to be setup on the system, and for the kickstart to create a /boot/efi/ partition. You can then use it to create UEFI bootable partitioned disk images. --- docs/livemedia-creator.rst | 50 ++++++++++++++++++++++++++++++++++---- src/sbin/livemedia-creator | 20 +++++++++++++-- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/docs/livemedia-creator.rst b/docs/livemedia-creator.rst index 2a379eb7..f739e642 100644 --- a/docs/livemedia-creator.rst +++ b/docs/livemedia-creator.rst @@ -200,6 +200,12 @@ Example cmdline: ``sudo livemedia-creator --make-iso --no-virt --ks=./fedora-livemedia.ks`` +.. note:: + Using no-virt to create a partitioned disk image (eg. --make-disk or + --make-vagrant) will only create disks usable on the host platform (BIOS + or UEFI). You can create BIOS partitioned disk images on UEFI by using + virt. + AMI Images ---------- @@ -399,7 +405,7 @@ OpenStack supports partitioned disk images so ``--make-disk`` can be used to create images for importing into glance, OpenStack's image storage component. You need to have access to an OpenStack provider that allows image uploads, or setup your own using the instructions from the `RDO Project -`. +`_. The example kickstart, fedora-openstack.ks, is only slightly different than the fedora-minimal.ks one. It adds the cloud-init and cloud-utils-growpart @@ -440,14 +446,14 @@ Open Container Initiative Image Creation ---------------------------------------- The OCI is a new specification that is still being worked on. You can read more about it at -`the Open Container Initiative website `. You can create +`the Open Container Initiative website `_. You can create OCI images using the following command:: sudo livemedia-creator --make-oci --oci-config /path/to/config.json --oci-runtime /path/to/runtime.json \ --iso=/path/to/boot.iso --ks=/path/to/fedora-minimal.ks You must provide the config.json and runtime.json files to be included in the bundle, -their specifications can be found `on the OCI github project ` +their specifications can be found `on the OCI github project `_ output will be in the results directory with a default name of bundle.tar.xz This will work with ``--no-virt`` and inside a mock since it doesn't use any @@ -457,13 +463,13 @@ partitioned disk images. Vagrant Image Creation ---------------------- -`Vagrant ` images can be created using the following command:: +`Vagrant `_ images can be created using the following command:: sudo livemedia-creator --make-vagrant --vagrant-metadata /path/to/metadata.json \ --iso=/path/to/boot.iso --ks=/path/to/fedora-vagrant.ks The image created is a `vagrant-libvirt -` provider image and needs to have +`_ provider image and needs to have vagrant setup with libvirt before you can use it. The ``--vagrant-metadata`` file is optional, it will create a minimal one by @@ -479,6 +485,40 @@ This also works with ``--no-virt``, but will not work inside a mock due to its use of partitioned disk images and qcow2. +Creating UEFI disk images with virt +----------------------------------- + +Partitioned disk images can only be created for the same platform as the host system (BIOS or +UEFI). You can use virt to create BIOS images on UEFI systems, and it is also possible +to create UEFI images on BIOS systems using OVMF. You first need to setup your system with +the OVMF firmware. The details can be `found here linux-kvm OVMF page `_ +but it amounts to: + +1. Download the firmware.repo from `Gerd Hoffmann `_ and install it + in /etc/yum.repos.d/ + +2. Install the edk2.git-ovmf-x64 package + +3. Copy /usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd to /usr/share/OVMF/OVMF_CODE.fd + +4. Copy /usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd to /usr/share/OVMF/OVMF_VARS.fd + +Now you can run livemedia-creator with ``--virt-uefi`` to boot and install using UEFI:: + + sudo livemedia-creator --make-disk --virt-uefi --iso=/path/to/boot.iso \ + --ks=/path/to/fedora-minimal.ks + +Make sure that the kickstart you are using creates a /boot/efi partition by including this:: + + part /boot/efi --fstype="efi" --size=500 + +.. note:: + When using the resulting image with the current version of OVMF (edk2.git-ovmf-x64-0-20151103.b1295.ge5cffca) + it will not boot automatically because there is a problem with the fallback path. + You can boot it by entering the UEFI shell and running EFI/fedora/shim.efi and + then using efibootmgr to setup the correct boot entry. + + Debugging problems ------------------ diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index 32b562c4..d9d804dd 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -69,6 +69,8 @@ DRACUT_DEFAULT = ["--xz", "--add", "livenet dmsquash-live convertfs pollcdrom", ROOT_PATH = "/mnt/sysimage/" RUNTIME = "images/install.img" +UEFI_FIRMWARE="loader={0}/OVMF_CODE.fd,loader_ro=yes,loader_type=pflash,nvram_template={0}/OVMF_VARS.fd" + class InstallError(Exception): pass @@ -96,7 +98,7 @@ class VirtualInstall(object): def __init__(self, iso, ks_paths, disk_img, img_size=2048, kernel_args=None, memory=1024, vnc=None, arch=None, log_check=None, virtio_host="127.0.0.1", virtio_port=6080, - qcow2=False): + qcow2=False, boot_uefi=False, ovmf_path=None): """ Start the installation @@ -115,6 +117,8 @@ class VirtualInstall(object): :param str virtio_host: Hostname 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 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 @@ -172,6 +176,10 @@ class VirtualInstall(object): args.append("--arch") args.append(arch) + if boot_uefi and ovmf_path: + args.append("--boot") + args.append(UEFI_FIRMWARE.format(ovmf_path)) + log.info("Running virt-install.") try: execWithRedirect("virt-install", args, raise_err=True) @@ -800,7 +808,8 @@ def virt_install(opts, install_log, disk_img, disk_size): log_check = log_monitor.server.log_check, virtio_host = log_monitor.host, virtio_port = log_monitor.port, - qcow2=opts.qcow2) + qcow2=opts.qcow2, boot_uefi=opts.virt_uefi, + ovmf_path=opts.ovmf_path) virt.destroy() log_monitor.shutdown() @@ -1110,6 +1119,10 @@ def main(): help="Passed to --arch command") 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") # dracut arguments dracut_group = parser.add_argument_group("dracut arguments") @@ -1240,6 +1253,9 @@ def main(): if opts.make_vagrant and opts.vagrant_metadata and not os.path.exists(opts.vagrant_metadata): errors.append("Vagrant metadata file %s is missing" % opts.vagrant_metadata) + if opts.virt_uefi and not os.path.isdir(opts.ovmf_path): + errors.append("The OVMF firmware is missing from %s" % opts.ovmf_path) + if os.getuid() != 0: errors.append("You need to run this as root")