#!/bin/bash # inject-kubesolo.sh — Add KubeSolo binary, init system, and configs to rootfs set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" CACHE_DIR="${CACHE_DIR:-$PROJECT_ROOT/build/cache}" ROOTFS_DIR="${ROOTFS_DIR:-$PROJECT_ROOT/build/rootfs-work}" ROOTFS="$ROOTFS_DIR/rootfs" VERSION="$(cat "$PROJECT_ROOT/VERSION")" if [ ! -d "$ROOTFS" ]; then echo "ERROR: Rootfs not found: $ROOTFS" echo "Run extract-core.sh first." exit 1 fi KUBESOLO_BIN="$CACHE_DIR/kubesolo" if [ ! -f "$KUBESOLO_BIN" ]; then echo "ERROR: KubeSolo binary not found: $KUBESOLO_BIN" echo "See fetch-components.sh output for instructions." exit 1 fi echo "==> Injecting KubeSolo into rootfs..." # --- 1. KubeSolo binary --- mkdir -p "$ROOTFS/usr/local/bin" cp "$KUBESOLO_BIN" "$ROOTFS/usr/local/bin/kubesolo" chmod +x "$ROOTFS/usr/local/bin/kubesolo" echo " Installed KubeSolo binary ($(du -h "$KUBESOLO_BIN" | cut -f1))" # --- 2. Custom init system --- echo " Installing init system..." # Main init cp "$PROJECT_ROOT/init/init.sh" "$ROOTFS/sbin/init" chmod +x "$ROOTFS/sbin/init" # Init stages mkdir -p "$ROOTFS/usr/lib/kubesolo-os/init.d" for stage in "$PROJECT_ROOT"/init/lib/*.sh; do [ -f "$stage" ] || continue cp "$stage" "$ROOTFS/usr/lib/kubesolo-os/init.d/" chmod +x "$ROOTFS/usr/lib/kubesolo-os/init.d/$(basename "$stage")" done echo " Installed $(ls "$ROOTFS/usr/lib/kubesolo-os/init.d/" | wc -l) init stages" # Shared functions if [ -f "$PROJECT_ROOT/init/lib/functions.sh" ]; then cp "$PROJECT_ROOT/init/lib/functions.sh" "$ROOTFS/usr/lib/kubesolo-os/functions.sh" fi # Emergency shell if [ -f "$PROJECT_ROOT/init/emergency-shell.sh" ]; then cp "$PROJECT_ROOT/init/emergency-shell.sh" "$ROOTFS/usr/lib/kubesolo-os/emergency-shell.sh" chmod +x "$ROOTFS/usr/lib/kubesolo-os/emergency-shell.sh" fi # Shared library scripts (network, health) for lib in network.sh health.sh; do src="$PROJECT_ROOT/build/rootfs/usr/lib/kubesolo-os/$lib" [ -f "$src" ] && cp "$src" "$ROOTFS/usr/lib/kubesolo-os/$lib" done # Cloud-init binary (Go, built separately) CLOUDINIT_BIN="$CACHE_DIR/kubesolo-cloudinit" if [ -f "$CLOUDINIT_BIN" ]; then cp "$CLOUDINIT_BIN" "$ROOTFS/usr/lib/kubesolo-os/kubesolo-cloudinit" chmod +x "$ROOTFS/usr/lib/kubesolo-os/kubesolo-cloudinit" echo " Installed cloud-init binary ($(du -h "$CLOUDINIT_BIN" | cut -f1))" else echo " WARN: Cloud-init binary not found (run 'make build-cloudinit' to build)" fi # Update agent binary (Go, built separately) UPDATE_BIN="$CACHE_DIR/kubesolo-update" if [ -f "$UPDATE_BIN" ]; then cp "$UPDATE_BIN" "$ROOTFS/usr/lib/kubesolo-os/kubesolo-update" chmod +x "$ROOTFS/usr/lib/kubesolo-os/kubesolo-update" echo " Installed update agent ($(du -h "$UPDATE_BIN" | cut -f1))" else echo " WARN: Update agent not found (run 'make build-update-agent' to build)" fi # --- 3. Kernel modules list --- cp "$PROJECT_ROOT/build/config/modules.list" "$ROOTFS/usr/lib/kubesolo-os/modules.list" # --- 4. Sysctl config --- mkdir -p "$ROOTFS/etc/sysctl.d" cp "$PROJECT_ROOT/build/rootfs/etc/sysctl.d/k8s.conf" "$ROOTFS/etc/sysctl.d/k8s.conf" # --- 5. OS metadata --- echo "$VERSION" > "$ROOTFS/etc/kubesolo-os-version" cat > "$ROOTFS/etc/os-release" << EOF NAME="KubeSolo OS" VERSION="$VERSION" ID=kubesolo-os VERSION_ID=$VERSION PRETTY_NAME="KubeSolo OS $VERSION" HOME_URL="https://github.com/portainer/kubesolo" BUG_REPORT_URL="https://github.com/portainer/kubesolo/issues" EOF # --- 6. Default KubeSolo config --- mkdir -p "$ROOTFS/etc/kubesolo" if [ -f "$PROJECT_ROOT/build/rootfs/etc/kubesolo/defaults.yaml" ]; then cp "$PROJECT_ROOT/build/rootfs/etc/kubesolo/defaults.yaml" "$ROOTFS/etc/kubesolo/defaults.yaml" fi # --- 7. Essential directories --- mkdir -p "$ROOTFS/var/lib/kubesolo" mkdir -p "$ROOTFS/var/lib/containerd" mkdir -p "$ROOTFS/etc/kubesolo" mkdir -p "$ROOTFS/etc/cni/net.d" mkdir -p "$ROOTFS/opt/cni/bin" mkdir -p "$ROOTFS/var/log" mkdir -p "$ROOTFS/usr/local" mkdir -p "$ROOTFS/mnt/data" mkdir -p "$ROOTFS/run/containerd" # --- 8. Ensure /etc/hosts and /etc/resolv.conf exist --- if [ ! -f "$ROOTFS/etc/hosts" ]; then cat > "$ROOTFS/etc/hosts" << EOF 127.0.0.1 localhost ::1 localhost EOF fi if [ ! -f "$ROOTFS/etc/resolv.conf" ]; then cat > "$ROOTFS/etc/resolv.conf" << EOF nameserver 8.8.8.8 nameserver 1.1.1.1 EOF fi # --- Summary --- echo "" echo "==> Injection complete. Rootfs contents:" echo " Total size: $(du -sh "$ROOTFS" | cut -f1)" echo " KubeSolo: $(du -h "$ROOTFS/usr/local/bin/kubesolo" | cut -f1)" echo " Init stages: $(ls "$ROOTFS/usr/lib/kubesolo-os/init.d/" | wc -l)" echo ""