noisebell/scripts/deploy-pios-pi.sh

131 lines
4.8 KiB
Bash
Executable file

#!/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"
if [[ ! -x "$BIN_PATH" ]]; then
echo "built binary not found: $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 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/pi-to-cache-key' '$REMOTE_TMP_DIR/cache-to-pi-key' '$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[@]}" "$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/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 <<HOSTSEOF
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 $DEPLOY_HOSTNAME
HOSTSEOF
if ! command -v tailscale >/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 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/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/tailscale-auth-key
sudo chmod 600 /etc/noisebell/pi-to-cache-key /etc/noisebell/cache-to-pi-key /etc/noisebell/tailscale-auth-key
sudo tee /etc/noisebell/noisebell.env >/dev/null <<'ENVEOF'
NOISEBELL_GPIO_PIN=17
NOISEBELL_DEBOUNCE_SECS=5
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/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 ln -sfn "$REMOTE_RELEASE_DIR" "$REMOTE_CURRENT_LINK"
sudo systemctl daemon-reload
sudo systemctl enable noisebell.service
sudo systemctl restart noisebell.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."