mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-11-05 18:46:28 +00:00
a541ee312d
* feat(lambda): add the Lambda runtime image and guest agent
* fix(lambda): stop the guest agent after a timed-out invocation
* docs(lambda): declare the L-GUEST executor-to-agent contract
* refactor(vm): remove the unused virtio-serial port builder
Lambda guest control moves to TCP over the microVM's network, so no
caller needs SerialPorts. This reverts d7905107b.
* fix(lambda): drop the serial carrier from guest startup and keep virtio-net
run-agent no longer waits for a carrier device named on the kernel
command line, init loads virtio_net instead of virtio_console, and the
image keeps virtio_net's failover and net_failover dependencies. The
normal agent still refuses to start without an authenticated transport.
* feat(lambda): authenticate the guest's TCP control connection with pinned mutual TLS
hostlink loads the per-generation identity from fw_cfg and dials the host
over TLS 1.3 with ALPN spinifex-lambda-guest/1. VerifyPeer requires exactly
the pinned certificate, validates it, and checks its single URI SAN names
the expected scope and role. The L-GUEST contract now describes this
transport; message framing and fencing stay open, and the normal agent
still refuses to start.
* feat(lambda): add the host end of the guest's TCP mutual TLS connection
guestconn creates fresh host and guest identities for each environment
generation, produces the fw_cfg entries the guest reads, and accepts only
that generation's exact guest certificate. Peers on the untrusted bridge
that fail the handshake are closed and the listener keeps waiting until
its context ends; the cancel callback finishes before the deadline is
cleared so the listener can be reused.
The pinned-certificate check and the L-GUEST vocabulary move to
foundation/pki and contracts/lambda/v1 so both ends share them.
* docs(lambda): describe the shared connection vocabulary in the contract README
98 lines
3.6 KiB
Bash
Executable File
98 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# build-lambda-runtime-microvm-image.sh — build the Lambda runtime microVM kernel
|
|
# + initramfs: a guest running the Lambda guest agent, with virtio-net for its
|
|
# host control connection. It is not shipped.
|
|
#
|
|
# Inputs:
|
|
# $REPO_ROOT/build/microvm/lambda-runtime/{init.sh,inittab,run-agent}
|
|
# $REPO_ROOT/bin/lambda-agent (make bin/lambda-agent)
|
|
#
|
|
# Outputs:
|
|
# $REPO_ROOT/build/microvm/lambda-runtime/vmlinuz
|
|
# $REPO_ROOT/build/microvm/lambda-runtime/initramfs.cpio.gz
|
|
#
|
|
# Rootfs strategy and module stripping: scripts/lib/microvm-image.sh.
|
|
# shellcheck disable=SC2034 # variables are consumed by the sourced library
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
BUILD_DIR="$REPO_ROOT/build/microvm/lambda-runtime"
|
|
INIT_SH="$BUILD_DIR/init.sh"
|
|
INITTAB="$BUILD_DIR/inittab"
|
|
RUN_AGENT="$BUILD_DIR/run-agent"
|
|
LAMBDA_AGENT_BIN="$REPO_ROOT/bin/lambda-agent"
|
|
TAG="[build-lambda-runtime-microvm-image]"
|
|
|
|
ALPINE_VERSION="${ALPINE_VERSION:-3.24}"
|
|
ALPINE_MIRROR="${ALPINE_MIRROR:-https://dl-cdn.alpinelinux.org/alpine}"
|
|
# kmod: the image's own depmod/modprobe rebuild module metadata. busybox ships ip.
|
|
ALPINE_PACKAGES="busybox linux-virt kmod ca-certificates"
|
|
# tiny_power_button turns the ACPI power button into a signal busybox init
|
|
# handles as poweroff.
|
|
MICROVM_EXTRA_MODULES="${MICROVM_EXTRA_MODULES:-tiny_power_button}"
|
|
# virtio_net needs failover and net_failover, which the virtio* glob misses.
|
|
MICROVM_EXTRA_KEEP_GLOBS=("*failover*.ko*")
|
|
MICROVM_GATE_MODULES="qemu_fw_cfg virtio_net"
|
|
|
|
# shellcheck source=lib/microvm-image.sh
|
|
source "$REPO_ROOT/scripts/lib/microvm-image.sh"
|
|
|
|
echo "$TAG repo root: $REPO_ROOT"
|
|
echo "$TAG build dir: $BUILD_DIR"
|
|
|
|
microvm_check_tools
|
|
|
|
for f in "$INIT_SH" "$INITTAB" "$RUN_AGENT"; do
|
|
if [ ! -f "$f" ]; then
|
|
echo "ERROR: $f not found — cannot build initramfs" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
if [ ! -x "$LAMBDA_AGENT_BIN" ]; then
|
|
echo "ERROR: $LAMBDA_AGENT_BIN not found — run 'make bin/lambda-agent'" >&2
|
|
exit 1
|
|
fi
|
|
if ! file -b "$LAMBDA_AGENT_BIN" | grep -q "statically linked"; then
|
|
echo "ERROR: $LAMBDA_AGENT_BIN is not statically linked — it cannot run on the musl guest" >&2
|
|
exit 1
|
|
fi
|
|
|
|
microvm_init_dirs
|
|
microvm_make_rootfs
|
|
microvm_empty_dev
|
|
|
|
echo "$TAG installing init, inittab, run-agent and lambda-agent..."
|
|
install -m 0755 "$INIT_SH" "$CHROOT_DIR/init"
|
|
install -m 0644 "$INITTAB" "$CHROOT_DIR/etc/inittab"
|
|
mkdir -p "$CHROOT_DIR/usr/local/lib/lambda-runtime" "$CHROOT_DIR/usr/local/bin"
|
|
install -m 0755 "$RUN_AGENT" "$CHROOT_DIR/usr/local/lib/lambda-runtime/run-agent"
|
|
install -m 0755 "$LAMBDA_AGENT_BIN" "$CHROOT_DIR/usr/local/bin/lambda-agent"
|
|
# Function-code mountpoint and scratch space ship empty.
|
|
mkdir -p "$CHROOT_DIR/var/task" "$CHROOT_DIR/tmp" \
|
|
"$CHROOT_DIR/proc" "$CHROOT_DIR/sys" "$CHROOT_DIR/dev" "$CHROOT_DIR/etc/ssl/certs"
|
|
# The bootstrap runs unprivileged, so / must be traversable (mktemp -d makes it
|
|
# 0700) and nothing it runs from may be group-writable.
|
|
chmod 0755 "$CHROOT_DIR" "$CHROOT_DIR/var/task" "$CHROOT_DIR/usr/local/lib/lambda-runtime"
|
|
|
|
microvm_locate_kernel
|
|
microvm_strip_modules
|
|
microvm_strip_rootfs
|
|
microvm_stage_kernel
|
|
microvm_pack_initramfs
|
|
|
|
# Nothing reaches $BUILD_DIR until the staged pair passes these checks.
|
|
for out in vmlinuz initramfs.cpio.gz; do
|
|
if [ ! -s "$STAGE_DIR/$out" ]; then
|
|
echo "ERROR: staged $out is missing or empty" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
if ! gzip -t "$STAGE_DIR/initramfs.cpio.gz"; then
|
|
echo "ERROR: staged initramfs.cpio.gz is not valid gzip" >&2
|
|
exit 1
|
|
fi
|
|
mv -f "$STAGE_DIR/vmlinuz" "$BUILD_DIR/vmlinuz"
|
|
mv -f "$STAGE_DIR/initramfs.cpio.gz" "$BUILD_DIR/initramfs.cpio.gz"
|
|
echo ""
|
|
echo "$TAG done."
|