Files
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

3.2 KiB

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.