#!/bin/bash set -euo pipefail # This script is run in supermin to create a Fedora CoreOS style # disk image, very much in the spirit of the original # Container Linux (orig CoreOS) disk layout, although adapted # for OSTree, and using XFS for /, among other things. # Some more background in https://github.com/coreos/fedora-coreos-tracker/issues/18 # The layout is intentionally not very configurable at this time, # although see also https://github.com/coreos/coreos-assembler/pull/298 # For people building "derived"/custom FCOS-like systems, feel free to file # an issue and we can discuss configuration needs. # This fixed UUID is detected in ignition-dracut and changed # on firstboot: # https://github.com/coreos/ignition-dracut/blob/6136be3d9d38d7926a61cd4d1b4ba5f9baf0892f/dracut/30ignition/coreos-gpt-setup.sh#L7 uninitialized_gpt_uuid="00000000-0000-4000-a000-000000000001" # These UUIDs should be changed by code in fedora-coreos-config on firstboot, see # https://github.com/coreos/fedora-coreos-tracker/issues/465 bootfs_uuid="96d15588-3596-4b3c-adca-a2ff7279ea63" rootfs_uuid="910678ff-f77e-4a7d-8d53-86f2ac47a823" deploy_root= usage() { cat <<EOC ${0} creates a supermin virtual machine to create a Fedora CoreOS style disk image from an OSTree. Options: --config: JSON-formatted image.yaml --help: show this help --platform: Ignition platform ID --platforms-json: platforms.yaml in JSON format --no-x86-bios-bootloader: don't install BIOS bootloader on x86_64 --with-secure-execution: enable IBM SecureExecution You probably don't want to run this script by hand. This script is run as part of 'coreos-assembler build'. EOC } config= disk= platform=metal platforms_json= secure_execution=0 ignition_pubkey= x86_bios_bootloader=1 while [ $# -gt 0 ]; do flag="${1}"; shift; case "${flag}" in --config) config="${1}"; shift;; --help) usage; exit;; --no-x86-bios-bootloader) x86_bios_bootloader=0;; --platform) platform="${1}"; shift;; --platforms-json) platforms_json="${1}"; shift;; --with-secure-execution) secure_execution=1;; --write-ignition-pubkey-to) ignition_pubkey="${1}"; shift;; *) echo "${flag} is not understood."; usage; exit 10;; esac; done udevtrig() { udevadm trigger udevadm settle } export PATH=$PATH:/sbin:/usr/sbin arch="$(uname -m)" if [ -z "$platforms_json" ]; then echo "Missing --platforms-json" >&2 exit 1 fi # just copy it over to /tmp and work from there to minimize virtiofs I/O cp "${platforms_json}" /tmp/platforms.json platforms_json=/tmp/platforms.json platform_grub_cmds=$(jq -r ".${arch}.${platform}.grub_commands // [] | join(\"\\\\n\")" < "${platforms_json}") platform_kargs=$(jq -r ".${arch}.${platform}.kernel_arguments // [] | join(\" \")" < "${platforms_json}") disk=$(realpath /dev/disk/by-id/virtio-target) config="${config:?--config must be defined}" # https://github.com/coreos/coreos-assembler/pull/2480 dump_err_info () { lsblk -f || true } trap dump_err_info ERR # Parse the passed config JSON and extract a mandatory value getconfig() { k=$1 jq -re .\""$k"\" < "${config}" } # Return a configuration value, or default if not set getconfig_def() { k=$1 shift default=$1 shift jq -re .\""$k"\"//\""${default}"\" < "${config}" } rootfs_type=$(getconfig rootfs) case "${rootfs_type}" in xfs|ext4verity|btrfs) ;; *) echo "Invalid rootfs type: ${rootfs_type}" 1>&2; exit 1;; esac rootfs_args=$(getconfig_def "rootfs-args" "") bootfs=$(getconfig "bootfs") composefs=$(getconfig_def "composefs" "") grub_script=$(getconfig "grub-script") ostree_container=$(getconfig "ostree-container") ostree_container_spec="ostree-unverified-image:oci-archive:${ostree_container}" commit=$(getconfig "ostree-commit") ref=$(getconfig "ostree-ref") # We support not setting a remote name (used by RHCOS) remote_name=$(getconfig_def "ostree-remote" "") deploy_via_container=$(getconfig "deploy-via-container" "") container_imgref=$(getconfig "container-imgref" "") os_name=$(getconfig "osname") buildid=$(getconfig "buildid") imgid=$(getconfig "imgid") extra_kargs=$(getconfig "extra-kargs-string" "") # populate remaining kargs extra_kargs+=" ignition.platform.id=${platform}" if [ -n "${platform_kargs}" ]; then extra_kargs+=" ${platform_kargs}" fi set -x # Partition and create fs's. The 0...4...a...1 uuid is a sentinal used by coreos-gpt-setup # in ignition-dracut. It signals that the disk needs to have it's uuid randomized and the # backup header moved to the end of the disk. # Pin /se, /boot and / to the partition number 1, 3 and 4 respectively. Also insert reserved # partitions on aarch64/ppc64le to keep the 1,2,3,4 partition numbers aligned across # x86_64/aarch64/ppc64le. We decided not to try to achieve partition parity on s390x # because a bare metal install onto an s390x DASD translates the GPT to DASD partitions # and we only get three of those. https://github.com/coreos/fedora-coreos-tracker/issues/855 BOOTPN=3 ROOTPN=4 if [[ ${secure_execution} -eq 1 ]]; then SDPART=1 BOOTVERITYHASHPN=5 ROOTVERITYHASHPN=6 extra_kargs="${extra_kargs} swiotlb=262144" fi # shellcheck disable=SC2031 case "$arch" in x86_64) EFIPN=2 sgdisk -Z "$disk" \ -U "${uninitialized_gpt_uuid}" \ -n 1:0:+1M -c 1:BIOS-BOOT -t 1:21686148-6449-6E6F-744E-656564454649 \ -n ${EFIPN}:0:+127M -c ${EFIPN}:EFI-SYSTEM -t ${EFIPN}:C12A7328-F81F-11D2-BA4B-00A0C93EC93B \ -n ${BOOTPN}:0:+384M -c ${BOOTPN}:boot \ -n ${ROOTPN}:0:0 -c ${ROOTPN}:root -t ${ROOTPN}:0FC63DAF-8483-4772-8E79-3D69D8477DE4 ;; aarch64) RESERVEDPN=1 EFIPN=2 sgdisk -Z "$disk" \ -U "${uninitialized_gpt_uuid}" \ -n ${RESERVEDPN}:0:+1M -c ${RESERVEDPN}:reserved -t ${RESERVEDPN}:8DA63339-0007-60C0-C436-083AC8230908 \ -n ${EFIPN}:0:+127M -c ${EFIPN}:EFI-SYSTEM -t ${EFIPN}:C12A7328-F81F-11D2-BA4B-00A0C93EC93B \ -n ${BOOTPN}:0:+384M -c ${BOOTPN}:boot \ -n ${ROOTPN}:0:0 -c ${ROOTPN}:root -t ${ROOTPN}:0FC63DAF-8483-4772-8E79-3D69D8477DE4 ;; s390x) sgdisk_args=() rootp_end=0 if [[ ${secure_execution} -eq 1 ]]; then # shellcheck disable=SC2206 sgdisk_args+=(-n ${SDPART}:0:+200M -c ${SDPART}:se -t ${SDPART}:0FC63DAF-8483-4772-8E79-3D69D8477DE4) # we need to leave space for the verity hash partitions (and add 1MB otherwise sgdisk can't fit them for some reason) rootp_end=-$((128+256+1))M fi # shellcheck disable=SC2206 sgdisk_args+=(-n ${BOOTPN}:0:+384M -c ${BOOTPN}:boot \ -n ${ROOTPN}:0:${rootp_end} -c ${ROOTPN}:root -t ${ROOTPN}:0FC63DAF-8483-4772-8E79-3D69D8477DE4) if [[ ${secure_execution} -eq 1 ]]; then # note these length values are hardcoded in both rootp_end above and in `cmd-buildextend-metal` # shellcheck disable=SC2206 sgdisk_args+=(-n ${BOOTVERITYHASHPN}:0:+128M -c ${BOOTVERITYHASHPN}:boothash \ -n ${ROOTVERITYHASHPN}:0:+256M -c ${ROOTVERITYHASHPN}:roothash) fi # NB: in the bare metal case when targeting ECKD DASD disks, this # partition table is not what actually gets written to disk in the end: # coreos-installer has code which transforms it into a DASD-compatible # partition table and copies each partition individually bitwise. sgdisk -Z "$disk" -U "${uninitialized_gpt_uuid}" "${sgdisk_args[@]}" ;; ppc64le) PREPPN=1 RESERVEDPN=2 # ppc64le doesn't use special uuid for root partition sgdisk -Z "$disk" \ -U "${uninitialized_gpt_uuid}" \ -n ${PREPPN}:0:+4M -c ${PREPPN}:PowerPC-PReP-boot -t ${PREPPN}:9E1A2D38-C612-4316-AA26-8B49521E5A8B \ -n ${RESERVEDPN}:0:+1M -c ${RESERVEDPN}:reserved -t ${RESERVEDPN}:8DA63339-0007-60C0-C436-083AC8230908 \ -n ${BOOTPN}:0:+384M -c ${BOOTPN}:boot \ -n ${ROOTPN}:0:0 -c ${ROOTPN}:root -t ${ROOTPN}:0FC63DAF-8483-4772-8E79-3D69D8477DE4 ;; esac sgdisk -p "$disk" udevtrig boot_dev="${disk}${BOOTPN}" root_dev="${disk}${ROOTPN}" bootargs= # Detect if the target system supports orphan_file. # https://github.com/coreos/coreos-assembler/pull/3653#issuecomment-1813181723 # Ideally, we'd do feature detection here but there's no clean way to do that. # So just use version comparisons. (But ideally ideally, we use the mkfs.* # binaries from the target system, not cosa.) e2fsprogs_version=$(jq -r '.["rpmostree.rpmdb.pkglist"][] | select(.[0] == "e2fsprogs") | .[2]' \ "builds/${buildid}/${arch}/commitmeta.json") if [ "${e2fsprogs_version}" != "1.47.0" ] && \ [ "$(echo -e "${e2fsprogs_version}\n1.47.0" | sort -V | tail -n1)" = "1.47.0" ]; then # target system has e2fsprogs older than 1.47.0; it won't support # orphan_file so make sure we opt out of it bootargs+=" -O ^orphan_file" fi case "${bootfs}" in ext4verity) # Need blocks to match host page size; TODO # really mkfs.ext4 should know this. bootargs+=" -b $(getconf PAGE_SIZE) -O verity" ;; ext4) ;; *) echo "Unhandled bootfs: ${bootfs}" 1>&2; exit 1 ;; esac if [[ ${secure_execution} -eq 1 ]]; then # Unencrypted partition for sd-boot # shellcheck disable=SC2086 mkfs.ext4 ${bootargs} "${disk}${SDPART}" -L se -U random fi # shellcheck disable=SC2086 mkfs.ext4 ${bootargs} "${boot_dev}" -L boot -U "${bootfs_uuid}" udevtrig if [ ${EFIPN:+x} ]; then mkfs.fat "${disk}${EFIPN}" -n EFI-SYSTEM # BIOS boot partition has no FS; it's for BIOS GRUB # partition $PREPPN has no FS; it's for PowerPC PReP Boot fi case "${rootfs_type}" in ext4verity) # As of today, xfs doesn't support verity, so we have a choice of fs-verity or reflinks. # Now, fs-verity doesn't in practice gain us a huge amount of security because # there are other "persistence vectors". See # https://blog.verbum.org/2017/06/12/on-dm-verity-and-operating-systems/ # https://github.com/coreos/rpm-ostree/issues/702 # And reflinks are *very* useful for the container stack with overlayfs (and in general). # So basically, we're choosing performance over half-implemented security. # Eventually, we'd like both - once XFS gains verity (probably not too hard), # we could unconditionally enable it there. # shellcheck disable=SC2086 mkfs.ext4 -b "$(getconf PAGE_SIZE)" -O verity -L root "${root_dev}" -U "${rootfs_uuid}" ${rootfs_args} ;; btrfs) # shellcheck disable=SC2086 mkfs.btrfs -L root "${root_dev}" -U "${rootfs_uuid}" ${rootfs_args} ;; xfs|"") # shellcheck disable=SC2086 mkfs.xfs "${root_dev}" -L root -m reflink=1 -m uuid="${rootfs_uuid}" ${rootfs_args} ;; *) echo "Unknown rootfs_type: $rootfs_type" 1>&2 exit 1 ;; esac udevtrig # since we normally run in supermin container and we need # support parallel runs, use /tmp rootfs=/tmp/rootfs # mount the partitions rm -rf ${rootfs} mkdir -p ${rootfs} mount -o discard "${root_dev}" ${rootfs} chcon "$(matchpathcon -n /)" ${rootfs} mkdir ${rootfs}/boot chcon "$(matchpathcon -n /boot)" $rootfs/boot mount "${boot_dev}" $rootfs/boot chcon "$(matchpathcon -n /boot)" $rootfs/boot # FAT doesn't support SELinux labeling, it uses "genfscon", so we # don't need to give it a label manually. if [ ${EFIPN:+x} ]; then mkdir ${rootfs}/boot/efi mount "${disk}${EFIPN}" $rootfs/boot/efi fi if [[ ${secure_execution} -eq 1 ]]; then mkdir ${rootfs}/se chcon "$(matchpathcon -n /boot)" $rootfs/se fi # Now that we have the basic disk layout, initialize the basic # OSTree layout, load in the ostree commit and deploy it. ostree admin init-fs --modern $rootfs # May be overridden below (e.g. s390x) ostree config --repo $rootfs/ostree/repo set sysroot.bootloader none # Opt-in to https://github.com/ostreedev/ostree/pull/1767 AKA # https://github.com/ostreedev/ostree/issues/1265 ostree config --repo $rootfs/ostree/repo set sysroot.readonly true if test -n "${composefs}"; then ostree config --repo $rootfs/ostree/repo set ex-integrity.composefs true fi # Initialize the "stateroot" ostree admin os-init "$os_name" --sysroot $rootfs # Propagate flags into target repository if [ "${rootfs_type}" = "ext4verity" ] && [ -z "${composefs}" ]; then ostree config --repo=$rootfs/ostree/repo set ex-fsverity.required 'true' fi # Compute kargs allkargs="$extra_kargs" # shellcheck disable=SC2031 if [ "$arch" != s390x ]; then # Note that $ignition_firstboot is interpreted by grub at boot time, # *not* the shell here. Hence the backslash escape. allkargs+=" \$ignition_firstboot" fi if test -n "${deploy_via_container}"; then kargsargs="" for karg in $allkargs do kargsargs+="--karg=$karg " done # shellcheck disable=SC2086 ostree container image deploy --imgref "${ostree_container_spec}" \ ${container_imgref:+--target-imgref $container_imgref} \ --write-commitid-to /tmp/commit.txt \ --stateroot "$os_name" --sysroot $rootfs $kargsargs deploy_commit=$(cat /tmp/commit.txt) rm /tmp/commit.txt else # Pull the container image... time ostree container image pull $rootfs/ostree/repo "${ostree_container_spec}" # But we default to not leaving a ref for the image around, so the # layers will get GC'd on the first update if the # user doesn't switch to a container image. ostree --repo=$rootfs/ostree/repo refs --delete ostree/container/image ostree --repo=$rootfs/ostree/repo prune --refs-only --depth=0 # Deploy it, using an optional remote prefix if test -n "${remote_name}"; then deploy_ref="${remote_name}:${ref}" ostree refs --repo $rootfs/ostree/repo --create "${deploy_ref}" "${commit}" else deploy_ref=$commit fi kargsargs="" for karg in $allkargs do kargsargs+="--karg-append=$karg " done # shellcheck disable=SC2086 ostree admin deploy "${deploy_ref}" --sysroot $rootfs --os "$os_name" $kargsargs deploy_commit=$commit fi # Sanity check deploy_root="$rootfs/ostree/deploy/${os_name}/deploy/${deploy_commit}.0" test -d "${deploy_root}" || (echo "failed to find $deploy_root"; exit 1) # This will allow us to track the version that an install # originally used; if we later need to understand something # like "exactly what mkfs.xfs version was used" we can do # that via looking at the upstream build and finding the # build logs for it, getting the coreos-assembler version, # and getting the `rpm -qa` from that. # # build: The coreos-assembler build ID; today we support # having the same ostree commit in different image builds. # ref: The ostree ref used; useful for cross-checking. # ostree-commit: Similar to `ref`; one can derive this from looking # at the coreos-assembler builds, but it's very # convenient to have here as a strong cross-reference. # imgid: The full image name, the same as will end up in the # `images` dict in `meta.json`. cat > $rootfs/.coreos-aleph-version.json << EOF { "build": "${buildid}", "ref": "${ref}", "ostree-commit": "${commit}", "imgid": "${imgid}" } EOF install_uefi() { # https://github.com/coreos/fedora-coreos-tracker/issues/510 # See also https://github.com/ostreedev/ostree/pull/1873#issuecomment-524439883 chroot_run bootupctl backend install --src-root="/" "/sysroot" # We have a "static" grub config file that basically configures grub to look # in the RAID called "md-boot", if it exists, or the partition labeled "boot". local target_efi="$rootfs/boot/efi" local grubefi grubefi=$(find "${target_efi}/EFI/" -maxdepth 1 -type d | grep -v BOOT) local vendor_id="${grubefi##*/}" local vendordir="${target_efi}/EFI/${vendor_id}" mkdir -p "${vendordir}" cat > "${vendordir}/grub.cfg" << 'EOF' if [ -e (md/md-boot) ]; then # The search command might pick a RAID component rather than the RAID, # since the /boot RAID currently uses superblock 1.0. See the comment in # the main grub.cfg. set prefix=md/md-boot else if [ -f ${config_directory}/bootuuid.cfg ]; then source ${config_directory}/bootuuid.cfg fi if [ -n "${BOOT_UUID}" ]; then search --fs-uuid "${BOOT_UUID}" --set prefix --no-floppy else search --label boot --set prefix --no-floppy fi fi set prefix=($prefix)/grub2 configfile $prefix/grub.cfg boot EOF install_grub_cfg } # copy the grub config and any other files we might need install_grub_cfg() { # 0700 to match the RPM permissions which I think are mainly in case someone has # manually set a grub password mkdir -p $rootfs/boot/grub2 chmod 0700 $rootfs/boot/grub2 printf "%s\n" "$grub_script" | \ sed -E 's@(^# CONSOLE-SETTINGS-START$)@\1'"${platform_grub_cmds:+\\n${platform_grub_cmds}}"'@' \ > $rootfs/boot/grub2/grub.cfg # Copy platforms table if it's non-empty for this arch # shellcheck disable=SC2031 if jq -e ".$arch" < "$platforms_json" > /dev/null; then mkdir -p "$rootfs/boot/coreos" jq ".$arch" < "$platforms_json" > "$rootfs/boot/coreos/platforms.json" fi } # For some commands, we need to make sure to use the binary and userspace of the # target system. XXX: Switch to bwrap. chroot_run() { for mnt in dev proc sys run var tmp; do mount --rbind "/$mnt" "${deploy_root}/$mnt" done mount --rbind "${rootfs}" "${deploy_root}/sysroot" chroot "${deploy_root}" "$@" umount --recursive "${deploy_root}/sysroot" for mnt in dev proc sys run var tmp; do umount --recursive "${deploy_root}/$mnt" done } generate_gpgkeys() { local pkey pkey="${1}" local tmp_home tmp_home=$(mktemp -d /tmp/gpg-XXXXXX) gpg --homedir "${tmp_home}" --batch --passphrase '' --yes --quick-gen-key "Secure Execution (secex) $buildid" rsa4096 encr none gpg --homedir "${tmp_home}" --armor --export secex > "${ignition_pubkey}" gpg --homedir "${tmp_home}" --armor --export-secret-key secex > "${pkey}" rm -rf "${tmp_home}" } # Other arch-specific bootloader changes # shellcheck disable=SC2031 case "$arch" in x86_64) # UEFI install_uefi if [ "${x86_bios_bootloader}" = 1 ]; then # And BIOS grub in addition. See also # https://github.com/coreos/fedora-coreos-tracker/issues/32 # Install BIOS/PReP bootloader using the target system's grub2-install, # see https://github.com/coreos/coreos-assembler/issues/3156 chroot_run /sbin/grub2-install \ --target i386-pc \ --boot-directory $rootfs/boot \ --modules mdraid1x \ "$disk" fi ;; aarch64) # Our aarch64 is UEFI only. install_uefi ;; ppc64le) # to populate PReP Boot, i.e. support pseries chroot_run /sbin/grub2-install --target=powerpc-ieee1275 --boot-directory $rootfs/boot --no-nvram "${disk}${PREPPN}" install_grub_cfg ;; s390x) ostree config --repo $rootfs/ostree/repo set sysroot.bootloader zipl rdcore_zipl_args=("--boot-mount=$rootfs/boot" "--append-karg=ignition.firstboot") # in the secex case, we run zipl at the end; in the non-secex case, we need # to run it now because zipl wants rw access to the bootfs if [[ ${secure_execution} -ne 1 ]]; then # in case builder itself runs with SecureExecution rdcore_zipl_args+=("--secex-mode=disable") chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}" fi ;; esac # enable support for GRUB password # shellcheck disable=SC2031 if [ "$arch" != s390x ]; then ostree config --repo $rootfs/ostree/repo set sysroot.bls-append-except-default 'grub_users=""' fi # For local secex build we create an empty file and later mount-bind real private key to it, # so rdcore could append it to initrd. Best approach is to teach rdcore how to append file # with different source and dest- paths. if [[ ${secure_execution} -eq 1 ]] && [[ ! -e /dev/disk/by-id/virtio-genprotimg ]]; then touch "${deploy_root}/usr/lib/coreos/ignition.asc" fi touch $rootfs/boot/ignition.firstboot fstrim -a -v # Ensure the filesystem journals are flushed for fs in $rootfs/boot $rootfs; do mount -o remount,ro "$fs" fsfreeze -f "$fs" fsfreeze -u "$fs" done umount -R $rootfs create_dmverity() { local partlabel=$1; shift local mountpoint=$1; shift local datapart="/dev/disk/by-partlabel/${partlabel}" local hashpart="/dev/disk/by-partlabel/${partlabel}hash" # We have to use 512 here to match the filesystem sector size. It's less # efficient, but meh, it's for first boot only. Alternatively we could # change the filesystem sector size higher up. veritysetup format "${datapart}" "${hashpart}" \ --root-hash-file "/tmp/${partlabel}-roothash" \ --data-block-size 512 veritysetup open "${datapart}" "${partlabel}" "${hashpart}" \ --root-hash-file "/tmp/${partlabel}-roothash" mount -o ro "/dev/mapper/${partlabel}" "${mountpoint}" } # Save genprotimg input for later and don't run zipl here rdcore_replacement() { local se_kargs_append se_initrd se_kernel se_parmfile local blsfile kernel initrd local se_script_dir se_tmp_disk se_tmp_mount se_tmp_boot se_kargs_append=("ignition.firstboot") while [ $# -gt 0 ]; do se_kargs_append+=("$1") shift done se_script_dir="/usr/lib/coreos-assembler/secex-genprotimgvm-scripts" se_tmp_disk=$(realpath /dev/disk/by-id/virtio-genprotimg) se_tmp_mount=$(mktemp -d /tmp/genprotimg-XXXXXX) se_tmp_boot="${se_tmp_mount}/genprotimg" mount "${se_tmp_disk}" "${se_tmp_mount}" mkdir "${se_tmp_boot}" se_initrd="${se_tmp_boot}/initrd.img" se_kernel="${se_tmp_boot}/vmlinuz" se_parmfile="${se_tmp_boot}/parmfile" # Ignition GPG private key mkdir -p "${se_tmp_boot}/usr/lib/coreos" generate_gpgkeys "${se_tmp_boot}/usr/lib/coreos/ignition.asc" blsfile=$(find "${rootfs}"/boot/loader/entries/*.conf) echo "$(grep options "${blsfile}" | cut -d' ' -f2-)" "${se_kargs_append[@]}" > "${se_parmfile}" kernel="${rootfs}/boot/$(grep linux "${blsfile}" | cut -d' ' -f2)" initrd="${rootfs}/boot/$(grep initrd "${blsfile}" | cut -d' ' -f2)" cp "${kernel}" "${se_kernel}" cp "${initrd}" "${se_initrd}" # genprotimg and zipl will be done outside this script # copy scripts for that step to the tmp disk cp "${se_script_dir}/genprotimg-script.sh" "${se_script_dir}/post-script.sh" "${se_tmp_mount}/" umount "${se_tmp_mount}" rmdir "${se_tmp_mount}" } if [[ ${secure_execution} -eq 1 ]]; then # set up dm-verity for the rootfs and bootfs create_dmverity root $rootfs create_dmverity boot $rootfs/boot # We need to run the genprotimg step in a separate step for rhcos release images if [ ! -e /dev/disk/by-id/virtio-genprotimg ]; then echo "Building local Secure Execution Image, running zipl and genprotimg" generate_gpgkeys "/tmp/ignition.asc" mount --rbind "/tmp/ignition.asc" "${deploy_root}/usr/lib/coreos/ignition.asc" # run zipl with root hashes as kargs rdcore_zipl_args+=("--secex-mode=enforce" "--hostkey=/dev/disk/by-id/virtio-hostkey") rdcore_zipl_args+=("--append-karg=rootfs.roothash=$(cat /tmp/root-roothash)") rdcore_zipl_args+=("--append-karg=bootfs.roothash=$(cat /tmp/boot-roothash)") rdcore_zipl_args+=("--append-file=/usr/lib/coreos/ignition.asc") chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}" else echo "Building release Secure Execution Image, zipl and genprotimg will be run later" rdcore_replacement "rootfs.roothash=$(cat /tmp/root-roothash)" "bootfs.roothash=$(cat /tmp/boot-roothash)" fi # unmount and close everything umount -R $rootfs veritysetup close boot veritysetup close root fi rmdir $rootfs