chore: housekeeping for v0.3 prep
- Pin KUBESOLO_VERSION in versions.env (was soft-defaulted in fetch-components.sh) - Gitignore screenshots, macOS resource forks, and common image extensions - Update README roadmap: x86_64 stable, ARM64 generic in progress (v0.3), ARM64 RPi paused pending hardware - Add docs/ci-runners.md documenting the Odroid arm64-linux Gitea runner Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
165
docs/ci-runners.md
Normal file
165
docs/ci-runners.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# CI Runners
|
||||
|
||||
KubeSolo OS is built and tested on Gitea Actions runners. This document records the
|
||||
runners currently in service and how to register a new one if a host is wiped.
|
||||
|
||||
## Active runners
|
||||
|
||||
| Name | Host | Arch | OS | Labels | Notes |
|
||||
|------|------|------|-----|--------|-------|
|
||||
| `odroid-arm64` | `odroid.local` | aarch64 | Ubuntu 22.04 LTS | `arm64-linux`, `ubuntu-latest`, `ubuntu-24.04`, `ubuntu-22.04` | Native ARM64 builder; 6 cores, 1.8 GB RAM + 4 GB swap; runs as systemd service `act_runner` |
|
||||
|
||||
## Workflow targeting
|
||||
|
||||
ARM64-specific jobs target the Odroid via the `arm64-linux` label:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-arm64:
|
||||
runs-on: arm64-linux
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: make rootfs-arm64
|
||||
```
|
||||
|
||||
Generic ubuntu jobs that don't care about arch fall through to whichever runner picks
|
||||
them up first; on the Odroid they run in Docker via the `ubuntu-latest` /
|
||||
`ubuntu-22.04` / `ubuntu-24.04` labels.
|
||||
|
||||
## Registering a new runner
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Linux host (Ubuntu / Debian preferred; the install instructions below use Ubuntu
|
||||
22.04+ paths).
|
||||
- Outbound HTTPS to the Gitea instance.
|
||||
- Root access on the runner host (the runner needs to create loop devices and run
|
||||
`mkfs.ext4` for disk-image builds).
|
||||
- A Gitea Actions runner registration token. Get it from:
|
||||
- **Repo-scoped:** `<repo>/settings/actions/runners` → "Create new Runner"
|
||||
- **Org-scoped (preferred for this project):** `<org>/-/settings/actions/runners` →
|
||||
"Create new Runner"
|
||||
- **Site-scoped:** `/-/admin/actions/runners` → "Create new Runner"
|
||||
|
||||
### Step 1 — Add swap if the host has <4 GB RAM
|
||||
|
||||
Kernel builds in later phases need ~2 GB resident; tight hosts will OOM-kill `cc1`
|
||||
without swap.
|
||||
|
||||
```bash
|
||||
sudo fallocate -l 4G /swapfile
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||
```
|
||||
|
||||
### Step 2 — Install the gitea-runner binary
|
||||
|
||||
Pinned to a known-good version. Check
|
||||
<https://gitea.com/gitea/runner/releases> for the current stable tag before
|
||||
bumping.
|
||||
|
||||
```bash
|
||||
sudo -i
|
||||
mkdir -p /opt/act_runner && cd /opt/act_runner
|
||||
|
||||
# Bump VERSION to the current stable release as needed
|
||||
VERSION=1.0.3
|
||||
ARCH=$(uname -m | sed 's/aarch64/arm64/; s/x86_64/amd64/')
|
||||
|
||||
curl -fL "https://gitea.com/gitea/runner/releases/download/v${VERSION}/gitea-runner-${VERSION}-linux-${ARCH}" \
|
||||
-o act_runner
|
||||
chmod +x act_runner
|
||||
./act_runner --version
|
||||
```
|
||||
|
||||
> The upstream project was renamed `act_runner` → `gitea-runner` at the v1.0.0
|
||||
> release. The release asset filenames use `gitea-runner-*` even though we keep the
|
||||
> local binary named `act_runner` to match this systemd unit. The CLI surface
|
||||
> (`register`, `daemon`, `generate-config`) is unchanged.
|
||||
|
||||
### Step 3 — Register against Gitea
|
||||
|
||||
```bash
|
||||
./act_runner register --no-interactive \
|
||||
--instance https://git.oe74.net \
|
||||
--token PASTE_TOKEN_HERE \
|
||||
--name <hostname> \
|
||||
--labels arm64-linux # adjust label for amd64 hosts
|
||||
```
|
||||
|
||||
This creates a `.runner` file with the registration credentials.
|
||||
|
||||
### Step 4 — Generate and tune config
|
||||
|
||||
```bash
|
||||
./act_runner generate-config > config.yaml
|
||||
```
|
||||
|
||||
In `config.yaml`, confirm the `runner.labels:` block includes the labels you want.
|
||||
The `:host` suffix routes jobs directly to the host (no Docker wrapper) — required
|
||||
for disk-image builds that need loop devices and `mkfs`.
|
||||
|
||||
Example labels for an arm64 host:
|
||||
|
||||
```yaml
|
||||
runner:
|
||||
labels:
|
||||
- "arm64-linux:host"
|
||||
- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
|
||||
- "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04"
|
||||
- "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
|
||||
```
|
||||
|
||||
### Step 5 — Install as a systemd service
|
||||
|
||||
```bash
|
||||
cat > /etc/systemd/system/act_runner.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Gitea Actions runner
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/opt/act_runner/act_runner daemon --config /opt/act_runner/config.yaml
|
||||
WorkingDirectory=/opt/act_runner
|
||||
User=root
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now act_runner
|
||||
systemctl status act_runner --no-pager
|
||||
```
|
||||
|
||||
### Step 6 — Verify in Gitea UI
|
||||
|
||||
Visit the runners page at the scope you registered against. The runner should appear
|
||||
as `Idle` with the labels you configured.
|
||||
|
||||
## Removing a runner
|
||||
|
||||
On the host:
|
||||
|
||||
```bash
|
||||
systemctl disable --now act_runner
|
||||
rm -rf /opt/act_runner /etc/systemd/system/act_runner.service
|
||||
systemctl daemon-reload
|
||||
```
|
||||
|
||||
Then delete the runner entry from the Gitea Actions UI so Gitea stops trying to
|
||||
schedule against it.
|
||||
|
||||
## Operational notes
|
||||
|
||||
- The runner stores in-progress job working directories under `/tmp/act_runner` by
|
||||
default. Large disk-image builds may need that path moved to a larger volume —
|
||||
edit `host.workdir_parent:` in `config.yaml`.
|
||||
- Logs are visible via `journalctl -u act_runner -f`.
|
||||
- If a job is interrupted (e.g. host reboot mid-build), the Gitea UI will mark it as
|
||||
failed/cancelled. Re-run from the Actions UI.
|
||||
Reference in New Issue
Block a user