| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- #!/bin/sh
- # ==========================================================================
- # WeBrake installer — run this INSIDE an existing Alpine Linux LXC.
- # wget -qO- https://gogs.av2x.dev/av2x/WeBrake/raw/master/install.sh | ash
- #
- # It will refuse to run on a Proxmox host. Nothing is ever installed from
- # the host side; GPU passthru is host *configuration* only (see README).
- # Files are pulled from the repo. token.json is generated locally and is
- # never fetched from, nor pushed to, the repository.
- # ==========================================================================
- set -eu
- REPO_BASE="${WEBRAKE_REPO_BASE:-https://gogs.av2x.dev/av2x/WeBrake/raw}"
- BRANCHES="${WEBRAKE_BRANCH:-master main}"
- APP_DIR="/opt/webrake"
- DATA_DIR="/var/lib/webrake"
- PORT="${WEBRAKE_PORT:-8090}"
- say() { printf '\033[1;33m[WeBrake]\033[0m %s\n' "$*"; }
- die() { printf '\033[1;31m[WeBrake]\033[0m %s\n' "$*" >&2; exit 1; }
- # fetch <dest> <validator-grep> <path> [alt-path…] — tries every branch/path
- # combo and validates the payload so a Gogs error/login page is never installed.
- fetch() {
- dest="$1"; check="$2"; shift 2
- for br in $BRANCHES; do
- for p in "$@"; do
- url="$REPO_BASE/$br/$p"
- if wget -q -O "$dest.tmp" "$url" && [ -s "$dest.tmp" ] \
- && head -c 4096 "$dest.tmp" | grep -q "$check"; then
- mv "$dest.tmp" "$dest"
- say " fetched $p (branch: $br)"
- return 0
- fi
- done
- done
- rm -f "$dest.tmp"
- return 1
- }
- # ---- guard rails ---------------------------------------------------------
- [ "$(id -u)" = "0" ] || die "Run as root inside the Alpine container."
- command -v pveversion >/dev/null 2>&1 && \
- die "This looks like a Proxmox HOST. Run the installer inside the Alpine LXC instead."
- [ -f /etc/alpine-release ] || \
- die "This installer targets Alpine Linux. /etc/alpine-release not found."
- say "Installing on Alpine $(cat /etc/alpine-release)"
- # ---- packages ------------------------------------------------------------
- say "Installing packages (python3, flask, handbrake, VA-API drivers)…"
- apk update >/dev/null
- apk add --no-cache python3 py3-flask wget ca-certificates >/dev/null
- if ! command -v HandBrakeCLI >/dev/null 2>&1; then
- if ! apk add --no-cache handbrake >/dev/null 2>&1; then
- say "handbrake not in enabled repos — trying community/testing…"
- REL="$(cut -d. -f1,2 /etc/alpine-release)"
- apk add --no-cache handbrake \
- --repository="https://dl-cdn.alpinelinux.org/alpine/v${REL}/community" \
- >/dev/null 2>&1 || \
- apk add --no-cache handbrake \
- --repository="https://dl-cdn.alpinelinux.org/alpine/edge/community" \
- --repository="https://dl-cdn.alpinelinux.org/alpine/edge/main" \
- >/dev/null 2>&1 || \
- die "Could not install the 'handbrake' package. Enable the community repository in /etc/apk/repositories and re-run."
- fi
- fi
- say "HandBrakeCLI: $(HandBrakeCLI --version 2>/dev/null | head -n1 || echo installed)"
- # GPU userspace drivers (harmless if no GPU is passed through)
- apk add --no-cache libva libva-utils mesa-va-gallium intel-media-driver libdrm >/dev/null 2>&1 || \
- say "VA-API driver packages unavailable on this release — skipping (software encode still works)."
- # ---- app files from repo ---------------------------------------------------
- say "Pulling application files from ${REPO_BASE} (branches tried: ${BRANCHES})…"
- mkdir -p "$APP_DIR/static" "$DATA_DIR/uploads" "$DATA_DIR/output" "$DATA_DIR/jobs"
- fetch "$APP_DIR/app.py" "^#!/usr/bin/env python3" "app.py" \
- || die "Failed to fetch a valid app.py — check the repo URL, branch name, and that the repo is public."
- fetch "$APP_DIR/static/index.html" "^<!DOCTYPE html>" "static/index.html" "index.html" \
- || die "Failed to fetch a valid index.html — expected at static/index.html (or repo root) on branch master or main."
- fetch "$APP_DIR/update.sh" "^#!/bin/sh" "update.sh" \
- || die "Failed to fetch a valid update.sh from the repo."
- chmod +x "$APP_DIR/update.sh"
- # ---- token.json (generated locally, NEVER from the repo) -------------------
- if [ -f "$APP_DIR/token.json" ]; then
- say "token.json already exists — keeping existing secrets."
- else
- say "Generating token.json (local secrets — not stored in the repo)…"
- python3 - "$APP_DIR/token.json" <<'PYEOF'
- import json, secrets, sys, os
- path = sys.argv[1]
- tok = {
- "api_token": secrets.token_urlsafe(32),
- "secret_key": secrets.token_urlsafe(32),
- "require_auth": False,
- "bots": {}
- }
- with open(path, "w") as f:
- json.dump(tok, f, indent=2)
- os.chmod(path, 0o600)
- print(" api_token:", tok["api_token"])
- PYEOF
- say "Set \"require_auth\": true in $APP_DIR/token.json to require this token for all API/bot access."
- fi
- # ---- OpenRC service ---------------------------------------------------------
- say "Installing OpenRC service…"
- cat > /etc/init.d/webrake <<EOF
- #!/sbin/openrc-run
- name="webrake"
- description="WeBrake — HandBrake web UI"
- command="/usr/bin/python3"
- command_args="$APP_DIR/app.py"
- command_background=true
- pidfile="/run/webrake.pid"
- output_log="/var/log/webrake.log"
- error_log="/var/log/webrake.log"
- export WEBRAKE_PORT="$PORT"
- export WEBRAKE_DATA="$DATA_DIR"
- depend() {
- need net
- }
- EOF
- chmod +x /etc/init.d/webrake
- rc-update add webrake default >/dev/null 2>&1 || true
- rc-service webrake restart >/dev/null 2>&1 || rc-service webrake start
- IP="$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | head -n1)"
- say "Done. WeBrake is running at: http://${IP:-<container-ip>}:${PORT}"
- say "Update any time with: $APP_DIR/update.sh"
|