#!/usr/bin/env bash # ──────────────────────────────────────────────────────────────────── # Pi Multi-FX Pedal — systemd service installer # # Installs pi-multifx-pedal.service + multi-fx-pedal.target and # enables them for auto-start on boot. # # Usage: # sudo ./install_service.sh [install_dir] # # install_dir Path to the pedal installation (default: /opt/pi-multifx-pedal) # ──────────────────────────────────────────────────────────────────── set -euo pipefail INSTALL_DIR="${1:-/opt/pi-multifx-pedal}" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" # ── Colour helpers ───────────────────────────────────────────────── info() { printf "\e[34m[INFO] %s\e[0m\n" "$*"; } ok() { printf "\e[32m[ OK ] %s\e[0m\n" "$*"; } warn() { printf "\e[33m[WARN] %s\e[0m\n" "$*"; } err() { printf "\e[31m[FAIL] %s\e[0m\n" "$*"; } # ── Root check ───────────────────────────────────────────────────── if [[ $EUID -ne 0 ]]; then err "This script must be run as root (sudo ./install_service.sh)" exit 1 fi # ── Architecture check (must be RPi) ─────────────────────────────── ARCH="$(uname -m)" if [[ "$ARCH" != "aarch64" && "$ARCH" != "armv7l" ]]; then warn "Not a Raspberry Pi (detected: $ARCH) — service files will be written" warn "but will not be enabled (no systemctl available in containers)." NO_SYSTEMCTL=true fi info "========== Pi Multi-FX Pedal — Service Installer ==========" info "Install dir: $INSTALL_DIR" info "Project dir: $PROJECT_DIR" echo "" # ── Step 1: Create install directory ─────────────────────────────── info "Step 1: Creating install directory..." mkdir -p "$INSTALL_DIR" ok "Install directory ready: $INSTALL_DIR" # ── Step 2: Copy project files ───────────────────────────────────── info "Step 2: Copying project files..." # Copy everything except .venv, __pycache__, .git, etc. rsync -a --delete \ --exclude='.git' \ --exclude='__pycache__' \ --exclude='*.pyc' \ --exclude='.venv' \ --exclude='venv' \ --exclude='.scone' \ --exclude='systemd/' \ --exclude='*.so' \ --exclude='*.nam' \ --exclude='*.wav' \ --exclude='*.aiff' \ "$PROJECT_DIR/" "$INSTALL_DIR/" ok "Project files copied to $INSTALL_DIR" # ── Step 3: Create Python virtual environment ────────────────────── info "Step 3: Setting up Python virtual environment..." if [[ ! -d "$INSTALL_DIR/.venv" ]]; then python3 -m venv "$INSTALL_DIR/.venv" ok "Virtual environment created at $INSTALL_DIR/.venv" else info "Virtual environment already exists" fi # Install/update dependencies "$INSTALL_DIR/.venv/bin/pip" install --quiet --upgrade pip "$INSTALL_DIR/.venv/bin/pip" install --quiet -r "$INSTALL_DIR/requirements.txt" 2>&1 | tail -1 ok "Python dependencies installed" # ── Step 4: Generate service files from Python module ────────────── info "Step 4: Generating systemd service units..." PYTHON_BIN="$INSTALL_DIR/.venv/bin/python3" SERVICES_MODULE="src.system.services" # Generate pi-multifx-pedal.service $PYTHON_BIN -c " import sys sys.path.insert(0, '$INSTALL_DIR') from src.system.services import pedal_service_content print(pedal_service_content(install_dir='$INSTALL_DIR')) " > /etc/systemd/system/pi-multifx-pedal.service ok "Generated /etc/systemd/system/pi-multifx-pedal.service" # Generate multi-fx-pedal.target $PYTHON_BIN -c " import sys sys.path.insert(0, '$INSTALL_DIR') from src.system.services import pedal_target_content print(pedal_target_content()) " > /etc/systemd/system/multi-fx-pedal.target ok "Generated /etc/systemd/system/multi-fx-pedal.target" # ── Step 5: Reload and enable ────────────────────────────────────── info "Step 5: Reloading systemd and enabling services..." if [[ "${NO_SYSTEMCTL:-false}" != true ]]; then systemctl daemon-reload systemctl enable pi-multifx-pedal.service systemctl enable multi-fx-pedal.target ok "Services enabled: pi-multifx-pedal.service + multi-fx-pedal.target" else info "Skipping systemctl enable (non-RPi environment)" fi # ── Step 6: Add 'pi' user to audio group ─────────────────────────── if groups pi | grep -q '\baudio\b' 2>/dev/null; then ok "User 'pi' already in audio group" else usermod -a -G audio pi 2>/dev/null || true info "Added 'pi' to audio group (will take effect on next login)" fi # ── Optional: Set up log rotation ────────────────────────────────── LOGROTATE_FILE="/etc/logrotate.d/pi-multifx-pedal" if [[ ! -f "$LOGROTATE_FILE" ]]; then cat > "$LOGROTATE_FILE" <<'LOGROTATE' /var/log/pi-multifx-pedal/*.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate } LOGROTATE ok "Log rotation configured at $LOGROTATE_FILE" fi # ── Summary ──────────────────────────────────────────────────────── echo "" info "========== Installation Complete ==========" echo "" echo " Service: pi-multifx-pedal.service" echo " Target: multi-fx-pedal.target" echo " Install: $INSTALL_DIR" echo " Config: ~/.pedal/config.yaml" echo " Presets: ~/.pedal/presets/" echo "" info "Start now:" echo " sudo systemctl start multi-fx-pedal.target" echo "" info "Check status:" echo " sudo systemctl status pi-multifx-pedal.service" echo "" info "Tail logs:" echo " journalctl -fu pi-multifx-pedal.service" echo "" info "Stop the pedal:" echo " sudo systemctl stop multi-fx-pedal.target"