Files

158 lines
6.7 KiB
Bash

#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Installation guidée d'Ohm Stream Downloader (premier setup).
#
# bash scripts/install.sh (depuis un clone du dépôt)
# curl -fsSL <gitea>/raw/branch/main/scripts/install.sh | bash
#
# Options non interactives : --dir <chemin> --port <n>
# (les valeurs passées en option court-circuitent les questions)
#
# Pose les questions (destination des animés, port), génère les secrets,
# écrit .env, branche le montage Docker, démarre et attend le service.
# ---------------------------------------------------------------------------
set -euo pipefail
REGISTRY_HOST="git.lanro.eu"
REPO_URL="https://${REGISTRY_HOST}/Roman/ohm_streaming.git"
COMPOSE_FILE="docker-compose.yml"
BOLD="\033[1m"; DIM="\033[2m"; GREEN="\033[32m"; YELLOW="\033[33m"; RED="\033[31m"; RESET="\033[0m"
step() { printf "\n${BOLD}▸ %s${RESET}\n" "$1"; }
ok() { printf " ${GREEN}✔${RESET} %s\n" "$1"; }
warn() { printf " ${YELLOW}⚠${RESET} %s\n" "$1"; }
die() { printf " ${RED}✖ %s${RESET}\n" "$1" >&2; exit 1; }
ARG_DIR="" ARG_PORT=""
while [ $# -gt 0 ]; do
case "$1" in
--dir) ARG_DIR="$2"; shift 2;;
--port) ARG_PORT="$2"; shift 2;;
*) shift;;
esac
done
ask() { # ask <question> <défaut> — lit /dev/tty pour rester compatible curl|bash
local answer=""
if [ -r /dev/tty ]; then
read -r -p "$(printf ' %s ${DIM}[%s]${RESET} ' "$1" "$2")" answer </dev/tty 2>/dev/null || true
fi
echo "${answer:-$2}"
}
rand_hex() { # rand_hex <nb octets>
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex "$1"
else
head -c "$1" /dev/urandom | od -An -tx1 | tr -d ' \n'
fi
}
printf "${BOLD}⛩ Ohm Stream Downloader — installation${RESET}\n"
printf "${DIM}Télécharge et streame des animes — Docker + Watchtower${RESET}\n"
# ---------------------------------------------------------------- prérequis
step "Vérification des prérequis"
command -v docker >/dev/null 2>&1 || die "Docker n'est pas installé. → curl -fsSL https://get.docker.com | sh"
docker compose version >/dev/null 2>&1 || die "Le plugin Docker Compose manque (paquet docker-compose-plugin)."
ok "Docker + Compose présents"
# Depuis un clone ? sinon on clone (permet curl … | bash)
if [ ! -f "$COMPOSE_FILE" ]; then
INSTALL_DIR="$(ask "Dossier d'installation" "$HOME/ohm_streaming")"
if [ -e "$INSTALL_DIR" ]; then
[ -f "$INSTALL_DIR/$COMPOSE_FILE" ] || die "$INSTALL_DIR existe déjà (et n'est pas une installation Ohm)."
step "Mise à jour du clone existant"
git -C "$INSTALL_DIR" pull --ff-only || warn "git pull a échoué, on continue avec la version locale."
else
step "Récupération du projet"
command -v git >/dev/null 2>&1 || die "git est requis pour cloner $REPO_URL"
git clone "$REPO_URL" "$INSTALL_DIR"
fi
cd "$INSTALL_DIR"
fi
ok "Projet prêt dans $(pwd)"
# ---------------------------------------------------------------- destination des épisodes
step "Destination des épisodes téléchargés"
if [ -n "$ARG_DIR" ]; then
HOST_DIR="$ARG_DIR"
else
printf " 1) ${BOLD}Dossier dédié « ohm »${RESET} (recommandé) : Ohm crée/utilise un dossier\n\
à part, à ajouter à ta bibliothèque Plex. Tes dossiers Sonarr/Plex\n\
existants ne sont JAMAIS modifiés.\n\
2) Dossier de ton choix (ex. un sous-dossier de ta biblio d'animes).\n\
S'il n'est pas vide, Ohm importera aussi les fichiers déjà présents.\n"
MODE="$(ask "Choix (1/2)" "1")"
if [ "$MODE" = "1" ]; then
HOST_DIR="$(ask "Chemin du dossier dédié" "/opt/ohm/animes")"
else
HOST_DIR="$(ask "Chemin du dossier de téléchargement" "/plex_videos/anime/ohm")"
fi
fi
if [ -e "$HOST_DIR" ] && [ -n "$(ls -A "$HOST_DIR" 2>/dev/null)" ]; then
warn "$HOST_DIR n'est pas vide : Ohm l'adoptera tel quel (droits existants conservés)."
warn "Le conteneur (uid 1000) doit pouvoir y écrire."
fi
if ! mkdir -p "$HOST_DIR" 2>/dev/null; then
printf ' sudo mkdir -p %q && sudo chown 1000:1000 %q\n' "$HOST_DIR" "$HOST_DIR" >&2
die "Impossible de créer $HOST_DIR — crée-le avec sudo puis relance."
fi
ok "Épisodes → $HOST_DIR (un dossier vide est pris en charge automatiquement)"
# ---------------------------------------------------------------- port + secrets
step "Configuration"
PORT="${ARG_PORT:-$(ask "Port HTTP exposé" "8777")}"
step "Écriture de .env"
if [ -f .env ]; then
cp .env ".env.backup.$(date +%s)"
warn ".env existant sauvegardé"
fi
SECRET_KEY="$(rand_hex 32)"
WT_TOKEN="$(rand_hex 24)"
cat > .env <<EOF
# Généré par scripts/install.sh le $(date '+%Y-%m-%d %H:%M')
OHM_SECRET_KEY=${SECRET_KEY}
WATCHTOWER_TOKEN=${WT_TOKEN}
OHM_PORT=${PORT}
EOF
chmod 600 .env
ok "Secrets générés (OHM_SECRET_KEY, WATCHTOWER_TOKEN)"
# ---------------------------------------------------------------- compose : montage téléchargements
step "Configuration du montage Docker"
cp "$COMPOSE_FILE" "$COMPOSE_FILE.dist"
if sed -i "s|^\([[:space:]]*- \)\./downloads:/downloads.*$|\1${HOST_DIR}:/downloads|" "$COMPOSE_FILE" \
&& grep -q -- "${HOST_DIR}:/downloads" "$COMPOSE_FILE"; then
ok "/downloads → $HOST_DIR (original conservé en $COMPOSE_FILE.dist)"
else
mv "$COMPOSE_FILE.dist" "$COMPOSE_FILE"
die "Montage introuvable dans $COMPOSE_FILE — édite la ligne ./downloads:/downloads à la main."
fi
# ---------------------------------------------------------------- démarrage
step "Démarrage (docker compose up -d)"
docker compose up -d || die "Démarrage échoué — logs : docker compose logs"
step "Attente du démarrage"
HEALTH_URL="http://127.0.0.1:${PORT}/health"
for i in $(seq 1 30); do
if curl -sf "$HEALTH_URL" >/dev/null 2>&1 || wget -q -O /dev/null "$HEALTH_URL" 2>/dev/null; then
break
fi
sleep 2
if [ "$i" = "30" ]; then docker compose logs --tail 30 ohm; die "Le service ne répond pas sur $HEALTH_URL"; fi
done
ok "Service en ligne"
HOST_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
printf "\n${BOLD}${GREEN}⛩ Ohm Stream est prêt !${RESET}\n\n"
printf " URL : ${BOLD}http://%s:%s${RESET}\n" "${HOST_IP:-<ip-serveur>}" "$PORT"
printf " Épisodes : %s\n" "$HOST_DIR"
printf " 1er compte : ${BOLD}le compte créé en premier devient administrateur${RESET}\n\n"
printf " ${DIM}Plex : ajoute %s comme dossier d'une bibliothèque (ou comme dossier\n supplémentaire de ta bibliothèque animes) — les épisodes arrivent rangés par\n animé : <Animé>/<Animé> - E12 (VOSTFR).mp4${RESET}\n\n" "$HOST_DIR"
printf " ${DIM}Commandes : docker compose logs -f · stop · pull && up -d (mise à jour)${RESET}\n"