os: build bootable images

This commit is contained in:
Alex Zenla
2024-03-10 00:22:24 +00:00
parent 817509bcef
commit 4894bd9d1c
28 changed files with 384 additions and 82 deletions

View File

@ -4,5 +4,10 @@ set -e
TOOLS_DIR="$(dirname "${0}")"
RUST_TARGET="$("${TOOLS_DIR}/target.sh")"
if [ "${RUST_LIBC}" = "musl" ] && [ -f "/etc/alpine-release" ]
then
export RUSTFLAGS="-Ctarget-feature=-crt-static"
fi
export CARGO_BUILD_TARGET="${RUST_TARGET}"
exec cargo "${@}"

View File

@ -5,3 +5,4 @@ REAL_SCRIPT="$(realpath "${0}")"
cd "$(dirname "${REAL_SCRIPT}")/../.."
find hack -type f -name '*.sh' -print0 | xargs -0 shellcheck -x
find os/internal -type f -name '*.sh' -print0 | xargs -0 shellcheck -x

25
hack/dist/apk.sh vendored Executable file
View File

@ -0,0 +1,25 @@
#!/bin/sh
set -e
# shellcheck source-path=SCRIPTDIR source=common.sh
. "$(dirname "${0}")/common.sh"
export RUST_LIBC="musl"
KRATA_SYSTAR_OPENRC=1 "${KRATA_DIR}/hack/dist/systar.sh"
KRATA_VERSION="$("${KRATA_DIR}/hack/dist/version.sh")"
TARGET_ARCH="$("${KRATA_DIR}/hack/build/arch.sh")"
cd "${OUTPUT_DIR}"
rm -f "krata_${KRATA_VERSION}_${TARGET_ARCH}.apk"
fpm -s tar -t apk \
--name krata \
--license agpl3 \
--version "${KRATA_VERSION}" \
--architecture "${TARGET_ARCH}" \
--description "Krata Hypervisor" \
--url "https://krata.dev" \
--maintainer "Edera Team <contact@edera.dev>" \
"${OUTPUT_DIR}/system-openrc.tgz"

4
hack/dist/bundle.sh vendored
View File

@ -9,7 +9,7 @@ then
KRATA_KERNEL_BUILD_JOBS="2"
fi
BUNDLE_TAR="${OUTPUT_DIR}/bundle.tgz"
BUNDLE_TAR="${OUTPUT_DIR}/bundle-systemd.tgz"
rm -f "${BUNDLE_TAR}"
BUNDLE_DIR="$(mktemp -d /tmp/krata-bundle.XXXXXXXXXXXXX)"
BUNDLE_DIR="${BUNDLE_DIR}/krata"
@ -21,7 +21,7 @@ do
cp "${KRATA_DIR}/target/${RUST_TARGET}/release/${X}" "${BUNDLE_DIR}/${X}"
done
./hack/initrd/build.sh
if [ "${KRATA_BUNDLE_SKIP_KERNEL_BUILD}" != "1" ]
if [ "${KRATA_KERNEL_BUILD_SKIP}" != "1" ]
then
./hack/kernel/build.sh "-j${KRATA_KERNEL_BUILD_JOBS}"
fi

2
hack/dist/deb.sh vendored
View File

@ -27,4 +27,4 @@ fpm -s tar -t deb \
--deb-systemd "${KRATA_DIR}/resources/systemd/kratanet.service" \
--deb-systemd-enable \
--deb-systemd-auto-start \
"${OUTPUT_DIR}/system.tgz"
"${OUTPUT_DIR}/system-systemd.tgz"

23
hack/dist/systar.sh vendored
View File

