Two real v0.3.0 bugs that surface on first-boot:
1. KubeSolo v1.1.4+ owns its pod-masquerade rules directly via
nft add table ip kubesolo-masq
instead of going through kube-proxy/CNI. Without the standalone nft
CLI in PATH, KubeSolo FATALs at startup with:
"nft": executable file not found in $PATH
then the init exits and the kernel panics on PID 1 death.
inject-kubesolo.sh now also copies /usr/sbin/nft and its non-shared
libraries (libnftables, libedit, libjansson, libgmp, libtinfo, libbsd,
libmd). The iptables-nft block above already covered libmnl, libnftnl,
libxtables, libc, ld.
2. The host-access banner ("From your host machine, run: curl -s
http://localhost:8080 ...") was gated on the kubeconfig appearing
within 120s. When KubeSolo crashed early (bug 1 above) or simply took
longer than the wait window, the user never saw the connection
instructions.
90-kubesolo.sh now:
- writes the banner to /etc/motd so it shows on any later shell
(SSH ext, emergency shell, console login)
- prints the banner to console unconditionally, after the wait
loop, regardless of whether the kubeconfig was found
Both fixes are pure rootfs changes — no kernel rebuild required.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bind kubeconfig HTTP server to 0.0.0.0:8080 (was 127.0.0.1) so integration
tests can reach it via QEMU SLIRP port forwarding. Add shared wait_for_boot
and fetch_kubeconfig helpers to qemu-helpers.sh. Update all 5 integration
tests to fetch kubeconfig via HTTP and use it for kubectl authentication.
All 6 tests pass on Linux with KVM: boot (18s), security (7/7), K8s ready
(15s), workload deploy, local storage, network policy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Security hardening: bind kubeconfig server to localhost, mount hardening
(noexec/nosuid/nodev on tmpfs), sysctl network hardening, kernel module
loading lock after boot, SHA256 checksum verification for downloads,
kernel AppArmor + Audit support, complain-mode AppArmor profiles for
containerd and kubelet, and security integration test.
ARM64 Raspberry Pi support: piCore64 base extraction, RPi kernel build
from raspberrypi/linux fork, RPi firmware fetch, SD card image with 4-
partition GPT and tryboot A/B mechanism, BootEnv Go interface abstracting
GRUB vs RPi boot environments, architecture-aware build scripts, QEMU
aarch64 dev VM and boot test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- dev-vm.sh: rewrite for macOS (bsdtar ISO extraction, Homebrew mkfs.ext4
detection, direct kernel boot, TCG acceleration, port 8080 forwarding)
- inject-kubesolo.sh: add CA certificates bundle from builder so containerd
can verify TLS when pulling from registries (Docker Hub, etc.)
- 50-network.sh: add DNS fallback (10.0.2.3 + 8.8.8.8) when DHCP client
doesn't populate /etc/resolv.conf
- 90-kubesolo.sh: serve kubeconfig via HTTP on port 8080 for reliable
retrieval from host, add 127.0.0.1 and 10.0.2.15 to API server SANs
- portainer.go: add headless Service to Edge Agent manifest (required for
agent peer discovery DNS lookup)
- 10-parse-cmdline.sh + init.sh: add kubesolo.edge_id/edge_key boot params
- 20-persistent-mount.sh: auto-format unformatted data disks on first boot
- hack/fix-portainer-service.sh: helper to patch running cluster
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>