- hamlab install / uninstall (internal/setup): systemd or OpenRC, elevates through sudo or doas, runs as the invoking user, sets or generates the password, names only journal groups that exist, waits for /healthz, reports an active firewalld/ufw. --purge and the data chown never touch a directory that isn't Ham Lab's alone. - install.sh: curl-able bootstrap (arch detection, SHA256SUMS, offline beside the binaries, noexec /tmp fallback). make release builds dist/ for amd64, arm64, arm (ARMv6), 386, riscv64. Every build is CGO_ENABLED=0; the native one used to link glibc. - internal/priv replaces every literal `sudo -n`: uid 0, sudo or doas. - Updates acts on dnf, zypper, pacman and apk as well as apt; dnf shows installed versions. - Services falls back to the plain systemctl table before systemd 246 and says so on hosts without systemd. Disks falls back to /sys/block without lsblk. - Listener binds with IP_FREEBIND, so a LAN address that isn't up at boot is no failure. - Self-update: the new build must pass `check` against the live config, is put in place by atomic rename, and the daemon re-execs itself (same under any supervisor). - State and config writes are fsynced; a corrupt state.json is set aside, not fatal. - Terminal shutdown no longer empties the saved list, so names come back after a restart by design rather than by winning a race. - Config default is ~/.config/hamlab; an existing ~/apps/hamlab is still found. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
78 lines
3.0 KiB
Bash
Executable File
78 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# Ham Lab installer: fetches the build for this machine and hands over to `hamlab install`,
|
|
# which sets up the binary, config, login password and a boot-time service.
|
|
#
|
|
# curl -fsSL "$HAMLAB_URL/install.sh" | sh
|
|
# curl -fsSL "$HAMLAB_URL/install.sh" | sh -s -- --listen 0.0.0.0:8100 --tls auto
|
|
# ./install.sh # beside the hamlab-linux-* files: installs offline
|
|
#
|
|
# Everything after `--` goes to `hamlab install` (see `hamlab install -h`).
|
|
#
|
|
# HAMLAB_URL where hamlab-linux-<arch> and SHA256SUMS are served from
|
|
# HAMLAB_TOKEN access token, when that place is a private Gitea/Forgejo repo
|
|
set -eu
|
|
|
|
HAMLAB_URL="${HAMLAB_URL:-https://git.bigham.dev/mitchell/hamlab/releases/download/@VERSION@}"
|
|
|
|
die() { echo "install.sh: $*" >&2; exit 1; }
|
|
|
|
[ "$(uname -s)" = Linux ] || die "Ham Lab runs on Linux; this is $(uname -s)"
|
|
case "$(uname -m)" in
|
|
x86_64|amd64) arch=amd64 ;;
|
|
aarch64|arm64) arch=arm64 ;;
|
|
armv6l|armv7l|armv8l|arm) arch=arm ;;
|
|
i386|i486|i586|i686) arch=386 ;;
|
|
riscv64) arch=riscv64 ;;
|
|
*) die "no build for $(uname -m) (have: amd64, arm64, arm, 386, riscv64)" ;;
|
|
esac
|
|
file="hamlab-linux-$arch"
|
|
|
|
tmp=$(mktemp -d 2>/dev/null || mktemp -d -t hamlab)
|
|
trap 'rm -rf "$tmp"' EXIT INT TERM
|
|
|
|
fetch() { # url dest
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl -fsSL ${HAMLAB_TOKEN:+-H "Authorization: token $HAMLAB_TOKEN"} -o "$2" "$1"
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
wget -q ${HAMLAB_TOKEN:+--header="Authorization: token $HAMLAB_TOKEN"} -O "$2" "$1"
|
|
else
|
|
die "need curl or wget"
|
|
fi
|
|
}
|
|
|
|
here=$(cd "$(dirname "$0")" 2>/dev/null && pwd || echo .)
|
|
if [ -f "$here/$file" ]; then
|
|
cp "$here/$file" "$tmp/hamlab"
|
|
[ -f "$here/SHA256SUMS" ] && cp "$here/SHA256SUMS" "$tmp/SHA256SUMS"
|
|
else
|
|
echo "Downloading $file" >&2
|
|
fetch "$HAMLAB_URL/$file" "$tmp/hamlab" || die "download failed: $HAMLAB_URL/$file"
|
|
fetch "$HAMLAB_URL/SHA256SUMS" "$tmp/SHA256SUMS" 2>/dev/null || rm -f "$tmp/SHA256SUMS"
|
|
fi
|
|
|
|
if [ -f "$tmp/SHA256SUMS" ] && command -v sha256sum >/dev/null 2>&1; then
|
|
want=$(awk -v f="$file" '$2 == f || $2 == "*" f { print $1 }' "$tmp/SHA256SUMS")
|
|
got=$(sha256sum "$tmp/hamlab" | awk '{ print $1 }')
|
|
[ -n "$want" ] || die "SHA256SUMS has no entry for $file"
|
|
[ "$want" = "$got" ] || die "checksum mismatch for $file"
|
|
fi
|
|
|
|
chmod 0755 "$tmp/hamlab"
|
|
bin="$tmp/hamlab"
|
|
if ! "$bin" version >/dev/null 2>&1; then
|
|
# a noexec /tmp is the usual reason: try from the home directory
|
|
alt="${HOME:-/root}/.hamlab-install.$$"
|
|
trap 'rm -rf "$tmp" "$alt"' EXIT INT TERM
|
|
cp "$bin" "$alt" 2>/dev/null && chmod 0755 "$alt" || true
|
|
"$alt" version >/dev/null 2>&1 || die "the $arch build doesn't run on this machine"
|
|
bin="$alt"
|
|
fi
|
|
|
|
# Piped from curl, stdin is this script: take the password prompt from the terminal.
|
|
case " $* " in *password-stdin*) piped=0 ;; *) piped=1 ;; esac
|
|
if [ "$piped" = 1 ] && [ ! -t 0 ] && [ -r /dev/tty ] && (: </dev/tty) 2>/dev/null; then
|
|
"$bin" install "$@" </dev/tty
|
|
else
|
|
"$bin" install "$@"
|
|
fi
|