5 Commits
v0.3.1 ... main

Author SHA1 Message Date
53268a1564 docs: roll README + CHANGELOG forward past v0.3.1
All checks were successful
CI / Go Tests (push) Successful in 1m53s
CI / Shellcheck (push) Successful in 1m1s
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Successful in 1m28s
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Successful in 1m23s
README:
- Status line bumped from v0.3.0 to v0.3.1 with the actually-validated
  framing (K8s Ready under QEMU virt+HVF, CoreDNS + local-path +
  nginx all Running) and a link to CHANGELOG.md for full notes.
- Roadmap: Phase 7 (generic ARM64) flipped to "Complete (v0.3.1, K8s
  Ready under QEMU virt+HVF)". OCI cosign verification, LABEL=KSOLODATA
  on ARM64, and real-hardware ARM64 validation move from "Planned for
  v0.3.1" to "Planned for v0.3.2" — they didn't make this release.

CHANGELOG:
- New "[Unreleased]" section covering the four post-v0.3.1 CI / repo
  housekeeping commits: drop tag trigger on build-arm64.yaml (04a5cd2),
  gitignore .env/credentials (48267e1), fix gated x86 job staying
  "queued" instead of "skipped" (fb24e64), and paths-ignore on
  build-arm64.yaml so workflow/docs-only commits skip the 60-minute
  kernel rebuild (e1b8a69).

No runtime changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 22:46:12 -06:00
e1b8a69294 ci(arm64): skip kernel rebuild on workflow/docs-only changes
All checks were successful
CI / Go Tests (push) Successful in 1m52s
CI / Shellcheck (push) Successful in 1m2s
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Successful in 1m31s
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Successful in 1m32s
`build-arm64.yaml` reruns the 60-minute mainline kernel build on every push
to main. That's the right behavior when kernel fragments / init scripts /
build scripts change — it's pure burn when only workflows or docs do.

Add `paths-ignore` for `.gitea/workflows/**`, `.github/workflows/**`,
`docs/**`, top-level `*.md`, `CHANGELOG.md`, `README.md`, `.gitignore`.

Any change that affects what we build (kernel fragment, module list, init,
build/) still triggers a fresh run.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 19:41:54 -06:00
fb24e641ce ci: fix gated x86 job staying 'queued' instead of 'skipped'
Some checks failed
CI / Go Tests (push) Has started running
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
ARM64 Build / Build generic ARM64 disk image (push) Failing after 14m12s
After v0.3.1 published successfully, run 524 stayed in 'queued' status
overall even though all 5 jobs that actually ran completed at success.
Cause: the gated build-iso-amd64 job is `if: false` with
`runs-on: amd64-linux`. No runner matches `amd64-linux`, so Gitea
queued the job indefinitely waiting for one. The `if:` expression
is only evaluated when a runner actually picks up the job, so the
skip never fires.

Switch the runs-on to `ubuntu-latest` (which our Odroid claims). The
runner picks the job up, evaluates `if: false`, marks it `skipped`,
and the run as a whole concludes properly.

Comment block updated to flag the two lines to flip when a real
amd64-linux runner is registered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 19:38:15 -06:00
48267e1cbc chore: gitignore .env / credentials files
Some checks failed
ARM64 Build / Build generic ARM64 disk image (push) Has been cancelled
CI / Go Tests (push) Failing after 11s
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been skipped
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been skipped
CI / Shellcheck (push) Successful in 1m9s
A .env file at the repo root was used to plumb a Gitea PAT to the
release workflow's API calls. It wasn't gitignored — risk of an
accidental `git add -A` shipping the secret to the public-ish remote.

Add .env / .env.* / *.token / *.pat to .gitignore so secrets stay
local. No content changes to .env itself; that file remains untracked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:55:59 -06:00
04a5cd2cd3 ci: drop tag trigger from build-arm64.yaml to avoid duplicate work
Some checks failed
ARM64 Build / Build generic ARM64 disk image (push) Has been cancelled
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
The v0.3.1 retag triggered BOTH .gitea/workflows/build-arm64.yaml AND
.gitea/workflows/release.yaml. Both build the ARM64 disk image from
scratch on the Odroid runner — each kernel build takes ~60 min. The
build-arm64 run finished first (uploaded as a workflow artifact, scoped
to that run), then release.yaml started another from-scratch build to
get the same artifact for the actual Gitea release. That's a wasted hour
on a constrained runner.

