From 9cad6ba3064c1fda8a0f0f791b9daec7cf0ddc3b Mon Sep 17 00:00:00 2001 From: FailedProxy Date: Mon, 6 Apr 2026 01:11:30 +0000 Subject: [PATCH] added icons and improved ux --- Master.conf | 35 ++++++++-------- Orchestrators/daily_sync.sh | 32 ++++++++------ Rsync/rsync.sh | 38 ++++++++++------- common.sh | 84 +++++++++++++++++++++++++------------ 4 files changed, 119 insertions(+), 70 deletions(-) diff --git a/Master.conf b/Master.conf index bd81bea..00d445e 100644 --- a/Master.conf +++ b/Master.conf @@ -16,10 +16,10 @@ ENABLE_LOGGING=true # false = only echo user-facing messages # ------------------ Git, Pull & Execute Script ----------------- -REPO_SSH="git@192.168.50.2:FailedProxy/Unraid_Scripts.git" -TARGET_DIR="/mnt/user/appdata/unraid_scripts" -GITEA_SSH_KEY="/root/.ssh/id_gitea_rsync" -SSH_PORT=221 + REPO_SSH="git@192.168.50.2:FailedProxy/Unraid_Scripts.git" + TARGET_DIR="/mnt/user/appdata/unraid_scripts" + GITEA_SSH_KEY="/root/.ssh/id_gitea_rsync" + SSH_PORT=221 # -------------------Rsync Script Defaults----------------------- # These are the fallback values used when no matching profile is found. @@ -51,19 +51,20 @@ SSH_PORT=221 # Shares synced once daily by Orchestrators/daily_sync.sh # Add or remove paths here to manage what gets synced. # These shares have no profile entry and fall through to DEFAULT_RSYNC_OPTS above. -DAILY_SYNC_SHARES=( - /mnt/user/Anime_Movies-Old - /mnt/user/Anime_Shows-Old - /mnt/user/Anime_Shows - /mnt/user/Books - /mnt/user/Intros - /mnt/user/Kids_Movies - /mnt/user/Kids_Tv_Shows - /mnt/user/Movies - /mnt/user/Music_Videos - /mnt/user/Nextcloud - /mnt/user/stand-up_comedy - /mnt/user/Tv_Shows + DAILY_SYNC_SHARES=( + /mnt/user/Anime_Movies-Old + /mnt/user/Anime_Shows-Old + /mnt/user/Anime_Shows + /mnt/user/Books + /mnt/user/Intros + /mnt/user/Kids_Movies + /mnt/user/Kids_Tv_Shows + /mnt/user/Movies + /mnt/user/Music_Videos + /mnt/user/Nextcloud + /mnt/user/stand-up_comedy + /mnt/user/Tv_Shows + /mnt/user/appdata-Failover/Gmer4Lfe/ ) # ------------------- unRAID essentail scripts ------------------ diff --git a/Orchestrators/daily_sync.sh b/Orchestrators/daily_sync.sh index 3a630c5..a890da6 100644 --- a/Orchestrators/daily_sync.sh +++ b/Orchestrators/daily_sync.sh @@ -23,9 +23,16 @@ echo "--- $ICON_GEAR Setup ---" detect_hosts resolve_remote_ip -# Single connectivity check upfront — fail fast before attempting all shares -# against an unreachable host rather than failing per-share through the loop +# ----------------------------------------------------------------------------------------------- +# --- $ICON_SHIELD Pre-flight Checks --- +# ----------------------------------------------------------------------------------------------- +echo "" +echo "--- $ICON_SHIELD Pre-flight Checks ---" + +# Single connectivity and rootfs check upfront — fail fast before attempting all shares +# Individual share and disk checks run per-share inside rsync.sh check_connectivity +check_remote_rootfs # ----------------------------------------------------------------------------------------------- # Tracking @@ -41,7 +48,7 @@ SHARE_COUNT=${#DAILY_SYNC_SHARES[@]} # ----------------------------------------------------------------------------------------------- echo "" echo "--- $ICON_SYNC Daily Sync Starting — $(date '+%Y-%m-%d %H:%M:%S') ---" -echo "Shares: $SHARE_COUNT" +echo "$ICON_SUMMARY Shares: $SHARE_COUNT" echo "" SHARE_INDEX=0 @@ -57,6 +64,7 @@ for SHARE in "${DAILY_SYNC_SHARES[@]}"; do SHARE_END=$(date +%s) SHARE_TIMES+=("$SHARE_NAME:$((SHARE_END - SHARE_START))") PASS+=("$SHARE_NAME") + echo "$ICON_DONE $SHARE_NAME complete" else SHARE_END=$(date +%s) SHARE_TIMES+=("$SHARE_NAME:$((SHARE_END - SHARE_START))") @@ -71,11 +79,11 @@ TOTAL_END=$(date +%s) TOTAL_DURATION=$((TOTAL_END - TOTAL_START)) # ----------------------------------------------------------------------------------------------- -# --- $ICON_SUCCESS Summary --- +# --- $ICON_SUMMARY Summary --- # ----------------------------------------------------------------------------------------------- -echo "===== DAILY SYNC SUMMARY =====" -echo "Started: $(date -d @$TOTAL_START '+%Y-%m-%d %H:%M:%S')" -echo "Finished: $(date -d @$TOTAL_END '+%Y-%m-%d %H:%M:%S')" +echo "===== $ICON_SUMMARY DAILY SYNC SUMMARY =====" +echo "$ICON_TIME Started: $(date -d @$TOTAL_START '+%Y-%m-%d %H:%M:%S')" +echo "$ICON_TIME Finished: $(date -d @$TOTAL_END '+%Y-%m-%d %H:%M:%S')" echo "" for entry in "${SHARE_TIMES[@]}"; do SHARE_NAME="${entry%%:*}" @@ -83,14 +91,14 @@ for entry in "${SHARE_TIMES[@]}"; do if printf '%s\n' "${FAIL[@]}" | grep -qx "$SHARE_NAME"; then echo " $ICON_ERROR $SHARE_NAME — $(format_duration $DURATION)" else - echo " $ICON_SUCCESS $SHARE_NAME — $(format_duration $DURATION)" + echo " $ICON_DONE $SHARE_NAME — $(format_duration $DURATION)" fi done echo "" -echo " Passed: ${#PASS[@]}/$SHARE_COUNT" -echo " Failed: ${#FAIL[@]}/$SHARE_COUNT" -echo " Duration: $(format_duration $TOTAL_DURATION)" -echo "==============================" +echo " $ICON_SUCCESS Passed: ${#PASS[@]}/$SHARE_COUNT" +echo " $ICON_ERROR Failed: ${#FAIL[@]}/$SHARE_COUNT" +echo " $ICON_TIME Duration: $(format_duration $TOTAL_DURATION)" +echo "=========================================" [[ ${#FAIL[@]} -gt 0 ]] && exit 1 exit 0 \ No newline at end of file diff --git a/Rsync/rsync.sh b/Rsync/rsync.sh index 0d3422c..8daf6fa 100644 --- a/Rsync/rsync.sh +++ b/Rsync/rsync.sh @@ -36,13 +36,23 @@ echo "--- $ICON_GEAR Setup ---" detect_hosts resolve_remote_ip + +# ----------------------------------------------------------------------------------------------- +# --- $ICON_SHIELD Pre-flight Checks --- +# ----------------------------------------------------------------------------------------------- +echo "" +echo "--- $ICON_SHIELD Pre-flight Checks ---" + check_connectivity check_remote_rootfs check_remote_share "$DIRECTORY" check_remote_disks "$DIRECTORY" +# ----------------------------------------------------------------------------------------------- # Profile is inferred from the directory basename (lowercased) # e.g. /mnt/user/appdata-Failover/Arrs_Stack → arrs_stack +# ----------------------------------------------------------------------------------------------- +echo "" PROFILE_NAME=$(basename "$DIRECTORY" | tr '[:upper:]' '[:lower:]') info "$ICON_GEAR Loading profile: $PROFILE_NAME" @@ -72,9 +82,9 @@ stop_containers # ----------------------------------------------------------------------------------------------- echo "" echo "--- $ICON_SYNC Transfer ---" -echo "Source: $DIRECTORY" -echo "Remote: $REMOTE_SERVER:$DIRECTORY" -echo "Profile: $PROFILE_NAME" +echo "$ICON_RUN Source: $DIRECTORY" +echo "$ICON_NET Remote: $REMOTE_SERVER:$DIRECTORY" +echo "$ICON_GEAR Profile: $PROFILE_NAME" echo "" get_rsync_opts @@ -97,7 +107,7 @@ for i in $(seq 1 "$RETRY_COUNT"); do if rsync "${RSYNC_OPTS[@]}" \ -e "ssh -i $SSH_KEY -T -o Compression=no -o IPQoS=throughput" \ "$DIRECTORY" "root@${REMOTE_SERVER}:$(dirname "$DIRECTORY")/"; then - success "Rsync complete" + echo "$ICON_DONE Rsync complete" RSYNC_SUCCESS=true break else @@ -107,29 +117,29 @@ for i in $(seq 1 "$RETRY_COUNT"); do done # ----------------------------------------------------------------------------------------------- -# --- $ICON_RUN Containers --- +# --- $ICON_START Containers --- # ----------------------------------------------------------------------------------------------- echo "" -echo "--- $ICON_RUN Containers ---" +echo "--- $ICON_START Containers ---" start_containers END=$(date +%s) # ----------------------------------------------------------------------------------------------- -# --- Summary --- +# --- $ICON_SUMMARY Summary --- # ----------------------------------------------------------------------------------------------- echo "" -echo "===== SUMMARY =====" -echo "Directory: $DIRECTORY" -echo "Profile: $PROFILE_NAME" -echo "Duration: $(format_duration $((END - START)))" +echo "===== $ICON_SUMMARY SUMMARY =====" +echo "$ICON_RUN Directory: $DIRECTORY" +echo "$ICON_GEAR Profile: $PROFILE_NAME" +echo "$ICON_TIME Duration: $(format_duration $((END - START)))" if [[ "$RSYNC_SUCCESS" == true ]]; then - echo "Status: $ICON_SUCCESS DONE" + echo "$ICON_DONE Status: $ICON_SUCCESS DONE" else - echo "Status: $ICON_ERROR FAILED after $RETRY_COUNT attempts" + echo "$ICON_ERROR Status: $ICON_ERROR FAILED after $RETRY_COUNT attempts" fi -echo "===================" +echo "=========================" [[ "$RSYNC_SUCCESS" == false ]] && exit 1 exit 0 \ No newline at end of file diff --git a/common.sh b/common.sh index e1ba03d..64ab2bb 100644 --- a/common.sh +++ b/common.sh @@ -2,7 +2,7 @@ # ----------------------------------------------------------------------------------------------- # ----------------- UNRAID OPS COMMON LIBRARY (STABLE FRAMEWORK v1) ---------------------------- # ----------------------------------------------------------------------------------------------- -# Version: 1.4 +# Version: 1.5 # ----------------------------------------------------------------------------------------------- # Changelog: # v1.0 — Initial stable framework @@ -18,19 +18,50 @@ # v1.4 — check_remote_disks added — verifies all physical disks backing a share are mounted # Discovers disk layout automatically at runtime, no configuration required # Aborts if any single disk backing the share is offline or unmounted +# v1.5 — Full icon set expanded — each operation and state has its own distinct icon +# All function output updated to use correct icon per context +# Icons grouped and commented by category for clarity # ----------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------------- # ICONS +# Each icon has one job — do not reuse across different contexts. +# ----------------------------------------------------------------------------------------------- + +# System / Host +ICON_HOST="🖥️" # host detection +ICON_NET="🌐" # network / IP resolution +ICON_PING="📡" # connectivity check +ICON_GEAR="⚙️" # setup section header / profile load + +# Health Checks +ICON_DISK="💾" # disk checks +ICON_HEALTH="🩺" # rootfs / share health checks +ICON_SHIELD="🛡️" # pre-flight section header + +# Containers +ICON_STOP="⛔" # stop command being issued +ICON_STOPPED="🔴" # container confirmed stopped +ICON_START="▶️" # start command being issued +ICON_STARTED="💚" # container confirmed started +ICON_RUNNING="🟢" # container already running when checked +ICON_NOT_RUNNING="🔴" # container already stopped when checked + +# Transfer +ICON_SYNC="🔄" # transfer section header +ICON_RUN="🚀" # sync starting / rsync attempt +ICON_RETRY="🔁" # retry attempt +ICON_DONE="🏁" # transfer complete + +# Summary +ICON_SUMMARY="📋" # summary section header +ICON_TIME="⏱️" # duration line + +# Output ICON_INFO="ℹ️" ICON_WARN="⚠️" ICON_ERROR="❌" ICON_SUCCESS="✅" -ICON_RUN="🚀" -ICON_STOP="🛑" -ICON_RETRY="🔁" -ICON_SYNC="🔄" -ICON_GEAR="⚙️" -ICON_DISK="💾" # ----------------------------------------------------------------------------------------------- # OUTPUT HELPERS @@ -149,7 +180,7 @@ detect_hosts() { [[ -z "$SSH_KEY" ]] && error "Missing SSH key mapping for $LOCAL_SERVER_NAME → $REMOTE_SERVER_NAME" && exit 1 - info "$ICON_GEAR Host: $LOCAL_SERVER_NAME → $REMOTE_SERVER_NAME" + info "$ICON_HOST Host: $LOCAL_SERVER_NAME → $REMOTE_SERVER_NAME" } # ----------------------------------------------------------------------------------------------- @@ -159,12 +190,12 @@ detect_hosts() { # Exits if resolution fails — likely means Tailscale is down or peer is offline. # ----------------------------------------------------------------------------------------------- resolve_remote_ip() { - log "$ICON_SYNC Resolving remote IP for $REMOTE_SERVER_NAME..." + log "Resolving remote IP for $REMOTE_SERVER_NAME..." REMOTE_SERVER=$(tailscale ip -4 "$REMOTE_SERVER_NAME" 2>/dev/null) [[ -z "$REMOTE_SERVER" ]] && error "Failed to resolve Tailscale IP for $REMOTE_SERVER_NAME" && exit 1 - info "$ICON_SYNC Remote IP: $REMOTE_SERVER" + info "$ICON_NET Remote IP: $REMOTE_SERVER" } # ----------------------------------------------------------------------------------------------- @@ -176,11 +207,11 @@ resolve_remote_ip() { check_connectivity() { log "Checking connectivity to $REMOTE_SERVER..." if ! ping -c1 -W3 "$REMOTE_SERVER" &>/dev/null; then - error "Remote $REMOTE_SERVER ($REMOTE_SERVER_NAME) is unreachable" + error "$ICON_PING Remote $REMOTE_SERVER ($REMOTE_SERVER_NAME) is unreachable" info "Hint: tailscale status | grep $REMOTE_SERVER_NAME" exit 1 fi - log "Remote is reachable" + info "$ICON_PING $REMOTE_SERVER_NAME is reachable" } # ----------------------------------------------------------------------------------------------- @@ -204,14 +235,14 @@ check_remote_rootfs() { if [[ "$REMOTE_USAGE" -ge "${ROOTFS_WARN:-75}" ]]; then echo "" - error "Remote rootfs is ${REMOTE_USAGE}% full — threshold is ${ROOTFS_WARN:-75}%" + error "$ICON_HEALTH Remote rootfs is ${REMOTE_USAGE}% full — threshold is ${ROOTFS_WARN:-75}%" warn "Array may be down or drives missing on $REMOTE_SERVER_NAME" info "Hint: Check array status on $REMOTE_SERVER_NAME before retrying" echo "" exit 1 fi - success "Remote rootfs: ${REMOTE_USAGE}% used (threshold: ${ROOTFS_WARN:-75}%)" + info "$ICON_HEALTH Remote rootfs: ${REMOTE_USAGE}% used (threshold: ${ROOTFS_WARN:-75}%)" } # ----------------------------------------------------------------------------------------------- @@ -232,7 +263,7 @@ check_remote_share() { if [[ "$SHARE_EXISTS" != "yes" ]]; then echo "" - error "Remote share does not exist: $dir" + error "$ICON_HEALTH Remote share does not exist: $dir" warn "Array may not be started or share is not configured on $REMOTE_SERVER_NAME" info "Hint: Check shares and array status on $REMOTE_SERVER_NAME before retrying" echo "" @@ -244,14 +275,14 @@ check_remote_share() { if [[ "$SHARE_EMPTY" == "yes" ]]; then echo "" - warn "Remote share exists but is empty: $dir" + warn "$ICON_HEALTH Remote share exists but is empty: $dir" warn "Drives may not be mounted on $REMOTE_SERVER_NAME — aborting to protect data" info "Hint: Verify array and drive assignments on $REMOTE_SERVER_NAME before retrying" echo "" exit 1 fi - success "Remote share verified: $dir" + info "$ICON_HEALTH Remote share verified: $dir" } # ----------------------------------------------------------------------------------------------- @@ -276,7 +307,7 @@ check_remote_disks() { if [[ -z "$DISK_PATHS" ]]; then echo "" - error "No disks found backing share $share_name on $REMOTE_SERVER_NAME" + error "$ICON_DISK No disks found backing share $share_name on $REMOTE_SERVER_NAME" warn "Share may not exist on any disk or array may not be started" info "Hint: Check array and share configuration on $REMOTE_SERVER_NAME" echo "" @@ -286,7 +317,6 @@ check_remote_disks() { local all_ok=true while IFS= read -r disk_share_path; do - # Extract the disk mountpoint — e.g. /mnt/disk8 from /mnt/disk8/Movies local disk_mount disk_mount=$(dirname "$disk_share_path") local disk_name @@ -296,9 +326,9 @@ check_remote_disks() { "mountpoint -q '$disk_mount' && echo yes || echo no" 2>/dev/null) if [[ "$MOUNTED" == "yes" ]]; then - success "$ICON_DISK $disk_name online — $share_name present" + info "$ICON_DISK $disk_name $ICON_RUNNING — $share_name present" else - error "$disk_name is not mounted — $share_name may be incomplete" + error "$ICON_DISK $disk_name $ICON_STOPPED — $share_name missing or incomplete" all_ok=false fi done <<< "$DISK_PATHS" @@ -347,12 +377,12 @@ stop_containers() { RUNNING_CONTAINERS+=("$c") if ssh -i "$SSH_KEY" root@"$REMOTE_SERVER" "docker stop $c" >/dev/null; then - success "$c stopped" + echo "$ICON_STOPPED $c stopped" else error "Failed to stop $c" fi else - warn "$c is not running, skipping" + echo "$ICON_NOT_RUNNING $c is not running, skipping" fi done } @@ -388,9 +418,9 @@ start_containers() { sleep "$CONTAINER_DELAY" fi - echo "$ICON_RUN Starting $c..." + echo "$ICON_START Starting $c..." if ssh -i "$SSH_KEY" root@"$REMOTE_SERVER" "docker start $c" >/dev/null; then - success "$c started" + echo "$ICON_STARTED $c started" else error "Failed to start $c" fi @@ -421,7 +451,7 @@ get_rsync_opts() { # Useful for verifying profile resolution and variable state before a live run. # ----------------------------------------------------------------------------------------------- show_status() { - echo "===== STATUS =====" + echo "===== $ICON_SUMMARY STATUS =====" echo "Local: $LOCAL_SERVER_NAME" echo "Remote: $REMOTE_SERVER_NAME" echo "IP: $REMOTE_SERVER" @@ -431,5 +461,5 @@ show_status() { echo "Containers: ${CRITICAL_CONTAINER_NAMES[*]}" echo "Delayed: ${DELAYED_CONTAINERS[*]}" echo "Excludes: ${EXCLUDE_DIRS[*]}" - echo "==================" + echo "========================" } \ No newline at end of file