image: initrd layer

This commit is contained in:
Malte Poll 2023-09-11 15:52:05 +02:00 committed by Malte Poll
parent d904766b9c
commit 4ef3d10be3
14 changed files with 375 additions and 0 deletions

25
image/initrd/BUILD.bazel Normal file
View File

@ -0,0 +1,25 @@
load("//bazel/mkosi:mkosi_image.bzl", "mkosi_image")
mkosi_image(
name = "initrd",
srcs = [
"mkosi.postinst",
] + glob([
"mkosi.skeleton/**",
"reposdir/**",
]),
outs = [
"image",
"image.cpio.zst",
],
extra_trees = [
"//image:sysroot_tar",
"//disk-mapper/cmd:disk-mapper-package.tar",
],
mkosi_conf = "mkosi.conf",
tags = [
"manual",
"no-cache",
],
visibility = ["//visibility:public"],
)

43
image/initrd/mkosi.conf Normal file
View File

@ -0,0 +1,43 @@
[Distribution]
Distribution=fedora
Release=38
[Output]
Format=cpio
Output=image
SourceDateEpoch=0
[Content]
MakeInitrd=yes
Bootable=no
Packages=systemd
systemd-networkd
systemd-resolved
systemd-udev
dbus
util-linux
gzip
kmod
tpm2-tools
curl # for azure provision service
# nvme / disk / udev tools
Packages=udev
nvme-cli
ec2-utils
WALinuxAgent-udev
xxd
google-compute-engine-guest-configs-udev # google_nvme_id
device-mapper
cryptsetup
PackageManagerTrees=reposdir:/etc/yum.repos.d
RemoveFiles=/var/log
RemoveFiles=/var/cache
RemoveFiles=/etc/pki/ca-trust/extracted/java/cacerts
/usr/lib/sysimage/libdnf5/transaction_history.sqlite*
/var/cache/ldconfig/aux-cache
# https://github.com/authselect/authselect/pull/348
# RemoveFiles=/etc/authselect/*
CleanPackageMetadata=true
Seed=b04a9a33-4559-4af4-8b38-9249cf933229

16
image/initrd/mkosi.postinst Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euxo pipefail
# ensure google_nvme_id is executable
chmod o+x "${BUILDROOT}/usr/lib/udev/google_nvme_id"
chmod g+x "${BUILDROOT}/usr/lib/udev/google_nvme_id"
chmod u+x "${BUILDROOT}/usr/lib/udev/google_nvme_id"
# mask unwanted services
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrmachine.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrfs-root.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrfs@.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrphase@.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrphase-initrd.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrphase-sysinit.service"
ln -s /dev/null "${BUILDROOT}/etc/systemd/system/systemd-pcrphase.service"

View File

@ -0,0 +1,13 @@
enable prepare-state-disk.service
enable aws-nvme-disk.service
enable gcp-nvme-disk.service
enable azure-provisioning.service
enable dbus.service
enable dbus-broker.service
enable dbus-daemon.service
enable systemd-timesyncd.service
enable systemd-resolved.service
enable systemd-networkd.service
enable systemd-networkd-wait-online.service
enable systemd-udev.service
enable configure-constel-csp.service

View File

@ -0,0 +1,18 @@
[Unit]
Description=Force symlink creation for AWS nvme disks
Before=prepare-state-disk.service
After=network-online.target
Wants=network-online.target
ConditionKernelCommandLine=constel.csp=aws
[Service]
Type=oneshot
ExecStart=/bin/bash /usr/sbin/aws-nvme-disk
RemainAfterExit=yes
StandardOutput=tty
StandardInput=tty
StandardError=tty
TimeoutSec=infinity
[Install]
WantedBy=basic.target multi-user.target

View File

@ -0,0 +1,16 @@
[Unit]
Description=Azure Provisioning
After=network-online.target
Wants=network-online.target
ConditionKernelCommandLine=constel.csp=azure
[Service]
Type=oneshot
ExecStart=/usr/local/bin/azure-provisioning
RemainAfterExit=yes
StandardOutput=tty
StandardInput=tty
StandardError=tty
[Install]
WantedBy=basic.target multi-user.target

View File