Limit build-arm64.yaml to push-to-main (for early breakage detection)
and manual workflow_dispatch. Tag-driven release pipelines are
release.yaml's job alone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:47:11 -06:00
5 changed files with 71 additions and 16 deletions

View File

@@ -1,11 +1,26 @@
name: ARM64 Build name: ARM64 Build
# Triggers on push to main and on tags. Skipped on PRs to keep PR feedback fast; # Smoke-test workflow for main-branch ARM64 builds. Triggers on push to main
# manual via Gitea UI ("Run workflow") if needed. # (so we catch breakages early) and on manual dispatch.
#
# Tag pushes are intentionally NOT a trigger — release.yaml handles tags and
# also produces the disk image. Triggering both on the same tag wastes an
# hour of Odroid time on a duplicate kernel build.
#
# `paths-ignore` keeps workflow-file and docs-only commits from kicking off
# a 60-minute Odroid rebuild. If you change a kernel fragment, init script,
# or build/script, this WILL fire — that's by design.
on: on:
push: push:
branches: [main] branches: [main]
tags: ['v*'] paths-ignore:
- '.gitea/workflows/**'
- '.github/workflows/**'
- 'docs/**'
- '*.md'
- 'CHANGELOG.md'
- 'README.md'
- '.gitignore'
workflow_dispatch: workflow_dispatch:
jobs: jobs:

View File

@@ -76,14 +76,15 @@ jobs:
build-iso-amd64: build-iso-amd64:
name: Build x86_64 ISO + disk image name: Build x86_64 ISO + disk image
# Routes to a runner with the `amd64-linux` label. As of v0.3.x no such # Gated until an amd64-linux runner is registered. We use `runs-on:
# runner exists in this Gitea instance — the only runner is the Odroid # ubuntu-latest` (which the Odroid claims) so SOME runner picks the job
# which is arm64 and would fail apt-installing grub-efi-amd64-bin / # up and evaluates `if: false`, marking it `skipped` instead of leaving
# syslinux because those packages aren't in the arm64 ports repo. The # it `queued` forever — the latter holds the overall run in `queued`
# job stays in the workflow (so it auto-runs once an amd64 runner is # state even when every load-bearing job is complete. When we get an
# registered) but is gated and the release job continues without it. # amd64 runner, flip `if: false` to `false` -> `true` (and flip the
if: false # remove this line once an amd64-linux runner is registered # `runs-on:` back to `amd64-linux`).
runs-on: amd64-linux if: false
runs-on: ubuntu-latest
needs: build-binaries needs: build-binaries
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

6
.gitignore vendored
View File

@@ -16,6 +16,12 @@ build/rootfs-work/
*.swo *.swo
*~ *~
# Secrets — never commit
.env
.env.*
*.token
*.pat
# OS # OS
.DS_Store .DS_Store
._* ._*

View File

@@ -5,6 +5,39 @@ All notable changes to KubeSolo OS are documented in this file.
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), 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). versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
Pure CI / repository housekeeping; no runtime changes since v0.3.1. All
items below shake out workflow-loop bugs exposed by the v0.3.1 release
flow on Gitea Actions.
### Fixed (CI)
- `build-arm64.yaml` no longer triggers on tag pushes. `release.yaml`
already produces the ARM64 disk image as part of the release flow, so
triggering both on the same tag wasted an hour of Odroid runner time
on a duplicate kernel build. (`04a5cd2`)
- The gated `build-iso-amd64` job in `release.yaml` (`if: false` until an
amd64-linux runner exists) used to advertise `runs-on: amd64-linux`.
With no matching runner, Gitea left the job queued forever and the
overall workflow run never transitioned to `success` — even though
every load-bearing job had finished and the release was already
published. Now uses `runs-on: ubuntu-latest` so any runner picks the
job up just long enough to evaluate `if: false` and mark it `skipped`.
(`fb24e64`)
- `build-arm64.yaml` now ignores workflow-file, docs, and `*.md` changes
via `paths-ignore` (`.gitea/workflows/**`, `.github/workflows/**`,
`docs/**`, top-level `*.md`, `.gitignore`). Workflow- / docs-only
commits no longer kick off a 60-minute kernel rebuild on the Odroid.
Any change to a kernel fragment, init script, or build script still
triggers the full build, as intended. (`e1b8a69`)
### Changed
- `.gitignore` now excludes `.env`, `.env.*`, `*.token`, `*.pat` to keep
Gitea PATs and other credentials used during release ops from being
accidentally committed. (`48267e1`)
## [0.3.1] - 2026-05-15 ## [0.3.1] - 2026-05-15
First fully-functional generic ARM64 release. v0.3.0 shipped the build First fully-functional generic ARM64 release. v0.3.0 shipped the build

