release: 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
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
Promote VERSION from 0.3.0-dev to 0.3.0. Finalise CHANGELOG entry with phases 5-8 work (state machine + metrics, channels + maintenance windows, OCI multi-arch distribution, pre-flight gates + deeper healthcheck + auto-rollback). Refresh README quick-start to show both x86_64 and generic ARM64 paths; update the roadmap status table to mark all v0.3 phases complete and explicitly track the v0.3.1 follow-ups (OCI cosign, LABEL=KSOLODATA on ARM64, real-hardware validation). Add docs/release-notes-0.3.0.md as the operator-facing summary, including a v0.2.x -> v0.3.0 migration section (non-breaking on live systems) and the known-limitations list copied from CHANGELOG. All tests green: cloud-init module, all 10 update-module packages, shellcheck across init / build / test / hack scripts under the v0.3 severity policy. Tagging is intentionally NOT done from this commit — that's a manual step so the operator can decide when v0.3.0 is final. After tagging: git tag -a v0.3.0 -m "KubeSolo OS v0.3.0" git push origin v0.3.0 The push triggers .gitea/workflows/build-arm64.yaml which runs the full ARM64 build on the Odroid runner. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
93
CHANGELOG.md
93
CHANGELOG.md
@@ -5,7 +5,12 @@ All notable changes to KubeSolo OS are documented in this file.
|
||||
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.3.0-dev] - unreleased
|
||||
## [0.3.0] - 2026-05-14
|
||||
|
||||
The main themes: generic ARM64 (not just Raspberry Pi), an honest update
|
||||
lifecycle with state file + metrics, OCI multi-arch distribution via ghcr.io,
|
||||
and policy gates (channels, maintenance windows, version stepping-stones,
|
||||
pre-flight checks, auto-rollback).
|
||||
|
||||
### Added
|
||||
|
||||
@@ -30,6 +35,68 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
- `docs/arm64-status.md` — Phase 3 status snapshot, known limitations, what's
|
||||
needed to ship.
|
||||
- `docs/ci-runners.md` — Gitea Actions runner setup (Odroid arm64-linux).
|
||||
- Update agent state machine and observability (`update/pkg/state`):
|
||||
- Persistent on-disk `state.json` at `/var/lib/kubesolo/update/state.json`
|
||||
(atomic write via tmp + rename). Records Phase (Idle / Checking /
|
||||
Downloading / Staged / Activated / Verifying / Success / RolledBack /
|
||||
Failed), FromVersion, ToVersion, StartedAt, UpdatedAt, LastError,
|
||||
AttemptCount, HealthCheckFailures.
|
||||
- `apply`, `activate`, `healthcheck`, `rollback` all transition state
|
||||
explicitly on entry / exit / failure. Errors land in LastError so
|
||||
`status` can show why.
|
||||
- `kubesolo-update status --json` emits the full state for
|
||||
orchestration tooling. Human-readable mode adds an "Update Lifecycle"
|
||||
section when not idle.
|
||||
- New Prometheus metrics: `kubesolo_update_phase{phase="..."}` (all 9
|
||||
phase labels always emitted), `kubesolo_update_attempts_total`,
|
||||
`kubesolo_update_last_attempt_timestamp_seconds`.
|
||||
- Channels, maintenance windows, version policy (`update/pkg/config`):
|
||||
- `/etc/kubesolo/update.conf` (key=value, comments, missing-OK) configures
|
||||
server, channel, maintenance_window, pubkey, healthcheck_url,
|
||||
auto_rollback_after.
|
||||
- `cloud-init` top-level `updates:` block writes `update.conf` on first
|
||||
boot. Empty block leaves any existing file alone.
|
||||
- `apply` enforces four gates before download: maintenance window,
|
||||
channel match, runtime architecture match, min_compatible_version
|
||||
stepping-stone. All gate failures land in the state machine as Failed
|
||||
with a clear LastError. `--force` bypasses window + node-block-label.
|
||||
- `UpdateMetadata` JSON gains `channel`, `min_compatible_version`,
|
||||
`architecture` (all optional, omitempty).
|
||||
- OCI registry distribution (`update/pkg/oci`, ~280 LOC, 9 tests):
|
||||
- `kubesolo-update apply --registry ghcr.io/<org>/kubesolo-os --tag stable`
|
||||
pulls update artifacts from any OCI-compliant registry. Multi-arch
|
||||
indexes resolve to the runtime.GOARCH-matching manifest automatically.
|
||||
- Custom media types: `application/vnd.kubesolo.os.kernel.v1+octet-stream`
|
||||
and `application/vnd.kubesolo.os.initramfs.v1+gzip`. Annotations:
|
||||
`io.kubesolo.os.{version,channel,architecture,min_compatible_version,
|
||||
release_notes,release_date}`.
|
||||
- End-to-end digest verification from manifest to blobs via oras-go/v2.
|
||||
- `build/scripts/push-oci-artifact.sh` publishes per-arch artifacts via
|
||||
`oras`. Multi-arch index composition documented inline.
|
||||
- Dependencies added (update module only): oras.land/oras-go/v2 and
|
||||
transitive opencontainers/{go-digest,image-spec} + golang.org/x/sync.
|
||||
- Pre-flight gates and deeper healthcheck (`update/pkg/health` extended,
|
||||
`update/pkg/partition` extended):
|
||||
- Free-space pre-flight on the passive partition (image + 10% headroom)
|
||||
via `partition.FreeBytes` / `HasFreeSpaceFor`.
|
||||
- Node-block-label pre-flight: refuses if the local K8s node carries
|
||||
`updates.kubesolo.io/block=true`. Silently allowed when no kubeconfig
|
||||
(air-gap). Skipped by `--force`.
|
||||
- `CheckKubeSystemReady` waits until every kube-system pod has held
|
||||
Running for ≥ N seconds (configurable via
|
||||
`--kube-system-settle`).
|
||||
- `CheckProbeURL` GETs an operator-supplied URL; 200 = pass. Configurable
|
||||
via `--healthcheck-url` or `healthcheck_url=` in update.conf.
|
||||
- `CheckDiskWritable` writes / fsyncs / reads / deletes a probe file
|
||||
under `/var/lib/kubesolo` to catch a wedged data partition.
|
||||
- `--auto-rollback-after N` (also `auto_rollback_after=` in update.conf):
|
||||
after N consecutive post-activation healthcheck failures, the agent
|
||||
calls `ForceRollback()` and the operator/init reboots. Reset to 0 on
|
||||
a clean pass.
|
||||
- `.gitea/workflows/build-arm64.yaml` — full ARM64 build on the Odroid
|
||||
self-hosted runner. Triggers on push to main, tags, and workflow_dispatch.
|
||||
Boot smoke test marked continue-on-error pending KVM or real-hardware
|
||||
validation.
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -78,13 +145,23 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
### Known limitations (deferred to follow-up)
|
||||
|
||||
- ARM64 `kubesolo.data=LABEL=KSOLODATA` resolution doesn't work yet —
|
||||
piCore's `blkid`/`findfs` crash in QEMU and our static busybox lacks the
|
||||
applets. Hardcoded `/dev/vda4` as a workaround. Production fix: ship
|
||||
static `blkid`/`findfs` or replace LABEL resolution with a sysfs walk.
|
||||
- AppArmor profile load fails on ARM64 (apparmor_parser ABI mismatch).
|
||||
- KubeSolo's image-import deadline can fire under QEMU TCG (software
|
||||
emulation). On real hardware (or with KVM) the import finishes in seconds.
|
||||
- **ARM64 LABEL= resolution** doesn't work yet — piCore's `blkid`/`findfs`
|
||||
crash in QEMU and our static busybox lacks the applets. Hardcoded
|
||||
`/dev/vda4` as a workaround in `build/grub/grub-arm64.cfg`. Production
|
||||
fix: ship static `blkid`/`findfs` or replace LABEL resolution with a
|
||||
sysfs walk.
|
||||
- **AppArmor profile load fails on ARM64** (apparmor_parser ABI mismatch).
|
||||
Init reports it; boot continues without enforcement.
|
||||
- **OCI signature verification** is deferred. The HTTP transport still
|
||||
honours `--pubkey` for `.sig` files; the OCI transport is digest-verified
|
||||
end-to-end via oras-go but does not yet consume cosign-style referrer
|
||||
attestations. Targeted for v0.3.1.
|
||||
- **Real-hardware validation** of the generic ARM64 image is still
|
||||
pending. Builds and boots end-to-end under QEMU virt; production
|
||||
certification waits on a Graviton / Ampere run.
|
||||
- **QEMU TCG performance** can trigger KubeSolo's first-boot image-import
|
||||
deadline. Not a defect in the OS itself; real hardware and KVM-accelerated
|
||||
QEMU complete the import in seconds.
|
||||
|
||||
## [0.2.0] - 2026-02-12
|
||||
|
||||
|
||||
Reference in New Issue
Block a user