- scripts/install.sh : premier setup interactif (destination des épisodes, port, secrets auto-générés, montage, démarrage) — options --dir/--port/ --skip-login pour une install non interactive - Épisodes rangés par animé sur le disque : <Animé>/<Animé> - E12 (VOSTFR).mp4 (meilleur parsing Plex, suppression du dossier quand il se vide) - Entrypoint : chown récursif uniquement si le dossier de téléchargements est vide — une bibliothèque Plex/Sonarr existante n'est jamais modifiée - Scan disque récursif (sous-dossiers par animé restaurés) - README : installation guidée + section « Bibliothèque Plex / Sonarr »
174 lines
7.5 KiB
Bash
174 lines
7.5 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> --skip-login
|
|
# (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="" ARG_SKIP_LOGIN=0
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--dir) ARG_DIR="$2"; shift 2;;
|
|
--port) ARG_PORT="$2"; shift 2;;
|
|
--skip-login) ARG_SKIP_LOGIN=1; shift;;
|
|
*) 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)"
|
|
|
|
# ---------------------------------------------------------------- registre privé
|
|
step "Accès au registre privé ($REGISTRY_HOST)"
|
|
if [ "$ARG_SKIP_LOGIN" = "1" ]; then
|
|
warn "--skip-login : connexion au registre ignorée"
|
|
elif docker login "$REGISTRY_HOST" 2>/dev/null; then
|
|
ok "Connecté au registre"
|
|
else
|
|
warn "Pas encore connecté — un compte Gitea avec accès lecture au dépôt est requis."
|
|
if [ "$(ask "Se connecter maintenant (docker login) ?" "o")" = "o" ]; then
|
|
docker login "$REGISTRY_HOST" || die "docker login a échoué — relance le script après t'être connecté."
|
|
ok "Connecté au registre"
|
|
else
|
|
die "Sans docker login, l'image ne pourra pas être tirée."
|
|
fi
|
|
fi
|
|
|
|
# ---------------------------------------------------------------- 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"
|