View File

@@ -2,7 +2,7 @@
An immutable, bootable Linux distribution purpose-built for [KubeSolo](https://github.com/portainer/kubesolo) — Portainer's ultra-lightweight single-node Kubernetes. An immutable, bootable Linux distribution purpose-built for [KubeSolo](https://github.com/portainer/kubesolo) — Portainer's ultra-lightweight single-node Kubernetes.
> **Status (v0.3.0):** x86_64 and generic ARM64 (UEFI / virtio / mainline kernel) both build and boot end-to-end. Update agent has an explicit state machine, OCI registry distribution alongside HTTP, channel + maintenance-window + version-stepping-stone gates, and auto-rollback. ARM64 Raspberry Pi support remains paused pending physical hardware. See [docs/release-notes-0.3.0.md](docs/release-notes-0.3.0.md) for the full v0.3.0 changelog. > **Status (v0.3.1):** First fully-validated generic ARM64 release. x86_64 and ARM64 (UEFI / virtio / mainline kernel) both build and boot end-to-end; v0.3.1 closes the dual-glibc, nftables address-family, and kube-proxy expression-module gaps that kept v0.3.0 from reaching a Ready node on ARM64. Validated end-to-end under QEMU virt + HVF on Apple Silicon: `kubectl get nodes` reports `Ready`, CoreDNS, local-path-provisioner, and an nginx test workload all `Running`. The update agent has an explicit state machine, OCI registry distribution alongside HTTP, channel + maintenance-window + version-stepping-stone gates, and auto-rollback. ARM64 Raspberry Pi support remains paused pending physical hardware. See [CHANGELOG.md](CHANGELOG.md) for the full v0.3.1 changelog and [docs/release-notes-0.3.0.md](docs/release-notes-0.3.0.md) for the v0.3.0 milestone summary.
## What is this? ## What is this?
@@ -245,12 +245,12 @@ Metrics include: `kubesolo_os_info`, `boot_success`, `boot_counter`, `uptime_sec
| 5 | CI/CD, OCI distribution, Prometheus metrics, ARM64 cross-compile | Complete | | 5 | CI/CD, OCI distribution, Prometheus metrics, ARM64 cross-compile | Complete |
| 6 | Security hardening, AppArmor | Complete | | 6 | Security hardening, AppArmor | Complete |
| - | Custom kernel build for container runtime fixes | Complete (x86_64) | | - | Custom kernel build for container runtime fixes | Complete (x86_64) |
| 7 | ARM64 generic (mainline kernel, UEFI, virtio) | Complete (v0.3.0, QEMU validated) | | 7 | ARM64 generic (mainline kernel, UEFI, virtio) | Complete (v0.3.1, K8s Ready under QEMU virt+HVF) |
| 8 | Update engine v2 (state machine, channels, OCI, pre-flight gates) | Complete (v0.3.0) | | 8 | Update engine v2 (state machine, channels, OCI, pre-flight gates) | Complete (v0.3.0) |
| - | ARM64 Raspberry Pi (custom kernel, firmware, SD card image) | Paused — needs hardware | | - | ARM64 Raspberry Pi (custom kernel, firmware, SD card image) | Paused — needs hardware |
| - | OCI cosign signature verification | Planned for v0.3.1 | | - | OCI cosign signature verification | Planned for v0.3.2 |
| - | LABEL=KSOLODATA on ARM64 (replace blkid/findfs path) | Planned for v0.3.1 | | - | LABEL=KSOLODATA on ARM64 (replace blkid/findfs path) | Planned for v0.3.2 |
| - | Real-hardware ARM64 validation (Graviton / Ampere) | Planned for v0.3.1 | | - | Real-hardware ARM64 validation (Graviton / Ampere) | Planned for v0.3.2 |
## License ## License