• v0.3.1 eb39787cf3

    KubeSolo OS v0.3.1
    Some checks failed
    CI / Go Tests (push) Successful in 2m30s
    CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Successful in 1m37s
    CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Successful in 2m0s
    CI / Shellcheck (push) Failing after 10m50s
    ARM64 Build / Build generic ARM64 disk image (push) Failing after 1h6m52s
    Release / Test (push) Successful in 1m59s
    Release / Build Binaries (linux-amd64) (push) Successful in 1m33s
    Release / Build Binaries (linux-arm64) (push) Successful in 1m40s
    Release / Build ARM64 disk image (push) Successful in 1h11m43s
    Release / Publish Gitea Release (push) Successful in 3m1s
    Release / Build x86_64 ISO + disk image (push) Has been cancelled
    Stable

    adelorenzo released this 2026-05-16 01:07:39 +02:00 | 5 commits to main since this release

    See docs/release-notes-0.3.1.md
    and CHANGELOG.md for the full release notes.

    Downloads

    • kubesolo-os-0.3.1.arm64.img.xz — ARM64 raw disk image (A/B GPT, UEFI)
    • kubesolo-cloudinit-linux-{amd64,arm64} — standalone cloud-init parser
    • kubesolo-update-linux-{amd64,arm64} — standalone update agent
    • SHA256SUMS — checksums for every artifact above

    x86_64 ISO + disk image: not built automatically yet. The
    release workflow's amd64 build job needs an amd64-linux runner,
    which this Gitea instance doesn't have yet. To produce them
    yourself, clone the repo at this tag and run make iso disk-image
    on any Linux amd64 host.

    Verify

    sha256sum -c SHA256SUMS
    

    Quick start (ARM64)

    # On Graviton/Ampere/any UEFI ARM64 host:
    xz -d kubesolo-os-0.3.1.arm64.img.xz
    sudo dd if=kubesolo-os-0.3.1.arm64.img of=/dev/sdX bs=4M status=progress
    
    # Under qemu-system-aarch64 (Apple Silicon w/ HVF):
    UEFI_FW=$(brew --prefix qemu)/share/qemu/edk2-aarch64-code.fd
    qemu-system-aarch64 -M virt -accel hvf -cpu host -m 2048 -smp 2 \
      -nographic -bios "$UEFI_FW" \
      -drive file=kubesolo-os-0.3.1.arm64.img,format=raw,if=virtio,media=disk \
      -device virtio-rng-pci \
      -net nic,model=virtio \
      -net user,hostfwd=tcp::6443-:6443,hostfwd=tcp::8080-:8080
    

    Then from the host: curl http://localhost:8080 > ~/.kube/kubesolo-config
    and kubectl --kubeconfig ~/.kube/kubesolo-config get nodes.

    Downloads
  • v0.3.0 3b47e7af68

    KubeSolo OS v0.3.0
    Some checks failed
    CI / Go Tests (push) Successful in 1m29s
    CI / Shellcheck (push) Successful in 46s
    ARM64 Build / Build generic ARM64 disk image (push) Failing after 3s
    Release / Test (push) Successful in 1m21s
    CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Successful in 1m19s
    CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Successful in 1m36s
    Release / Build Binaries (amd64, linux, linux-amd64) (push) Failing after 1m27s
    Release / Build Binaries (arm64, linux, linux-arm64) (push) Failing after 1m17s
    Release / Build ISO (amd64) (push) Has been skipped
    Release / Create Release (push) Has been skipped
    Stable

    adelorenzo released this 2026-05-15 03:14:14 +02:00 | 15 commits to main since this release

    KubeSolo OS v0.3.0 — Release Notes

    Released: 2026-05-14

    v0.3.0 is the second feature release after v0.2.0 and the first release that
    ships a generic ARM64 build alongside x86_64. The update agent grew up: it
    now has an explicit on-disk lifecycle, OCI registry distribution, and a
    fleet-friendly set of policy gates (channels, maintenance windows,
    version-stepping-stones, pre-flight checks, auto-rollback).

    This document is the operator-facing summary. The full per-phase changelog
    lives in CHANGELOG.md.

    What's new

    Generic ARM64 build

    The image you build with make disk-image-arm64 now targets any UEFI-capable
    ARM64 host: AWS Graviton, Oracle Ampere, generic ARM64 servers, future SBCs
    with UEFI-compatible firmware. The kernel comes from kernel.org mainline LTS
    (6.12.10 by default, configurable via MAINLINE_KERNEL_VERSION in
    build/config/versions.env).

    This is distinct from the Raspberry Pi build path. RPi keeps its
    specialised kernel from raspberrypi/linux with bcm-defconfig + custom DTBs;
    the generic ARM64 path uses mainline + arm64-defconfig + UEFI/virtio. See
    docs/arm64-architecture.md for the file-by-file
    split.

    KubeSolo bumped to v1.1.5 (was v1.1.0). New flags surfaced via cloud-init:

    • kubesolo.full — disable edge-optimised k8s overrides
    • kubesolo.disable-ipv6 — disable IPv6 cluster-wide
    • kubesolo.db-wal-repair — recover from unclean shutdowns

    Update lifecycle is now observable

    The update agent writes a state.json at /var/lib/kubesolo/update/state.json
    recording where the current attempt is in the lifecycle:

    idle → checking → downloading → staged → activated → verifying → success
                                                                  ↘ rolled_back
                                                                  ↘ failed
    

    kubesolo-update status --json emits the full state for orchestration tooling.
    The Prometheus metrics endpoint gains three new series:

    • kubesolo_update_phase{phase="..."} — 1 for current phase, 0 for others (all 9 always emitted)
    • kubesolo_update_attempts_total
    • kubesolo_update_last_attempt_timestamp_seconds

    OCI registry distribution

    Update artifacts can now be pulled from any OCI-compliant registry alongside
    the existing HTTP latest.json protocol:

    # HTTP, unchanged from v0.2:
    kubesolo-update apply --server https://updates.example.com
    
    # New: OCI from ghcr.io (or quay.io, harbor, zot, ...)
    kubesolo-update apply --registry ghcr.io/yourorg/kubesolo-os --tag stable
    

    Multi-arch is handled transparently — the same stable tag points at a
    manifest index, the agent picks the manifest matching its runtime.GOARCH.

    Publish your own artifacts with build/scripts/push-oci-artifact.sh. See
    the script's header comment for the full publishing flow.

    Policy gates

    apply now enforces five gates before destroying the passive slot:

    1. Maintenance window (configurable, e.g. 03:00-05:00; wrapping
      midnight supported)
    2. Node-block-label — refuses if the K8s node carries
      updates.kubesolo.io/block=true (workload-author kill switch)
    3. Channelstable / beta / edge must match between the artifact
      metadata and the local channel
    4. Architecture — refuses cross-arch artifacts via runtime.GOARCH check
    5. Min compatible version — stepping-stone enforcement; refuses an
      upgrade that bypasses a required intermediate version

    --force bypasses the maintenance window and node-block label (channel /
    arch / min-version are non-negotiable). Failures are recorded in state.json
    with a clear LastError field.

    Healthcheck deepening + auto-rollback

    kubesolo-update healthcheck grew three optional probes:

    • Kube-system pods must hold Running for ≥ N seconds before passing
    • Operator probe URL — GET an operator-supplied endpoint; 200 = pass
    • Disk smoke test — write/fsync/read/delete a probe file under
      /var/lib/kubesolo to catch a wedged data partition

    Plus auto-rollback: with --auto-rollback-after N (or auto_rollback_after=
    in update.conf), after N consecutive post-activation failures, the agent
    calls ForceRollback() and the operator/init is expected to reboot. The
    counter resets on a clean pass.

    Persistent configuration via /etc/kubesolo/update.conf

    Cloud-init writes this file on first boot from a new updates: block; you
    can also hand-edit it. Recognised keys:

    server = https://updates.example.com         # or omit if using registry
    registry =                                   # OCI registry ref (alt to server)
    channel = stable
    maintenance_window = 03:00-05:00
    pubkey = /etc/kubesolo/update-pubkey.hex
    healthcheck_url = http://localhost:8000/ready
    auto_rollback_after = 3
    

    Cloud-init full reference at
    cloud-init/examples/full-config.yaml.

    Migration from v0.2.x

    This is a non-breaking release for live systems. v0.2.x → v0.3.0 changes:

    • state.json will appear at /var/lib/kubesolo/update/state.json the
      first time a v0.3 agent runs apply. Pre-existing v0.2 deployments without
      this file are fine — the agent treats a missing file as fresh Idle state.
    • update.conf is optional. v0.2 deployments that pass everything via
      CLI flags keep working unchanged.
    • HTTP latest.json protocol unchanged. Existing update servers don't
      need a rebuild.
    • GRUB env (boot counter, active slot) unchanged. The bootloader's
      rollback behaviour is the same.
    • No new mandatory kernel command-line parameters.

    To opt into the new lifecycle, transports, and gates, drop in an
    update.conf (or update cloud-init) and switch to --registry if you want
    OCI distribution.

    Known limitations

    These shipped intentionally with v0.3.0 and are explicitly tracked for
    v0.3.1+:

    • OCI signature verification — the OCI transport is digest-verified
      end-to-end via oras-go, but does not yet consume cosign-style referrer
      attestations. The HTTP transport still honours --pubkey for .sig
      files.
    • ARM64 LABEL=KSOLODATA resolution doesn't work yet — piCore's
      blkid/findfs crash on QEMU virt under our mainline kernel; the
      static busybox-static we ship doesn't include those applets.
      build/grub/grub-arm64.cfg hardcodes kubesolo.data=/dev/vda4 as a
      workaround. On real ARM64 hardware the device path may differ.
    • Real-hardware ARM64 validation is pending. The image builds and
      boots end-to-end under QEMU virt; production certification waits on a
      Graviton / Ampere run.
    • AppArmor profile load fails on ARM64 (apparmor_parser ABI mismatch).
      Init reports the failure; boot continues without AppArmor enforcement.
    • QEMU TCG performance can trigger KubeSolo's first-boot image-import
      deadline. Not an OS defect; real hardware and KVM-accelerated QEMU
      complete the import in seconds.

    How to upgrade your build host

    git pull
    make distclean   # optional — drops the build cache; full rebuild takes ~30 min
    make iso         # or disk-image, or disk-image-arm64
    

    The Docker-based builder (make docker-build) regenerates its own image
    from build/Dockerfile.builder on next invocation; oras 1.2.3 and
    busybox-static are now included.

    Acknowledgements

    v0.3.0 work was driven by a single multi-week pair-programming session
    working through Phases 0–9 of the v0.3 roadmap. The Odroid self-hosted
    Gitea Actions runner (odroid.local, arm64-linux) carried every ARM64
    build during development.

    Downloads
  • v0.2.0 4e3f1d6cf0

    KubeSolo OS v0.2.0
    Some checks failed
    CI / Go Tests (push) Has been cancelled
    CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
    CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
    CI / Shellcheck (push) Has been cancelled
    Release / Test (push) Has been cancelled
    Release / Build Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
    Release / Build Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
    Release / Build ISO (amd64) (push) Has been cancelled
    Release / Create Release (push) Has been cancelled
    Stable

    adelorenzo released this 2026-02-13 02:27:54 +01:00 | 44 commits to main since this release

    What's New

    Cloud-Init: Full KubeSolo Flag Support

    • All 10 documented KubeSolo CLI flags can now be configured via cloud-init YAML
    • New flags: --local-storage-shared-path, --debug, --pprof-server, --portainer-edge-id, --portainer-edge-key, --portainer-edge-async
    • New full-config.yaml example showing all supported parameters
    • Configuration reference table added to docs/cloud-init.md

    Phase 6: Security Hardening & ARM64

    • Security hardening: mount hardening, sysctl, kernel module lock
    • AppArmor support with complain-mode profiles for containerd and kubelet
    • ARM64 Raspberry Pi support with A/B boot via tryboot
    • BootEnv abstraction for GRUB and RPi boot environments

    Build System Fixes

    • x86_64 disk image: kpartx-based partition mapping for Docker builds
    • ARM64: corrected piCore64 URL and extraction logic
    • ARM64: full build pipeline with KubeSolo ARM64 binary, cross-compiled Go binaries, kernel modules
    • RPi firmware: fixed tar wildcard extraction
    • Docker builder: added kpartx and unzip tools

    Downloads

    • kubesolo-os-0.2.0.iso — Bootable x86_64 ISO (168 MB)
    • kubesolo-os-0.2.0.img.xz — x86_64 disk image with A/B partitions (334 MB, xz compressed)
    • kubesolo-os-0.2.0.rpi.img.xz — ARM64 Raspberry Pi SD card image with A/B boot (309 MB, xz compressed)

    See CHANGELOG.md for full details.

    Downloads
  • v0.1.0 f3d86e4d8f

    KubeSolo OS v0.1.0
    Some checks failed
    CI / Go Tests (push) Has been cancelled
    CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
    CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
    CI / Shellcheck (push) Has been cancelled
    Release / Test (push) Has been cancelled
    Release / Build Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
    Release / Build Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
    Release / Build ISO (amd64) (push) Has been cancelled
    Release / Create Release (push) Has been cancelled
    Stable

    adelorenzo released this 2026-02-12 09:23:28 +01:00 | 53 commits to main since this release

    First release with all 5 design-doc phases complete.

    Highlights

    • Custom kernel (6.18.2-tinycore64) with container-critical configs
    • POSIX sh init system with staged boot sequence
    • Go cloud-init parser with network, hostname, Portainer Edge support
    • A/B atomic updates with GRUB boot counter rollback
    • Ed25519 image signing, Prometheus metrics, ARM64 cross-compilation
    • CI/CD via Gitea Actions, OCI image packaging, USB provisioning
    • macOS QEMU dev VM with direct kernel boot and HTTP kubeconfig serving

    Assets

    • kubesolo-os-0.1.0.iso — Bootable ISO (167 MB)

    Quick Start

    # Boot in QEMU
    ./hack/dev-vm.sh output/kubesolo-os-0.1.0.iso
    
    # Get kubeconfig from host
    curl -s http://localhost:8080 > ~/.kube/kubesolo-config
    kubectl --kubeconfig ~/.kube/kubesolo-config get nodes
    
    Downloads