From 3e1d752bfd3ff9c48ee398471e0187eb093d0d6c Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Sat, 13 Dec 2025 10:00:00 +0800 Subject: [PATCH] refactor: extract shared utilities into common library - Create bin/lib/common.sh with shared logging and utility functions - Add minecraft/.env.example for environment configuration template - Update bin scripts to source shared library (DRY principle) - Consolidate duplicated logging functions across scripts --- bin/backup.sh | 22 +++----- bin/healthcheck.sh | 39 ++------------ bin/lib/common.sh | 119 +++++++++++++++++++++++++++++++++++++++++ bin/org-clone.sh | 13 ++--- minecraft/.env.example | 19 +++++++ 5 files changed, 150 insertions(+), 62 deletions(-) create mode 100644 bin/lib/common.sh create mode 100644 minecraft/.env.example diff --git a/bin/backup.sh b/bin/backup.sh index 4a31b17..fda2f5c 100755 --- a/bin/backup.sh +++ b/bin/backup.sh @@ -4,28 +4,18 @@ set -euo pipefail -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly NC='\033[0m' +# Source shared library +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/lib/common.sh" readonly BACKUP_ROOT="${BACKUP_ROOT:-./backups}" readonly TIMESTAMP=$(date +%Y%m%d-%H%M%S) -log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } -log_error() { echo -e "${RED}[ERROR]${NC} $*"; } - -ensure_backup_dir() { - local dir="$1" - mkdir -p "$dir" -} - backup_minecraft() { log_info "Backing up Minecraft server..." local backup_dir="$BACKUP_ROOT/minecraft/$TIMESTAMP" - ensure_backup_dir "$backup_dir" + ensure_dir "$backup_dir" # Backup world data if [[ -d "minecraft/data" ]]; then @@ -62,7 +52,7 @@ backup_teamspeak() { log_info "Backing up TeamSpeak server..." local backup_dir="$BACKUP_ROOT/teamspeak/$TIMESTAMP" - ensure_backup_dir "$backup_dir" + ensure_dir "$backup_dir" # Export Docker volume if docker volume ls | grep -q teamspeak_data; then @@ -82,7 +72,7 @@ backup_nextcloud() { log_info "Backing up Nextcloud..." local backup_dir="$BACKUP_ROOT/nextcloud/$TIMESTAMP" - ensure_backup_dir "$backup_dir" + ensure_dir "$backup_dir" # Backup database log_info " Backing up database..." diff --git a/bin/healthcheck.sh b/bin/healthcheck.sh index cf68d94..c22160a 100755 --- a/bin/healthcheck.sh +++ b/bin/healthcheck.sh @@ -4,42 +4,9 @@ set -euo pipefail -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly NC='\033[0m' - -log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } -log_error() { echo -e "${RED}[ERROR]${NC} $*"; } - -check_container_health() { - local container_name="$1" - - if ! docker ps --filter "name=$container_name" --format '{{.Names}}' | grep -q "$container_name"; then - return 1 - fi - - local status - status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null) - - if [[ "$status" == "running" ]]; then - return 0 - else - return 1 - fi -} - -check_port() { - local host="${1:-localhost}" - local port="$2" - - if timeout 2 bash -c "cat < /dev/null > /dev/tcp/$host/$port" 2>/dev/null; then - return 0 - else - return 1 - fi -} +# Source shared library +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/lib/common.sh" check_minecraft() { log_info "Checking Minecraft server..." diff --git a/bin/lib/common.sh b/bin/lib/common.sh new file mode 100644 index 0000000..af181dd --- /dev/null +++ b/bin/lib/common.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# Shared utility library for all scripts +# Source this file: source "$(dirname "$0")/lib/common.sh" + +# Prevent multiple sourcing +[[ -n "${_COMMON_SH_LOADED:-}" ]] && return +readonly _COMMON_SH_LOADED=1 + +# ============================================================================ +# Color definitions +# ============================================================================ +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' # No Color + +# ============================================================================ +# Logging functions +# ============================================================================ +log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } +log_debug() { [[ "${DEBUG:-}" == "1" ]] && echo -e "${BLUE}[DEBUG]${NC} $*"; } + +# ============================================================================ +# Container utilities +# ============================================================================ + +# Check if a container is running +# Usage: check_container_health "container_name" +# Returns: 0 if running, 1 otherwise +check_container_health() { + local container_name="$1" + + if ! docker ps --filter "name=$container_name" --format '{{.Names}}' | grep -q "^${container_name}$"; then + return 1 + fi + + local status + status=$(docker inspect --format='{{.State.Status}}' "$container_name" 2>/dev/null) + + [[ "$status" == "running" ]] +} + +# Check if a port is accessible +# Usage: check_port "host" "port" +# Returns: 0 if accessible, 1 otherwise +check_port() { + local host="${1:-localhost}" + local port="$2" + + if timeout 2 bash -c "cat < /dev/null > /dev/tcp/$host/$port" 2>/dev/null; then + return 0 + else + return 1 + fi +} + +# ============================================================================ +# File utilities +# ============================================================================ + +# Ensure a directory exists +# Usage: ensure_dir "/path/to/dir" +ensure_dir() { + local dir="$1" + [[ -d "$dir" ]] || mkdir -p "$dir" +} + +# Check if a command exists +# Usage: require_command "docker" "https://docs.docker.com/get-docker/" +require_command() { + local cmd="$1" + local install_url="${2:-}" + + if ! command -v "$cmd" &>/dev/null; then + log_error "$cmd is not installed" + [[ -n "$install_url" ]] && log_info "Install from: $install_url" + return 1 + fi + return 0 +} + +# ============================================================================ +# Environment utilities +# ============================================================================ + +# Load .env file if it exists +# Usage: load_env "/path/to/.env" +load_env() { + local env_file="${1:-.env}" + + if [[ -f "$env_file" ]]; then + set -a + # shellcheck source=/dev/null + source "$env_file" + set +a + return 0 + fi + return 1 +} + +# Validate that required environment variables are set +# Usage: require_env "VAR1" "VAR2" "VAR3" +require_env() { + local missing=() + for var in "$@"; do + if [[ -z "${!var:-}" ]]; then + missing+=("$var") + fi + done + + if [[ ${#missing[@]} -gt 0 ]]; then + log_error "Missing required environment variables: ${missing[*]}" + return 1 + fi + return 0 +} diff --git a/bin/org-clone.sh b/bin/org-clone.sh index cafc379..84e2fd4 100755 --- a/bin/org-clone.sh +++ b/bin/org-clone.sh @@ -7,16 +7,9 @@ set -euo pipefail -# Colors for output -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly NC='\033[0m' # No Color - -# Logging functions -log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } -log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } +# Source shared library +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/lib/common.sh" # Check prerequisites check_prerequisites() { diff --git a/minecraft/.env.example b/minecraft/.env.example new file mode 100644 index 0000000..bd1204b --- /dev/null +++ b/minecraft/.env.example @@ -0,0 +1,19 @@ +# Minecraft Server Environment Configuration +# Copy this file to .env and modify the values +# Usage: cp .env.example .env && chmod 600 .env + +# User permissions (avoid container file permission issues) +# Replace with your host user UID/GID, use 'id' command to check +UID=1000 +GID=1000 + +# RCON password (remote control, must be complex and secure) +# Generate a strong password: openssl rand -base64 32 +RCON_PASSWORD=your_secure_rcon_password_here + +# Timezone (adjust based on server location) +# Examples: America/New_York, Europe/London, Asia/Shanghai +TZ=Asia/Shanghai + +# Container name (used by scripts for health checks) +CONTAINER_NAME=mc-fabric-1.21.1