@ -6,11 +6,17 @@ set -e
"${KRATA_DIR}/hack/dist/bundle.sh"
SYSTAR="${OUTPUT_DIR}/system.tgz"
SYSTAR_VARIANT="systemd"
if [ "${KRATA_SYSTAR_OPENRC}" = "1" ]
then
SYSTAR_VARIANT="openrc"
fi
SYSTAR="${OUTPUT_DIR}/system-${SYSTAR_VARIANT}.tgz"
rm -f "${SYSTAR}"
SYSTAR_DIR="$(mktemp -d /tmp/krata-systar.XXXXXXXXXXXXX)"
cd "${SYSTAR_DIR}"
tar xf "${OUTPUT_DIR}/bundle.tgz"
tar xf "${OUTPUT_DIR}/bundle-systemd.tgz"
mkdir sys
cd sys
@ -19,8 +25,17 @@ mkdir -p usr/bin usr/libexec
mv ../krata/kratactl usr/bin
mv ../krata/kratanet ../krata/kratad usr/libexec/
mkdir -p usr/lib/systemd/system
mv ../krata/kratad.service ../krata/kratanet.service usr/lib/systemd/system/
if [ "${SYSTAR_VARIANT}" = "openrc" ]
then
mkdir -p etc/init.d
cp "${KRATA_DIR}/resources/openrc/kratad" etc/init.d/kratad
cp "${KRATA_DIR}/resources/openrc/kratanet" etc/init.d/kratanet
chmod +x etc/init.d/kratad
chmod +x etc/init.d/kratanet
else
mkdir -p usr/lib/systemd/system
mv ../krata/kratad.service ../krata/kratanet.service usr/lib/systemd/system/
fi
mkdir -p usr/share/krata/guest
mv ../krata/kernel ../krata/initrd usr/share/krata/guest

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/sh
set -e
REAL_SCRIPT="$(realpath "${0}")"
@ -16,5 +16,5 @@ cp "target/${RUST_TARGET}/release/krataguest" "${INITRD_DIR}/init"
chmod +x "${INITRD_DIR}/init"
cd "${INITRD_DIR}"
mkdir -p "${KRATA_DIR}/target/initrd"
find . | cpio -R 0:0 --reproducible -o -H newc --quiet > "${KRATA_DIR}/target/initrd/initrd"
find . | cpio -R 0:0 --ignore-devno --renumber-inodes -o -H newc --quiet > "${KRATA_DIR}/target/initrd/initrd"
rm -rf "${INITRD_DIR}"

View File

@ -12,6 +12,11 @@ cd "${KRATA_DIR}"
. "${KERNEL_DIR}/config.sh"
KERNEL_SRC="${KERNEL_DIR}/linux-${KERNEL_VERSION}"
if [ -z "${KRATA_KERNEL_BUILD_JOBS}" ]
then
KRATA_KERNEL_BUILD_JOBS="2"
fi
if [ ! -f "${KERNEL_SRC}/Makefile" ]
then
rm -rf "${KERNEL_SRC}"
@ -34,14 +39,14 @@ then
fi
cp "${KERNEL_CONFIG_FILE}" "${KERNEL_SRC}/.config"
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" olddefconfig
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" olddefconfig
if [ "${TARGET_ARCH}" = "x86_64" ]
then
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" bzImage
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" -j"${KRATA_KERNEL_BUILD_JOBS}" bzImage
elif [ "${TARGET_ARCH}" = "arm64" ]
then
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" Image.gz
make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" -j"${KRATA_KERNEL_BUILD_JOBS}" Image.gz
fi
if [ "${TARGET_ARCH}" = "x86_64" ]

95
hack/os/build.sh Executable file
View File

