From d140526bd0a447efb79b870d35f5a9a487ea6394 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 10 Oct 2019 01:28:43 +0000 Subject: [PATCH] Remove code invoking Anaconda to build disk images Since ppc64le has some support for this that just landed in master, remove most of the code and references to Anaconda. We create disk images directly on all architectures. Some more background in: https://github.com/coreos/coreos-assembler/issues/91 --- Dockerfile | 1 - build.sh | 54 ------ src/cmd-build | 2 +- src/cmd-buildextend-metal | 83 +++------ src/cmd-compress | 2 +- src/cmdlib.sh | 29 ---- src/create_disk.sh | 1 - src/deps-aarch64.txt | 2 +- src/deps.txt | 8 +- src/gf-anaconda-cleanup | 103 ----------- src/image-base.ks | 49 ------ src/virt-install | 350 -------------------------------------- 12 files changed, 33 insertions(+), 651 deletions(-) delete mode 100755 src/gf-anaconda-cleanup delete mode 100644 src/image-base.ks delete mode 100755 src/virt-install diff --git a/Dockerfile b/Dockerfile index 56ecee4aae..bba9343c5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,6 @@ RUN ./build.sh install_rpms # Ok copy in the rest of them for the next few steps COPY ./ /root/containerbuild/ RUN ./build.sh write_archive_info -RUN ./build.sh install_anaconda RUN ./build.sh make_and_makeinstall RUN ./build.sh configure_user diff --git a/build.sh b/build.sh index 6bc33cfdbf..06eacc73ba 100755 --- a/build.sh +++ b/build.sh @@ -89,59 +89,6 @@ _prep_make_and_make_install() { fi } -# For now keep using the f29 anaconda. There's no golden f30 image yet and it -# doesn't support the installclass stuff and hopefully we'll stop using it soon. -installer_release=29 - -# Download url is different for primary and secondary fedora -# Primary Fedora - https://download.fedoraproject.org/pub/fedora/linux/releases/ -# Secondary Fedora - https://download.fedoraproject.org/pub/fedora-secondary/releases/ -declare -A repository_dirs -repository_dirs[aarch64]=fedora/linux -repository_dirs[armhfp]=fedora/linux -repository_dirs[x86_64]=fedora/linux -repository_dirs[ppc64le]=fedora-secondary -repository_dirs[s390x]=fedora-secondary - -repository_dir=${repository_dirs[$arch]} -INSTALLER=https://download.fedoraproject.org/pub/$repository_dir/releases/$installer_release/Everything/$arch/iso/Fedora-Everything-netinst-$arch-$installer_release-1.2.iso -INSTALLER_CHECKSUM=https://download.fedoraproject.org/pub/$repository_dir/releases/$installer_release/Everything/$arch/iso/Fedora-Everything-$installer_release-1.2-$arch-CHECKSUM - -install_anaconda() { - if [ "$arch" == "x86_64" ]; then - return - fi - - # Overriding install URL - if [ -n "${INSTALLER_URL_OVERRIDE-}" ]; then - INSTALLER="${INSTALLER_URL_OVERRIDE}" - echo "info: Overriding the install URL with contents of INSTALLER_URL_OVERRIDE" - fi - # Overriding install checksum URL - if [ -n "${INSTALLER_CHECKSUM_URL_OVERRIDE-}" ]; then - INSTALLER_CHECKSUM="${INSTALLER_CHECKSUM_URL_OVERRIDE}" - echo "info: Overriding the install checksum URL with contents of INSTALLER_CHECKSUM_URL_OVERRIDE" - fi - - installer_bn=$(basename "${INSTALLER}") - checksums_bn=$(basename "${INSTALLER_CHECKSUM}") - - anacondadir=/usr/lib/coreos-assembler-anaconda - if ! [ -f "${anacondadir}/${installer_bn}" ]; then - ( - mkdir -p $anacondadir - cd $anacondadir - rm tmp -rf && mkdir -p tmp - cd tmp - curl -L --remote-name-all "${INSTALLER}" "${INSTALLER_CHECKSUM}" - sha256sum -c "${checksums_bn}" - mv "${installer_bn}" "${checksums_bn}" .. - cd .. - rmdir tmp - ) - fi -} - make_and_makeinstall() { _prep_make_and_make_install make && make install @@ -183,7 +130,6 @@ else configure_yum_repos install_rpms write_archive_info - install_anaconda make_and_makeinstall configure_user fi diff --git a/src/cmd-build b/src/cmd-build index 44e760719c..24d9ca0c83 100755 --- a/src/cmd-build +++ b/src/cmd-build @@ -138,7 +138,7 @@ if [ -n "${previous_commit}" ]; then fi fi - # and point the ref to it if there isn't one already (in which case it might be newer, but e.g. Anaconda failed) + # and point the ref to it if there isn't one already (in which case it might be newer, but e.g. creating disk failed) if ! ostree rev-parse --repo="${tmprepo}" "${ref}" &>/dev/null; then ostree refs --repo="${tmprepo}" --create "${ref}" "${previous_commit}" fi diff --git a/src/cmd-buildextend-metal b/src/cmd-buildextend-metal index 0a82c96e8f..828593139e 100755 --- a/src/cmd-buildextend-metal +++ b/src/cmd-buildextend-metal @@ -63,17 +63,8 @@ if [ $# -ne 0 ]; then fi case "$basearch" in - "x86_64"|"aarch64"|"s390x"|"ppc64le") use_anaconda=;; - *) - # for qemu, we can fallback to Anaconda - if [[ ${image_type} == qemu ]]; then - use_anaconda=1 - else - # otherwise, we don't know how to create bare metal images for this - # architecture - fatal "$basearch is not supported for this command" - fi - ;; + "x86_64"|"aarch64"|"s390x"|"ppc64le") ;; + *) fatal "$basearch is not supported for this command" ;; esac if [[ "$basearch" != "s390x" && $image_type == dasd ]]; then @@ -176,51 +167,33 @@ ostree_remote="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).g save_var_subdirs="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("save-var-subdirs-for-selabel-workaround", "NONE"))' < "$configdir/image.yaml")" luks_flag="$(python3 -c 'import sys, yaml; lf=yaml.safe_load(sys.stdin).get("luks_rootfs", ""); print("--luks-rootfs" if lf.lower() in ("yes", "true") else "")' < "$configdir/image.yaml")" - -if [ -z "${use_anaconda}" ]; then - qemu-img create -f ${image_format} "${path}.tmp" "$size" - # In the anaconda path, run_virtinstall dereferences in the ref_is_temp - # case. Here, we need to dereference ourselves. - ref_arg=${ref} - if [ -n "${ref_is_temp}" ]; then - ref_arg=${commit} - fi - target_drive=("-drive" "if=virtio,id=target,format=${image_format},file=${path}.tmp") - if [[ $image_format == raw && $image_type == dasd ]]; then - target_drive=("-drive" "if=none,id=target,format=${image_format},file=${path}.tmp" \ - # we need 4096 block size for ECKD DASD - "-device" "virtio-blk-ccw,drive=target,physical_block_size=4096,logical_block_size=4096,scsi=off") - fi - runvm "${target_drive[@]}" -- \ - /usr/lib/coreos-assembler/create_disk.sh \ - --disk /dev/vda \ - --buildid "${build}" \ - --imgid "${img}" \ - --grub-script /usr/lib/coreos-assembler/grub.cfg \ - --kargs "\"${kargs}\"" \ - --osname "${name}" \ - --ostree-ref "${ref_arg}" \ - --ostree-remote "${ostree_remote}" \ - --ostree-repo "${ostree_repo}" \ - --save-var-subdirs "${save_var_subdirs}" \ - "${luks_flag}" - mv "${path}.tmp" "$path" - echo "{}" > tmp/vm-iso-checksum.json -else - [ "${image_type}" == qemu ] - mkdir -p tmp/anaconda - # forgive me for this sin - checksum_location=$(find /usr/lib/coreos-assembler-anaconda/ -name '*CHECKSUM' | head -1) - img_base=tmp/${name}-${build}-base.qcow2 - run_virtinstall "${ostree_repo}" "${ref}" "${PWD}"/"${img_base}" --variant=cloud - /usr/lib/coreos-assembler/gf-platformid "$(pwd)"/"${img_base}" "${path}" qemu - vm_iso_checksum=$(awk '/SHA256.*iso/{print$NF}' "${checksum_location}") - cat > tmp/vm-iso-checksum.json < tmp/vm-iso-checksum.json # there's probably a jq one-liner for this... python3 -c " diff --git a/src/cmd-compress b/src/cmd-compress index 4a0cb34a37..a918c387f4 100755 --- a/src/cmd-compress +++ b/src/cmd-compress @@ -52,7 +52,7 @@ def get_cpu_param(param): return int(f.read().strip()) -# XXX: should dedupe this with logic in virt-install and put in the shared lib +# XXX: should dedupe this with logic in cmdlib and put in the shared lib def xz_threads(): with open("/proc/1/cgroup") as f: in_k8s = re.search(r'.*kubepods.*', f.read()) diff --git a/src/cmdlib.sh b/src/cmdlib.sh index c8a17353ac..6ca8498ef4 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -650,35 +650,6 @@ sha256sum_str() { sha256sum | cut -f 1 -d ' ' } -# This generates the "base image"; not specific to a platform. -run_virtinstall() { - local ostree_repo=$1; shift - local ostree_rev=$1; shift - local dest=$1; shift - local tmpdest="${dest}.tmp" - - # forgive me for this sin - local iso_location - iso_location=$(find /usr/lib/coreos-assembler-anaconda/ -name '*.iso' | head -1) - - # if the ref is temporary, then we want a checksum refspec - if [ -n "${ref_is_temp}" ]; then - set -- "$@" --delete-ostree-ref - ostree_rev=$(ostree rev-parse --repo="${ostree_repo}" "${ostree_rev}") - fi - - /usr/lib/coreos-assembler/virt-install --create-disk --dest="${tmpdest}" \ - --tmpdir "${PWD}/tmp" --fs9p \ - --kickstart-out "${PWD}"/tmp/flattened.ks \ - --console-log-file "${PWD}/install.log" \ - --ostree-remote="${name}" --ostree-stateroot="${name}" \ - --ostree-ref="${ostree_rev}" \ - --location "${iso_location}" \ - --configdir="${configdir}" \ - --ostree-repo="${ostree_repo}" "$@" - mv "${tmpdest}" "${dest}" -} - get_latest_build() { if [ -L "${workdir:-$(pwd)}/builds/latest" ]; then readlink "${workdir:-$(pwd)}/builds/latest" diff --git a/src/create_disk.sh b/src/create_disk.sh index db93770d28..53aa28fa5d 100755 --- a/src/create_disk.sh +++ b/src/create_disk.sh @@ -243,7 +243,6 @@ cat > rootfs/.coreos-aleph-version.json << EOF } EOF -# See the equivalent code in gf-anaconda-cleanup # /var hack: we'd like to remove all of /var, but SELinux issues prevent that. # see https://github.com/coreos/ignition-dracut/pull/79#issuecomment-488446949 if [ "${save_var_subdirs}" != NONE ]; then diff --git a/src/deps-aarch64.txt b/src/deps-aarch64.txt index 74c8725c8f..0771a8c588 100644 --- a/src/deps-aarch64.txt +++ b/src/deps-aarch64.txt @@ -1,4 +1,4 @@ -# For grub install when creating images without anaconda +# For grub install when creating images grub2 # For creating bootable UEFI media on aarch64 diff --git a/src/deps.txt b/src/deps.txt index b8a59268b1..2967f928a4 100644 --- a/src/deps.txt +++ b/src/deps.txt @@ -23,12 +23,8 @@ selinux-policy-targeted rpm-build # Standard build tools make git rpm-build -# virt-install dependencies -libvirt libguestfs-tools /usr/bin/qemu-img /usr/bin/virsh /usr/bin/virt-install -qemu-kvm - -# And we process kickstarts -/usr/bin/ksflatten +# virt dependencies +libguestfs-tools /usr/bin/qemu-img qemu-kvm # ostree-releng-scripts dependencies rsync diff --git a/src/gf-anaconda-cleanup b/src/gf-anaconda-cleanup deleted file mode 100755 index e84ea28ebd..0000000000 --- a/src/gf-anaconda-cleanup +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env bash -# This runs after virt-install to undo things leftover from Anaconda. -set -euo pipefail - -dn=$(dirname "$0") -# shellcheck source=src/cmdlib.sh -. "${dn}"/cmdlib.sh -# shellcheck source=src/libguestfish.sh -. "${dn}"/libguestfish.sh - -SAVE_VAR= -options=$(getopt --options '' --longoptions save-var-subdirs-for-selabel-workaround -- "$@") -eval set -- "$options" -while true; do - case "$1" in - --save-var-subdirs-for-selabel-workaround) SAVE_VAR=1;; - --) shift; break;; - esac - shift -done - -src="$1" -shift - -set -x -coreos_gf_run "${src}" -# We don't have a way to do this with Anaconda/kickstart right now. -# This bootstraps us to be able to do all of the mounts. -coreos_gf set-label /dev/sda2 boot -coreos_gf_run_mount "${src}" - -fb=/boot/ignition.firstboot -exists=$(coreos_gf exists "${fb}") -if [ "${exists}" = false ]; then - cat << EOF ---------- - error: Couldn't find ${fb} - most likely Anaconda failed." - error: If 9pfs is available, you can find logs in: tmp/build/tmp/anaconda" ---------- -EOF - exit 1 -fi - -# Remove most things written by anaconda in /etc, except -# for /etc/fstab mainly. -for x in "sysconfig/anaconda" "sysconfig/network" "hostname" "crypttab" "resolv.conf" "X11" "systemd/system/default.target" "shadow-"; do - coreos_gf rm-rf "${deploydir}/etc/${x}" -done -for x in $(coreos_gf glob-expand "${deploydir}/etc/sysconfig/network-scripts/"'*'); do - coreos_gf rm-rf "${x}" -done -for x in $(coreos_gf find "${deploydir}/etc/ostree/remotes.d/"); do - e=$(coreos_gf exists "${deploydir}/usr/etc/${x}") - if [ "${e}" = "true" ]; then - continue - fi - coreos_gf rm "${deploydir}/etc/ostree/remotes.d/${x}" -done - -# Next remove cruft from the *physical* root as nothing should be using those; -# Anaconda is creating them today. -for x in $(coreos_gf glob-expand '/*'); do - case $x in - /ostree/|/boot/) continue;; - *) coreos_gf rm-rf "${x}" - esac -done - -var="${stateroot}/var" - -# By default, we nuke all of /var unless explicitly requested not to. Anaconda -# creates stuff in there, but we want the canonical source to be -# systemd-tmpfiles and Ignition. -if [ -z "${SAVE_VAR}" ]; then - coreos_gf glob rm-rf "${var}/*" - coreos_gf_shutdown - exit 0 -fi - -# See the equivalent code in create_disk.sh -# /var hack: we'd like to remove all of /var, but SELinux issues prevent that. -# see https://github.com/coreos/ignition-dracut/pull/79#issuecomment-488446949 -# For now we retain just /var/lib/systemd (for the random seed) and /var/log -# for the journal, which init before systemd-tmpfiles. -# Also just leave /var/home and /var/roothome; this allows early Ignition in -# RHCOS to add users and drop files in /root. (On FCOS, we don't strictly -# *need* this because we run systemd-tmpfiles). -coreos_gf ls "${var}" | while read -r x; do - case "$x" in - log|lib) continue;; - home|roothome) coreos_gf glob rm-rf "${var}/${x}/*";; - *) coreos_gf rm-rf "${var}/${x}" - esac -done -coreos_gf ls "${var}/lib" | while read -r x; do - if [ "${x}" = "systemd" ]; then continue; fi - coreos_gf rm-rf "${var}/lib/${x}" -done -for x in "lib/systemd" "log"; do - coreos_gf glob rm-rf "${var}/${x}/*" -done - -coreos_gf_shutdown diff --git a/src/image-base.ks b/src/image-base.ks deleted file mode 100644 index ace7fc9692..0000000000 --- a/src/image-base.ks +++ /dev/null @@ -1,49 +0,0 @@ -# Currently the coreos-assembler tool is generating -# disk images via Anaconda (inside virt-install). -# This is likely to change in the future; see -# https://github.com/coreos/coreos-assembler/issues/75#issuecomment-421139257 -# https://github.com/coreos/fedora-coreos-tracker/issues/18 -# -text -lang en_US.UTF-8 -keyboard us -timezone --utc Etc/UTC -selinux --enforcing -# Ensure the root password is disabled (should be the default) -rootpw --lock --iscrypted locked -# We don't want Anaconda to touch the firewall -firewall --disabled - -# prjquota is for quota enablement for containers: https://bugzilla.redhat.com/show_bug.cgi?id=1658386 -# rw and $ignition_firstboot are used by https://github.com/coreos/ignition-dracut/ -# Console settings are so we see output everywhere -# %%KARGS%% is for distro-specific arguments -bootloader --timeout=1 --append="console=%%TERM%%,115200n8 console=tty0 rootflags=defaults,prjquota rw %%KARGS%% $ignition_firstboot" -# Anaconda currently writes out configs for this which we don't want to persist; see below -network --bootproto=dhcp --onboot=on - -zerombr -clearpart --initlabel --all --disklabel=gpt - -# https://github.com/coreos/fedora-coreos-tracker/issues/18 -# See also coreos-growpart.service defined in fedora-coreos-base.yaml -# You can change this partition layout, but note that the `boot` and `root` -# filesystem labels are currently mandatory (they're interpreted by coreos-assembler). -reqpart --add-boot -# Explicitly enable reflinks since at least as of Fedora 29 it wasn't enabled by default -# The 1000 here doesn't matter too much, the disk size is either defined by -# image.yaml, or for bare metal the size is calculated to fit in virt-install. -# Either way we use --grow to expand to the outer size. And then when the system -# boots for real, the coreos-growpart.service will run to fit the provisioned space -# (e.g. in AWS the root volume size, on bare metal the size of the physical disk, etc.) -part / --size=1000 --fstype="xfs" --label=root --grow --mkfsoptions="-m reflink=1" - -reboot - -%post --erroronfail -# See gf-anaconda-cleanup -mkdir -p /var/lib/systemd - -# Remove any persistent NIC rules generated by udev -rm -vf /etc/udev/rules.d/*persistent-net*.rules -%end diff --git a/src/virt-install b/src/virt-install deleted file mode 100755 index 4f76cd1933..0000000000 --- a/src/virt-install +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env python3 -# NOTE: PYTHONUNBUFFERED is set in cmdlib.sh for unbuffered output -# -# Wrapper for virt-install designed to run in a container -# environment, and using defaults targeted for CoreOS. -# https://github.com/coreos/coreos-assembler/issues/7 -# Today, this requires a Kickstart (and an installer ISO path); -# we might change things down the line to have defaults for -# one or both. - -import os -import sys -import argparse -import subprocess -import io -import time -import re -import tempfile -import yaml -import json -import threading -import http.server - -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from cosalib.cmdlib import get_basearch - -PID = os.getpid() - -# Currently we spin up a temporary webserver, but we could also -# do something more custom over a virtio-serial channel or so. -PORT = 8000 - -# Soon we should create the filesystem outside of anaconda -ANACONDA_BOOT_SIZE_MB = 1024 - - -def fatal(msg): - print('error: {}'.format(msg), file=sys.stderr) - raise SystemExit(1) - - -# Set of valid keys in image.yaml -IMAGE_CONF_KEYS = ['size', 'postprocess-script', 'extra-kargs', - 'save-var-subdirs-for-selabel-workaround', 'ostree-remote', - 'squashfs-compression'] - -parser = argparse.ArgumentParser() -parser.add_argument("--dest", help="Destination disk", - action='store', required=True) -parser.add_argument("--tmpdir", help="Temporary directory", - action='store', required=True) -parser.add_argument("--create-disk", help="Automatically create disk as qcow2, parsing kickstart for size", - action='store_true') -parser.add_argument("--configdir", help="coreos-assembler configdir", - action='store', required=True) -parser.add_argument("--variant", help="Configure image variant", - choices=('metal-bios', 'metal-uefi', 'cloud'), default=None) -parser.add_argument("--kickstart-out", help="Save flattened kickstart", - action='store') -parser.add_argument("--location", help="Installer location", - action='store', required=True) -parser.add_argument("--memory", help="Memory size in MB", - action='store', type=int, - default=os.environ.get("VIRT_INSTALL_MEMORY", 1024)) -parser.add_argument("--console-log-file", help="Console log file", - action='store') -parser.add_argument("--fs9p", help="Make use of 9p", - action='store_true') -# Note https://bugzilla.redhat.com/show_bug.cgi?id=1379389 -parser.add_argument("--ostree-repo", help="Path to OSTree repo", - action='store', required=True) -parser.add_argument("--ostree-stateroot", help="OSTree stateroot", - action='store') -parser.add_argument("--ostree-ref", help="OSTree ref", - action='store') -parser.add_argument("--delete-ostree-ref", help="Delete the OSTree ref after installation", - action='store_true') -parser.add_argument("--ostree-remote", help="OSTree remote", - action='store') -parser.add_argument("--wait", help="Number of minutes to wait", - action='store', type=int, - default=os.environ.get("VIRT_INSTALL_WAIT", 10)) -args = parser.parse_args() - - -# Copy of bits from https://pagure.io/standard-test-roles/pull-request/223 -def get_libvirt_smp_arg(): - """Determine the number of CPUs that should be visible in the guest. - See e.g. https://www.redhat.com/archives/libvirt-users/2017-June/msg00025.html - We want to match the number of host physical cores. - """ - - # When running under K8S, the scehduling may be much more restrictive than - # physical core count, and the code below will assign that count, leading - # to a VM hang. (e.g. 64 vcpu's to a 1 cpu assignment...) - p1c = open("/proc/1/cgroup") - if re.search(r'.*kubepods.*', p1c.read()): - return '--vcpus=sockets=1,cores=1,threads=1' - - # We may be run in a cgroup with fewer cores available than physical. - available_cpu = int(subprocess.check_output(['nproc']).strip()) - # https://stackoverflow.com/questions/6481005/how-to-obtain-the-number-of-cpus-cores-in-linux-from-the-command-line - core_sockets = set() - for line in io.BytesIO(subprocess.check_output(['lscpu', '-b', '-p=Core,Socket'])): - if line.startswith(b'#'): - continue - core_sockets.add(line.strip()) - sockets = min(available_cpu, len(core_sockets)) - return '--vcpus=sockets={},cores=1,threads=1'.format(sockets) - - -def run(fn, argv, **kwargs): - print("cmd: {}".format(subprocess.list2cmdline(argv))) - try: - return fn(argv, **kwargs) - except subprocess.CalledProcessError as e: - raise SystemExit(f"{e}") - - -def run_sync_verbose(argv, **kwargs): - run(subprocess.check_call, argv, **kwargs) - - -if args.kickstart_out: - ks_tmp = open(args.kickstart_out, 'w') -else: - ks_tmp = tempfile.NamedTemporaryFile(mode='w', prefix="coreos-virtinstall", suffix=".ks") - -with open(args.configdir + '/image.yaml') as f: - image_conf = yaml.safe_load(f) -for k in image_conf: - if k not in IMAGE_CONF_KEYS: - fatal(f"Unknown key '{k}' in image.yaml") -disk_size = int(image_conf['size']) -extra_kargs = image_conf.get('extra-kargs', []) - -with open('/usr/lib/coreos-assembler/image-base.ks') as basef: - buf = basef.read() - buf = buf.replace('%%KARGS%%', ' '.join(extra_kargs)) - buf = buf.replace('%%TERM%%', os.environ.get('DEFAULT_TERMINAL', 'ttyS0')) - ks_tmp.write(buf) - -# To support different distro builds using Fedora anaconda, -# installclass must be explicit for anaconda to find the correct directory. -if subprocess.call(['ostree', f"--repo={args.ostree_repo}", 'ls', args.ostree_ref, "/usr/lib/ostree-boot/efi/EFI/redhat"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0: - print("Detected /usr/lib/ostree-boot/efi/EFI/redhat, adding Red Hat Enterprise Linux installclass.") - ks_tmp.write(""" - %anaconda - installclass --name="Red Hat Enterprise Linux" - %end - """) - -# This is an implementation detail of https://github.com/coreos/ignition-dracut -# So we hardcode it here. -# See: https://github.com/coreos/ignition-dracut/pull/12 -ks_tmp.write(""" -%post --erroronfail -touch /boot/ignition.firstboot -%end -""") - -# Grab the ipv4 address of the container -default_iface = subprocess.check_output(['ip', '-4', 'route', 'list', '0/0']).split()[4] -output = subprocess.check_output(['ip', '-4', '-oneline', 'addr', 'show', default_iface]) -ipv4 = re.match(r'.*inet ([\d.]+)/\d\d.*', str(output)).group(1) - -if args.ostree_repo: - assert args.ostree_stateroot - assert args.ostree_remote - assert args.ostree_ref - ks_tmp.write(f""" -ostreesetup --nogpg --osname={args.ostree_stateroot} --remote={args.ostree_remote} --url=http://{ipv4}:{PORT}/ --ref="{args.ostree_ref}" - """) - -if args.fs9p: - ks_tmp.write(""" -%pre -set -euo pipefail -# Hacky bits to copy out all of the Anaconda logs on shutdown -mkdir -p /mnt/logs -mount -t 9p -o rw,trans=virtio,version=9p2000.L /mnt/logs /mnt/logs -cat >/etc/systemd/system/coreos-virtinstall-logs.service <= 2 - -ks_tmp.flush() - -n_requests = 0 - - -class RequestHandler(http.server.SimpleHTTPRequestHandler): - def __init__(self, *myargs, **kwargs): - super().__init__(*myargs, directory=args.ostree_repo, **kwargs) - - def log_request(code, size): - global n_requests - n_requests += 1 - - -def run_webserver(): - try: - print(f"Listening on {ipv4}:{PORT}") - server = http.server.ThreadingHTTPServer((ipv4, PORT), RequestHandler) - server.serve_forever() - except Exception as e: - sys.stderr.write(f"Http thread failed:\n{e}\n") - sys.stderr.flush() - os._exit(1) - - -try: - vinstall_args = ["virt-install", "--connect=qemu:///session", - "--name={}".format(domain)] - # use noautoconsole for fedora since we will use console=log.file - # for el7 just use the serial console - if os.environ['ISFEDORA'] != '': - vinstall_args.append('--noautoconsole') - else: - vinstall_args.append('--nographics') - if args.console_log_file: - vinstall_args.append("--console=log.file={}".format(args.console_log_file)) - tail_proc = subprocess.Popen(["/bin/sh", "-c", f"tail --pid={PID} -F {args.console_log_file} | grep anaconda"]) - - # Note this is racy, we should be waiting for the webserver to be up - # (Or switch to doing this over virtio) - http_thread = threading.Thread(target=run_webserver, daemon=True) - http_thread.start() - - if args.fs9p: - vinstall_args.append(f"--filesystem=source={args.tmpdir}/anaconda,target=/mnt/logs,accessmode=mapped") - vinstall_args.append(f"--filesystem=source={args.ostree_repo},target=/install/ostree/repo,accessmode=mapped") - - location_arg = f"--location={args.location}" - if have_virtinstall_2: - # This way we don't go through libosinfo. This is hardcoding the layout of the - # ISO, but that's fine since we pin a version of it. - # https://bugzilla.redhat.com/show_bug.cgi?id=1659242 - - # set correct location of the kernel image and initrd - basearch = get_basearch() - if basearch == "x86_64": - location_arg += ",kernel=isolinux/vmlinuz,initrd=isolinux/initrd.img" - elif basearch == "ppc64le": - location_arg += ",kernel=ppc/ppc64/vmlinuz,initrd=ppc/ppc64/initrd.img" - elif basearch == "aarch64": - location_arg += ",kernel=images/pxeboot/vmlinuz,initrd=images/pxeboot/initrd.img" - elif basearch == "s390x": - location_arg += ",kernel=images/kernel.img,initrd=images/initrd.img" - else: - raise SystemExit("Unknown machine architecture " + basearch + " can't determine the kernel and initrd location") - - vinstall_args.extend(["--wait={}".format(args.wait), "--noreboot", "--nographics", - "--memory={}".format(args.memory), get_libvirt_smp_arg(), - "--os-variant=rhel7.6", "--rng=/dev/urandom", - "--cpu=host-passthrough", - "--check", "path_in_use=off", - "--network=user", # user mode networking - location_arg, - "--disk=path={},cache=unsafe".format(args.dest), - "--initrd-inject={}".format(ks_tmp.name), - "--extra-args", "ks=file://{} console=tty0 console={},115200n8 inst.cmdline inst.notmux".format(os.path.basename(ks_tmp.name), os.environ.get('DEFAULT_TERMINAL', 'ttyS0'))]) - if args.variant == 'metal-uefi': - vinstall_args.append('--boot=uefi') - run_sync_verbose(vinstall_args) - print(f"virt-install: Served {n_requests} requests via internal webserver") - # And strip out all of the Anaconda stuff in /var; this uses libguestfs - # to ensure we fully control the code. - cleanup_argv = ['/usr/lib/coreos-assembler/gf-anaconda-cleanup', args.dest] - if image_conf.get('save-var-subdirs-for-selabel-workaround'): - cleanup_argv += ['--save-var-subdirs-for-selabel-workaround'] - run_sync_verbose(cleanup_argv) - - # This one is part of the "API" we provide to config repositories. At least - # RHEL CoreOS will use it to change the OS to appear to have been provisioned - # from an oscontainer. - config_image_post = image_conf.get("postprocess-script") - if config_image_post is not None: - run_sync_verbose([os.path.join(args.configdir, config_image_post), args.dest]) - -finally: - subprocess.call(['virsh', '--connect=qemu:///session', 'undefine', '--nvram', domain]) - if tail_proc is not None: - tail_proc.terminate() -print("Completed install to disk image: {}".format(args.dest))