Skip to content

Commit d9d6655

Browse files
jschintagbgilbert
authored andcommitted
buildextend-metal: Add options for rhcos secex build pipeline
Allow customizing qemu arguments and add the option to execute genprotimg outside of cosa. Add the option to run a post script after disk creation. Background: To build RHCOS Secure Execution Images, we need to use a special hostkey, which we do not have direct access to. Therefore we need to execute extra steps in this case. Signed-off-by: Jan Schintag <[email protected]>
1 parent 6273af9 commit d9d6655

File tree

6 files changed

+208
-19
lines changed

6 files changed

+208
-19
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ install:
104104
cp -df -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler/ci $$(find ci/ -maxdepth 1 -type f)
105105
install -d $(DESTDIR)$(PREFIX)/lib/coreos-assembler/cosalib
106106
install -D -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler/cosalib $$(find src/cosalib/ -maxdepth 1 -type f)
107+
install -d $(DESTDIR)$(PREFIX)/lib/coreos-assembler/secex-genprotimgvm-scripts
108+
install -D -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler/secex-genprotimgvm-scripts $$(find src/secex-genprotimgvm-scripts/ -maxdepth 1 -type f)
107109
install -d $(DESTDIR)$(PREFIX)/bin
108110
install bin/coreos-assembler $(DESTDIR)$(PREFIX)/bin/
109111
ln -sf ../lib/coreos-assembler/cp-reflink $(DESTDIR)$(PREFIX)/bin/

src/cmd-buildextend-metal

+34-14
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ EOF
3535

3636
# Parse options
3737
hostkey=src/config/secex-hostkey
38+
genprotimgvm=
3839
rc=0
3940
build=
4041
force=
41-
options=$(getopt --options h --longoptions help,force,build:,hostkey: -- "$@") || rc=$?
42+
options=$(getopt --options h --longoptions help,force,build:,hostkey:,genprotimgvm: -- "$@") || rc=$?
4243
[ $rc -eq 0 ] || {
4344
print_help
4445
exit 1
@@ -58,8 +59,13 @@ while true; do
5859
shift
5960
;;
6061
--hostkey)
61-
hostkey="$2"
62-
shift;;
62+
hostkey=$(realpath "$2")
63+
shift
64+
;;
65+
--genprotimgvm)
66+
genprotimgvm="$2"
67+
shift
68+
;;
6369
--)
6470
shift
6571
break
@@ -88,15 +94,6 @@ esac
8894
if [[ "$basearch" != "s390x" && $image_type == dasd ]]; then
8995
fatal "$basearch is not supported for building dasd images"
9096
fi
91-
disk_args=()
92-
# SecureExecution extra stuff
93-
secex_hostkey_drive=()
94-
if [[ $secure_execution -eq "1" ]]; then
95-
hostkey=$(realpath "$hostkey")
96-
disk_args+=("--with-secure-execution")
97-
secex_hostkey_drive=("-drive" "if=none,id=hostkey,format=raw,file=$hostkey,readonly=on" \
98-
"-device" "virtio-blk,serial=hostkey,drive=hostkey")
99-
fi
10097

10198
# shellcheck disable=SC2031
10299
export LIBGUESTFS_BACKEND=direct
@@ -185,6 +182,23 @@ if [ "${rootfs_type}" = "ext4verity" ]; then
185182
BLKSIZE="$(getconf PAGE_SIZE)"
186183
fi
187184

