#!/bin/sh # Install shelfkeeperd as a systemd user service. Portable: run it on any # Linux box with systemd (this machine, a Raspberry Pi, ...). # # ./deploy/install-service.sh [path-to-shelfkeeperd-binary] # # With no argument it builds the binary from the repo (needs Go on PATH or # in ~/sdk/go). With an argument it installs that prebuilt binary — use this # on a Pi after `GOOS=linux GOARCH=arm64 go build -o shelfkeeperd ./cmd/shelfkeeperd`. # # Layout it creates: # ~/.local/bin/shelfkeeperd the binary # ~/.local/bin/offimport the offline product-database importer # ~/.local/share/shelfkeeper/config key=value config (holds the API key) # ~/.local/share/shelfkeeper/shelfkeeper.db database # ~/.local/share/shelfkeeper/blobs/ photo blobs # ~/.local/share/shelfkeeper/off.sqlite product dump (copied if found) # ~/.config/systemd/user/shelfkeeper.service set -eu BIN_DIR="$HOME/.local/bin" DATA_DIR="$HOME/.local/share/shelfkeeper" UNIT_DIR="$HOME/.config/systemd/user" CONFIG="$DATA_DIR/config" REPO_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) mkdir -p "$BIN_DIR" "$DATA_DIR/blobs" "$UNIT_DIR" # --- binary --------------------------------------------------------------- if [ "${1:-}" ]; then cp "$1" "$BIN_DIR/shelfkeeperd" chmod +x "$BIN_DIR/shelfkeeperd" echo "prebuilt shelfkeeperd installed — offimport not built; build it yourself: go build -o $BIN_DIR/offimport ./cmd/offimport (or cross-build GOOS=linux GOARCH=arm64 CGO_ENABLED=0 on the dev box and copy it here)" else command -v go >/dev/null 2>&1 || PATH="$HOME/sdk/go/bin:$PATH" command -v go >/dev/null 2>&1 || { echo "no Go toolchain and no binary given" >&2; exit 1; } echo "building shelfkeeperd..." (cd "$REPO_DIR" && go build -o "$BIN_DIR/shelfkeeperd" ./cmd/shelfkeeperd) chmod +x "$BIN_DIR/shelfkeeperd" echo "building offimport..." (cd "$REPO_DIR" && go build -o "$BIN_DIR/offimport" ./cmd/offimport) chmod +x "$BIN_DIR/offimport" fi # --- config + API key (kept across reinstalls) ---------------------------- if [ ! -f "$CONFIG" ]; then KEY=$(head -c 24 /dev/urandom | base64 | tr -d '/+=' | head -c 32) umask 077 cat > "$CONFIG" < "$UNIT_DIR/shelfkeeper.service" </dev/null || echo "note: could not enable linger (service stops at logout)" echo "run: $BIN_DIR/offimport -install-cron -out $DATA_DIR/off.sqlite" # --- health probe (scheme and port follow the config) --------------------- # the port is whatever follows the LAST colon, so "[::1]:8443" works too PORT=$(sed -n 's/^ *addr *=.*:\([0-9][0-9]*\) *$/\1/p' "$CONFIG" | tail -1) PORT=${PORT:-8080} # The commented-out template lines start with '#', so they do not match: only # a config that really sets both keys switches the probe to https. if grep -qE '^[[:space:]]*tls_cert[[:space:]]*=' "$CONFIG" && grep -qE '^[[:space:]]*tls_key[[:space:]]*=' "$CONFIG"; then SCHEME=https # -k: the certificate is issued for the public name, not for "localhost". CURL_OPTS="-fsk" else SCHEME=http CURL_OPTS="-fs" fi sleep 1 if curl $CURL_OPTS "$SCHEME://localhost:$PORT/healthz" >/dev/null; then echo "shelfkeeper is up: $SCHEME://$(hostname):$PORT/ (key in $CONFIG)" else echo "service installed but /healthz not answering yet — check: systemctl --user status shelfkeeper" >&2 exit 1 fi