@ -0,0 +1,18 @@
[Unit]
Description=Force symlink creation for GCP nvme disks
Before=prepare-state-disk.service
After=network-online.target
Wants=network-online.target
ConditionKernelCommandLine=constel.csp=gcp
[Service]
Type=oneshot
ExecStart=/bin/bash /usr/sbin/gcp-nvme-disk
RemainAfterExit=yes
StandardOutput=tty
StandardInput=tty
StandardError=tty
TimeoutSec=infinity
[Install]
WantedBy=basic.target multi-user.target

View File

@ -0,0 +1,21 @@
[Unit]
Description=Prepare encrypted state disk
Before=initrd-fs.target
After=network-online.target nss-lookup.target configure-constel-csp.service
After=export_constellation_debug.service
Wants=network-online.target
Requires=initrd-root-fs.target configure-constel-csp.service
FailureAction=reboot-immediate
[Service]
Type=oneshot
EnvironmentFile=/run/constellation.env
ExecStart=/bin/bash /usr/sbin/prepare-state-disk $CONSTELLATION_DEBUG_FLAGS
RemainAfterExit=yes
StandardOutput=tty
StandardInput=tty
StandardError=tty
TimeoutSec=infinity
[Install]
WantedBy=basic.target

View File

@ -0,0 +1,2 @@
[Install]
WantedBy=initrd.target

View File

@ -0,0 +1,64 @@
#!/usr/bin/env bash
# source https://learn.microsoft.com/en-us/azure/virtual-machines/linux/no-agent
set -euo pipefail
shopt -s inherit_errexit
attempts=1
until [[ ${attempts} -gt 5 ]]; do
echo "obtaining goal state - attempt ${attempts}"
goalstate=$(curl --fail -v -X 'GET' -H "x-ms-agent-name: azure-vm-register" \
-H "Content-Type: text/xml;charset=utf-8" \
-H "x-ms-version: 2012-11-30" \
"http://168.63.129.16/machine/?comp=goalstate")
if [[ $? -eq 0 ]]; then
echo "successfully retrieved goal state"
retrieved_goal_state=true
break
fi
sleep 5
attempts=$((attempts + 1))
done
if [[ ${retrieved_goal_state} != "true" ]]; then
echo "failed to obtain goal state - cannot register this VM"
exit 1
fi
container_id=$(grep ContainerId <<< "${goalstate}" | sed 's/\s*<\/*ContainerId>//g' | sed 's/\r$//')
instance_id=$(grep InstanceId <<< "${goalstate}" | sed 's/\s*<\/*InstanceId>//g' | sed 's/\r$//')
ready_doc=$(
cat << EOF
<?xml version="1.0" encoding="utf-8"?>
<Health xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GoalStateIncarnation>1</GoalStateIncarnation>
<Container>
<ContainerId>${container_id}</ContainerId>
<RoleInstanceList>
<Role>
<InstanceId>${instance_id}</InstanceId>
<Health>
<State>Ready</State>
</Health>
</Role>
</RoleInstanceList>
</Container>
</Health>
EOF
)
attempts=1
until [[ ${attempts} -gt 5 ]]; do
echo "registering with Azure - attempt ${attempts}"
curl --fail -v -X 'POST' -H "x-ms-agent-name: azure-vm-register" \
-H "Content-Type: text/xml;charset=utf-8" \
-H "x-ms-version: 2012-11-30" \
-d "${ready_doc}" \
"http://168.63.129.16/machine?comp=health"
if [[ $? -eq 0 ]]; then
echo "successfully register with Azure"
break
fi
sleep 5 # sleep to prevent throttling from wire server
done