185+
disk_args=()
186+
qemu_args=()
187+
# SecureExecution extra stuff
188+
if [[ $secure_execution -eq "1" ]]; then
189+
disk_args+=("--with-secure-execution")
190+
if [ -z "${genprotimgvm}" ]; then
191+
qemu_args+=("-drive" "if=none,id=hostkey,format=raw,file=$hostkey,readonly=on" \
192+
"-device" "virtio-blk,serial=hostkey,drive=hostkey")
193+
else
194+
genprotimg_img="${PWD}/secex-genprotimg.img"
195+
qemu-img create -f raw "${genprotimg_img}" 512M
196+
mkfs.ext4 "${genprotimg_img}"
197+
qemu_args+=("-drive" "if=none,id=genprotimg,format=raw,file=${genprotimg_img}" \
198+
"-device" "virtio-blk,serial=genprotimg,drive=genprotimg")
199+
fi
200+
fi
201+
188202
echo "Estimating disk size..."
189203
# The additional 35% here is obviously a hack, but we can't easily completely fill the filesystem,
190204
# and doing so has apparently negative performance implications.
@@ -223,7 +237,7 @@ extra_target_device_opts=""
223237
if [[ $image_type == dasd || $image_type == metal4k ]]; then
224238
extra_target_device_opts=",physical_block_size=4096,logical_block_size=4096"
225239
fi
226-
target_drive=("-drive" "if=none,id=target,format=${image_format},file=${path}.tmp,cache=unsafe" \
240+
qemu_args+=("-drive" "if=none,id=target,format=${image_format},file=${path}.tmp,cache=unsafe" \
227241
"-device" "virtio-blk,serial=target,drive=target${extra_target_device_opts}")
228242

229243
# Generate the JSON describing the disk we want to build
@@ -246,13 +260,19 @@ if [ -e "${configdir}/platforms.yaml" ]; then
246260
platforms_json="${workdir}/tmp/platforms.json"
247261
yaml2json "${configdir}/platforms.yaml" "${platforms_json}"
248262
fi
249-
runvm "${target_drive[@]}" "${secex_hostkey_drive[@]}" -- \
263+
runvm "${qemu_args[@]}" -- \
250264
/usr/lib/coreos-assembler/create_disk.sh \
251265
--config "$(pwd)"/image-for-disk.json \
252266
--kargs "\"${kargs}\"" \
253267
--platform "${ignition_platform_id}" \
254268
${platforms_json:+--platforms-json "${platforms_json}"} \
255269
"${disk_args[@]}"
270+
271+
if [[ $secure_execution -eq "1" && -n "${genprotimgvm}" ]]; then
272+
/usr/lib/coreos-assembler/secex-genprotimgvm-scripts/runvm.sh \
273+
--genprotimgvm "${genprotimgvm}" -- "${qemu_args[@]}"
274+
fi
275+
256276
/usr/lib/coreos-assembler/finalize-artifact "${path}.tmp" "${path}"
257277

258278
sha256=$(sha256sum_str < "${img}")

src/create_disk.sh

+50-5
Original file line numberDiff line numberDiff line change
@@ -544,16 +544,61 @@ create_dmverity() {
544544
mount -o ro "/dev/mapper/${partlabel}" "${mountpoint}"
545545
}
546546

547+
# Save genprotimg input for later and don't run zipl here
548+
rdcore_replacement() {
549+
local se_kargs_append se_initrd se_kernel se_parmfile
550+
local blsfile kernel initrd
551+
local se_script_dir se_tmp_disk se_tmp_mount se_tmp_boot
552+
553+
se_kargs_append=("ignition.firstboot")
554+
while [ $# -gt 0 ]; do
555+
se_kargs_append+=("$1")
556+
shift
557+
done
558+
559+
se_script_dir="/usr/lib/coreos-assembler/secex-genprotimgvm-scripts"
560+
se_tmp_disk=$(realpath /dev/disk/by-id/virtio-genprotimg)
561+
se_tmp_mount=$(mktemp -d /tmp/genprotimg-XXXXXX)
562+
se_tmp_boot="${se_tmp_mount}/genprotimg"
563+
mount "${se_tmp_disk}" "${se_tmp_mount}"
564+
mkdir "${se_tmp_boot}"
565+
566+
se_initrd="${se_tmp_boot}/initrd.img"
567+
se_kernel="${se_tmp_boot}/vmlinuz"
568+
se_parmfile="${se_tmp_boot}/parmfile"
569+
570+
blsfile=$(find "${rootfs}"/boot/loader/entries/*.conf)
571+
echo "$(grep options "${blsfile}" | cut -d' ' -f2-)" "${se_kargs_append[@]}" > "${se_parmfile}"
572+
kernel="${rootfs}/boot/$(grep linux "${blsfile}" | cut -d' ' -f2)"
573+
initrd="${rootfs}/boot/$(grep initrd "${blsfile}" | cut -d' ' -f2)"
574+
cp "${kernel}" "${se_kernel}"
575+
cp "${initrd}" "${se_initrd}"
576+
577+
# genprotimg and zipl will be done outside this script
578+
# copy scripts for that step to the tmp disk
579+
cp "${se_script_dir}/genprotimg-script.sh" "${se_script_dir}/post-script.sh" "${se_tmp_mount}/"
580+
581+
umount "${se_tmp_mount}"
582+
rmdir "${se_tmp_mount}"
583+
}
584+
547585
if [[ ${secure_execution} -eq 1 ]]; then
548586
# set up dm-verity for the rootfs and bootfs
549587
create_dmverity root $rootfs
550588
create_dmverity boot $rootfs/boot
551589

552-
# run zipl with root hashes as kargs
553-
rdcore_zipl_args+=("--secex-mode=enforce" "--hostkey=/dev/disk/by-id/virtio-hostkey")
554-
rdcore_zipl_args+=("--append-karg=rootfs.roothash=$(cat /tmp/root-roothash)")
555-
rdcore_zipl_args+=("--append-karg=bootfs.roothash=$(cat /tmp/boot-roothash)")
556-
chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}"
590+
# We need to run the genprotimg step in a separate step for rhcos release images
591+
if [ ! -e /dev/disk/by-id/virtio-genprotimg ]; then
592+
echo "Building local Secure Execution Image, running zipl and genprotimg"
593+
# run zipl with root hashes as kargs
594+
rdcore_zipl_args+=("--secex-mode=enforce" "--hostkey=/dev/disk/by-id/virtio-hostkey")
595+
rdcore_zipl_args+=("--append-karg=rootfs.roothash=$(cat /tmp/root-roothash)")
596+
rdcore_zipl_args+=("--append-karg=bootfs.roothash=$(cat /tmp/boot-roothash)")
597+
chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}"
598+
else
599+
echo "Building release Secure Execution Image, zipl and genprotimg will be run later"
600+
rdcore_replacement "rootfs.roothash=$(cat /tmp/root-roothash)" "bootfs.roothash=$(cat /tmp/boot-roothash)"
601+
fi
557602

558603
# unmount and close everything
559604
umount -R $rootfs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!bin/bash
2+
3+
set -exuo pipefail
4+
5+
echo "Preparing for genprotimg-daemon"
6+
7+
source="/build/genprotimg"
8+
destination="/genprotimg"
9+
10+
# Files need to be named correctly
11+
# genprotimg daemon can only see /genprotimg folder
12+
cp "${source}/vmlinuz" "${source}/initrd.img" "${source}/parmfile" "${destination}/"
13+
14+
# Signal daemon that it can run genprotimg
15+
touch "${destination}/signal.file"
16+
17+
# Wait for genprotimg execution
18+
while [ -e "$destination/signal.file" ] && [ ! -e "$destination/error" ]; do
19+
sleep 5
20+
done
21+
if [ -e "$destination/error" ] || [ ! -e "${destination}/se.img" ]; then
22+
ls -lha $destination
23+
echo "Failed to run genprotimg"
24+
exit 1
25+
fi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
set -exuo pipefail
4+
5+
echo "Moving sdboot and executing zipl"
6+
7+
workdir="/build"
8+
sdboot="/genprotimg/se.img"
9+
genprotimg_dir="${workdir}/genprotimg"
10+
se_boot=$(mktemp -d /tmp/se-XXXXXX)
11+
12+
disk=$(realpath /dev/disk/by-id/virtio-target)
13+
disk_se="${disk}1"
14+
15+
mount "${disk_se}" "${se_boot}"
16+
cp "${sdboot}" "${se_boot}/sdboot"
17+
zipl -V -i ${se_boot}/sdboot -t ${se_boot}
18+
19+
# Disable debug output, the last message should be success
20+
set +x
21+
echo "Success, added sdboot to image and executed zipl"
22+
23+
umount "${se_boot}"
24+
rm -rf "${se_boot}"
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
workdir="/srv"
6+
vmrundir="${workdir}/tmp/build.secex"
7+
memory_default=2048
8+
runvm_console="${vmrundir}/runvm-console.txt"
9+
genprotimgvm=
10+
qemu_args=()
11+
while true; do
12+
case "$1" in
13+
--genprotimgvm)
14+
genprotimgvm="$2"
15+
shift
16+
;;
17+
--)
18+
shift
19+
break
20+
;;
21+
-*)
22+
fatal "$0: unrecognized option: $1"
23+
exit 1
24+
;;
25+
*)
26+
break
27+
;;
28+
esac
29+
shift
30+
done
31+
if [ -z "${genprotimgvm}" ]; then
32+
echo "Missing option --genprotimgvm"
33+
fi
34+
while [ $# -gt 0 ]; do
35+
qemu_args+=("$1")
36+
shift
37+
done
38+
39+
set -x
40+
41+
[[ -d "${vmrundir}" ]] && rm -rf "${vmrundir}"
42+
mkdir "${vmrundir}"
43+
touch "${runvm_console}"
44+
45+
kola_args=(kola qemuexec -m "${COSA_SUPERMIN_MEMORY:-${memory_default}}" --auto-cpus -U --workdir none \
46+
--console-to-file "${runvm_console}")
47+
48+
base_qemu_args=(-drive "if=none,id=buildvm,format=qcow2,snapshot=on,file=${genprotimgvm},index=1" -device virtio-blk-ccw,drive=buildvm,bootindex=1 \
49+
-no-reboot -nodefaults -device virtio-serial \
50+
-device virtserialport,chardev=virtioserial0,name=cosa-cmdout -chardev stdio,id=virtioserial0
51+
)
52+
53+
if [ -z "${GENPROTIMGVM_SE_OFF:-}" ]; then
54+
base_qemu_args+=(-object s390-pv-guest,id=pv0 -machine confidential-guest-support=pv0)
55+
else
56+
echo "No secure execution enabled for build-VM, happy debugging"
57+
fi
58+
59+
if ! "${kola_args[@]}" -- "${base_qemu_args[@]}" \
60+
"${qemu_args[@]}" <&-; then # the <&- here closes stdin otherwise qemu waits forever
61+
cat "${runvm_console}"
62+
echo "Failed to run 'kola qemuexec'"
63+
exit 1
64+
fi
65+
66+
cat "${runvm_console}"
67+
68+
if ! grep -q "Success, added sdboot to image and executed zipl" "${runvm_console}"; then
69+
echo "Could not find success message, genprotimg failed."
70+
exit 1
71+
fi
72+
73+
exit 0

0 commit comments

Comments
 (0)