From 9641bebda8df2e96ad5fdbface8e81da54ee8d7d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 8 Jun 2026 00:27:15 +0000 Subject: [PATCH] filebrowser.sh: support standalone execution (sudo bash filebrowser.sh) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add standalone bootstrap block at the top (BASH_SOURCE[0] == $0 guard): - If lib/common.sh is present (repo cloned), source it — gets real helpers and picks up any existing ~/docker/.config site settings automatically - If not (one-off copy), inline minimal stubs: logging, require_docker (checks Docker is installed, gives install hint if not), prompt_text/yn (match common.sh eval pattern so install_filebrowser locals work), configure_caddy_for_service (no-op with manual hint), write_readme - Sets DOCKER_DIR, ACTUAL_USER, SITE_TZ etc. with sensible defaults - register_service becomes a no-op (no wizard menu to register into) - Execution deferred via _RUN_STANDALONE flag to after function definition Still works identically when sourced by setup.sh — the bootstrap block is skipped entirely in that path. https://claude.ai/code/session_01UZus2Q9gNTfUdqSMrhuX29 --- services/filebrowser.sh | 91 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/services/filebrowser.sh b/services/filebrowser.sh index 5299171..bbb2ad0 100644 --- a/services/filebrowser.sh +++ b/services/filebrowser.sh @@ -1,6 +1,94 @@ #!/bin/bash # services/filebrowser.sh — FileBrowser web-based file manager. # Part of the modular post-install system (sourced by setup.sh). +# +# Can also be run standalone on any machine: +# sudo bash filebrowser.sh +# (Docker must already be installed when run standalone) + +# ── Standalone bootstrap ────────────────────────────────────────────────────── +# Detected when the script is executed directly rather than sourced by setup.sh. +# Sets up helpers and globals, then defers execution until after the function +# definition at the bottom of this file. +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + [[ "$(id -u)" == "0" ]] || { echo "Run with sudo: sudo bash $0"; exit 1; } + + _SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + _COMMON="$_SELF_DIR/../lib/common.sh" + + if [[ -f "$_COMMON" ]]; then + # Full repo present — use the real helpers (picks up ~/docker/.config too) + # shellcheck source=../lib/common.sh + source "$_COMMON" + else + # One-off copy — inline minimal stubs + log_info() { echo -e "\033[0;34m[INFO]\033[0m $*"; } + log_success() { echo -e "\033[0;32m[OK]\033[0m $*"; } + log_warning() { echo -e "\033[1;33m[WARN]\033[0m $*"; } + log_error() { echo -e "\033[0;31m[ERROR]\033[0m $*" >&2; } + + require_docker() { + command -v docker &>/dev/null || { + log_error "Docker not found. Install it first:" + log_error " curl -fsSL https://get.docker.com | sudo sh" + return 1 + } + docker compose version &>/dev/null || { + log_error "Docker Compose plugin missing:" + log_error " sudo apt-get install -y docker-compose-plugin" + return 1 + } + } + + ensure_docker_dir_ownership() { + chown -R "$ACTUAL_USER:$ACTUAL_USER" "$@" 2>/dev/null || true + } + + # Match common.sh's eval-based pattern so local vars in install_* are set correctly + prompt_text() { + local _q="$1" _def="$2" _var="$3" _r + [[ "${UNATTENDED:-false}" == "true" ]] && { eval "$_var='$_def'"; return; } + read -r -p " $_q " _r + eval "$_var='${_r:-$_def}'" + } + + prompt_yn() { + local _q="$1" _def="$2" _var="$3" _r + [[ "${UNATTENDED:-false}" == "true" ]] && { eval "$_var='$_def'"; return; } + read -r -p " $_q " _r + eval "$_var='${_r:-$_def}'" + } + + configure_caddy_for_service() { + if [[ -d "$DOCKER_DIR/caddy" ]]; then + log_info "Caddy detected — configure reverse proxy manually (standalone mode)." + log_info " Add to Caddyfile: reverse_proxy filebrowser:80" + else + log_info "Access FileBrowser directly on port 8085." + fi + } + + write_readme() { + local _dir="$1"; shift + mkdir -p "$_dir" + cat > "$_dir/README.md" + } + fi + + # Globals — use existing site config values if present, otherwise sensible defaults + DOCKER_DIR="${DOCKER_DIR:-$HOME/docker}" + ACTUAL_USER="${ACTUAL_USER:-${SUDO_USER:-$USER}}" + ACTUAL_HOME="$(getent passwd "$ACTUAL_USER" 2>/dev/null | cut -d: -f6 || echo "$HOME")" + DRY_RUN="${DRY_RUN:-false}" + UNATTENDED="${UNATTENDED:-false}" + SITE_TZ="${SITE_TZ:-$(cat /etc/timezone 2>/dev/null || echo UTC)}" + SITE_DOMAIN="${SITE_DOMAIN:-example.com}" + SITE_CADDY_NET="${SITE_CADDY_NET:-caddy_net}" + + register_service() { :; } # no-op — no wizard to register into + _RUN_STANDALONE=1 +fi +# ───────────────────────────────────────────────────────────────────────────── register_service filebrowser utilities "Web file manager (FileBrowser)" 8085 @@ -115,3 +203,6 @@ MD echo " Default login: admin / admin (change immediately!)" echo "" } + +# Run immediately when executed directly (deferred until after function definition) +[[ "${_RUN_STANDALONE:-0}" == 1 ]] && install_filebrowser