Files
tools-legacy/openspec/changes/archive/2026-10-06-fpagent-installer-multiarch/design.md
T
adebisi-fa 8d42faf707 docs(openspec): archive fpagent-installer-multiarch and sync specs
Bundle selection is now architecture-aware, not just codename-aware, and the
no-compatible-bundle failure names the host architecture. Merged into the
fpagent-installer spec and archived the change.
2026-10-06 19:19:23 +01:00

73 lines
3.2 KiB
Markdown

# Design: fpagent-installer-multiarch
## Context
The hosted installer (`tools/public/fpagent/install.sh`) runs on the field
laptop and proxies the private release through `tools.yrka.app`. It resolves
the release's asset names with a small `python3` snippet and hardcodes the
x86_64 suffix. fingerprint-agent v1.5.0 added an i386 build:
- online: `fpagent-<version>-linux-x86_64.tar.gz`, `fpagent-<version>-linux-i386.tar.gz`
- offline: `fpagent-<version>-ubuntu-<release>-x86_64.tar.gz` (x86_64 only)
The bundle's own installer already refuses a binary whose ELF class does not
match the host, so the hosted installer only has to pick the right asset.
## Goals / Non-goals
- Goal: on any supported host (x86_64, i386) pick the release bundle built for
that architecture, and record its version.
- Non-goal: changing `tools/server.js`. It proxies whatever the release lists,
and asset filtering/naming is unchanged.
- Non-goal: i386 offline (codename) bundles. fingerprint-agent ships those
x86_64-only; i386 hosts fall back to the generic online bundle whose
installer apt-get's libfprint.
- Non-goal: adding a production environment knob for the architecture. The
host's own `uname -m` is the source of truth.
## Decisions
### Architecture from `uname -m`, resolved once
Map `x86_64|amd64` → `x86_64`, `i386|i486|i586|i686` → `i386`, anything else →
fail before any download. This mirrors `deploy/install.sh` in fingerprint-agent
so the hosted and bundled installers agree on what is supported.
### Selection order: codename bundle, then generic, both arch-scoped
With `codename` from `/etc/os-release`:
1. `-ubuntu-<codename>-<arch>.tar.gz`
2. `-linux-<arch>.tar.gz`
The codename attempt is skipped when the host has no codename. Because offline
bundles are x86_64-only, an i386 host simply finds no codename asset and falls
to step 2. The suffix match keeps one architecture's bundle from ever matching
another's (`-linux-i386` does not end with `-linux-x86_64`).
### Version regex derived from the architecture
The version is the git hash embedded in the asset name. The existing regex only
listed the x86_64 endings, so it produced an empty version for an i386 bundle
and nothing was recorded. The regex must accept the same set of endings the
selection can produce: `linux-x86_64`, `linux-i386` and
`ubuntu-<codename>-x86_64`.
### Tests stub `uname`
The installer takes the architecture from the host, so a test cannot assert the
i386 path on an x86_64 CI box by running the real `uname`. A test prepends a
temp directory holding a fake `uname` to `PATH`, which is contained and needs no
production-only override. Assertions are made on the gateway requests the script
makes (which asset it asks for), the way the existing `--tag` test does.
## Risks / trade-offs
- A 64-bit userland on a 32-bit kernel is exotic; `uname -m` is the documented
choice for the bundled installer, so the hosted one follows it rather than
trying a second heuristic. `ponytail:` if such hosts appear, add a
`getconf LONG_BIT` fallback in both installers at once.
- The generated `install.sh --help` text duplicates the bundle installer's
flags list. It can drift again; keeping it short and pointing at the bundle
installer's own help limits the cost.