curtin-dev team mailing list archive
-
curtin-dev team
-
Mailing list archive
-
Message #00583
[Merge] ~raharper/curtin:fix/vmtest-add-trusty-hwe-x-uefi into curtin:master
Ryan Harper has proposed merging ~raharper/curtin:fix/vmtest-add-trusty-hwe-x-uefi into curtin:master.
Commit message:
Add Trusty/UEFI/HWE-X vmtest, drop realpath add, drop shell code
The fix provided for addressing Trusty UEFI with HWE-X kernel is
not needed due to the refactor of the grub install code into python.
This branch:
- removes the added package
- creates a Trusty UEFI with HWE-X to match bug test scenario
- remove helpers/install-grub
- remove install-grub code from helpers/common
Requested reviews:
curtin developers (curtin-dev)
For more details, see:
https://code.launchpad.net/~raharper/curtin/+git/curtin/+merge/385226
--
Your team curtin developers is requested to review the proposed merge of ~raharper/curtin:fix/vmtest-add-trusty-hwe-x-uefi into curtin:master.
diff --git a/curtin/commands/curthooks.py b/curtin/commands/curthooks.py
index 11c718a..d66afa7 100644
--- a/curtin/commands/curthooks.py
+++ b/curtin/commands/curthooks.py
@@ -1176,11 +1176,6 @@ def install_missing_packages(cfg, target, osfamily=DISTROS.debian):
# AMD64 has shim-signed for SecureBoot support
if arch == "amd64":
uefi_pkgs.append("shim-signed")
-
- # realpath is part of coreutils in Xenial+, older versions need
- # the package to be installed.
- if not util.which("realpath"):
- uefi_pkgs.append("realpath")
else:
raise ValueError('Unknown grub2 package list for distro: %s' %
osfamily)
diff --git a/helpers/common b/helpers/common
index 5638d39..4afb6a1 100644
--- a/helpers/common
+++ b/helpers/common
@@ -29,19 +29,6 @@ EOF
[ $# -eq 0 ] || echo "$@"
}
-grub_install_usage() {
- cat <<EOF
-Usage: ${0##*/} [ options ] mount-point target-dev
-
- perform grub-install with mount-point onto target-dev.
-
- options:
- --uefi install grub-efi instead of grub-pc
- --update-nvram request grub to update nvram
-EOF
- [ $# -eq 0 ] || echo "$@"
-}
-
cleanup() {
if [ -d "$TEMP_D" ]; then
rm -Rf "$TEMP_D"
@@ -480,569 +467,4 @@ getsize() {
fi
}
-is_md() {
- case "${1##*/}" in
- md[0-9]) return 0;;
- esac
- return 1
-}
-
-get_carryover_params() {
- local cmdline=" $1 " extra="" lead="" carry_extra="" carry_lead=""
- # return a string to append to installed systems boot parameters
- # it may include a '--' after a '---'
- # see LP: 1402042 for some history here.
- # this is similar to 'user-params' from d-i
- local preferred_sep="---" # KERNEL_CMDLINE_COPY_TO_INSTALL_SEP
- local legacy_sep="--"
- case "$cmdline" in
- *\ ${preferred_sep}\ *)
- extra=${cmdline#* ${preferred_sep} }
- lead=${cmdline%% ${preferred_sep} *}
- ;;
- *\ ${legacy_sep}\ *)
- extra="${cmdline#* ${legacy_sep} }"
- lead=${cmdline%% ${legacy_sep} *}
- ;;
- *)
- extra=""
- lead="$cmdline"
- ;;
- esac
-
- if [ -n "$extra" ]; then
- carry_extra=$(set -f;
- c="";
- for p in $extra; do
- case "$p" in
- (BOOTIF=*|initrd=*|BOOT_IMAGE=*) continue;;
- esac
- c="$c $p";
- done
- echo "${c# }"
- )
- fi
-
- # these get copied even if they werent after the separator
- local padded=" $carry_extra "
- carry_lead=$(set -f;
- padded=" ${carry_extra} "
- c=""
- for p in $lead; do
- # skip any that are already in carry_extra
- [ "${padded#* $p }" != "$padded" ] && continue
- case "$p" in
- (console=*) c="$c $p";;
- esac
- done
- echo "${c# }"
- )
- [ -n "${carry_lead}" -a -n "${carry_extra}" ] &&
- carry_lead="${carry_lead} "
- _RET="${carry_lead}${carry_extra}"
-}
-
-shell_config_update() {
- # shell_config_update(file, name, value)
- # update variable 'name' setting value to 'val' in shell syntax 'file'.
- # if 'name' is not present, then append declaration.
- local file="$1" name="$2" val="$3"
- if ! [ -f "$file" ] || ! grep -q "^$name=" "$file"; then
- debug 2 "appending to $file shell $name=\"$val\""
- echo "$name=\"$val\"" >> "$file"
- return
- fi
- local cand="" del=""
- for cand in "|" "," "/"; do
- [ "${val#*${del}}" = "${val}" ] && del="$cand" && break
- done
- [ -n "$del" ] || {
- error "Couldn't find a sed delimiter for '$val'";
- return 1;
- }
-
- sed -i -e "s${del}^$name=.*${del}$name=\"$val\"${del}" "$file" ||
- { error "Failed editing '$file' to set $name=$val"; return 1; }
- debug 2 "updated $file to set $name=\"$val\""
- return 0
-}
-
-apply_grub_cmdline_linux_default() {
- local mp="$1" newargs="$2" edg="${3:-etc/default/grub}"
- local gcld="GRUB_CMDLINE_LINUX_DEFAULT"
- debug 1 "setting $gcld to '$newargs' in $edg"
- shell_config_update "$mp/$edg" "$gcld" "$newargs" || {
- error "Failed to set '$gcld=$newargs' in $edg"
- return 1
- }
-}
-
-get_parent_disk() {
- # Look up the parent /dev path via sysfs. Using the partition
- # kname (nvme0n1p1), construct a /sys/class/block path, use
- # realpath to resolve this to an absolute path which includes
- # the parent:
- # /sys/devices/pci0000:00/*/*/nvme/nvme0/nvme0n1/nvme0n1p1
- # dirname to extract the parent, then read the 'dev' entry
- # /sys/devices/pci0000:00/*/*/nvme/nvme0/nvme0n1/dev
- # which contains the MAJOR:MINOR value and construct a /dev/block
- # path which is a symbolic link that udev constructs that points
- # to the real device name and use realpath to return the absolute path.
- # /dev/block/259:0 -> ../nvme0n1
- local devpath="${1}"
- local kname=$(basename "$devpath")
- local syspath=$(realpath "/sys/class/block/$kname")
- local disksyspath=$(dirname "$syspath")
- local diskmajmin=$(cat "${disksyspath}/dev")
- local diskdevpath=$(realpath "/dev/block/${diskmajmin}")
- echo $diskdevpath
-}
-
-install_grub() {
- local long_opts="uefi,update-nvram,os-family:"
- local getopt_out="" mp_efi=""
- getopt_out=$(getopt --name "${0##*/}" \
- --options "" --long "${long_opts}" -- "$@") &&
- eval set -- "${getopt_out}"
-
- local uefi=0 update_nvram=0 os_family=""
-
- while [ $# -ne 0 ]; do
- cur="$1"; next="$2";
- case "$cur" in
- --os-family) os_family=${next};;
- --uefi) uefi=$((${uefi}+1));;
- --update-nvram) update_nvram=$((${update_nvram}+1));;
- --) shift; break;;
- esac
- shift;
- done
-
- [ $# -lt 2 ] && { grub_install_usage "must provide mount-point and target-dev" 1>&2; return 1; }
-
- local mp="$1"
- local cmdline tmp r=""
- shift
- local grubdevs
- grubdevs=( "$@" )
- if [ "${#grubdevs[@]}" = "1" -a "${grubdevs[0]}" = "none" ]; then
- grubdevs=( )
- fi
- debug 1 "grubdevs: [${grubdevs[@]}]"
-
- # find the mp device
- local mp_dev="" fstype=""
- mp_dev=$(awk -v "MP=$mp" '$2 == MP { print $1 }' /proc/mounts) || {
- error "unable to determine device for mount $mp";
- return 1;
- }
- debug 1 "/proc/mounts shows $mp_dev is mounted at $mp"
-
- fstype=$(awk -v MP=$mp '$2 == MP { print $3 }' /proc/mounts) || {
- error "unable to fstype for mount $mp";
- return 1;
- }
-
- [ -z "$mp_dev" ] && {
- error "did not find '$mp' in /proc/mounts"
- cat /proc/mounts 1>&2
- return 1
- }
- # check if parsed mount point is a block device
- # error unless fstype is zfs, where entry will not point to block device.
- if ! [ -b "$mp_dev" ] && [ "$fstype" != "zfs" ]; then
- # error unless mp is zfs, entry doesn't point to block devs
- error "$mp_dev ($fstype) is not a block device!"; return 1;
- fi
-
- local os_variant=""
- if [ -e "${mp}/etc/os-release" ]; then
- os_variant=$(chroot "$mp" \
- /bin/sh -c 'echo $(. /etc/os-release; echo $ID)')
- else
- # Centos6 doesn't have os-release, so check for centos/redhat release
- # looks like: CentOS release 6.9 (Final)
- for rel in $(ls ${mp}/etc/*-release); do
- os_variant=$(awk '{print tolower($1)}' $rel)
- [ -n "$os_variant" ] && break
- done
- fi
- [ $? != 0 ] &&
- { error "Failed to read ID from $mp/etc/os-release"; return 1; }
-
- local rhel_ver=""
- case $os_variant in
- debian|ubuntu) os_family="debian";;
- centos|rhel)
- os_family="redhat"
- rhel_ver=$(chroot "$mp" rpm -E '%rhel')
- ;;
- esac
-
- # ensure we have both settings, family and variant are needed
- [ -n "${os_variant}" -a -n "${os_family}" ] ||
- { error "Failed to determine os variant and family"; return 1; }
-
- # get target arch
- local target_arch="" r="1"
- case $os_family in
- debian)
- target_arch=$(chroot "$mp" dpkg --print-architecture)
- r=$?
- ;;
- redhat)
- target_arch=$(chroot "$mp" rpm -E '%_arch')
- r=$?
- ;;
- esac
- [ $r -eq 0 ] || {
- error "failed to get target architecture [$r]"
- return 1;
- }
-
- # grub is not the bootloader you are looking for
- if [ "${target_arch}" = "s390x" ]; then
- return 0;
- fi
-
- # set correct grub package
- local grub_name=""
- local grub_target=""
- case "$target_arch" in
- i386|amd64)
- # debian
- grub_name="grub-pc"
- grub_target="i386-pc"
- ;;
- x86_64)
- case $rhel_ver in
- 6) grub_name="grub";;
- 7|8) grub_name="grub2-pc";;
- *)
- error "Unknown rhel_ver [$rhel_ver]";
- return 1;
- ;;
- esac
- grub_target="i386-pc"
- ;;
- esac
- if [ "${target_arch#ppc64}" != "${target_arch}" ]; then
- grub_name="grub-ieee1275"
- grub_target="powerpc-ieee1275"
- elif [ "$uefi" -ge 1 ]; then
- grub_name="grub-efi-$target_arch"
- case "$target_arch" in
- x86_64)
- # centos 7+, no centos6 support
- # grub2-efi-x64 installs a signed grub bootloader while
- # curtin uses grub2-efi-x64-modules to generate grubx64.efi.
- # Either works just check that one of them is installed.
- grub_name="grub2-efi-x64 grub2-efi-x64-modules"
- grub_target="x86_64-efi"
- ;;
- amd64)
- grub_target="x86_64-efi";;
- arm64)
- grub_target="arm64-efi";;
- esac
- fi
-
- # check that the grub package is installed
- local r=$?
- case $os_family in
- debian)
- tmp=$(chroot "$mp" dpkg-query --show \
- --showformat='${Status}\n' $grub_name)
- r=$?
- ;;
- redhat)
- tmp=$(chroot "$mp" rpm -q \
- --queryformat='install ok installed\n' $grub_name)
- r=$?
- ;;
- esac
- if [ $r -ne 0 -a $r -ne 1 ]; then
- error "failed to check if $grub_name installed";
- return 1;
- fi
- # Check that any of the packages in $grub_name are installed. If
- # grub_name contains multiple packages, as it does for CentOS 7+,
- # only one package has to be installed for this to pass.
- if ! echo $tmp | grep -q 'install ok installed'; then
- debug 1 "$grub_name not installed, not doing anything"
- return 1
- fi
-
- local grub_d="etc/default/grub.d"
- # ubuntu writes to /etc/default/grub.d/50-curtin-settings.cfg
- # to avoid tripping prompts on upgrade LP: #564853
- local mygrub_cfg="$grub_d/50-curtin-settings.cfg"
- case $os_family in
- redhat)
- grub_d="etc/default"
- mygrub_cfg="etc/default/grub";;
- esac
- [ -d "$mp/$grub_d" ] || mkdir -p "$mp/$grub_d" ||
- { error "Failed to create $grub_d"; return 1; }
-
- # LP: #1179940 . The 50-cloudig-settings.cfg file is written by the cloud
- # images build and defines/override some settings. Disable it.
- local cicfg="$grub_d/50-cloudimg-settings.cfg"
- if [ -f "$mp/$cicfg" ]; then
- debug 1 "moved $cicfg out of the way"
- mv "$mp/$cicfg" "$mp/$cicfg.disabled"
- fi
-
- # get the user provided / carry-over kernel arguments
- local newargs=""
- read cmdline < /proc/cmdline &&
- get_carryover_params "$cmdline" && newargs="$_RET" || {
- error "Failed to get carryover parrameters from cmdline";
- return 1;
- }
- # always append rd.auto=1 for centos
- case $os_family in
- redhat)
- newargs="${newargs:+${newargs} }rd.auto=1";;
- esac
- debug 1 "carryover command line params '$newargs'"
-
- if [ "${REPLACE_GRUB_LINUX_DEFAULT:-1}" != "0" ]; then
- apply_grub_cmdline_linux_default "$mp" "$newargs" || {
- error "Failed to apply grub cmdline."
- return 1
- }
- fi
-
- if [ "${DISABLE_OS_PROBER:-1}" == "1" ]; then
- {
- echo "# Curtin disable grub os prober that might find other OS installs."
- echo "GRUB_DISABLE_OS_PROBER=true"
- } >> "$mp/$mygrub_cfg"
- fi
-
- if [ -n "${GRUB_TERMINAL}" ]; then
- {
- echo "# Curtin configured GRUB_TERMINAL value"
- echo "GRUB_TERMINAL=${GRUB_TERMINAL}"
- } >> "$mp/$mygrub_cfg"
- fi
-
- debug 1 "processing grubdevs values for expansion if needed"
- local short="" bd="" grubdev grubdevs_new=""
- grubdevs_new=()
- for grubdev in "${grubdevs[@]}"; do
- if is_md "$grubdev"; then
- debug 1 "$grubdev is raid, find members"
- short=${grubdev##*/}
- for bd in "/sys/block/$short/slaves/"/*; do
- [ -d "$bd" ] || continue
- bd=${bd##*/}
- bd="/dev/${bd%[0-9]}" # FIXME: part2bd
- debug 1 "Add dev $bd to grubdevs_new"
- grubdevs_new[${#grubdevs_new[@]}]="$bd"
- done
- else
- debug 1 "Found dev [$grubdev] add to grubdevs_new"
- grubdevs_new[${#grubdevs_new[@]}]="$grubdev"
- fi
- done
- grubdevs=( "${grubdevs_new[@]}" )
- debug 1 "updated grubdevs: [${grubdevs[@]}]"
-
- if [ "$uefi" -ge 1 ]; then
- nvram="--no-nvram"
- if [ "$update_nvram" -ge 1 ]; then
- nvram=""
- fi
- debug 1 "number of entries in grubdevs_new: ${#grubdevs[@]}"
- if [ "${#grubdevs_new[@]}" -eq 1 ] && [ -b "${grubdevs_new[0]}" ]; then
- debug 1 "Found a single entry in grubdevs, ${grubdevs_new[0]}"
- # Currently UEFI can only be pointed to one system partition. If
- # for some reason multiple install locations are given only use the
- # first.
- efi_dev="${grubdevs_new[0]}"
- debug 1 "efi_dev=[${efi_dev}]"
- elif [ "${#grubdevs_new[@]}" -gt 1 ]; then
- error "Only one grub device supported on UEFI!"
- exit 1
- else
- debug 1 "no storage config, parsing /proc/mounts with awk"
- # If no storage configuration was given try to determine the system
- # partition.
- efi_dev=$(awk -v "MP=${mp}/boot/efi" '$2 == MP { print $1 }' /proc/mounts)
- debug 1 "efi_dev=[${efi_dev}]"
- [ -n "$efi_dev" ] || {
- error "Failed to find efi device from parsing /proc/mounts"
- return 1
- }
-
- fi
- # The partition number of block device name need to be determined here
- # so both getting the UEFI device from Curtin config and discovering it
- # work.
- efi_part_num=$(cat /sys/class/block/$(basename $efi_dev)/partition)
- debug 1 "efi_part_num: $efi_part_num"
- [ -n "${efi_part_num}" ] || {
- error "Failed to determine $efi_dev partition number"
- return 1
- }
- efi_disk=$(get_parent_disk "$efi_dev")
- debug 1 "efi_disk: [$efi_disk]"
- [ -b "${efi_disk}" ] || {
- error "${efi_disk} is not a valid block device"
- return 1
- }
- debug 1 "curtin uefi: installing ${grub_name} to: /boot/efi"
- chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc '
- echo "before grub-install efiboot settings"
- efibootmgr -v || echo "WARN: efibootmgr exited $?"
- bootid="$4"
- efi_disk="$5"
- efi_part_num="$6"
- grubpost=""
- grubmulti="/usr/lib/grub/grub-multi-install"
- case $bootid in
- debian|ubuntu)
- grubcmd="grub-install"
- if [ -e "${grubmulti}" ]; then
- grubcmd="${grubmulti}"
- fi
- dpkg-reconfigure "$1"
- update-grub
- ;;
- centos|redhat|rhel)
- grubcmd="grub2-install"
- # RHEL uses redhat instead of the os_variant rhel for the bootid.
- if [ "$bootid" = "rhel" ]; then
- bootid="redhat"
- fi
- if [ -f /boot/efi/EFI/$bootid/grubx64.efi ]; then
- grubpost="grub2-mkconfig -o /boot/efi/EFI/$bootid/grub.cfg"
- else
- grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg"
- fi
- ;;
- *)
- echo "Unsupported OS: $bootid" 1>&2
- exit 1
- ;;
- esac
- # grub-install in 12.04 does not contain --no-nvram, --target,
- # or --efi-directory
- target="--target=$2"
- no_nvram="$3"
- efi_dir="--efi-directory=/boot/efi"
- gi_out=$($grubcmd --help 2>&1)
- echo "$gi_out" | grep -q -- "$no_nvram" || no_nvram=""
- echo "$gi_out" | grep -q -- "--target" || target=""
- echo "$gi_out" | grep -q -- "--efi-directory" || efi_dir=""
-
- # Do not overwrite grubx64.efi if it already exists. grub-install
- # generates grubx64.efi and overwrites any existing binary in
- # /boot/efi/EFI/$bootid. This binary is not signed and will cause
- # secure boot to fail.
- #
- # CentOS, RHEL, Fedora ship the signed boot loader in the package
- # grub2-efi-x64 which installs the signed boot loader to
- # /boot/efi/EFI/$bootid/grubx64.efi. All Curtin has to do is
- # configure the firmware. This mirrors what Anaconda does.
- #
- # Debian and Ubuntu come with a patched version of grub which
- # add the install flag --uefi-secure-boot which is enabled by
- # default. When enabled if a signed version of grub exists on
- # the filesystem it will be copied into /boot/efi/EFI/$bootid.
- # Stock Ubuntu images do not ship with anything in /boot. Those
- # files are generated by installing a kernel and grub.
- echo "Dumping /boot/efi contents"
- find /boot/efi
- echo "Checking for existing EFI grub entry on ESP"
- if [ "$grubcmd" = "grub2-install" -a -f /boot/efi/EFI/$bootid/grubx64.efi ]; then
- if [ -z "$no_nvram" ]; then
- # UEFI firmware should be pointed to the shim if available to
- # enable secure boot.
- for boot_uefi in \
- /boot/efi/EFI/$bootid/shimx64.efi \
- /boot/efi/EFI/BOOT/BOOTX64.EFI \
- /boot/efi/EFI/$bootid/grubx64.efi; do
- if [ -f $boot_uefi ]; then
- break
- fi
- done
- loader=$(echo ${boot_uefi##/boot/efi} | sed "s|/|\\\|g")
- efibootmgr --create --write-signature --label $bootid \
- --disk $efi_disk --part $efi_part_num --loader $loader
- rc=$?
- [ "$rc" != "0" ] && { exit $rc; }
- else
- echo "skip EFI entry creation due to \"$no_nvram\" flag"
- fi
- else
- echo "No previous EFI grub entry found on ESP, use $grubcmd"
- if [ "${grubcmd}" = "${grubmulti}" ]; then
- $grubcmd
- else
- $grubcmd $target $efi_dir \
- --bootloader-id=$bootid --recheck $no_nvram
- fi
- fi
- [ -z "$grubpost" ] || $grubpost;' \
- -- "$grub_name" "$grub_target" "$nvram" "$os_variant" "$efi_disk" "$efi_part_num" </dev/null ||
- { error "failed to install grub!"; return 1; }
-
- chroot "$mp" sh -exc '
- echo "after grub-install efiboot settings"
- efibootmgr -v || echo "WARN: efibootmgr exited $?"
- ' -- </dev/null ||
- { error "failed to list efi boot entries!"; return 1; }
- else
- # Note: dpkg-reconfigure calls grub-install on ppc64
- # this means that using '--no-nvram' below ends up
- # failing very oddly. This is because grub's post-inst
- # runs grub-install with no target. That ends up
- # updating nvram badly, and then the grub-install would
- # not fix it because of the no-nvram there.
- debug 1 "curtin non-uefi: installing ${grub_name} to: ${grubdevs[*]}"
- chroot "$mp" env DEBIAN_FRONTEND=noninteractive sh -exc '
- pkg=$1; shift;
- bootid=$1; shift;
- bootver=$1; shift;
- grubpost=""
- case $bootid in
- debian|ubuntu)
- grubcmd="grub-install"
- dpkg-reconfigure "$pkg"
- update-grub
- ;;
- centos|redhat|rhel)
- case $bootver in
- 6) grubcmd="grub-install";;
- 7|8) grubcmd="grub2-install"
- grubpost="grub2-mkconfig -o /boot/grub2/grub.cfg";;
- *)
- echo "Unknown rhel_ver [$bootver]"
- exit 1
- esac
- ;;
- *)
- echo "Unsupported OS: $bootid"; 1>&2
- exit 1
- ;;
- esac
- for d in "$@"; do
- echo $grubcmd "$d";
- $grubcmd "$d" || exit; done
- [ -z "$grubpost" ] || $grubpost;' \
- -- "${grub_name}" "${os_variant}" "${rhel_ver}" "${grubdevs[@]}" </dev/null ||
- { error "failed to install grub!"; return 1; }
- fi
-
- if [ -n "${mp_efi}" ]; then
- umount "$mp_efi" ||
- { error "failed to unmount $mp_efi"; return 1; }
- fi
-
- return
-}
-
# vi: ts=4 expandtab syntax=sh
diff --git a/helpers/install-grub b/helpers/install-grub
deleted file mode 100755
index e1bfb23..0000000
--- a/helpers/install-grub
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-# This file is part of curtin. See LICENSE file for copyright and license info.
-
-[ "${0%/*}" = "$0" ] && . ./common || . "${0%/*}/common"
-install_grub "$@"
-
-# vi: ts=4 expandtab syntax=sh
diff --git a/tests/vmtests/test_uefi_basic.py b/tests/vmtests/test_uefi_basic.py
index 90940dd..6438ba5 100644
--- a/tests/vmtests/test_uefi_basic.py
+++ b/tests/vmtests/test_uefi_basic.py
@@ -89,6 +89,10 @@ class PreciseHWETUefiTestBasic(relbase.precise_hwe_t, PreciseUefiTestBasic):
__test__ = False
+class TrustyHWEXUefiTestBasic(relbase.trusty_hwe_x, TestBasicAbs):
+ __test__ = False
+
+
class XenialGAUefiTestBasic(relbase.xenial_ga, TestBasicAbs):
__test__ = True
Follow ups