diff --git a/.github/actions/test/integration/build/action.yml b/.github/actions/test/integration/build/action.yml index b324d34e..eca53a32 100644 --- a/.github/actions/test/integration/build/action.yml +++ b/.github/actions/test/integration/build/action.yml @@ -99,14 +99,21 @@ runs: chmod 600 /opt/ssh_host_ed25519_key SSH_KEY=$(cat /opt/ssh_host_ed25519_key.pub) echo "SSH_KEY=$SSH_KEY" >> $GITHUB_ENV - sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane.yaml + cp ./.github/actions/test/integration/build/dev-user-butane.yaml ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + yq '.storage.files += load("./.github/actions/test/integration/build/root-hints.yaml")' ./.github/actions/test/integration/build/dev-user-butane.yaml > ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + + sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml PASSWORD=$(openssl passwd "password") echo "PASSWORD=$PASSWORD" >> $GITHUB_ENV - sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane.yaml - sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane.yaml + sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml - butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane.yaml > "/opt/${TAG}.ign" + butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml > "/opt/${TAG}-hv1.ign" + butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml > "/opt/${TAG}-hv2.ign" - name: Download ubuntu cloud image shell: bash diff --git a/.github/actions/test/integration/build/dev-user-butane.yaml b/.github/actions/test/integration/build/dev-user-butane.yaml index f7a331f1..9eb08a14 100644 --- a/.github/actions/test/integration/build/dev-user-butane.yaml +++ b/.github/actions/test/integration/build/dev-user-butane.yaml @@ -37,12 +37,6 @@ storage: # custom 192.168.122.2 hv1 192.168.122.3 hv2 - - path: /opt/persist/root-hints.yaml - mode: 0644 - contents: - inline: | - hints: - - size: lt 500G # turn off hugepages, not required for this test # also SIGNIFICANTLY reduces test runtime - path: /opt/persist/hugepages.env diff --git a/.github/actions/test/integration/build/root-hints.yaml b/.github/actions/test/integration/build/root-hints.yaml new file mode 100644 index 00000000..59159664 --- /dev/null +++ b/.github/actions/test/integration/build/root-hints.yaml @@ -0,0 +1,6 @@ +- path: /opt/persist/root-hints.yaml + mode: 0644 + contents: + inline: | + hints: + - size: lt 500G diff --git a/.github/actions/test/integration/setup/action.yml b/.github/actions/test/integration/setup/action.yml index 915b282b..1b8b1bea 100644 --- a/.github/actions/test/integration/setup/action.yml +++ b/.github/actions/test/integration/setup/action.yml @@ -15,7 +15,8 @@ runs: - name: Copy ignition file shell: bash run: | - sudo cp "/opt/${TAG}.ign" /var/lib/libvirt/images/hv.ign + sudo cp "/opt/${TAG}-hv1.ign" /var/lib/libvirt/images/HV1.ign + sudo cp "/opt/${TAG}-hv2.ign" /var/lib/libvirt/images/HV2.ign - name: Create HyperVisor 1 shell: bash diff --git a/.github/actions/test/integration/setup/hv.xml b/.github/actions/test/integration/setup/hv.xml index 90ab559f..63341fbf 100644 --- a/.github/actions/test/integration/setup/hv.xml +++ b/.github/actions/test/integration/setup/hv.xml @@ -32,6 +32,6 @@ - + diff --git a/features/_usi/initrd.include/usr/bin/detect_disk b/features/_usi/initrd.include/usr/bin/detect_disk index 0a8fb937..d061a300 100755 --- a/features/_usi/initrd.include/usr/bin/detect_disk +++ b/features/_usi/initrd.include/usr/bin/detect_disk @@ -4,10 +4,6 @@ set -Eeuo pipefail ROOT_HINTS_FILE="/sysroot/opt/persist/root-hints.yaml" -if ! [[ -f $ROOT_HINTS_FILE ]]; then - echo "no root-hints.yaml provided, error" - exit 1 -fi if kname=$(/usr/bin/root-hints $ROOT_HINTS_FILE); then echo "/dev/${kname}" else diff --git a/features/_usi/initrd.include/usr/bin/persist b/features/_usi/initrd.include/usr/bin/persist index 018dffcd..7a6ad93f 100755 --- a/features/_usi/initrd.include/usr/bin/persist +++ b/features/_usi/initrd.include/usr/bin/persist @@ -6,6 +6,11 @@ if ! disk_dev=$(/usr/bin/detect_disk); then exit 1 fi +if [[ ! -b "$disk_dev" ]]; then + echo "Device $disk_dev not found, exiting" + exit 1 +fi + # clean up the disk sgdisk -Z "$disk_dev" sgdisk -o "$disk_dev" diff --git a/features/_usi/initrd.include/usr/bin/root-hints b/features/_usi/initrd.include/usr/bin/root-hints index 5186752f..360bac06 100755 --- a/features/_usi/initrd.include/usr/bin/root-hints +++ b/features/_usi/initrd.include/usr/bin/root-hints @@ -2,12 +2,17 @@ set -Eeuo pipefail +# setup error trap +trap 'err "Error occurred at line $LINENO while executing: $BASH_COMMAND"' ERR + function yqroot() { cat "$1" | chroot /sysroot /usr/bin/yq -c '.hints | .[]' } function err() { echo "$@" 1>&2 + + lsblk -bOJ | jq } function filter() { @@ -27,25 +32,94 @@ function filter() { fi if [[ $val =~ ^[0-9]+[KMGT]+$ ]]; then val=$(echo "$val" | numfmt --from=iec) - echo "and ${col^^} $op ${val}" + echo "${col^^} $op ${val}" else - echo "and ${col^^} $op \"${val}\"" + echo "${col^^} $op \"${val}\"" fi +} +function blockdevicesize() { + local kname="$1" + lsblk -bOJ | jq --arg kname "$kname" -r '.blockdevices.[] | select(.kname == $kname).size' } +udevadm settle + yamlFile="$1" +esp_disk="" +if [ -e "/dev/disk/by-label/ESP" ]; then + esp_partition=$(basename "$(readlink -f /dev/disk/by-label/ESP)") + esp_disk=$(basename "$(readlink -f "/sys/class/block/$esp_partition/..")") +fi + +# TODO: likely go rather with device uuid or alike #if dev=$(yq -e .dev "$yamlFile" 2> /dev/null); then # echo "$dev" # exit 0 #fi -flsblk="TYPE eq \"disk\"" -while IFS= read -r r; do - f=$(filter "$r") - flsblk="$flsblk $f" -done < <(yqroot "$yamlFile" ) +declare -a flsblk=() +# check if yaml file exists and is valid, if so, use it to build the filter for lsblk +if [ -f "$yamlFile" ] && yq -e . "$yamlFile" >/dev/null 2>&1; then + while IFS= read -r r; do + flsblk+=("$(filter "$r")") + done < <(yqroot "$yamlFile") +fi + +LSBLK_JSON="" + +function join { + local SEPARATOR="$1" + shift + printf "%s${SEPARATOR}" "$@" | sed --unbuffered "s/${SEPARATOR}$//" +} + +# if flsblk contains elements, we join them by 'and' and use the filter with lsblk +if [ ${#flsblk[@]} -gt 0 ]; then + flsfilter=$(join " and " "${flsblk[@]}") + echo "Using filter: $flsfilter" 1>&2 + LSBLK_JSON=$(lsblk --sort size --exclude 1,2,3,4,7,11 --filter "$flsfilter" -OJ) +else + # no hints, hence we choose the smallest disk we find. we exclude ram disk, + # floppy, ide, dynamically allocated, loopback and scsi cd-rom devices + LSBLK_JSON=$(lsblk --sort size --exclude 1,2,3,4,7,11 -OJ) +fi -#echo "$flsblk" -lsblk --filter "$flsblk" --noheadings -o kname +# from the resulting list of disks we pick the first disk that are writeable +kname=$(echo "$LSBLK_JSON" | jq -r '[.blockdevices.[]|select(.type? == "disk" and .ro? == false)][0].kname // ""') + +# check which disk to use. +# 1. if kname is empty: +# * we check if we have an esp_disk, if so we use it +# * otherwise we fail +# 2. if kname is not empty: +# * we check if we have an esp_disk, if not we use +# * kname, otherwise we check if they are the same, if not we fail, otherwise we use kname/esp_disk +if [ -z "$kname" ]; then + if [ -z "$esp_disk" ]; then + err "No suitable disk found" + exit 1 + fi + echo "Warning: No suitable disk found, falling back to ESP disk ${esp_disk}" 1>&2 + echo "$esp_disk" +else + if [ -z "$esp_disk" ]; then + # no esp_disk using kname + echo "$kname" + exit 0 + fi + + if [ "$kname" != "$esp_disk" ]; then + # check if desvice size are the same + err "Error: Found disk ${kname} does not match ESP disk ${esp_disk}." 1>&2 + kname_size=$(blockdevicesize "$kname") + esp_disk_size=$(blockdevicesize "$esp_disk") + if [ "$kname_size" != "$esp_disk_size" ]; then + err "Error: Found disk ${kname} size ${kname_size} does not match ESP disk ${esp_disk} size ${esp_disk_size}." 1>&2 + exit 1 + fi + fi + # kname == esp_disk or esp_disk has similar size to kname + echo "$esp_disk" +fi