feat(install): generic-arm64 best-effort support (Armbian SBCs)#2879
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends Anthias’ installer, image build pipeline, and viewer runtime wiring to support a best-effort generic-arm64 device type for non-Raspberry-Pi aarch64 SBCs (e.g., Armbian on Rock Pi / Orange Pi / Banana Pi), while also fixing a host-agent systemd venv regression and improving network interface detection on SBCs.
Changes:
- Add
generic-arm64device detection across install/upgrade scripts, Ansible validation/mapping, and CI image publishing (latest-generic-arm64). - Reuse the existing x86 Qt6 + cage + Wayland mpv viewer path for
generic-arm64(omitting VAAPI drivers). - Fix host-agent systemd ExecStart venv path by provisioning a persistent
~/.anthias-venvand expand host-agent NIC prefix detection (end*).
Reviewed changes
Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
website/layouts/_default/get-started.html |
Update supported-hardware copy/table and add best-effort ARM SBC note. |
website/data/faq.yaml |
Add/expand FAQ entries describing generic ARM SBC support and limitations. |
website/content/get-started.md |
Update page metadata description to include generic ARM SBCs. |
tools/image_builder/utils.py |
Add generic-arm64 build target and align viewer deps/wiring with x86 (cage/Wayland). |
tools/image_builder/constants.py |
Allow generic-arm64 as a build target option. |
tests/test_media_player.py |
Add a MediaPlayerProxy selection test for generic-arm64. |
src/anthias_viewer/media_player.py |
Route generic-arm64 to mpv and Wayland VO like x86; use env override to avoid pi1 fallback misrouting. |
src/anthias_host_agent/__main__.py |
Include end* NIC prefix so SBC Ethernet interfaces are detected for IP display. |
README.md |
Document best-effort generic ARM SBC support and expectations. |
docker/Dockerfile.viewer.j2 |
Use Wayland Qt platform for generic-arm64 same as x86. |
bin/upgrade_containers.sh |
Add aarch64 fallback to generic-arm64 and strip Pi-only /dev/vchiq devices for it. |
bin/start_viewer.sh |
Run viewer under cage for generic-arm64 same as x86. |
bin/install.sh |
Add generic-arm64 support, skip Pi-only Ansible tags, guard sources.list rewrite, and only call main when executed directly. |
ansible/site.yml |
Validate DEVICE_TYPE=generic-arm64. |
ansible/roles/system/tasks/docker.yml |
Map generic-arm64 to arm64 and install docker-buildx-plugin. |
ansible/roles/anthias/templates/anthias-host-agent.service |
Point host-agent ExecStart to the new persistent venv. |
ansible/roles/anthias/tasks/main.yml |
Create a persistent ~/.anthias-venv via uv sync for host-managed services. |
.github/workflows/scripts/mirror-latest-tags.sh |
Mirror latest-generic-arm64 tags alongside existing boards. |
.github/workflows/docker-build.yaml |
Add generic-arm64 to the docker-build matrix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… Orange Pi, …) Wires up a `generic-arm64` device_type so the installer recognises any aarch64 host that isn't a Raspberry Pi and runs the same Anthias stack on it. Closes #2849 (Tier 1). * `bin/install.sh::set_device_type` + `bin/upgrade_containers.sh` get an `aarch64` fallback branch, INTRO_MESSAGE / unsupported-message copy refreshed, raspberry-pi-tagged ansible tasks skipped on generic-arm64 (same as x86), vchiq strip extended. * ansible: validated set in `site.yml`, `docker_arch_by_device_type` gains `generic-arm64: arm64`. `docker-buildx-plugin` added to the apt-install list — required for MODE=build with `--platform=` Dockerfiles, harmless on pull-mode boards. Pre-existing host_agent service unit hardcoded `~/installer_venv/bin/python` (an ephemeral tmpdir post-#2843); split into a persistent `~/.anthias-venv` that ansible syncs before installing the unit. * image_builder: `generic-arm64` build target, Qt6 + cage + wayland like x86; `va-driver-all` deliberately *not* shipped — Rockchip / Allwinner / Amlogic mainline hwdec goes through V4L2 M2M / request API, not VAAPI, so mesa-va-drivers would be dead weight. * viewer: `start_viewer.sh` reuses the x86 cage path for generic-arm64; `media_player.py` routes generic-arm64 to MPV (the `device_helper.get_device_type()` fallback returns 'pi1' on non-Pi aarch64 hosts, so the proxy needs the DEVICE_TYPE env override that pi4-64 already uses). New test added. * host_agent: `SUPPORTED_INTERFACES` gains `end` prefix — Rockchip GMAC etc. surface as `end0` on systemd predictable naming, which was previously filtered out, leaving the splash page stuck on "Detecting network…". * CI: docker-build matrix + mirror-latest-tags publish `latest-generic-arm64` alongside the existing per-board tags. * Docs: README, marketing site supported-hardware table, and FAQ get a plain-language "Yes, on a best-effort basis" entry that spells out the software-decode trade-off, the SoCs known to work well (RK3399 / RK35xx / Allwinner H6 / Amlogic GXBB-GXL-GXM / S905X3), and the boards to avoid (Allwinner H616 / H618). Per-SoC hardware decode (`rkmpp`, `cedrus`, `meson-vdec`) is the planned Tier-2 follow-up. Validated end-to-end on a Rock Pi 4B (Armbian trixie, RK3399, 1GB RAM) via build-on-device: install completes, web UI reachable, all four asset types (image, H.264 1080p60, H.265 1080p60, webpage) cycle through the viewer cleanly, mpv pure-decode benchmark shows 0 dropped frames over the full 60s of each clip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… task ansible-lint's partial-become rule fires on `become_user:` without a matching `become:` at the same level, even when the play-level become already covers it. Explicit pairing keeps lint quiet without changing runtime behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ansible: drop `creates:` guard on the runtime venv sync — `uv sync` is idempotent (sub-second resolver check when nothing changed), so re-running unconditionally means dependency updates from a pyproject.toml / uv.lock change actually land on upgrade instead of silently skipping. Idempotency surfaced via `changed_when` keyed on uv's `+/-/~` package-action prefix so steady-state runs stay `ok`. - ansible: rework docker-buildx-plugin comment to justify the install on its own merits (any MODE=build run needs it because of `FROM --platform=$BUILDPLATFORM` in Dockerfiles) rather than tying it to generic-arm64 lacking published tags — that explanation becomes stale the moment this PR merges and CI publishes them. - viewer: `get_alsa_audio_device()` short-circuits on `DEVICE_TYPE=generic-arm64` before the Pi-firmware dispatch, since the Rock Pi / Orange Pi / Banana Pi class of board has none of the `vc4hdmi*` or `Headphones` ALSA cards. Defers to ALSA's `default` device; operators with a non-standard sink can override via `~/.asoundrc` (already bind-mounted into the viewer container). - tests: new assertions that generic-arm64 routes mpv through `--vo=gpu --gpu-context=wayland` and `--audio-device=alsa/default`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d7ec3af to
6a961f2
Compare
…ware copy Copilot flagged the previous wording — "running Raspberry Pi OS, Debian, or Armbian (Trixie or Bookworm)" — as misleading: the parenthetical reads as if Raspberry Pi OS and Armbian are themselves "Trixie or Bookworm", but those are Debian codenames, and Armbian builds can also be Ubuntu-based. Split the sentence so the codenames are tied explicitly to Debian. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot caught that the `is_raspberry_pi` helper in docker.yml was defined as `ansible_architecture in ['aarch64', 'armv7l', 'armv6l']`, which is also true on generic-arm64 (Rock Pi / Orange Pi / …). That silently applied the Pi-only `gpio` group to non-Pi SBCs. device_type is the authoritative discriminator and is validated upstream in ansible/site.yml's pre_tasks, so use it directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per review feedback: `generic-arm64` was the original working name for the new aarch64 non-Pi fallback. `arm64` is shorter and parallels `x86` — both are architecture-generic device_types that catch any host without a board-specific image, sitting alongside the per-board labels (pi2 / pi3 / pi4-64 / pi5). User-facing prose still says "generic 64-bit ARM" or "Armbian on Rock Pi / Orange Pi / …" for context. Mechanical s/generic-arm64/arm64/ across install scripts, ansible, image_builder, viewer / start_viewer, host_agent, tests, CI matrix, mirror-latest-tags, Dockerfile.viewer.j2, README. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Master's #2881 (e2e-test findings) added an `installer_venv` persistent venv provisioned by `bin/install.sh::provision_host_agent_venv` and kept the systemd unit ExecStart pointed at that stable path. Drops the duplicate ansible-side `.anthias-venv` task and reverts the unit-template path I'd introduced — master's approach is upstream and avoids rewriting the unit path on devices installed pre-refactor. * Master's #2880 replaced the gum UI with whiptail. The auto-merge took whiptail's wiring; my arm64-aware INTRO_MESSAGE / set_device_type / Pi-tag-skip branches survived alongside it. * Master's #2878 viewer locale changes auto-merged with my arm64 start_viewer.sh conditional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- viewer: get_alsa_audio_device's arm64 short-circuit now logs the registered ALSA cards (from /proc/asound/cards — aplay isn't in the viewer image) once per process when DEVICE_TYPE=arm64, so an operator reporting "no HDMI audio" carries enough breadcrumbs in journalctl alone to pick the right ~/.asoundrc override. - ansible: rewrite the docker-buildx-plugin size claim — 15 MB download / 67 MB extracted, from the deb metadata on arm64. - viewer: MediaPlayerProxy.get_instance comment block split into a two-bullet rationale, calling out the pi4-64 and arm64 cases separately so a future reader doesn't mistake the lead sentence for "pi4-64-only". - install.sh / upgrade_containers.sh: spell out that the aarch64 catch-all in set_device_type is intentional — a future Pi model whose model string drifts past the regexes lands here too, trading software decode + no Pi-boot tweaks for a louder fail. - README + FAQ: tighten the Plymouth caveat from "few seconds of black" to "kernel boot log scrolls until the viewer takes over", which is what actually happens on most U-Boot ARM SBCs. - ansible: rename the docker.yml var from `is_raspberry_pi` to `device_is_pi` now that it's derived from device_type rather than `ansible_architecture`, so the name matches what it does. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
Copilot flagged that "Armbian" in the new docs is ambiguous —
Armbian builds come in both Debian-based (Bookworm/Trixie) and
Ubuntu-based (Jammy/Noble) flavours. The installer's ansible role
wires Docker's apt repo under
download.docker.com/linux/debian/{{ ansible_distribution_release }},
which 404s on the Ubuntu codenames, so an Ubuntu-Armbian user
following the current docs would hit a broken install at the very
first `apt update`.
Narrowing the wording in README, the marketing site's
supported-hardware blurb, and the FAQ to "Debian-based Armbian" so
users pick the right image. Extending the installer/playbook to
handle Ubuntu-based Armbian is a separate follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
| <div class="max-w-3xl mx-auto"> | ||
| <h2 id="supported-hardware" class="text-2xl font-bold">Supported hardware</h2> | ||
| <p class="text-zinc-500 mt-2">Anthias runs on Raspberry Pi single-board computers and 64-bit x86 PCs running Raspberry Pi OS or Debian (Trixie or Bookworm).</p> | ||
| <p class="text-zinc-500 mt-2">Anthias runs on Raspberry Pi single-board computers, 64-bit x86 PCs, and 64-bit ARM single-board computers (Rock Pi, Orange Pi, Banana Pi and similar via Armbian). Supported on Raspberry Pi OS, Debian (Trixie or Bookworm), and the corresponding Armbian builds.</p> |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #2849 (Tier 1).
Summary
arm64as a recognisedDEVICE_TYPEso the installer accepts any aarch64 host that isn't a Raspberry Pi (Armbian on Rock Pi, Orange Pi, Banana Pi and similar).va-driver-alldeliberately omitted (Rockchip / Allwinner / Amlogic mainline hwdec is V4L2 M2M / request API, not VAAPI —mesa-va-driverswould be dead weight on these SoCs; per-SoC hwdec is a Tier-2 follow-up).latest-arm64alongside the existing per-board tags, so the next merge gives normalMODE=pullinstalls a published image to land on.Notable code paths
bin/install.sh::set_device_typeandbin/upgrade_containers.shget anaarch64fallback branch.bin/install.sh::run_ansible_playbookextends the--skip-tags raspberry-piskip to arm64 (the Pi boot-partition tweaks don't apply on Armbian).ansible/site.ymlvalidated-set +docker_arch_by_device_typemap gainarm64.docker-buildx-pluginadded to the ansible apt-install list — needed forMODE=buildDockerfiles that use--platform=$BUILDPLATFORM(legacy builder dies on the very first FROM); harmless on pull-mode boards.tools/image_buildergets aarm64build target; viewer Dockerfile / runtime apt list /start_viewer.sh/media_player.pytreat arm64 the same as x86 (no/dev/fb0, cage compositor, mpv--vo=gpu --gpu-context=wayland).MediaPlayerProxypicks MPV via theDEVICE_TYPEenv override that pi4-64 already uses, sincedevice_helper.get_device_type()falls back to 'pi1' on any non-Pi aarch64 host.host_agent::SUPPORTED_INTERFACESgains theendprefix so Rockchip GMACs (which surface asend0under systemd predictable naming) show up in the splash page's IP list instead of leaving it stuck on "Detecting network…".Drive-by fixes uncovered by this work
anthias-host-agent.servicewas pinned to~/installer_venv/bin/python, which became an ephemeral tmpdir in fix(install): tmpdir installer_venv on Bookworm; drop getmac dep #2843 — service failed203/EXECon every install since. Split into a persistent~/.anthias-venvsynced by a new ansible task before the unit is enabled.bin/install.sh::install_packagesransed -i ... /etc/apt/sources.listunconditionally on non-x86; that file doesn't exist on Armbian (deb822 layout), soset -ekilled the installer. Now guarded by[ -f /etc/apt/sources.list ].Docs
Test plan
http://<ip>/(HTTP 200)./api/v2/network/ip-addressesreturns["192.168.200.155"]once host-agent service starts (was failing pre-fix).latest-arm64tags successfully (verified on next push to master).🤖 Generated with Claude Code