From 14ac2ae47113b8607bd6743ea26ee2b4060b6c15 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Tue, 3 Mar 2026 13:14:55 -0800 Subject: [PATCH] Add install/update script --- install/update.sh | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100755 install/update.sh diff --git a/install/update.sh b/install/update.sh new file mode 100755 index 0000000..1d1d5af --- /dev/null +++ b/install/update.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +set -euo pipefail + +## +# toes install / update +# Usage: curl -fsSL https://toes.dev/update | sh +# +# Installs or updates toes on a Raspberry Pi. +# Must be run as the 'toes' user with passwordless sudo. + +REPO="https://git.nose.space/defunkt/toes" +DEST=~/toes +APPS_DIR=~/apps +DATA_DIR=~/data + +BUNDLED_APPS="clock code cron env git metrics" + +# ── Helpers ────────────────────────────────────────────── + +quiet() { "$@" > /dev/null 2>&1; } + +info() { echo ">> $1"; } + +fail() { echo "ERROR: $1" >&2; exit 1; } + +# ── Preflight ──────────────────────────────────────────── + +echo "" +echo " toes - personal web appliance" +echo "" + +[ "$(whoami)" = "toes" ] || fail "Must be run as the 'toes' user." +sudo -n true 2>/dev/null || fail "Requires passwordless sudo." + +# ── System packages ────────────────────────────────────── + +info "Updating system packages" +quiet sudo apt-get update +quiet sudo apt-get install -y git libcap2-bin avahi-utils fish unzip + +if [ "$(getent passwd toes | cut -d: -f7)" != "/usr/bin/fish" ]; then + info "Setting fish as default shell" + quiet sudo chsh -s /usr/bin/fish toes +fi + +# ── Bun ────────────────────────────────────────────────── + +BUN="$HOME/.bun/bin/bun" + +if [ ! -x "$BUN" ]; then + info "Installing bun" + curl -fsSL https://bun.sh/install | bash > /dev/null 2>&1 + [ -x "$BUN" ] || fail "bun installation failed." +fi + +if [ ! -x /usr/local/bin/bun ]; then + sudo ln -sf "$BUN" /usr/local/bin/bun +fi + +sudo setcap 'cap_net_bind_service=+ep' "$BUN" + +# ── Clone or pull ──────────────────────────────────────── + +if [ -d "$DEST/.git" ]; then + info "Pulling latest toes" + git -C "$DEST" fetch origin main + git -C "$DEST" reset --hard origin/main +else + info "Cloning toes" + git clone "$REPO" "$DEST" +fi + +# ── Directories ────────────────────────────────────────── + +mkdir -p "$APPS_DIR" "$DATA_DIR" + +# ── Dependencies & build ───────────────────────────────── + +info "Installing dependencies" +cd "$DEST" && quiet bun install + +info "Building" +cd "$DEST" && quiet bun run build + +# ── Bundled apps ───────────────────────────────────────── + +info "Installing bundled apps" +for app in $BUNDLED_APPS; do + [ -d "$DEST/apps/$app" ] || continue + echo " $app" + cp -r "$DEST/apps/$app" "$APPS_DIR/" + if [ -f "$APPS_DIR/$app/package.json" ]; then + quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app" + fi +done + +# ── Systemd ────────────────────────────────────────────── + +info "Installing toes service" +sudo install -m 644 "$DEST/scripts/toes.service" /etc/systemd/system/toes.service +sudo systemctl daemon-reload +sudo systemctl enable toes + +info "Restarting toes" +sudo systemctl restart toes + +# ── Done ───────────────────────────────────────────────── + +VERSION=$(cd "$DEST" && git describe --tags --always 2>/dev/null || echo "unknown") + +echo "" +echo " toes $VERSION is running!" +echo " http://$(hostname).local" +echo ""