View File

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Copyright (c) Edgeless Systems GmbH
#
# SPDX-License-Identifier: AGPL-3.0-only
set -euo pipefail
shopt -s extglob nullglob inherit_errexit
AWS_STATE_DISK_DEVICENAME="sdb"
AWS_STATE_DISK_SYMLINK="/dev/${AWS_STATE_DISK_DEVICENAME}"
function onError {
echo "Failed to symlink state disk"
sleep 2 # give the serial console time to print the error message
}
trap onError ERR
# hack: aws nvme udev rules are never executed. Create symlinks for the nvme devices manually.
while [[ ! -L ${AWS_STATE_DISK_SYMLINK} ]]; do
for nvmedisk in /dev/nvme*n1; do
linkname=$(nvme amzn id-ctrl -b "${nvmedisk}" | tail -c +3073 | head -c 32 | tr -d ' ') || true
if [[ -n ${linkname} ]] && [[ ${linkname} == "${AWS_STATE_DISK_DEVICENAME}" ]]; then
ln -s "${nvmedisk}" "${AWS_STATE_DISK_SYMLINK}"
fi
done
if [[ -L ${AWS_STATE_DISK_SYMLINK} ]]; then
break
fi
echo "Waiting for state disk to appear.."
sleep 2
done
echo "AWS state disk found"
echo "${AWS_STATE_DISK_SYMLINK}" → "$(readlink -f "${AWS_STATE_DISK_SYMLINK}")"

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Copyright (c) Edgeless Systems GmbH
#
# SPDX-License-Identifier: AGPL-3.0-only
set -euo pipefail
shopt -s extglob nullglob inherit_errexit
GCP_STATE_DISK_SYMLINK="/dev/disk/by-id/google-state-disk"
function onError {
echo "Failed to symlink state disk"
sleep 2 # give the serial console time to print the error message
}
trap onError ERR
# hack: gcp nvme udev rules are never executed. Create symlinks for the nvme devices manually.
while [[ ! -L ${GCP_STATE_DISK_SYMLINK} ]]; do
for nvmedisk in /dev/nvme?n?; do
/usr/lib/udev/google_nvme_id -s -d "${nvmedisk}"
done
if [[ -L ${GCP_STATE_DISK_SYMLINK} ]]; then
break
fi
echo "Waiting for state disk to appear.."
sleep 2
done
echo "GCP state disk found"
echo "${GCP_STATE_DISK_SYMLINK}" → "$(readlink -f "${GCP_STATE_DISK_SYMLINK}")"

View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Copyright (c) Edgeless Systems GmbH
#
# SPDX-License-Identifier: AGPL-3.0-only
set -euo pipefail
shopt -s inherit_errexit
function onError {
echo "Failed to prepare state disk"
sleep 2 # give the serial console time to print the error message
}
trap onError ERR
# parsing of the command line arguments. check if argv[1] is --debug
verbosity=0
if [[ $# -gt 0 ]]; then
if [[ $1 == "--debug" ]]; then
verbosity=-1
echo "[Constellation] Debug mode enabled"
else
echo "[Constellation] Unknown argument: $1"
exit 1
fi
else
echo "[Constellation] Debug mode disabled"
fi
# Prepare the encrypted volume by either initializing it with a random key or by aquiring the key from another bootstrapper.
# Store encryption key (random or recovered key) in /run/cryptsetup-keys.d/state.key
disk-mapper \
-csp "${CONSTEL_CSP}" \
-v "${verbosity}"

View File

@ -0,0 +1,39 @@
[amzn2-core]
name=Amazon Linux 2 core repository
#mirrorlist=$awsproto://$amazonlinux.$awsregion.$awsdomain/$releasever/$product/$target/$basearch/mirror.list
mirrorlist=https://amazonlinux-2-repos-us-east-2.s3.dualstack.us-east-2.amazonaws.com/2/core/latest/x86_64/mirror.list
priority=10
gpgcheck=1
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
gpgkey=https://cdn.amazonlinux.com/_assets/11CF1F95C87F5B1A.asc
enabled=1
metadata_expire=300
mirrorlist_expire=300
report_instanceid=yes
includepkgs=ec2-utils
# [amzn2-core-source]
# name=Amazon Linux 2 core repository - source packages
# mirrorlist=$awsproto://$amazonlinux.$awsregion.$awsdomain/$releasever/$product/$target/SRPMS/mirror.list
# priority=10
# gpgcheck=1
# #gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
# gpgkey=https://cdn.amazonlinux.com/_assets/11CF1F95C87F5B1A.asc
# enabled=0
# metadata_expire=300
# mirrorlist_expire=300
# report_instanceid=yes
# includepkgs=ec2-utils
# [amzn2-core-debuginfo]
# name=Amazon Linux 2 core repository - debuginfo packages
# mirrorlist=$awsproto://$amazonlinux.$awsregion.$awsdomain/$releasever/$product/$target/debuginfo/$basearch/mirror.list
# priority=10
# gpgcheck=1
# #gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
# gpgkey=https://cdn.amazonlinux.com/_assets/11CF1F95C87F5B1A.asc
# enabled=0
# metadata_expire=300
# mirrorlist_expire=300
# report_instanceid=yes
# includepkgs=ec2-utils