Skip to content

Commit 88e7892

Browse files
committed
pure script
1 parent 1ff9287 commit 88e7892

6 files changed

Lines changed: 44 additions & 21 deletions

File tree

os-image/start.sh

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
#!/bin/bash
22
set -e
33

4+
# UUID v5 (RFC 4122, SHA-1 based): deterministic UUID from NAMESPACE_URL + name.
5+
# Pure bash + sha1sum — no Python required.
6+
uuid_v5() {
7+
local hash
8+
hash=$( { printf '\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8'
9+
printf '%s' "$1"; } | sha1sum | cut -c1-32 )
10+
local vb; vb=$(printf '%02x' "$(( (16#${hash:16:2} & 0x3f) | 0x80 ))")
11+
printf '%s-%s-5%s-%s%s-%s\n' \
12+
"${hash:0:8}" "${hash:8:4}" "${hash:13:3}" \
13+
"$vb" "${hash:18:2}" "${hash:20:12}"
14+
}
15+
416
echo "=== Cocoon MicroVM Engine: Bootstrapping (Multi-Layer OCI) ==="
517

618
# 0. Check KVM
@@ -10,7 +22,18 @@ if [ ! -w "/dev/kvm" ]; then
1022
fi
1123
ARCH=$(uname -m)
1224

13-
# 1. Download Cloud Hypervisor
25+
# 1. Install dependencies
26+
_MISSING=""
27+
command -v jq >/dev/null 2>&1 || _MISSING="$_MISSING jq"
28+
command -v mkfs.erofs >/dev/null 2>&1 || _MISSING="$_MISSING erofs-utils"
29+
command -v mkfs.ext4 >/dev/null 2>&1 || _MISSING="$_MISSING e2fsprogs"
30+
command -v wget >/dev/null 2>&1 || _MISSING="$_MISSING wget"
31+
if [ -n "$_MISSING" ]; then
32+
echo "[1/7] Installing missing dependencies:$_MISSING"
33+
sudo apt-get install -y -qq $_MISSING
34+
fi
35+
36+
# 2. Download Cloud Hypervisor
1437
CH_VERSION="v51.0"
1538
CH_BIN="./cloud-hypervisor"
1639
if [ ! -x "$CH_BIN" ]; then
@@ -20,9 +43,9 @@ if [ ! -x "$CH_BIN" ]; then
2043
fi
2144
sudo setcap cap_net_admin+ep "$CH_BIN"
2245

23-
# 2. Extract Layers via Crane
46+
# 4. Extract Layers via Crane
2447
if [ -n "$IMAGE_NAME" ]; then
25-
echo "[2/5] Extracting layers for '$IMAGE_NAME'..."
48+
echo "[4/7] Extracting layers for '$IMAGE_NAME'..."
2649
rm -f layer*.erofs boot/vmlinuz* boot/initrd.img*
2750

2851
# Download Crane
@@ -36,16 +59,16 @@ if [ -n "$IMAGE_NAME" ]; then
3659
tar -xf image.tar -C image_temp
3760

3861
# Process layers (Bottom up)
39-
LAYERS=$(python3 -c 'import json; print("\n".join(json.load(open("image_temp/manifest.json"))[0]["Layers"]))')
62+
LAYERS=$(jq -r '.[0].Layers[]' image_temp/manifest.json)
4063

4164
IDX=0
4265
for L in $LAYERS; do
4366
echo " Layer $IDX -> layer${IDX}.erofs"
4467
tar -xf "image_temp/$L" boot/ 2>/dev/null || true
4568
# Compress layer to EROFS
46-
# UUID v5: deterministically derived from the layer path, which encodes the
47-
# content digest (e.g. "blobs/sha256/abc123.../"). Same OCI layer -> same UUID.
48-
LAYER_UUID=$(python3 -c "import uuid,sys; print(uuid.uuid5(uuid.NAMESPACE_URL, sys.argv[1]))" "$L")
69+
# UUID v5: deterministically derived from the layer path (which encodes the
70+
# content digest). Same OCI layer -> same UUID. Pure bash + sha1sum, no Python.
71+
LAYER_UUID=$(uuid_v5 "$L")
4972
if gzip -t "image_temp/$L" 2>/dev/null; then
5073
gzip -dc "image_temp/$L" | mkfs.erofs --tar=f -zlz4hc -C16384 -T0 -U "$LAYER_UUID" "layer${IDX}.erofs"
5174
else
@@ -56,13 +79,13 @@ if [ -n "$IMAGE_NAME" ]; then
5679
rm -rf image_temp image.tar
5780
fi
5881

