#!/usr/bin/env bash set -euo pipefail TARGET_HOST=${1:-pi@noisebell-pi.local} DEPLOY_HOSTNAME=${DEPLOY_HOSTNAME:-noisebell-pi} SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) REPO_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd) RELEASE_ID=${RELEASE_ID:-$(date +%Y%m%d-%H%M%S)} REMOTE_RELEASE_DIR=${REMOTE_RELEASE_DIR:-/opt/noisebell/releases/$RELEASE_ID} REMOTE_CURRENT_LINK=${REMOTE_CURRENT_LINK:-/opt/noisebell/current} REMOTE_TMP_DIR=${REMOTE_TMP_DIR:-/home/pi/noisebell-deploy-tmp} TMP_DIR=$(mktemp -d) cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT SSH_OPTS=( -o StrictHostKeyChecking=accept-new ) echo "Building static aarch64 Noisebell binary locally..." PACKAGE_PATH=$(nix build .#packages.aarch64-linux.noisebell-static --print-out-paths --no-link) BIN_PATH="$PACKAGE_PATH/bin/noisebell" RELAY_PACKAGE_PATH=$(nix build .#packages.aarch64-linux.noisebell-relay-static --print-out-paths --no-link) RELAY_BIN_PATH="$RELAY_PACKAGE_PATH/bin/noisebell-relay" if [[ ! -x "$BIN_PATH" ]]; then echo "built binary not found: $BIN_PATH" >&2 exit 1 fi if [[ ! -x "$RELAY_BIN_PATH" ]]; then echo "built relay binary not found: $RELAY_BIN_PATH" >&2 exit 1 fi if ! command -v agenix >/dev/null 2>&1; then echo "agenix is required in your shell to decrypt secrets locally" >&2 exit 1 fi echo "Decrypting Pi secrets locally..." ( cd "$REPO_ROOT/secrets" RULES="$REPO_ROOT/secrets/secrets.nix" agenix -d pi-to-cache-key.age > "$TMP_DIR/pi-to-cache-key" RULES="$REPO_ROOT/secrets/secrets.nix" agenix -d cache-to-pi-key.age > "$TMP_DIR/cache-to-pi-key" RULES="$REPO_ROOT/secrets/secrets.nix" agenix -d relay-webhook-secret.age > "$TMP_DIR/relay-webhook-secret" RULES="$REPO_ROOT/secrets/secrets.nix" agenix -d homeassistant-webhook-id.age > "$TMP_DIR/homeassistant-webhook-id" RULES="$REPO_ROOT/secrets/secrets.nix" agenix -d tailscale-auth-key.age > "$TMP_DIR/tailscale-auth-key" ) chmod 600 "$TMP_DIR"/* echo "Preparing remote directories on $TARGET_HOST..." ssh "${SSH_OPTS[@]}" "$TARGET_HOST" "mkdir -p '$REMOTE_TMP_DIR' && rm -f '$REMOTE_TMP_DIR/noisebell' '$REMOTE_TMP_DIR/noisebell-relay' '$REMOTE_TMP_DIR/pi-to-cache-key' '$REMOTE_TMP_DIR/cache-to-pi-key' '$REMOTE_TMP_DIR/relay-webhook-secret' '$REMOTE_TMP_DIR/homeassistant-webhook-id' '$REMOTE_TMP_DIR/tailscale-auth-key' && sudo mkdir -p '$REMOTE_RELEASE_DIR' /etc/noisebell /opt/noisebell/releases /var/lib/noisebell" echo "Uploading binary and secret files..." scp "${SSH_OPTS[@]}" "$BIN_PATH" "$TARGET_HOST:$REMOTE_TMP_DIR/noisebell" scp "${SSH_OPTS[@]}" "$RELAY_BIN_PATH" "$TARGET_HOST:$REMOTE_TMP_DIR/noisebell-relay" scp "${SSH_OPTS[@]}" "$TMP_DIR/pi-to-cache-key" "$TARGET_HOST:$REMOTE_TMP_DIR/pi-to-cache-key" scp "${SSH_OPTS[@]}" "$TMP_DIR/cache-to-pi-key" "$TARGET_HOST:$REMOTE_TMP_DIR/cache-to-pi-key" scp "${SSH_OPTS[@]}" "$TMP_DIR/relay-webhook-secret" "$TARGET_HOST:$REMOTE_TMP_DIR/relay-webhook-secret" scp "${SSH_OPTS[@]}" "$TMP_DIR/homeassistant-webhook-id" "$TARGET_HOST:$REMOTE_TMP_DIR/homeassistant-webhook-id" scp "${SSH_OPTS[@]}" "$TMP_DIR/tailscale-auth-key" "$TARGET_HOST:$REMOTE_TMP_DIR/tailscale-auth-key" echo "Installing service and Tailscale on $TARGET_HOST..." ssh "${SSH_OPTS[@]}" "$TARGET_HOST" "DEPLOY_HOSTNAME='$DEPLOY_HOSTNAME' REMOTE_RELEASE_DIR='$REMOTE_RELEASE_DIR' REMOTE_CURRENT_LINK='$REMOTE_CURRENT_LINK' REMOTE_TMP_DIR='$REMOTE_TMP_DIR' bash -s" <<'EOF' set -euo pipefail sudo apt-get update sudo apt-get install -y curl rsync avahi-daemon sudo hostnamectl set-hostname "$DEPLOY_HOSTNAME" sudo tee /etc/hostname >/dev/null <<<"$DEPLOY_HOSTNAME" sudo tee /etc/hosts >/dev/null </dev/null 2>&1; then curl -fsSL https://tailscale.com/install.sh | sh fi sudo systemctl enable --now ssh avahi-daemon tailscaled sudo install -m 755 "$REMOTE_TMP_DIR/noisebell" "$REMOTE_RELEASE_DIR/noisebell" sudo install -m 755 "$REMOTE_TMP_DIR/noisebell-relay" "$REMOTE_RELEASE_DIR/noisebell-relay" sudo mv "$REMOTE_TMP_DIR/pi-to-cache-key" /etc/noisebell/pi-to-cache-key sudo mv "$REMOTE_TMP_DIR/cache-to-pi-key" /etc/noisebell/cache-to-pi-key sudo mv "$REMOTE_TMP_DIR/relay-webhook-secret" /etc/noisebell/relay-webhook-secret sudo mv "$REMOTE_TMP_DIR/homeassistant-webhook-id" /etc/noisebell/homeassistant-webhook-id sudo mv "$REMOTE_TMP_DIR/tailscale-auth-key" /etc/noisebell/tailscale-auth-key sudo chown root:root /etc/noisebell/pi-to-cache-key /etc/noisebell/cache-to-pi-key /etc/noisebell/relay-webhook-secret /etc/noisebell/homeassistant-webhook-id /etc/noisebell/tailscale-auth-key sudo chmod 600 /etc/noisebell/pi-to-cache-key /etc/noisebell/cache-to-pi-key /etc/noisebell/relay-webhook-secret /etc/noisebell/homeassistant-webhook-id /etc/noisebell/tailscale-auth-key sudo tee /etc/noisebell/noisebell.env >/dev/null <<'ENVEOF' NOISEBELL_GPIO_PIN=17 NOISEBELL_DEBOUNCE_MS=50 NOISEBELL_PORT=80 NOISEBELL_RETRY_ATTEMPTS=3 NOISEBELL_RETRY_BASE_DELAY_SECS=1 NOISEBELL_HTTP_TIMEOUT_SECS=10 NOISEBELL_ENDPOINT_URL=https://noisebell.extremist.software/webhook NOISEBELL_BIND_ADDRESS=0.0.0.0 NOISEBELL_ACTIVE_LOW=true RUST_LOG=info ENVEOF sudo chmod 600 /etc/noisebell/noisebell.env sudo tee /etc/noisebell/noisebell-relay.env >/dev/null <<'ENVEOF' NOISEBELL_RELAY_PORT=8090 NOISEBELL_RELAY_BIND_ADDRESS=0.0.0.0 NOISEBELL_RELAY_TARGET_BASE_URL=http://homeassistant.local:8123 NOISEBELL_RELAY_RETRY_ATTEMPTS=3 NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS=1 NOISEBELL_RELAY_HTTP_TIMEOUT_SECS=10 RUST_LOG=info ENVEOF sudo chmod 600 /etc/noisebell/noisebell-relay.env sudo tee /etc/systemd/system/noisebell.service >/dev/null <<'UNITEOF' [Unit] Description=Noisebell GPIO door monitor After=network-online.target tailscaled.service Wants=network-online.target [Service] Type=notify NotifyAccess=all EnvironmentFile=/etc/noisebell/noisebell.env ExecStart=/bin/bash -lc 'export NOISEBELL_API_KEY="$$(cat /etc/noisebell/pi-to-cache-key)"; export NOISEBELL_INBOUND_API_KEY="$$(cat /etc/noisebell/cache-to-pi-key)"; exec /opt/noisebell/current/noisebell' Restart=on-failure RestartSec=5 WatchdogSec=30 [Install] WantedBy=multi-user.target UNITEOF sudo tee /etc/systemd/system/noisebell-relay.service >/dev/null <<'UNITEOF' [Unit] Description=Noisebell relay webhook bridge After=network-online.target Wants=network-online.target [Service] Type=simple EnvironmentFile=/etc/noisebell/noisebell-relay.env ExecStart=/bin/bash -lc 'export NOISEBELL_RELAY_INBOUND_API_KEY="$$(cat /etc/noisebell/relay-webhook-secret)"; export NOISEBELL_RELAY_TARGET_WEBHOOK_ID="$$(cat /etc/noisebell/homeassistant-webhook-id)"; exec /opt/noisebell/current/noisebell-relay' Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target UNITEOF sudo ln -sfn "$REMOTE_RELEASE_DIR" "$REMOTE_CURRENT_LINK" sudo systemctl daemon-reload sudo systemctl enable noisebell.service sudo systemctl enable noisebell-relay.service sudo systemctl restart noisebell.service sudo systemctl restart noisebell-relay.service sudo systemctl restart avahi-daemon sudo tailscale up --auth-key="$(sudo cat /etc/noisebell/tailscale-auth-key)" --hostname=noisebell-pi || true rmdir "$REMOTE_TMP_DIR" 2>/dev/null || true echo "Noisebell deployed on Raspberry Pi OS." EOF echo "Done."