feat(fpagent): public installer and private-release proxy
Serve /fpagent/install.sh (also curl|bash) and proxy the private fingerprint-agent releases through /fpagent/releases/* using GITEA_RELEASE_INSTALL_KEY, so a field laptop needs no forge credentials. The installer picks the offline bundle for the host codename when present, verifies the published sha256, then hands off to the bundle's own installer.
This commit is contained in:
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env bash
|
||||
# install.sh — download and install the latest YOUreka Fingerprint Agent
|
||||
# (fpagent) release on this machine.
|
||||
#
|
||||
# Hosted at https://tools.yrka.app/fpagent/install.sh and meant to be piped
|
||||
# straight into bash on a field laptop:
|
||||
#
|
||||
# curl -fsSL https://tools.yrka.app/fpagent/install.sh | bash
|
||||
#
|
||||
# It downloads the bundle, verifies its sha256, then hands off to the bundle's
|
||||
# own installer, which handles libfprint, the udev rule, plugdev and the
|
||||
# systemd service. Every flag is forwarded to that installer, e.g.:
|
||||
#
|
||||
# curl -fsSL https://tools.yrka.app/fpagent/install.sh | bash -s -- --enable-service
|
||||
# curl -fsSL https://tools.yrka.app/fpagent/install.sh | bash -s -- --check
|
||||
#
|
||||
# The private release is reached through the tools app, so no credentials are
|
||||
# needed here.
|
||||
set -euo pipefail
|
||||
|
||||
BASE="${FPAGENT_BASE_URL:-https://tools.yrka.app/fpagent}"
|
||||
|
||||
say() { printf '%s\n' "$*"; }
|
||||
die() { printf '[FAIL] %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: curl -fsSL ${BASE}/install.sh | bash -s -- [installer options]
|
||||
|
||||
Downloads the latest fpagent release, verifies it, and runs its installer.
|
||||
Options are forwarded to that installer:
|
||||
--check preflight and report only; change nothing
|
||||
--offline never touch the network; fail if dependencies are missing
|
||||
--enable-service install and enable a systemd service (starts at boot)
|
||||
--service-user NAME user for the service (default: the invoking user)
|
||||
--install-path PATH binary destination (default: /usr/local/bin/fpagent)
|
||||
--uninstall remove the binary, the udev rule and the service
|
||||
-h, --help the installer's help
|
||||
|
||||
Environment:
|
||||
FPAGENT_BASE_URL override the download base (default: ${BASE})
|
||||
EOF
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for cmd in curl tar sha256sum python3; do
|
||||
command -v "$cmd" >/dev/null 2>&1 || die "$cmd is required but not installed"
|
||||
done
|
||||
|
||||
# Offline bundles ship the libfprint .deb closure for a specific Ubuntu
|
||||
# release; prefer the one matching this machine, else fall back to the generic
|
||||
# online bundle (whose installer apt-get's the dependency).
|
||||
codename="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release 2>/dev/null | tr -d '"')"
|
||||
|
||||
say "Fetching the latest Fingerprint Agent release..."
|
||||
meta="$(curl -fsSL "${BASE}/releases/latest")" || die "could not fetch the release list from ${BASE}"
|
||||
|
||||
readout="$(python3 -c '
|
||||
import json, sys
|
||||
codename = sys.argv[1]
|
||||
release = json.loads(sys.argv[2])
|
||||
assets = [a["name"] for a in release.get("assets", [])]
|
||||
|
||||
def pick(suffix):
|
||||
return next((n for n in assets if n.endswith(suffix) and not n.endswith(".sha256")), "")
|
||||
|
||||
name = pick("-ubuntu-" + codename + "-x86_64.tar.gz") if codename else ""
|
||||
if not name:
|
||||
name = pick("-linux-x86_64.tar.gz")
|
||||
print(release.get("tag", "") + "\t" + name)
|
||||
' "$codename" "$meta")" || die "could not parse the release metadata"
|
||||
|
||||
tag="${readout%%$'\t'*}"
|
||||
asset="${readout#*$'\t'}"
|
||||
[ -n "$tag" ] && [ -n "$asset" ] || die "no compatible bundle in the latest release (x86_64 required)"
|
||||
|
||||
say " release ${tag}"
|
||||
say " bundle ${asset}"
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
get() { curl -fsSL "$1" -o "$2" || die "download failed: $1"; }
|
||||
|
||||
say "Downloading and verifying..."
|
||||
get "${BASE}/releases/download/${tag}/${asset}" "${tmp}/${asset}"
|
||||
get "${BASE}/releases/download/${tag}/${asset}.sha256" "${tmp}/${asset}.sha256"
|
||||
(cd "$tmp" && sha256sum -c "${asset}.sha256") || die "checksum verification failed for ${asset}"
|
||||
|
||||
tar xzf "${tmp}/${asset}" -C "$tmp" || die "could not extract ${asset}"
|
||||
[ -x "${tmp}/install.sh" ] || die "the bundle does not contain install.sh"
|
||||
|
||||
say "Running the installer (pass --enable-service to start at boot)..."
|
||||
"${tmp}/install.sh" "$@"
|
||||
Reference in New Issue
Block a user