@ -0,0 +1,95 @@
#!/bin/sh
set -e
REAL_SCRIPT="$(realpath "${0}")"
cd "$(dirname "${REAL_SCRIPT}")/../.."
./hack/dist/apk.sh
KRATA_VERSION="$(./hack/dist/version.sh)"
TARGET_ARCH="$(./hack/build/arch.sh)"
TARGET_DIR="${PWD}/target"
TARGET_OS_DIR="${TARGET_DIR}/os"
mkdir -p "${TARGET_OS_DIR}"
cp "${TARGET_DIR}/dist/krata_${KRATA_VERSION}_${TARGET_ARCH}.apk" "${TARGET_OS_DIR}/krata.apk"
docker run --rm --privileged -v "${PWD}:/mnt" -it alpine:latest "/mnt/os/internal/stage1.sh"
sudo chown "${USER}:${GROUP}" "${TARGET_OS_DIR}/rootfs.tgz"
sudo modprobe nbd
NBD_DEVICE="$(find /dev -maxdepth 2 -name 'nbd[0-9]*' | while read -r DEVICE
do
if [ "$(sudo blockdev --getsize64 "${DEVICE}")" = "0" ]
then
echo "${DEVICE}"
break
fi
done)"
if [ -z "${NBD_DEVICE}" ]
then
echo "ERROR: unable to allocate nbd device" > /dev/stderr
exit 1
fi
OS_IMAGE="${TARGET_OS_DIR}/krata.qcow2"
EFI_PART="${NBD_DEVICE}p1"
ROOT_PART="${NBD_DEVICE}p2"
ROOT_DIR="${TARGET_OS_DIR}/root"
EFI_DIR="${ROOT_DIR}/boot/efi"
cleanup() {
trap '' EXIT HUP INT TERM
sudo umount -R "${ROOT_DIR}" > /dev/null 2>&1 || true
sudo umount "${EFI_PART}" > /dev/null 2>&1 || true
sudo umount "${ROOT_PART}" > /dev/null 2>&1 || true
sudo qemu-nbd --disconnect "${NBD_DEVICE}" > /dev/null 2>&1 || true
sudo rm -rf "${ROOT_DIR}"
}
rm -f "${OS_IMAGE}"
qemu-img create -f qcow2 "${TARGET_OS_DIR}/krata.qcow2" "2G"
trap cleanup EXIT HUP INT TERM
sudo qemu-nbd --connect="${NBD_DEVICE}" --cache=writeback -f qcow2 "${OS_IMAGE}"
printf '%s\n' \
'label: gpt' \
'name=efi,type=U,size=128M,bootable' \
'name=system,type=L' | sudo sfdisk "${NBD_DEVICE}"
sudo mkfs.fat -F32 -n EFI "${EFI_PART}"
sudo mkfs.ext4 -L root -E discard "${ROOT_PART}"
mkdir -p "${ROOT_DIR}"
sudo mount -t ext4 "${ROOT_PART}" "${ROOT_DIR}"
sudo mkdir -p "${EFI_DIR}"
sudo mount -t vfat "${EFI_PART}" "${EFI_DIR}"
sudo tar xf "${TARGET_OS_DIR}/rootfs.tar" -C "${ROOT_DIR}"
ROOT_UUID="$(sudo blkid "${ROOT_PART}" | sed -En 's/.*\bUUID="([^"]+)".*/\1/p')"
EFI_UUID="$(sudo blkid "${EFI_PART}" | sed -En 's/.*\bUUID="([^"]+)".*/\1/p')"
echo "${ROOT_UUID}"
sudo mkdir -p "${ROOT_DIR}/proc" "${ROOT_DIR}/dev" "${ROOT_DIR}/sys"
sudo mount -t proc none "${ROOT_DIR}/proc"
sudo mount --bind /dev "${ROOT_DIR}/dev"
sudo mount --make-private "${ROOT_DIR}/dev"
sudo mount --bind /sys "${ROOT_DIR}/sys"
sudo mount --make-private "${ROOT_DIR}/sys"
sudo cp "${PWD}/os/internal/stage2.sh" "${ROOT_DIR}/stage2.sh"
echo "${ROOT_UUID}" | sudo tee "${ROOT_DIR}/root-uuid" > /dev/null
sudo chroot "${ROOT_DIR}" /bin/sh -c "/stage2.sh"
sudo rm -f "${ROOT_DIR}/stage2.sh"
sudo rm -f "${ROOT_DIR}/root-uuid"
{
echo "# krata fstab"
echo "UUID=${ROOT_UUID} / ext4 relatime 0 1"
echo "UUID=${EFI_UUID} / vfat rw,relatime,fmask=0133,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2"
} | sudo tee "${ROOT_DIR}/etc/fstab" > /dev/null
cleanup
OS_SMALL_IMAGE="${TARGET_OS_DIR}/krata.small.qcow2"
qemu-img convert -O qcow2 "${OS_IMAGE}" "${OS_SMALL_IMAGE}"
mv -f "${OS_SMALL_IMAGE}" "${OS_IMAGE}"