#!/usr/bin/env bash # Script d'installation de Pilot v2 # Usage: # bash install_pilot.sh # premiere installation (clone depuis Gitea) # bash install_pilot.sh --update # mise a jour (git pull + recompile + relance) # bash install_pilot.sh --local # installe depuis le depot local (dev sur la meme machine) # # Le service est installe en tant que service UTILISATEUR (systemctl --user). # loginctl enable-linger permet le demarrage automatique au boot sans connexion graphique. # # Prerequis: # - rustup / cargo (https://rustup.rs) # - git # - sudo (pour loginctl enable-linger et l'ajout au groupe input) set -euo pipefail # ---------- Configuration ---------- GITEA_URL="https://gitea.maison43.duckdns.org/gilles/pilot" INSTALL_DIR="/home/gilles/pilot" SERVICE_NAME="pilot-v2" SERVICE_DIR="$HOME/.config/systemd/user" SERVICE_FILE="$SERVICE_DIR/${SERVICE_NAME}.service" LOCAL_REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" # Couleurs RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } step() { echo -e "\n${BLUE}==> $*${NC}"; } # ---------- Arguments ---------- MODE="install" for arg in "$@"; do case "$arg" in --update) MODE="update" ;; --local) MODE="local" ;; esac done # ---------- Prerequis ---------- step "Verification des prerequis" command -v git &>/dev/null || error "git non trouve. Installez-le: sudo apt install git" command -v cargo &>/dev/null || error "cargo non trouve. Installez Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" info "git et cargo disponibles" # ---------- Sources : clone, pull ou copie locale ---------- step "Preparation des sources" if [ "$MODE" = "local" ]; then # Copie depuis le depot de developpement local info "Synchronisation depuis le depot local: $LOCAL_REPO_DIR" if [ ! -d "$INSTALL_DIR" ]; then mkdir -p "$INSTALL_DIR" fi # Copie en preservant la config existante et en ignorant le dossier target # On copie tout sauf target/ et le config.yaml de l'install (s'il existe) ( cd "$LOCAL_REPO_DIR" find . -mindepth 1 \ ! -path './pilot-v2/target*' \ ! -path './.git*' \ -print0 | tar --null -T - -cf - | tar -C "$INSTALL_DIR" -xf - \ --exclude='./pilot-v2/config.yaml' 2>/dev/null || true ) # Copier le config.yaml seulement si absent if [ ! -f "$INSTALL_DIR/pilot-v2/config.yaml" ] && [ -f "$LOCAL_REPO_DIR/pilot-v2/config.yaml" ]; then cp "$LOCAL_REPO_DIR/pilot-v2/config.yaml" "$INSTALL_DIR/pilot-v2/config.yaml" fi info "Sources synchronisees dans $INSTALL_DIR" elif [ "$MODE" = "update" ]; then [ -d "$INSTALL_DIR/.git" ] || error "$INSTALL_DIR n'est pas un depot git. Lancez l'installation complete d'abord." info "Mise a jour depuis Gitea..." git -C "$INSTALL_DIR" pull info "Sources mises a jour" else # Installation complete depuis Gitea if [ -d "$INSTALL_DIR/.git" ]; then warn "Depot deja present dans $INSTALL_DIR." warn "Utilisez --update pour mettre a jour, ou --local pour copier depuis le depot dev." read -rp "Continuer et mettre a jour le depot existant ? [o/N] " confirm [[ "$confirm" =~ ^[oO]$ ]] || exit 0 git -C "$INSTALL_DIR" pull else if [ -d "$INSTALL_DIR" ] && [ "$(ls -A "$INSTALL_DIR" 2>/dev/null)" ]; then error "$INSTALL_DIR existe et n'est pas vide. Supprimez-le ou utilisez --local / --update." fi info "Clonage depuis $GITEA_URL..." git clone "$GITEA_URL" "$INSTALL_DIR" fi fi # ---------- Compilation ---------- step "Compilation du binaire (release)" cargo build --release --manifest-path "$INSTALL_DIR/pilot-v2/Cargo.toml" BINARY="$INSTALL_DIR/pilot-v2/target/release/pilot-v2" info "Binaire: $BINARY" # ---------- Configuration ---------- step "Configuration" CONFIG_FILE="$INSTALL_DIR/pilot-v2/config.yaml" EXAMPLE_FILE="$INSTALL_DIR/config/config.example.yaml" if [ ! -f "$CONFIG_FILE" ]; then if [ -f "$EXAMPLE_FILE" ]; then cp "$EXAMPLE_FILE" "$CONFIG_FILE" warn "config.yaml cree depuis l'exemple. A editer avant le demarrage:" warn " nano $CONFIG_FILE" warn "Points cles a configurer:" warn " - mqtt.host / username / password" warn " - device.name (nom de la machine dans Home Assistant)" warn " - bluetooth.devices[].mac (voir: bluetoothctl paired-devices)" else warn "Aucun exemple de config trouve. Creez $CONFIG_FILE manuellement." fi else info "config.yaml existant conserve" fi # Dossier iptv if [ -d "$INSTALL_DIR/iptv" ]; then info "Dossier iptv/ present: $INSTALL_DIR/iptv/" fi # ---------- Groupe input (pour la telecommande evdev) ---------- step "Permissions groupe input" if groups "$USER" | grep -qw input; then info "Utilisateur $USER deja dans le groupe input" else warn "Ajout de $USER au groupe input (necessaire pour la telecommande evdev)..." sudo usermod -aG input "$USER" warn "IMPORTANT: deconnectez-vous et reconnectez-vous pour que le groupe prenne effet." warn "Ou relancez le service apres reconnexion: systemctl --user restart $SERVICE_NAME" fi # ---------- Service systemd utilisateur ---------- step "Installation du service systemd utilisateur" mkdir -p "$SERVICE_DIR" # Detecter l'UID pour XDG_RUNTIME_DIR USER_ID=$(id -u) cat > "$SERVICE_FILE" </dev/null | grep -q "Linger=yes"; then info "Linger deja actif pour $USER" else if loginctl enable-linger "$USER" 2>/dev/null; then info "Linger active pour $USER — le service demarrera automatiquement au boot" elif sudo loginctl enable-linger "$USER" 2>/dev/null; then info "Linger active (via sudo) pour $USER" else warn "Impossible d'activer linger automatiquement." warn "Activez-le manuellement: loginctl enable-linger $USER" fi fi # ---------- Activation et demarrage ---------- step "Activation du service" systemctl --user daemon-reload systemctl --user enable "$SERVICE_NAME" info "Service active au demarrage" # Verifier si la config a l'air configuree CONFIG_READY=true if [ -f "$CONFIG_FILE" ]; then if grep -qE 'host:\s+""\s*$|host:\s*$' "$CONFIG_FILE" 2>/dev/null; then CONFIG_READY=false fi fi if systemctl --user is-active --quiet "$SERVICE_NAME" 2>/dev/null; then info "Redemarrage du service..." systemctl --user restart "$SERVICE_NAME" sleep 2 systemctl --user status "$SERVICE_NAME" --no-pager -l || true elif $CONFIG_READY; then info "Demarrage du service..." systemctl --user start "$SERVICE_NAME" || true sleep 2 systemctl --user status "$SERVICE_NAME" --no-pager -l || true else warn "Config non configuree (mqtt.host vide). Service NON demarre." warn "Editez $CONFIG_FILE puis lancez:" warn " systemctl --user start $SERVICE_NAME" fi # ---------- Resume ---------- echo "" echo "══════════════════════════════════════════════════" info "Installation terminee!" echo "" echo " Repertoire : $INSTALL_DIR" echo " Binaire : $BINARY" echo " Config : $CONFIG_FILE" echo " Service : $SERVICE_NAME (utilisateur)" echo "" echo " Commandes utiles:" echo " systemctl --user status $SERVICE_NAME" echo " systemctl --user start $SERVICE_NAME" echo " systemctl --user stop $SERVICE_NAME" echo " systemctl --user restart $SERVICE_NAME" echo " journalctl --user -u $SERVICE_NAME -f" echo "" echo " Mise a jour:" echo " bash $0 --update # depuis Gitea" echo " bash $0 --local # depuis le depot dev local" echo "" echo " Trouver les MAC Bluetooth:" echo " bluetoothctl paired-devices" echo "══════════════════════════════════════════════════"