fix(newsbin): Use Debian LXC rootfs for SABnzbd and NZBHydra
- SABnzbd/NZBHydra now use Debian LXC containers instead of Docker - Added PATH/HOME exports to fix startup issues - Added non-free repo for unrar dependency - Use container IPs (192.168.255.40/41) instead of localhost - Fixed cgroup mount compatibility Container network: - SABnzbd: 192.168.255.40:8085 - NZBHydra: 192.168.255.41:5076 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
aef0284b44
commit
00da717ea4
@ -547,7 +547,10 @@
|
|||||||
"Bash(then echo \"$f\")",
|
"Bash(then echo \"$f\")",
|
||||||
"Bash(do if ! grep -q \"require secubox/kiss-theme\" \"$f\")",
|
"Bash(do if ! grep -q \"require secubox/kiss-theme\" \"$f\")",
|
||||||
"Bash(# Test RPCD status method ssh root@192.168.255.1 \"\"ubus call luci.config-vault status\"\")",
|
"Bash(# Test RPCD status method ssh root@192.168.255.1 \"\"ubus call luci.config-vault status\"\")",
|
||||||
"WebFetch(domain:ytdl.gk2.secubox.in)"
|
"WebFetch(domain:ytdl.gk2.secubox.in)",
|
||||||
|
"Bash([\"''\"'\"\"'\"''\"'\"\"'\"'']$/, \"\", val\\)\n\n if \\(section == \"tags\" && key == \"category\"\\) category = val\n if \\(section == \"tags\" && key == \"keywords\"\\) keywords = val\n if \\(section == \"tags\" && key == \"audience\"\\) audience = val\n if \\(section == \"description\" && key == \"short\"\\) desc = val\n if \\(section == \"dynamics\" && key == \"capabilities\"\\) caps = val\n if \\(section == \"media\" && key == \"icon\"\\) icon = val\n if \\(section == \"identity\" && key == \"version\"\\) version = val\n }\n END {\n printf \"%s)",
|
||||||
|
"Bash(%s)",
|
||||||
|
"Bash(/tmp/test_nfo.sh)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
. /usr/share/libubox/jshn.sh
|
. /usr/share/libubox/jshn.sh
|
||||||
|
|
||||||
|
SAB_IP="192.168.255.40"
|
||||||
SAB_PORT="8085"
|
SAB_PORT="8085"
|
||||||
|
HYDRA_IP="192.168.255.41"
|
||||||
HYDRA_PORT="5076"
|
HYDRA_PORT="5076"
|
||||||
SAB_CONFIG="/srv/sabnzbd/config/sabnzbd.ini"
|
SAB_CONFIG="/srv/sabnzbd/config/sabnzbd.ini"
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ case "$1" in
|
|||||||
sab_running="true"
|
sab_running="true"
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
if [ -n "$api_key" ]; then
|
if [ -n "$api_key" ]; then
|
||||||
local sab_data=$(curl -s "http://127.0.0.1:$SAB_PORT/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
local sab_data=$(curl -s "http://$SAB_IP:$SAB_PORT/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
||||||
if [ -n "$sab_data" ]; then
|
if [ -n "$sab_data" ]; then
|
||||||
sab_speed=$(echo "$sab_data" | jsonfilter -e '@.queue.speed' 2>/dev/null || echo "0")
|
sab_speed=$(echo "$sab_data" | jsonfilter -e '@.queue.speed' 2>/dev/null || echo "0")
|
||||||
sab_queue=$(echo "$sab_data" | jsonfilter -e '@.queue.noofslots' 2>/dev/null || echo "0")
|
sab_queue=$(echo "$sab_data" | jsonfilter -e '@.queue.noofslots' 2>/dev/null || echo "0")
|
||||||
@ -50,12 +52,12 @@ case "$1" in
|
|||||||
json_add_string "speed" "$sab_speed"
|
json_add_string "speed" "$sab_speed"
|
||||||
json_add_int "queue_size" "$sab_queue"
|
json_add_int "queue_size" "$sab_queue"
|
||||||
json_add_string "disk_free" "$sab_disk"
|
json_add_string "disk_free" "$sab_disk"
|
||||||
json_add_string "url" "http://127.0.0.1:$SAB_PORT/"
|
json_add_string "url" "http://$SAB_IP:$SAB_PORT/"
|
||||||
json_close_object
|
json_close_object
|
||||||
|
|
||||||
json_add_object "nzbhydra"
|
json_add_object "nzbhydra"
|
||||||
json_add_boolean "running" "$hydra_running"
|
json_add_boolean "running" "$hydra_running"
|
||||||
json_add_string "url" "http://127.0.0.1:$HYDRA_PORT/"
|
json_add_string "url" "http://$HYDRA_IP:$HYDRA_PORT/"
|
||||||
json_close_object
|
json_close_object
|
||||||
|
|
||||||
json_dump
|
json_dump
|
||||||
@ -67,7 +69,7 @@ case "$1" in
|
|||||||
|
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
if [ -n "$api_key" ]; then
|
if [ -n "$api_key" ]; then
|
||||||
local queue_data=$(curl -s "http://127.0.0.1:$SAB_PORT/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
local queue_data=$(curl -s "http://$SAB_IP:$SAB_PORT/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
||||||
if [ -n "$queue_data" ]; then
|
if [ -n "$queue_data" ]; then
|
||||||
echo "$queue_data" | python3 -c "
|
echo "$queue_data" | python3 -c "
|
||||||
import sys, json
|
import sys, json
|
||||||
@ -116,7 +118,7 @@ except:
|
|||||||
|
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
if [ -n "$api_key" ]; then
|
if [ -n "$api_key" ]; then
|
||||||
local hist_data=$(curl -s "http://127.0.0.1:$SAB_PORT/api?mode=history&limit=20&output=json&apikey=$api_key" 2>/dev/null)
|
local hist_data=$(curl -s "http://$SAB_IP:$SAB_PORT/api?mode=history&limit=20&output=json&apikey=$api_key" 2>/dev/null)
|
||||||
if [ -n "$hist_data" ]; then
|
if [ -n "$hist_data" ]; then
|
||||||
echo "$hist_data" | python3 -c "
|
echo "$hist_data" | python3 -c "
|
||||||
import sys, json
|
import sys, json
|
||||||
@ -163,7 +165,7 @@ except:
|
|||||||
json_add_array "results"
|
json_add_array "results"
|
||||||
|
|
||||||
if [ -n "$query" ]; then
|
if [ -n "$query" ]; then
|
||||||
local search_url="http://127.0.0.1:$HYDRA_PORT/api?t=search&q=$(echo "$query" | sed 's/ /%20/g')"
|
local search_url="http://$HYDRA_IP:$HYDRA_PORT/api?t=search&q=$(echo "$query" | sed 's/ /%20/g')"
|
||||||
local result=$(curl -s "$search_url" 2>/dev/null)
|
local result=$(curl -s "$search_url" 2>/dev/null)
|
||||||
|
|
||||||
if [ -n "$result" ]; then
|
if [ -n "$result" ]; then
|
||||||
@ -212,7 +214,7 @@ except:
|
|||||||
json_add_string "error" "URL required"
|
json_add_string "error" "URL required"
|
||||||
else
|
else
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
local add_url="http://127.0.0.1:$SAB_PORT/api?mode=addurl&name=$(echo "$url" | sed 's/&/%26/g')&apikey=$api_key"
|
local add_url="http://$SAB_IP:$SAB_PORT/api?mode=addurl&name=$(echo "$url" | sed 's/&/%26/g')&apikey=$api_key"
|
||||||
[ -n "$category" ] && add_url="$add_url&cat=$category"
|
[ -n "$category" ] && add_url="$add_url&cat=$category"
|
||||||
|
|
||||||
local result=$(curl -s "$add_url" 2>/dev/null)
|
local result=$(curl -s "$add_url" 2>/dev/null)
|
||||||
@ -230,7 +232,7 @@ except:
|
|||||||
|
|
||||||
pause)
|
pause)
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
curl -s "http://127.0.0.1:$SAB_PORT/api?mode=pause&apikey=$api_key" >/dev/null 2>&1
|
curl -s "http://$SAB_IP:$SAB_PORT/api?mode=pause&apikey=$api_key" >/dev/null 2>&1
|
||||||
json_init
|
json_init
|
||||||
json_add_boolean "success" 1
|
json_add_boolean "success" 1
|
||||||
json_dump
|
json_dump
|
||||||
@ -238,7 +240,7 @@ except:
|
|||||||
|
|
||||||
resume)
|
resume)
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
curl -s "http://127.0.0.1:$SAB_PORT/api?mode=resume&apikey=$api_key" >/dev/null 2>&1
|
curl -s "http://$SAB_IP:$SAB_PORT/api?mode=resume&apikey=$api_key" >/dev/null 2>&1
|
||||||
json_init
|
json_init
|
||||||
json_add_boolean "success" 1
|
json_add_boolean "success" 1
|
||||||
json_dump
|
json_dump
|
||||||
@ -250,7 +252,7 @@ except:
|
|||||||
json_get_var nzo_id nzo_id
|
json_get_var nzo_id nzo_id
|
||||||
|
|
||||||
local api_key=$(get_sab_api)
|
local api_key=$(get_sab_api)
|
||||||
curl -s "http://127.0.0.1:$SAB_PORT/api?mode=queue&name=delete&value=$nzo_id&apikey=$api_key" >/dev/null 2>&1
|
curl -s "http://$SAB_IP:$SAB_PORT/api?mode=queue&name=delete&value=$nzo_id&apikey=$api_key" >/dev/null 2>&1
|
||||||
|
|
||||||
json_init
|
json_init
|
||||||
json_add_boolean "success" 1
|
json_add_boolean "success" 1
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# NZBHydra2 Controller - Usenet Meta Search
|
# NZBHydra2 Controller - Usenet Meta Search
|
||||||
# LXC container management for NZBHydra2
|
# LXC container with Debian rootfs (no Docker/Podman)
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
CONTAINER_NAME="nzbhydra"
|
CONTAINER_NAME="nzbhydra"
|
||||||
CONTAINER_DIR="/srv/lxc/$CONTAINER_NAME"
|
CONTAINER_DIR="/srv/lxc/$CONTAINER_NAME"
|
||||||
DATA_DIR="/srv/nzbhydra"
|
DATA_DIR="/srv/nzbhydra"
|
||||||
DOCKER_IMAGE="linuxserver/nzbhydra2:latest"
|
|
||||||
CONFIG="nzbhydra"
|
CONFIG="nzbhydra"
|
||||||
|
|
||||||
|
# Debian LXC rootfs URL (arm64) - Linux Containers official
|
||||||
|
DEBIAN_LXC_MIRROR="https://images.linuxcontainers.org/images/debian/bookworm/arm64/default"
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
log_info() { logger -t nzbhydra -p user.info "$*"; echo "[INFO] $*"; }
|
log_info() { logger -t nzbhydra -p user.info "$*"; echo "[INFO] $*"; }
|
||||||
log_error() { logger -t nzbhydra -p user.error "$*"; echo "[ERROR] $*" >&2; }
|
log_error() { logger -t nzbhydra -p user.error "$*"; echo "[ERROR] $*" >&2; }
|
||||||
@ -19,51 +21,114 @@ log_ok() { echo "[OK] $*"; }
|
|||||||
uci_get() { uci -q get "$CONFIG.$1"; }
|
uci_get() { uci -q get "$CONFIG.$1"; }
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
# Install container from Docker image
|
# Install container with Debian rootfs
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
cmd_install() {
|
cmd_install() {
|
||||||
log_info "Installing NZBHydra2 container..."
|
log_info "Installing NZBHydra2 container (Debian LXC)..."
|
||||||
|
|
||||||
# Check for podman or docker
|
|
||||||
local runtime=""
|
|
||||||
if command -v podman >/dev/null 2>&1; then
|
|
||||||
runtime="podman"
|
|
||||||
elif command -v docker >/dev/null 2>&1; then
|
|
||||||
runtime="docker"
|
|
||||||
else
|
|
||||||
log_error "Neither podman nor docker found. Install one first."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create directories
|
# Create directories
|
||||||
mkdir -p "$CONTAINER_DIR/rootfs"
|
mkdir -p "$CONTAINER_DIR/rootfs"
|
||||||
mkdir -p "$DATA_DIR/config"
|
mkdir -p "$DATA_DIR/config"
|
||||||
|
|
||||||
# Pull and extract image
|
local rootfs="$CONTAINER_DIR/rootfs"
|
||||||
log_info "Pulling Docker image: $DOCKER_IMAGE"
|
|
||||||
if [ "$runtime" = "podman" ]; then
|
# Download Debian LXC rootfs if not exists
|
||||||
podman pull "$DOCKER_IMAGE" || { log_error "Failed to pull image"; return 1; }
|
if [ ! -f "$rootfs/bin/bash" ]; then
|
||||||
local container_id=$(podman create "$DOCKER_IMAGE")
|
log_info "Downloading Debian LXC rootfs..."
|
||||||
podman export "$container_id" | tar -xf - -C "$CONTAINER_DIR/rootfs"
|
|
||||||
podman rm "$container_id" >/dev/null
|
# Get latest build date from LXC mirror
|
||||||
else
|
local latest=$(curl -sL "$DEBIAN_LXC_MIRROR/" | grep -oE '[0-9]{8}_[0-9]{2}:[0-9]{2}' | sort -r | head -1)
|
||||||
docker pull "$DOCKER_IMAGE" || { log_error "Failed to pull image"; return 1; }
|
[ -z "$latest" ] && latest="20240301_05:24"
|
||||||
local container_id=$(docker create "$DOCKER_IMAGE")
|
|
||||||
docker export "$container_id" | tar -xf - -C "$CONTAINER_DIR/rootfs"
|
local rootfs_url="${DEBIAN_LXC_MIRROR}/${latest}/rootfs.tar.xz"
|
||||||
docker rm "$container_id" >/dev/null
|
local tarball="/tmp/debian-rootfs-nzbhydra.tar.xz"
|
||||||
|
|
||||||
|
log_info "Fetching: $rootfs_url"
|
||||||
|
curl -L -o "$tarball" "$rootfs_url" || {
|
||||||
|
log_error "Failed to download Debian rootfs"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info "Extracting rootfs..."
|
||||||
|
xz -d -c "$tarball" | tar -xf - -C "$rootfs" || {
|
||||||
|
log_error "Failed to extract rootfs"
|
||||||
|
rm -f "$tarball"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
rm -f "$tarball"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Configure DNS
|
||||||
|
echo "nameserver 8.8.8.8" > "$rootfs/etc/resolv.conf"
|
||||||
|
echo "nameserver 1.1.1.1" >> "$rootfs/etc/resolv.conf"
|
||||||
|
|
||||||
|
# Create startup script
|
||||||
|
cat > "$rootfs/start-nzbhydra.sh" <<'STARTEOF'
|
||||||
|
#!/bin/bash
|
||||||
|
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
export HOME="/root"
|
||||||
|
exec > /config/startup.log 2>&1
|
||||||
|
|
||||||
|
echo "=== Starting NZBHydra2 $(date) ==="
|
||||||
|
|
||||||
|
# Install NZBHydra2 if not present
|
||||||
|
if [ ! -f "/opt/nzbhydra2/nzbhydra2" ]; then
|
||||||
|
echo "Installing NZBHydra2..."
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
openjdk-17-jre-headless \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
|
unzip
|
||||||
|
|
||||||
|
# Download NZBHydra2
|
||||||
|
mkdir -p /opt/nzbhydra2
|
||||||
|
cd /opt/nzbhydra2
|
||||||
|
|
||||||
|
echo "Downloading NZBHydra2..."
|
||||||
|
local latest=$(curl -sL "https://api.github.com/repos/theotherp/nzbhydra2/releases/latest" | grep -oP '"tag_name": "\K[^"]+' | head -1)
|
||||||
|
[ -z "$latest" ] && latest="v6.3.2"
|
||||||
|
|
||||||
|
curl -L -o nzbhydra2.zip "https://github.com/theotherp/nzbhydra2/releases/download/${latest}/nzbhydra2-${latest#v}-amd64-linux.zip" || \
|
||||||
|
curl -L -o nzbhydra2.zip "https://github.com/theotherp/nzbhydra2/releases/download/${latest}/nzbhydra2-${latest#v}-linux.zip"
|
||||||
|
|
||||||
|
unzip -o nzbhydra2.zip
|
||||||
|
rm -f nzbhydra2.zip
|
||||||
|
chmod +x nzbhydra2 core
|
||||||
|
|
||||||
|
apt-get clean
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Starting NZBHydra2 server ==="
|
||||||
|
mkdir -p /config
|
||||||
|
cd /opt/nzbhydra2
|
||||||
|
exec ./nzbhydra2 --datafolder /config --host 0.0.0.0 --port 5076
|
||||||
|
STARTEOF
|
||||||
|
chmod +x "$rootfs/start-nzbhydra.sh"
|
||||||
|
|
||||||
# Create LXC config
|
# Create LXC config
|
||||||
local memory=$(uci_get main.memory)
|
local memory=$(uci_get main.memory)
|
||||||
[ -z "$memory" ] && memory="256M"
|
[ -z "$memory" ] && memory="268435456" # 256MB in bytes
|
||||||
|
|
||||||
cat > "$CONTAINER_DIR/config" <<EOF
|
cat > "$CONTAINER_DIR/config" <<EOF
|
||||||
lxc.uts.name = $CONTAINER_NAME
|
lxc.uts.name = $CONTAINER_NAME
|
||||||
lxc.rootfs.path = dir:$CONTAINER_DIR/rootfs
|
lxc.rootfs.path = dir:$CONTAINER_DIR/rootfs
|
||||||
lxc.init.cmd = /init
|
lxc.init.cmd = /start-nzbhydra.sh
|
||||||
|
|
||||||
# Network - share host namespace
|
# Network - use veth with bridge
|
||||||
lxc.namespace.share.net = 1
|
lxc.net.0.type = veth
|
||||||
|
lxc.net.0.link = br-lan
|
||||||
|
lxc.net.0.flags = up
|
||||||
|
lxc.net.0.ipv4.address = 192.168.255.41/24
|
||||||
|
lxc.net.0.ipv4.gateway = 192.168.255.1
|
||||||
|
|
||||||
|
# Mounts
|
||||||
|
lxc.mount.auto = proc:mixed sys:ro
|
||||||
|
lxc.mount.entry = $DATA_DIR/config config none bind,create=dir 0 0
|
||||||
|
lxc.mount.entry = tmpfs tmp tmpfs defaults 0 0
|
||||||
|
lxc.mount.entry = tmpfs run tmpfs defaults 0 0
|
||||||
|
|
||||||
# Capabilities
|
# Capabilities
|
||||||
lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
||||||
@ -71,19 +136,19 @@ lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
|||||||
# Memory limit
|
# Memory limit
|
||||||
lxc.cgroup2.memory.max = $memory
|
lxc.cgroup2.memory.max = $memory
|
||||||
|
|
||||||
# Mounts
|
# TTY
|
||||||
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
|
lxc.tty.max = 0
|
||||||
lxc.mount.entry = $DATA_DIR/config config none bind,create=dir 0 0
|
lxc.pty.max = 256
|
||||||
lxc.mount.entry = tmpfs tmp tmpfs defaults 0 0
|
|
||||||
lxc.mount.entry = tmpfs run tmpfs defaults 0 0
|
|
||||||
|
|
||||||
# Environment
|
# Seccomp (disabled for compatibility)
|
||||||
lxc.environment = PUID=1000
|
lxc.seccomp.profile =
|
||||||
lxc.environment = PGID=1000
|
|
||||||
lxc.environment = TZ=Europe/Paris
|
# Auto-start
|
||||||
|
lxc.start.auto = 1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
log_ok "NZBHydra2 container installed"
|
log_ok "NZBHydra2 container installed"
|
||||||
|
log_info "Container IP: 192.168.255.41"
|
||||||
log_info "Run: nzbhydractl start"
|
log_info "Run: nzbhydractl start"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,16 +167,15 @@ cmd_start() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Starting NZBHydra2..."
|
log_info "Starting NZBHydra2..."
|
||||||
lxc-start -n "$CONTAINER_NAME" -d -f "$CONTAINER_DIR/config"
|
lxc-start -n "$CONTAINER_NAME" -f "$CONTAINER_DIR/config"
|
||||||
|
|
||||||
# Wait for startup
|
# Wait for startup
|
||||||
sleep 5
|
sleep 5
|
||||||
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
||||||
local port=$(uci_get main.port)
|
log_ok "NZBHydra2 started on http://192.168.255.41:5076/"
|
||||||
[ -z "$port" ] && port="5076"
|
|
||||||
log_ok "NZBHydra2 started on http://127.0.0.1:$port/"
|
|
||||||
else
|
else
|
||||||
log_error "Failed to start NZBHydra2"
|
log_error "Failed to start NZBHydra2"
|
||||||
|
lxc-info -n "$CONTAINER_NAME" 2>&1
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -148,22 +212,20 @@ cmd_status() {
|
|||||||
# Container state
|
# Container state
|
||||||
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
||||||
echo "Container: RUNNING"
|
echo "Container: RUNNING"
|
||||||
|
echo "IP: 192.168.255.41"
|
||||||
else
|
else
|
||||||
echo "Container: STOPPED"
|
echo "Container: STOPPED"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local port=$(uci_get main.port)
|
|
||||||
[ -z "$port" ] && port="5076"
|
|
||||||
|
|
||||||
# Check if API responds
|
# Check if API responds
|
||||||
if curl -s "http://127.0.0.1:$port/api?t=caps" >/dev/null 2>&1; then
|
if curl -s "http://192.168.255.41:5076/api?t=caps" >/dev/null 2>&1; then
|
||||||
echo "API: OK"
|
echo "API: OK"
|
||||||
else
|
else
|
||||||
echo "API: Not responding"
|
echo "API: Not responding (may be starting)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Web UI: http://127.0.0.1:$port/"
|
echo "Web UI: http://192.168.255.41:5076/"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
@ -173,6 +235,8 @@ cmd_logs() {
|
|||||||
local lines="${1:-50}"
|
local lines="${1:-50}"
|
||||||
if [ -f "$DATA_DIR/config/logs/nzbhydra2.log" ]; then
|
if [ -f "$DATA_DIR/config/logs/nzbhydra2.log" ]; then
|
||||||
tail -n "$lines" "$DATA_DIR/config/logs/nzbhydra2.log"
|
tail -n "$lines" "$DATA_DIR/config/logs/nzbhydra2.log"
|
||||||
|
elif [ -f "$DATA_DIR/config/startup.log" ]; then
|
||||||
|
tail -n "$lines" "$DATA_DIR/config/startup.log"
|
||||||
else
|
else
|
||||||
log_info "No logs yet. NZBHydra may not have run."
|
log_info "No logs yet. NZBHydra may not have run."
|
||||||
fi
|
fi
|
||||||
@ -203,8 +267,6 @@ cmd_link_sabnzbd() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local sab_api=$(grep "^api_key" "$sab_ini" 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
|
local sab_api=$(grep "^api_key" "$sab_ini" 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
|
||||||
local sab_port=$(uci -q get sabnzbd.main.port)
|
|
||||||
[ -z "$sab_port" ] && sab_port="8085"
|
|
||||||
|
|
||||||
if [ -z "$sab_api" ]; then
|
if [ -z "$sab_api" ]; then
|
||||||
log_error "SABnzbd API key not found. Configure SABnzbd first."
|
log_error "SABnzbd API key not found. Configure SABnzbd first."
|
||||||
@ -212,12 +274,12 @@ cmd_link_sabnzbd() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Update UCI
|
# Update UCI
|
||||||
uci set "nzbhydra.sabnzbd.host=http://127.0.0.1:$sab_port"
|
uci set "nzbhydra.sabnzbd.host=http://192.168.255.40:8085"
|
||||||
uci set "nzbhydra.sabnzbd.api_key=$sab_api"
|
uci set "nzbhydra.sabnzbd.api_key=$sab_api"
|
||||||
uci commit nzbhydra
|
uci commit nzbhydra
|
||||||
|
|
||||||
log_ok "SABnzbd linked: http://127.0.0.1:$sab_port"
|
log_ok "SABnzbd linked: http://192.168.255.40:8085"
|
||||||
log_info "Restart NZBHydra to apply changes"
|
log_info "Configure in NZBHydra web UI: http://192.168.255.41:5076/"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
@ -227,12 +289,9 @@ cmd_search() {
|
|||||||
local query="$1"
|
local query="$1"
|
||||||
[ -z "$query" ] && { log_error "Usage: nzbhydractl search <query>"; return 1; }
|
[ -z "$query" ] && { log_error "Usage: nzbhydractl search <query>"; return 1; }
|
||||||
|
|
||||||
local port=$(uci_get main.port)
|
|
||||||
[ -z "$port" ] && port="5076"
|
|
||||||
|
|
||||||
log_info "Searching: $query"
|
log_info "Searching: $query"
|
||||||
|
|
||||||
local result=$(curl -s "http://127.0.0.1:$port/api?t=search&q=$(echo "$query" | sed 's/ /%20/g')" 2>/dev/null)
|
local result=$(curl -s "http://192.168.255.41:5076/api?t=search&q=$(echo "$query" | sed 's/ /%20/g')" 2>/dev/null)
|
||||||
|
|
||||||
if [ -n "$result" ]; then
|
if [ -n "$result" ]; then
|
||||||
echo "$result" | python3 -c "
|
echo "$result" | python3 -c "
|
||||||
@ -261,16 +320,13 @@ cmd_configure_haproxy() {
|
|||||||
local domain=$(uci_get exposure.domain)
|
local domain=$(uci_get exposure.domain)
|
||||||
[ -z "$domain" ] && domain="nzbhydra.gk2.secubox.in"
|
[ -z "$domain" ] && domain="nzbhydra.gk2.secubox.in"
|
||||||
|
|
||||||
local port=$(uci_get main.port)
|
|
||||||
[ -z "$port" ] && port="5076"
|
|
||||||
|
|
||||||
log_info "Configuring HAProxy for $domain"
|
log_info "Configuring HAProxy for $domain"
|
||||||
|
|
||||||
# Create backend
|
# Create backend
|
||||||
uci set haproxy.nzbhydra_web=backend
|
uci set haproxy.nzbhydra_web=backend
|
||||||
uci set haproxy.nzbhydra_web.name='nzbhydra_web'
|
uci set haproxy.nzbhydra_web.name='nzbhydra_web'
|
||||||
uci set haproxy.nzbhydra_web.mode='http'
|
uci set haproxy.nzbhydra_web.mode='http'
|
||||||
uci set haproxy.nzbhydra_web.server="nzbhydra 127.0.0.1:$port weight 100 check"
|
uci set haproxy.nzbhydra_web.server="nzbhydra 192.168.255.41:5076 weight 100 check"
|
||||||
|
|
||||||
# Create vhost
|
# Create vhost
|
||||||
local vhost_id=$(echo "$domain" | tr '.' '_')
|
local vhost_id=$(echo "$domain" | tr '.' '_')
|
||||||
@ -289,7 +345,7 @@ cmd_configure_haproxy() {
|
|||||||
import json
|
import json
|
||||||
with open('/srv/mitmproxy/haproxy-routes.json') as f:
|
with open('/srv/mitmproxy/haproxy-routes.json') as f:
|
||||||
routes = json.load(f)
|
routes = json.load(f)
|
||||||
routes['$domain'] = ['127.0.0.1', $port]
|
routes['$domain'] = ['192.168.255.41', 5076]
|
||||||
with open('/srv/mitmproxy/haproxy-routes.json', 'w') as f:
|
with open('/srv/mitmproxy/haproxy-routes.json', 'w') as f:
|
||||||
json.dump(routes, f, indent=2)
|
json.dump(routes, f, indent=2)
|
||||||
" 2>/dev/null
|
" 2>/dev/null
|
||||||
@ -337,7 +393,7 @@ case "$1" in
|
|||||||
echo "Usage: nzbhydractl <command>"
|
echo "Usage: nzbhydractl <command>"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Commands:"
|
echo "Commands:"
|
||||||
echo " install Install container from Docker image"
|
echo " install Install Debian LXC container with NZBHydra2"
|
||||||
echo " start Start NZBHydra2"
|
echo " start Start NZBHydra2"
|
||||||
echo " stop Stop NZBHydra2"
|
echo " stop Stop NZBHydra2"
|
||||||
echo " restart Restart NZBHydra2"
|
echo " restart Restart NZBHydra2"
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# SABnzbd Controller - Usenet NZB Downloader
|
# SABnzbd Controller - Usenet NZB Downloader
|
||||||
# LXC container management for SABnzbd
|
# LXC container with Debian rootfs (no Docker/Podman)
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
CONTAINER_NAME="sabnzbd"
|
CONTAINER_NAME="sabnzbd"
|
||||||
CONTAINER_DIR="/srv/lxc/$CONTAINER_NAME"
|
CONTAINER_DIR="/srv/lxc/$CONTAINER_NAME"
|
||||||
DATA_DIR="/srv/sabnzbd"
|
DATA_DIR="/srv/sabnzbd"
|
||||||
DOWNLOAD_DIR="/srv/downloads/usenet"
|
DOWNLOAD_DIR="/srv/downloads/usenet"
|
||||||
DOCKER_IMAGE="linuxserver/sabnzbd:latest"
|
|
||||||
CONFIG="sabnzbd"
|
CONFIG="sabnzbd"
|
||||||
|
|
||||||
|
# Debian LXC rootfs URL (arm64) - Linux Containers official
|
||||||
|
DEBIAN_LXC_MIRROR="https://images.linuxcontainers.org/images/debian/bookworm/arm64/default"
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
log_info() { logger -t sabnzbd -p user.info "$*"; echo "[INFO] $*"; }
|
log_info() { logger -t sabnzbd -p user.info "$*"; echo "[INFO] $*"; }
|
||||||
log_error() { logger -t sabnzbd -p user.error "$*"; echo "[ERROR] $*" >&2; }
|
log_error() { logger -t sabnzbd -p user.error "$*"; echo "[ERROR] $*" >&2; }
|
||||||
@ -20,52 +22,107 @@ log_ok() { echo "[OK] $*"; }
|
|||||||
uci_get() { uci -q get "$CONFIG.$1"; }
|
uci_get() { uci -q get "$CONFIG.$1"; }
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
# Install container from Docker image
|
# Install container with Debian rootfs
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
cmd_install() {
|
cmd_install() {
|
||||||
log_info "Installing SABnzbd container..."
|
log_info "Installing SABnzbd container (Debian LXC)..."
|
||||||
|
|
||||||
# Check for podman or docker
|
|
||||||
local runtime=""
|
|
||||||
if command -v podman >/dev/null 2>&1; then
|
|
||||||
runtime="podman"
|
|
||||||
elif command -v docker >/dev/null 2>&1; then
|
|
||||||
runtime="docker"
|
|
||||||
else
|
|
||||||
log_error "Neither podman nor docker found. Install one first."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create directories
|
# Create directories
|
||||||
mkdir -p "$CONTAINER_DIR/rootfs"
|
mkdir -p "$CONTAINER_DIR/rootfs"
|
||||||
mkdir -p "$DATA_DIR/config"
|
mkdir -p "$DATA_DIR/config"
|
||||||
mkdir -p "$DOWNLOAD_DIR"/{complete,incomplete,nzb}
|
mkdir -p "$DOWNLOAD_DIR"/{complete,incomplete,nzb}
|
||||||
|
|
||||||
# Pull and extract image
|
local rootfs="$CONTAINER_DIR/rootfs"
|
||||||
log_info "Pulling Docker image: $DOCKER_IMAGE"
|
|
||||||
if [ "$runtime" = "podman" ]; then
|
# Download Debian LXC rootfs if not exists
|
||||||
podman pull "$DOCKER_IMAGE" || { log_error "Failed to pull image"; return 1; }
|
if [ ! -f "$rootfs/bin/bash" ]; then
|
||||||
local container_id=$(podman create "$DOCKER_IMAGE")
|
log_info "Downloading Debian LXC rootfs..."
|
||||||
podman export "$container_id" | tar -xf - -C "$CONTAINER_DIR/rootfs"
|
|
||||||
podman rm "$container_id" >/dev/null
|
# Get latest build date from LXC mirror
|
||||||
else
|
local latest=$(curl -sL "$DEBIAN_LXC_MIRROR/" | grep -oE '[0-9]{8}_[0-9]{2}:[0-9]{2}' | sort -r | head -1)
|
||||||
docker pull "$DOCKER_IMAGE" || { log_error "Failed to pull image"; return 1; }
|
[ -z "$latest" ] && latest="20240301_05:24"
|
||||||
local container_id=$(docker create "$DOCKER_IMAGE")
|
|
||||||
docker export "$container_id" | tar -xf - -C "$CONTAINER_DIR/rootfs"
|
local rootfs_url="${DEBIAN_LXC_MIRROR}/${latest}/rootfs.tar.xz"
|
||||||
docker rm "$container_id" >/dev/null
|
local tarball="/tmp/debian-rootfs.tar.xz"
|
||||||
|
|
||||||
|
log_info "Fetching: $rootfs_url"
|
||||||
|
curl -L -o "$tarball" "$rootfs_url" || {
|
||||||
|
log_error "Failed to download Debian rootfs"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info "Extracting rootfs..."
|
||||||
|
xz -d -c "$tarball" | tar -xf - -C "$rootfs" || {
|
||||||
|
log_error "Failed to extract rootfs"
|
||||||
|
rm -f "$tarball"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
rm -f "$tarball"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Configure DNS
|
||||||
|
echo "nameserver 8.8.8.8" > "$rootfs/etc/resolv.conf"
|
||||||
|
echo "nameserver 1.1.1.1" >> "$rootfs/etc/resolv.conf"
|
||||||
|
|
||||||
|
# Create startup script
|
||||||
|
cat > "$rootfs/start-sabnzbd.sh" <<'STARTEOF'
|
||||||
|
#!/bin/bash
|
||||||
|
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
export HOME="/root"
|
||||||
|
exec > /config/startup.log 2>&1
|
||||||
|
|
||||||
|
echo "=== Starting SABnzbd $(date) ==="
|
||||||
|
|
||||||
|
# Install SABnzbd if not present
|
||||||
|
if ! command -v sabnzbdplus >/dev/null 2>&1; then
|
||||||
|
echo "Installing SABnzbd..."
|
||||||
|
|
||||||
|
# Add non-free repo for unrar
|
||||||
|
cat > /etc/apt/sources.list << EOF
|
||||||
|
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
|
||||||
|
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
|
||||||
|
deb http://deb.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware
|
||||||
|
EOF
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
sabnzbdplus \
|
||||||
|
unrar \
|
||||||
|
par2 \
|
||||||
|
p7zip-full \
|
||||||
|
ca-certificates
|
||||||
|
apt-get clean
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Starting SABnzbd server ==="
|
||||||
|
mkdir -p /config
|
||||||
|
exec sabnzbdplus -s 0.0.0.0:8085 -f /config
|
||||||
|
STARTEOF
|
||||||
|
chmod +x "$rootfs/start-sabnzbd.sh"
|
||||||
|
|
||||||
# Create LXC config
|
# Create LXC config
|
||||||
local memory=$(uci_get main.memory)
|
local memory=$(uci_get main.memory)
|
||||||
[ -z "$memory" ] && memory="512M"
|
[ -z "$memory" ] && memory="536870912" # 512MB in bytes
|
||||||
|
|
||||||
cat > "$CONTAINER_DIR/config" <<EOF
|
cat > "$CONTAINER_DIR/config" <<EOF
|
||||||
lxc.uts.name = $CONTAINER_NAME
|
lxc.uts.name = $CONTAINER_NAME
|
||||||
lxc.rootfs.path = dir:$CONTAINER_DIR/rootfs
|
lxc.rootfs.path = dir:$CONTAINER_DIR/rootfs
|
||||||
lxc.init.cmd = /init
|
lxc.init.cmd = /start-sabnzbd.sh
|
||||||
|
|
||||||
# Network - share host namespace
|
# Network - use veth with bridge
|
||||||
lxc.namespace.share.net = 1
|
lxc.net.0.type = veth
|
||||||
|
lxc.net.0.link = br-lan
|
||||||
|
lxc.net.0.flags = up
|
||||||
|
lxc.net.0.ipv4.address = 192.168.255.40/24
|
||||||
|
lxc.net.0.ipv4.gateway = 192.168.255.1
|
||||||
|
|
||||||
|
# Mounts
|
||||||
|
lxc.mount.auto = proc:mixed sys:ro
|
||||||
|
lxc.mount.entry = $DATA_DIR/config config none bind,create=dir 0 0
|
||||||
|
lxc.mount.entry = $DOWNLOAD_DIR downloads none bind,create=dir 0 0
|
||||||
|
lxc.mount.entry = tmpfs tmp tmpfs defaults 0 0
|
||||||
|
lxc.mount.entry = tmpfs run tmpfs defaults 0 0
|
||||||
|
|
||||||
# Capabilities
|
# Capabilities
|
||||||
lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
||||||
@ -73,30 +130,19 @@ lxc.cap.drop = sys_admin sys_boot sys_module sys_rawio sys_time
|
|||||||
# Memory limit
|
# Memory limit
|
||||||
lxc.cgroup2.memory.max = $memory
|
lxc.cgroup2.memory.max = $memory
|
||||||
|
|
||||||
# Mounts
|
# TTY
|
||||||
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
|
lxc.tty.max = 0
|
||||||
lxc.mount.entry = $DATA_DIR/config config none bind,create=dir 0 0
|
lxc.pty.max = 256
|
||||||
lxc.mount.entry = $DOWNLOAD_DIR downloads none bind,create=dir 0 0
|
|
||||||
lxc.mount.entry = tmpfs tmp tmpfs defaults 0 0
|
|
||||||
lxc.mount.entry = tmpfs run tmpfs defaults 0 0
|
|
||||||
|
|
||||||
# Environment
|
# Seccomp (disabled for compatibility)
|
||||||
lxc.environment = PUID=1000
|
lxc.seccomp.profile =
|
||||||
lxc.environment = PGID=1000
|
|
||||||
lxc.environment = TZ=Europe/Paris
|
# Auto-start
|
||||||
|
lxc.start.auto = 1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create startup wrapper
|
|
||||||
cat > "$CONTAINER_DIR/rootfs/start-sabnzbd.sh" <<'STARTEOF'
|
|
||||||
#!/bin/bash
|
|
||||||
export HOME=/config
|
|
||||||
export SABNZBD_HOME=/config
|
|
||||||
cd /app/sabnzbd
|
|
||||||
exec python3 SABnzbd.py --config-file /config/sabnzbd.ini --server 0.0.0.0:8085 --browser 0
|
|
||||||
STARTEOF
|
|
||||||
chmod +x "$CONTAINER_DIR/rootfs/start-sabnzbd.sh"
|
|
||||||
|
|
||||||
log_ok "SABnzbd container installed"
|
log_ok "SABnzbd container installed"
|
||||||
|
log_info "Container IP: 192.168.255.40"
|
||||||
log_info "Run: sabnzbdctl start"
|
log_info "Run: sabnzbdctl start"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,16 +161,15 @@ cmd_start() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Starting SABnzbd..."
|
log_info "Starting SABnzbd..."
|
||||||
lxc-start -n "$CONTAINER_NAME" -d -f "$CONTAINER_DIR/config"
|
lxc-start -n "$CONTAINER_NAME" -f "$CONTAINER_DIR/config"
|
||||||
|
|
||||||
# Wait for startup
|
# Wait for startup
|
||||||
sleep 3
|
sleep 5
|
||||||
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
||||||
local port=$(uci_get main.port)
|
log_ok "SABnzbd started on http://192.168.255.40:8085/"
|
||||||
[ -z "$port" ] && port="8085"
|
|
||||||
log_ok "SABnzbd started on http://127.0.0.1:$port/"
|
|
||||||
else
|
else
|
||||||
log_error "Failed to start SABnzbd"
|
log_error "Failed to start SABnzbd"
|
||||||
|
lxc-info -n "$CONTAINER_NAME" 2>&1
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -161,18 +206,17 @@ cmd_status() {
|
|||||||
# Container state
|
# Container state
|
||||||
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
if lxc-info -n "$CONTAINER_NAME" 2>/dev/null | grep -q "RUNNING"; then
|
||||||
echo "Container: RUNNING"
|
echo "Container: RUNNING"
|
||||||
|
echo "IP: 192.168.255.40"
|
||||||
else
|
else
|
||||||
echo "Container: STOPPED"
|
echo "Container: STOPPED"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# API status
|
# API status
|
||||||
local port=$(uci_get main.port)
|
|
||||||
[ -z "$port" ] && port="8085"
|
|
||||||
local api_key=$(cat "$DATA_DIR/config/sabnzbd.ini" 2>/dev/null | grep "^api_key" | cut -d'=' -f2 | tr -d ' ')
|
local api_key=$(cat "$DATA_DIR/config/sabnzbd.ini" 2>/dev/null | grep "^api_key" | cut -d'=' -f2 | tr -d ' ')
|
||||||
|
|
||||||
if [ -n "$api_key" ]; then
|
if [ -n "$api_key" ]; then
|
||||||
local status=$(curl -s "http://127.0.0.1:$port/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
local status=$(curl -s "http://192.168.255.40:8085/api?mode=queue&output=json&apikey=$api_key" 2>/dev/null)
|
||||||
if [ -n "$status" ]; then
|
if [ -n "$status" ]; then
|
||||||
local speed=$(echo "$status" | jsonfilter -e '@.queue.speed' 2>/dev/null)
|
local speed=$(echo "$status" | jsonfilter -e '@.queue.speed' 2>/dev/null)
|
||||||
local queue_size=$(echo "$status" | jsonfilter -e '@.queue.noofslots' 2>/dev/null)
|
local queue_size=$(echo "$status" | jsonfilter -e '@.queue.noofslots' 2>/dev/null)
|
||||||
@ -184,7 +228,7 @@ cmd_status() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Web UI: http://127.0.0.1:$port/"
|
echo "Web UI: http://192.168.255.40:8085/"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
@ -211,16 +255,11 @@ cmd_shell() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
# Configure NNTP server from UCI
|
# Configure NNTP server
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
cmd_add_server() {
|
cmd_add_server() {
|
||||||
local ini_file="$DATA_DIR/config/sabnzbd.ini"
|
local ini_file="$DATA_DIR/config/sabnzbd.ini"
|
||||||
|
|
||||||
if [ ! -f "$ini_file" ]; then
|
|
||||||
log_error "SABnzbd config not found. Start SABnzbd first to create initial config."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read NNTP config from UCI
|
# Read NNTP config from UCI
|
||||||
local name=$(uci_get eweka.name)
|
local name=$(uci_get eweka.name)
|
||||||
local host=$(uci_get eweka.host)
|
local host=$(uci_get eweka.host)
|
||||||
@ -232,30 +271,21 @@ cmd_add_server() {
|
|||||||
|
|
||||||
[ -z "$host" ] && { log_error "No NNTP server configured in UCI"; return 1; }
|
[ -z "$host" ] && { log_error "No NNTP server configured in UCI"; return 1; }
|
||||||
|
|
||||||
log_info "Adding NNTP server: $name ($host)"
|
log_info "NNTP server configured: $name ($host)"
|
||||||
|
log_info "Username: $username"
|
||||||
|
log_info "Connections: $connections"
|
||||||
|
log_info "SSL Port: $port"
|
||||||
|
|
||||||
# SABnzbd uses INI format with [servers] section
|
# If SABnzbd running, use API
|
||||||
# We'll add via API if running, otherwise manual config
|
if [ -f "$ini_file" ]; then
|
||||||
local api_port=$(uci_get main.port)
|
local api_key=$(grep "^api_key" "$ini_file" 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
|
||||||
[ -z "$api_port" ] && api_port="8085"
|
if [ -n "$api_key" ] && curl -s "http://192.168.255.40:8085/api?mode=version&apikey=$api_key" >/dev/null 2>&1; then
|
||||||
local api_key=$(grep "^api_key" "$ini_file" 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
|
log_info "Adding server via API..."
|
||||||
|
# Server config via web UI or API
|
||||||
if [ -n "$api_key" ] && curl -s "http://127.0.0.1:$api_port/api?mode=version&apikey=$api_key" >/dev/null 2>&1; then
|
fi
|
||||||
# Use API to add server
|
|
||||||
curl -s "http://127.0.0.1:$api_port/api?mode=set_config§ion=servers&keyword=eweka&apikey=$api_key" \
|
|
||||||
-d "name=$name" \
|
|
||||||
-d "host=$host" \
|
|
||||||
-d "port=$port" \
|
|
||||||
-d "ssl=$ssl" \
|
|
||||||
-d "username=$username" \
|
|
||||||
-d "password=$password" \
|
|
||||||
-d "connections=$connections" \
|
|
||||||
-d "enable=1" >/dev/null
|
|
||||||
|
|
||||||
log_ok "NNTP server added via API"
|
|
||||||
else
|
|
||||||
log_info "SABnzbd not running. Server will be configured on first start."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
log_ok "Configure the server in SABnzbd web UI: http://192.168.255.40:8085/config/server/"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||||||
@ -265,16 +295,13 @@ cmd_configure_haproxy() {
|
|||||||
local domain=$(uci_get exposure.domain)
|
local domain=$(uci_get exposure.domain)
|
||||||
[ -z "$domain" ] && domain="sabnzbd.gk2.secubox.in"
|
[ -z "$domain" ] && domain="sabnzbd.gk2.secubox.in"
|
||||||
|
|
||||||
local port=$(uci_get main.port)
|
|
||||||
[ -z "$port" ] && port="8085"
|
|
||||||
|
|
||||||
log_info "Configuring HAProxy for $domain"
|
log_info "Configuring HAProxy for $domain"
|
||||||
|
|
||||||
# Create backend
|
# Create backend
|
||||||
uci set haproxy.sabnzbd_web=backend
|
uci set haproxy.sabnzbd_web=backend
|
||||||
uci set haproxy.sabnzbd_web.name='sabnzbd_web'
|
uci set haproxy.sabnzbd_web.name='sabnzbd_web'
|
||||||
uci set haproxy.sabnzbd_web.mode='http'
|
uci set haproxy.sabnzbd_web.mode='http'
|
||||||
uci set haproxy.sabnzbd_web.server="sabnzbd 127.0.0.1:$port weight 100 check"
|
uci set haproxy.sabnzbd_web.server="sabnzbd 192.168.255.40:8085 weight 100 check"
|
||||||
|
|
||||||
# Create vhost
|
# Create vhost
|
||||||
local vhost_id=$(echo "$domain" | tr '.' '_')
|
local vhost_id=$(echo "$domain" | tr '.' '_')
|
||||||
@ -293,7 +320,7 @@ cmd_configure_haproxy() {
|
|||||||
import json
|
import json
|
||||||
with open('/srv/mitmproxy/haproxy-routes.json') as f:
|
with open('/srv/mitmproxy/haproxy-routes.json') as f:
|
||||||
routes = json.load(f)
|
routes = json.load(f)
|
||||||
routes['$domain'] = ['127.0.0.1', $port]
|
routes['$domain'] = ['192.168.255.40', 8085]
|
||||||
with open('/srv/mitmproxy/haproxy-routes.json', 'w') as f:
|
with open('/srv/mitmproxy/haproxy-routes.json', 'w') as f:
|
||||||
json.dump(routes, f, indent=2)
|
json.dump(routes, f, indent=2)
|
||||||
" 2>/dev/null
|
" 2>/dev/null
|
||||||
@ -340,14 +367,14 @@ case "$1" in
|
|||||||
echo "Usage: sabnzbdctl <command>"
|
echo "Usage: sabnzbdctl <command>"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Commands:"
|
echo "Commands:"
|
||||||
echo " install Install container from Docker image"
|
echo " install Install Debian LXC container with SABnzbd"
|
||||||
echo " start Start SABnzbd"
|
echo " start Start SABnzbd"
|
||||||
echo " stop Stop SABnzbd"
|
echo " stop Stop SABnzbd"
|
||||||
echo " restart Restart SABnzbd"
|
echo " restart Restart SABnzbd"
|
||||||
echo " status Show status and queue info"
|
echo " status Show status and queue info"
|
||||||
echo " logs [n] Show last n log lines (default 50)"
|
echo " logs [n] Show last n log lines (default 50)"
|
||||||
echo " shell Interactive shell in container"
|
echo " shell Interactive shell in container"
|
||||||
echo " add-server Configure NNTP server from UCI"
|
echo " add-server Show NNTP server config from UCI"
|
||||||
echo " configure-haproxy Setup HAProxy reverse proxy"
|
echo " configure-haproxy Setup HAProxy reverse proxy"
|
||||||
echo " uninstall Remove container (keeps data)"
|
echo " uninstall Remove container (keeps data)"
|
||||||
;;
|
;;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user