59-
# 3. Prepare COW (Optimized for performance and sparse efficiency)
82+
# 5. Prepare COW (Optimized for performance and sparse efficiency)
6083
# lazy_itable_init=1 speeds up formatting on large sparse files
61-
echo "[3/5] Preparing optimized sparse COW disk..."
84+
echo "[5/7] Preparing optimized sparse COW disk..."
6285
truncate -s 10G cow.raw
6386
mkfs.ext4 -F -m 0 -q -E lazy_itable_init=1,lazy_journal_init=1,discard cow.raw
6487

65-
# 4. Build Arguments
88+
# 6. Build Arguments
6689
KERNEL=$(ls boot/vmlinuz-* | head -1)
6790
INITRD=$(ls boot/initrd.img-* | head -1)
6891
LAYER_FILES=$(ls -1 layer*.erofs | sort -V)
@@ -82,13 +105,13 @@ done
82105
# num_queues=2 (Match boot CPUs), queue_size=256 (Deep queue for better throughput)
83106
DISK_CONFIGS+=("path=cow.raw,readonly=off,direct=on,sparse=on,image_type=raw,num_queues=2,queue_size=256,serial=cocoon-cow")
84107

85-
# 5. Ignite (Added RNG and Ballooning for production stability)
86-
echo "[5/5] Igniting Cloud Hypervisor..."
108+
# 7. Ignite
109+
echo "[7/7] Igniting Cloud Hypervisor..."
87110
"$CH_BIN" --kernel "$KERNEL" --initramfs "$INITRD" \
88111
--disk "${DISK_CONFIGS[@]}" \
89112
--cmdline "console=ttyS0 loglevel=3 boot=cocoon cocoon.layers=${COCOON_LAYERS} cocoon.cow=cocoon-cow clocksource=kvm-clock rw" \
90113
--cpus "boot=2,max=8" \
91-
--memory "size=1024M,hugepages=on" \
114+
--memory "size=1024M$([ "$(cat /proc/sys/vm/nr_hugepages 2>/dev/null)" -gt 0 ] && echo ',hugepages=on')" \
92115
--rng "src=/dev/urandom" \
93116
--watchdog \
94117
--balloon "size=512M,deflate_on_oom=on,free_page_reporting=on" \

os-image/ubuntu/22.04/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ RUN --mount=type=secret,id=cocoon_script \
2626
# [Shift-Left System Hacks]
2727
truncate -s 0 /etc/fstab && \
2828
systemctl mask systemd-fsck-root.service systemd-remount-fs.service systemd-fsck@.service && \
29-
systemctl enable systemd-networkd systemd-timesyncd && \
29+
systemctl enable systemd-networkd systemd-resolved systemd-timesyncd && \
3030
mkdir -p /etc/systemd/network && \
3131
printf "[Match]\nName=e* v*\n[Network]\nDHCP=yes\n" > /etc/systemd/network/20-wired.network && \
3232
# [Final Touches]

os-image/ubuntu/hack.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ resolve_disk() {
88
local serial="$1" timeout="${COCOON_TIMEOUT:-10}" i=0
99
case "$timeout" in ''|*[!0-9]*) timeout=10 ;; esac
1010

11-
# Trigger udev to ensure device nodes are created before polling
12-
udevadm settle 2>/dev/null || true
13-
1411
while [ $i -lt $timeout ]; do
1512
for sysdev in /sys/block/vd*; do
1613
[ -d "$sysdev" ] || continue
@@ -51,6 +48,9 @@ mountroot() {
5148
[ -z "$LAYERS" ] && panic "cocoon.layers= not set"
5249
[ -z "$COW" ] && panic "cocoon.cow= not set"
5350

51+
# Wait for udev to finish processing all pending events once, before any disk lookups.
52+
udevadm settle 2>/dev/null || true
53+
5454
COCOON_INTERNAL="/.cocoon"
5555
mkdir -p "$COCOON_INTERNAL"
5656

storage/storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ type Storage interface {
1111
List(context.Context) ([]*types.Storage, error)
1212
Delete(context.Context, string) error
1313

14-
Config(context.Context, *types.VMConfig) (*types.StorageConfig, error)
14+
Config(context.Context, []*types.VMConfig) ([][]*types.StorageConfig, error)
1515
}

types/storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package types
33
import "time"
44

55
type Storage struct {
6+
ID string `json:"id"`
67
Name string `json:"name"`
78
Type string `json:"type"`
8-
Hex string `json:"hex"`
99
Size int64 `json:"size"`
1010
CreatedAt time.Time `json:"created_at"`
1111
}

types/vm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ package types
33
type VMConfig struct {
44
Name string `json:"name"`
55
CPU int `json:"cpu"`
6-
Memory int `json:"memory"`
7-
Storage int `json:"storage"`
6+
Memory int64 `json:"memory"`
7+
Storage int64 `json:"storage"`
88
}

0 commit comments

Comments
 (0)