# 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--linux-x86_64.tar.gz`, `fpagent--linux-i386.tar.gz` - offline: `fpagent--ubuntu--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--.tar.gz` 2. `-linux-.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--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.