docker rootfs defaults
This commit is contained in:
parent
5f3d60ef0f
commit
93c3d1a67b
6498 changed files with 64929 additions and 14 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,3 +6,4 @@ state/
|
|||
*.squashfs*
|
||||
squashfs-root/
|
||||
rootfs*
|
||||
wtf/*.deb
|
||||
|
|
|
|||
46
README.md
46
README.md
|
|
@ -26,8 +26,9 @@ Minimal Firecracker launcher.
|
|||
- `--name`: must be unique and match `[a-z0-9][a-z0-9-]{0,63}`.
|
||||
- `--vcpu`: defaults to 2, max 16.
|
||||
- `--ram`: MiB, defaults to 1024, max 32768.
|
||||
- `--rootfs`: path to the base rootfs image (default: `./rootfs.ext4`).
|
||||
- `--kernel`: path to the kernel image (default: `./vmlinux`).
|
||||
- `--rootfs`: path to the rootfs image (default: `./rootfs-docker.ext4`).
|
||||
- `--kernel`: path to the kernel image (default: `./wtf/root/boot/vmlinux-6.8.0-94-generic`).
|
||||
- `--initrd`: path to the initrd image (default: `./wtf/root/boot/initrd.img-6.8.0-94-generic`).
|
||||
- `--home-size`: M/G suffixes supported (default: 2G).
|
||||
- `--var-size`: M/G suffixes supported (default: 2G).
|
||||
|
||||
|
|
@ -62,10 +63,45 @@ Check status with:
|
|||
reboot
|
||||
```
|
||||
|
||||
## Customize Rootfs (Docker + Kernel Modules)
|
||||
Use `customize.sh` to build a writable rootfs with Docker and kernel modules
|
||||
preloaded so Docker works out of the box.
|
||||
|
||||
```
|
||||
./customize.sh rootfs-docker.ext4 --size 6G --docker
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--size`: optional size for the output image.
|
||||
- `--kernel`: kernel path (default: `./wtf/root/boot/vmlinux-6.8.0-94-generic`).
|
||||
- `--initrd`: initrd path (default: `./wtf/root/boot/initrd.img-6.8.0-94-generic`).
|
||||
- `--modules`: kernel modules directory (default: `./wtf/root/lib/modules/6.8.0-94-generic`).
|
||||
- `--docker`: install Docker packages into the image.
|
||||
|
||||
After boot, enable NAT and validate Docker:
|
||||
```
|
||||
./nat.sh up <id-or-name-prefix>
|
||||
ssh -i "./id_ed25519" root@<guest_ip> "systemctl enable --now docker"
|
||||
ssh -i "./id_ed25519" root@<guest_ip> "docker run --rm hello-world"
|
||||
```
|
||||
|
||||
## Build Rootfs On Demand
|
||||
`run.sh` defaults to `./rootfs-docker.ext4`. If it is missing, `run.sh` will
|
||||
invoke `make-rootfs.sh` to build it.
|
||||
|
||||
```
|
||||
./make-rootfs.sh
|
||||
```
|
||||
|
||||
`make-rootfs.sh` chooses the first available base image:
|
||||
- `./rootfs.ext4`
|
||||
- `./ubuntu-noble-rootfs/rootfs.ext4`
|
||||
- `./ubuntu-lts/rootfs.ext4`
|
||||
|
||||
## VM Info File
|
||||
Each VM writes `state/vms/<id>/vm.json` with:
|
||||
- `meta`: local metadata (id, name, pid, created_at, guest_ip, tap, api_sock, log, rootfs, kernel, snapshot info).
|
||||
- `config`: full `/vm/config` response from Firecracker.
|
||||
Each VM writes:
|
||||
- `state/vms/<id>/vm.json`: raw `/vm/config` response from Firecracker.
|
||||
- `state/vms/<id>/meta.json`: local metadata (id, name, pid, created_at, guest_ip, tap, api_sock, log, rootfs, kernel, snapshot info).
|
||||
|
||||
## Log Notes
|
||||
- `PCI: Fatal: No config space access function found` and `MissingAddressRange` lines are expected with `pci=off` in `run.sh`.
|
||||
|
|
|
|||
89
customize.sh
89
customize.sh
|
|
@ -7,7 +7,7 @@ log() {
|
|||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: ./customize.sh <output-rootfs> [--size <size>]
|
||||
Usage: ./customize.sh <output-rootfs> [--size <size>] [--base-rootfs <path>] [--kernel <path>] [--initrd <path>] [--docker] [--modules <dir>]
|
||||
|
||||
Creates a copy of rootfs.ext4, optionally resizes it, boots a VM using the
|
||||
copy as a writable rootfs, then applies base configuration and packages.
|
||||
|
|
@ -37,7 +37,8 @@ mkdir -p "$VM_ROOT"
|
|||
BASE_ROOTFS="$DIR/rootfs.ext4"
|
||||
FC_BIN="$DIR/firecracker"
|
||||
|
||||
KERNEL="$DIR/vmlinux"
|
||||
KERNEL="$DIR/wtf/root/boot/vmlinux-6.8.0-94-generic"
|
||||
INITRD="$DIR/wtf/root/boot/initrd.img-6.8.0-94-generic"
|
||||
SSH_KEY="$DIR/id_ed25519"
|
||||
|
||||
BR_DEV="br-fc"
|
||||
|
|
@ -47,12 +48,34 @@ DNS_SERVER="1.1.1.1"
|
|||
|
||||
OUT_ROOTFS=""
|
||||
SIZE_SPEC=""
|
||||
INSTALL_DOCKER=0
|
||||
MODULES_DIR="$DIR/wtf/root/lib/modules/6.8.0-94-generic"
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--size)
|
||||
SIZE_SPEC="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--base-rootfs)
|
||||
BASE_ROOTFS="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--kernel)
|
||||
KERNEL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--initrd)
|
||||
INITRD="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--docker)
|
||||
INSTALL_DOCKER=1
|
||||
shift
|
||||
;;
|
||||
--modules)
|
||||
MODULES_DIR="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
|
|
@ -79,6 +102,18 @@ if [[ ! -f "$BASE_ROOTFS" ]]; then
|
|||
log "base rootfs not found: $BASE_ROOTFS"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$KERNEL" ]]; then
|
||||
log "kernel not found: $KERNEL"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$INITRD" && ! -f "$INITRD" ]]; then
|
||||
log "initrd not found: $INITRD"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$MODULES_DIR" && ! -d "$MODULES_DIR" ]]; then
|
||||
log "modules dir not found: $MODULES_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -e "$OUT_ROOTFS" ]]; then
|
||||
log "output rootfs already exists: $OUT_ROOTFS"
|
||||
|
|
@ -197,11 +232,16 @@ sudo -E curl --unix-socket "$API_SOCK" -X PUT http://localhost/machine-config \
|
|||
|
||||
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}"
|
||||
|
||||
INITRD_JSON=""
|
||||
if [[ -n "$INITRD" ]]; then
|
||||
INITRD_JSON=", \"initrd_path\": \"$INITRD\""
|
||||
fi
|
||||
|
||||
sudo -E curl --unix-socket "$API_SOCK" -X PUT http://localhost/boot-source \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"kernel_image_path\": \"$KERNEL\",
|
||||
\"boot_args\": \"$KCMD\"
|
||||
\"boot_args\": \"$KCMD\"${INITRD_JSON}
|
||||
}" >/dev/null
|
||||
|
||||
sudo -E curl --unix-socket "$API_SOCK" -X PUT http://localhost/drives/rootfs \
|
||||
|
|
@ -258,13 +298,50 @@ fi
|
|||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -y install git less tree ca-certificates curl
|
||||
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
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -y install docker.io
|
||||
fi
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl enable --now docker || true
|
||||
fi
|
||||
fi
|
||||
git config --system init.defaultBranch main
|
||||
"
|
||||
|
||||
log "customization complete; shutting down"
|
||||
if [[ -n "$MODULES_DIR" ]]; then
|
||||
MODULES_BASE="$(basename "$MODULES_DIR")"
|
||||
log "copying kernel modules ($MODULES_BASE) into guest"
|
||||
tar -C "$(dirname "$MODULES_DIR")" -cf - "$MODULES_BASE" | \
|
||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
"root@${GUEST_IP}" bash -lc "set -e
|
||||
mkdir -p /lib/modules
|
||||
tar -C /lib/modules -xf -
|
||||
depmod -a \"$MODULES_BASE\"
|
||||
mkdir -p /etc/modules-load.d
|
||||
printf 'nf_tables\nnft_chain_nat\nveth\nbr_netfilter\noverlay\n' > /etc/modules-load.d/docker-netfilter.conf
|
||||
mkdir -p /etc/sysctl.d
|
||||
cat > /etc/sysctl.d/99-docker.conf <<'SYSCTL'
|
||||
net.bridge.bridge-nf-call-iptables = 1
|
||||
net.bridge.bridge-nf-call-ip6tables = 1
|
||||
net.ipv4.ip_forward = 1
|
||||
SYSCTL
|
||||
sysctl --system >/dev/null 2>&1 || true
|
||||
sync
|
||||
"
|
||||
fi
|
||||
|
||||
log "shutting down guest"
|
||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
"root@${GUEST_IP}" bash -lc "sync" || true
|
||||
sudo -E curl --unix-socket "$API_SOCK" -X PUT http://localhost/actions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "action_type": "SendCtrlAltDel" }' >/dev/null || true
|
||||
|
||||
sleep 2
|
||||
for _ in $(seq 1 200); do
|
||||
if ! ps -p "$FC_PID" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.05
|
||||
done
|
||||
log "done"
|
||||
|
|
|
|||
69
make-rootfs.sh
Normal file
69
make-rootfs.sh
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
log() {
|
||||
printf '[make-rootfs] %s\n' "$*"
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: ./make-rootfs.sh [--size <size>] [--base-rootfs <path>]
|
||||
|
||||
Builds rootfs-docker.ext4 using customize.sh. If --base-rootfs is omitted,
|
||||
the first existing file is used:
|
||||
./rootfs.ext4
|
||||
./ubuntu-noble-rootfs/rootfs.ext4
|
||||
./ubuntu-lts/rootfs.ext4
|
||||
EOF
|
||||
}
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
OUT_ROOTFS="$DIR/rootfs-docker.ext4"
|
||||
SIZE_SPEC="6G"
|
||||
BASE_ROOTFS=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--size)
|
||||
SIZE_SPEC="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--base-rootfs)
|
||||
BASE_ROOTFS="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log "unknown option: $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -f "$OUT_ROOTFS" ]]; then
|
||||
log "already exists: $OUT_ROOTFS"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z "$BASE_ROOTFS" ]]; then
|
||||
if [[ -f "$DIR/rootfs.ext4" ]]; then
|
||||
BASE_ROOTFS="$DIR/rootfs.ext4"
|
||||
elif [[ -f "$DIR/ubuntu-noble-rootfs/rootfs.ext4" ]]; then
|
||||
BASE_ROOTFS="$DIR/ubuntu-noble-rootfs/rootfs.ext4"
|
||||
elif [[ -f "$DIR/ubuntu-lts/rootfs.ext4" ]]; then
|
||||
BASE_ROOTFS="$DIR/ubuntu-lts/rootfs.ext4"
|
||||
else
|
||||
log "no base rootfs found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log "building $OUT_ROOTFS from $BASE_ROOTFS"
|
||||
exec "$DIR/customize.sh" "$OUT_ROOTFS" \
|
||||
--size "$SIZE_SPEC" \
|
||||
--base-rootfs "$BASE_ROOTFS" \
|
||||
--docker
|
||||
28
run.sh
28
run.sh
|
|
@ -15,6 +15,7 @@ Options:
|
|||
--ram <mib> RAM in MiB (default: 1024)
|
||||
--rootfs <path> Root filesystem image (default: ./rootfs.ext4)
|
||||
--kernel <path> Kernel image (default: ./vmlinux)
|
||||
--initrd <path> Initrd image (optional)
|
||||
--home-size <size> Home disk size (e.g. 4G, 10240M)
|
||||
--var-size <size> Var disk size (e.g. 4G, 10240M)
|
||||
-h, --help Show this help
|
||||
|
|
@ -29,8 +30,9 @@ VM_ROOT="$STATE/vms"
|
|||
mkdir -p "$VM_ROOT"
|
||||
|
||||
FC_BIN="$DIR/firecracker"
|
||||
DEFAULT_KERNEL="$DIR/vmlinux"
|
||||
DEFAULT_ROOTFS="$DIR/rootfs.ext4"
|
||||
DEFAULT_KERNEL="$DIR/wtf/root/boot/vmlinux-6.8.0-94-generic"
|
||||
DEFAULT_ROOTFS="$DIR/rootfs-docker.ext4"
|
||||
DEFAULT_INITRD="$DIR/wtf/root/boot/initrd.img-6.8.0-94-generic"
|
||||
SSH_KEY="$DIR/id_ed25519"
|
||||
NAMEGEN="$DIR/namegen"
|
||||
|
||||
|
|
@ -56,6 +58,7 @@ HOME_SIZE="$DEFAULT_HOME_SIZE"
|
|||
VAR_SIZE="$DEFAULT_VAR_SIZE"
|
||||
KERNEL="$DEFAULT_KERNEL"
|
||||
ROOTFS="$DEFAULT_ROOTFS"
|
||||
INITRD="$DEFAULT_INITRD"
|
||||
VM_NAME=""
|
||||
|
||||
shopt -s nullglob
|
||||
|
|
@ -109,6 +112,10 @@ while [[ $# -gt 0 ]]; do
|
|||
KERNEL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--initrd)
|
||||
INITRD="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--home-size)
|
||||
HOME_SIZE="${2:-}"
|
||||
shift 2
|
||||
|
|
@ -189,6 +196,12 @@ if ! [[ "$VM_NAME" =~ ^[a-z0-9][a-z0-9-]{0,63}$ ]]; then
|
|||
log "invalid --name value: $VM_NAME"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$ROOTFS" ]]; then
|
||||
if [[ "$ROOTFS" == "$DEFAULT_ROOTFS" && -x "$DIR/make-rootfs.sh" ]]; then
|
||||
log "rootfs missing; building via make-rootfs.sh"
|
||||
"$DIR/make-rootfs.sh"
|
||||
fi
|
||||
fi
|
||||
if [[ ! -f "$ROOTFS" ]]; then
|
||||
log "rootfs not found: $ROOTFS"
|
||||
exit 1
|
||||
|
|
@ -197,6 +210,10 @@ if [[ ! -f "$KERNEL" ]]; then
|
|||
log "kernel not found: $KERNEL"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$INITRD" && ! -f "$INITRD" ]]; then
|
||||
log "initrd not found: $INITRD"
|
||||
exit 1
|
||||
fi
|
||||
if name_taken "$VM_NAME"; then
|
||||
log "name already in use: $VM_NAME"
|
||||
exit 1
|
||||
|
|
@ -418,11 +435,16 @@ log "configuring machine"
|
|||
log "configuring boot source"
|
||||
KCMD="console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw ip=${GUEST_IP}::${BR_IP}:255.255.255.0::eth0:off:${DNS_SERVER} hostname=${VM_NAME}"
|
||||
|
||||
INITRD_JSON=""
|
||||
if [[ -n "$INITRD" ]]; then
|
||||
INITRD_JSON=", \"initrd_path\": \"$INITRD\""
|
||||
fi
|
||||
|
||||
"${CURL_CMD[@]}" --unix-socket "$API_SOCK" -X PUT http://localhost/boot-source \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"kernel_image_path\": \"$KERNEL\",
|
||||
\"boot_args\": \"$KCMD\"
|
||||
\"boot_args\": \"$KCMD\"${INITRD_JSON}
|
||||
}" >/dev/null
|
||||
|
||||
# Root filesystem
|
||||
|
|
|
|||
BIN
wtf/root/boot/initrd.img-6.8.0-94-generic
Normal file
BIN
wtf/root/boot/initrd.img-6.8.0-94-generic
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/block/bfq.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/block/bfq.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/842.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/842.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/ccm.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/ccm.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/cmac.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/cmac.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/ecc.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/ecc.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/essiv.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/essiv.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/hctr2.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/hctr2.ko.zst
Normal file
Binary file not shown.
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/lrw.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/lrw.ko.zst
Normal file
Binary file not shown.
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/lz4.ko.zst
Normal file
BIN
wtf/root/lib/modules/6.8.0-94-generic/kernel/crypto/lz4.ko.zst
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue