Streamline VM overlays and rootfs packages

Move the default guest package list into a repo manifest and record a hash beside built rootfs images so run/make-rootfs can warn when the docker-ready image is stale.

Switch the Firecracker launch path to a single sparse root overlay per VM instead of separate /home and /var disks, so many VMs can share the same base image while still installing packages under /var and working from /root.

Keep older images bootable by masking stale home.mount and var.mount units at boot, and scrub those obsolete fstab entries when customize.sh rebuilds an image. Verified with bash -n on the updated scripts; no live VM boot was run in this environment.
This commit is contained in:
Thales Maciel 2026-03-15 19:36:54 -03:00
parent 9191b7e370
commit 3cf33d1e0a
No known key found for this signature in database
GPG key ID: 33112E6833C34679
8 changed files with 206 additions and 204 deletions

View file

@ -31,6 +31,7 @@ parse_size() {
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$DIR/dns.sh"
source "$DIR/packages.sh"
STATE="$DIR/state"
VM_ROOT="$STATE/vms"
mkdir -p "$VM_ROOT"
@ -52,6 +53,7 @@ OUT_ROOTFS=""
SIZE_SPEC=""
INSTALL_DOCKER=0
MODULES_DIR="$DIR/wtf/root/lib/modules/6.8.0-94-generic"
PACKAGES_FILE="$(banger_packages_file)"
while [[ $# -gt 0 ]]; do
case "$1" in
--out)
@ -136,6 +138,25 @@ if ! command -v jq >/dev/null 2>&1; then
log "jq required"
exit 1
fi
if ! command -v sha256sum >/dev/null 2>&1; then
log "sha256sum required to record package manifest metadata"
exit 1
fi
if [[ ! -f "$PACKAGES_FILE" ]]; then
log "package manifest not found: $PACKAGES_FILE"
exit 1
fi
APT_PACKAGES=()
if ! banger_packages_read_array APT_PACKAGES "$PACKAGES_FILE"; then
log "package manifest is empty: $PACKAGES_FILE"
exit 1
fi
if ! PACKAGES_HASH="$(printf '%s\n' "${APT_PACKAGES[@]}" | banger_packages_hash_stream)"; then
log "failed to hash package manifest: $PACKAGES_FILE"
exit 1
fi
printf -v APT_PACKAGES_ESCAPED '%q ' "${APT_PACKAGES[@]}"
log "copying base rootfs to $OUT_ROOTFS"
cp --reflink=auto "$BASE_ROOTFS" "$OUT_ROOTFS"
@ -223,7 +244,7 @@ sudo -E curl --unix-socket "$API_SOCK" -X PUT http://localhost/machine-config \
"smt": false
}' >/dev/null
KCMD="console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw ip=${GUEST_IP}::${BR_IP}:255.255.255.0:${VM_NAME}:eth0:off:${DNS_SERVER} hostname=${VM_NAME}"
KCMD="console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw ip=${GUEST_IP}::${BR_IP}:255.255.255.0:${VM_NAME}:eth0:off:${DNS_SERVER} hostname=${VM_NAME} systemd.mask=home.mount systemd.mask=var.mount"
INITRD_JSON=""
if [[ -n "$INITRD" ]]; then
@ -286,13 +307,19 @@ log "enabling NAT for customization"
sudo -E ./nat.sh up "$VM_TAG" >/dev/null
log "waiting for SSH"
SSH_READY=0
for _ in $(seq 1 60); do
if ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
"root@${GUEST_IP}" "true" >/dev/null 2>&1; then
SSH_READY=1
break
fi
sleep 1
done
if [[ "$SSH_READY" -ne 1 ]]; then
log "ssh did not become ready on $GUEST_IP"
exit 1
fi
log "configuring guest"
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
@ -300,13 +327,8 @@ ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
printf 'nameserver %s\n' \"$DNS_SERVER\" > /etc/resolv.conf
echo \"$VM_NAME\" > /etc/hostname
printf '127.0.0.1 localhost\n127.0.1.1 %s\n' \"$VM_NAME\" > /etc/hosts
mkdir -p /home /var
if ! grep -q '^/dev/vdb ' /etc/fstab; then
echo '/dev/vdb /home ext4 defaults 0 2' >> /etc/fstab
fi
if ! grep -q '^/dev/vdc ' /etc/fstab; then
echo '/dev/vdc /var ext4 defaults 0 2' >> /etc/fstab
fi
touch /etc/fstab
sed -i '\|^/dev/vdb[[:space:]]\+/home[[:space:]]|d; \|^/dev/vdc[[:space:]]\+/var[[:space:]]|d' /etc/fstab
if ! grep -q '^tmpfs /run ' /etc/fstab; then
echo 'tmpfs /run tmpfs defaults,nodev,nosuid,mode=0755 0 0' >> /etc/fstab
fi
@ -315,7 +337,7 @@ if ! grep -q '^tmpfs /tmp ' /etc/fstab; then
fi
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
DEBIAN_FRONTEND=noninteractive apt-get -y install git less tree ca-certificates curl
DEBIAN_FRONTEND=noninteractive apt-get -y install ${APT_PACKAGES_ESCAPED}
if [[ \"$INSTALL_DOCKER\" == \"1\" ]]; then
DEBIAN_FRONTEND=noninteractive apt-get -y remove containerd || true
if ! DEBIAN_FRONTEND=noninteractive apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; then
@ -362,4 +384,5 @@ for _ in $(seq 1 200); do
fi
sleep 0.05
done
banger_write_rootfs_manifest_metadata "$OUT_ROOTFS" "$PACKAGES_HASH"
log "done"