Files
Varaverk/common.sh
T
2026-03-27 19:29:41 +00:00

205 lines
5.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# -----------------------------------------------------------------------------------------------
# ----------------- UNRAID OPS COMMON LIBRARY (STABLE FRAMEWORK v1) -----------------------
# -----------------------------------------------------------------------------------------------
# ICONS Profiles
ICON_INFO="️"
ICON_WARN="⚠️"
ICON_ERROR="❌"
ICON_SUCCESS="✅"
ICON_RUN="🚀"
ICON_STOP="🛑"
ICON_RETRY="🔁"
ICON_SYNC="🔄"
ICON_GEAR="⚙️"
# OUTPUT
info() { echo "$ICON_INFO [INFO] $*"; }
warn() { echo "$ICON_WARN [WARN] $*"; }
error() { echo "$ICON_ERROR [ERROR] $*"; }
success() { echo "$ICON_SUCCESS [OK] $*"; }
log() {
[[ "${ENABLE_LOGGING:-false}" == true ]] && echo "[LOG] $*"
}
# ARG PARSER
parse_args() {
ENABLE_LOGGING=${ENABLE_LOGGING:-false}
DRY_RUN=${DRY_RUN:-false}
SHOW_STATUS=${SHOW_STATUS:-false}
CLEAN_ARGS=()
for ARG in "$@"; do
if [[ "$ARG" == *=* ]]; then
VAR="${ARG%%=*}"
VAL="${ARG#*=}"
case "$VAR" in
LOG)
[[ "$VAL" == "true" ]] && ENABLE_LOGGING=true
[[ "$VAL" == "false" ]] && ENABLE_LOGGING=false
;;
*)
if declare -p "$VAR" &>/dev/null; then
printf -v "$VAR" '%s' "$VAL"
log "Set $VAR=$VAL"
else
warn "Unknown variable: $VAR"
fi
;;
esac
else
case "$ARG" in
--dry-run|-n) DRY_RUN=true ;;
--log) ENABLE_LOGGING=true ;;
--no-log) ENABLE_LOGGING=false ;;
--status|--summary) SHOW_STATUS=true ;;
--help|-h)
echo "Usage: script <dir> [--dry-run] [--log]"
exit 0
;;
*) CLEAN_ARGS+=("$ARG") ;;
esac
fi
done
PARSED_ARGS=("${CLEAN_ARGS[@]}")
}
# VALIDATION
require_var() {
[[ -z "${!1:-}" ]] && error "Missing required: $1" && exit 1
}
# HOST DETECTION
detect_hosts() {
LOCAL_HOSTNAME="$(hostname)"
if [[ "$LOCAL_HOSTNAME" == "$HOST1" ]]; then
LOCAL_SERVER_NAME="$HOST1"
REMOTE_SERVER_NAME="$HOST2"
elif [[ "$LOCAL_HOSTNAME" == "$HOST2" ]]; then
LOCAL_SERVER_NAME="$HOST2"
REMOTE_SERVER_NAME="$HOST1"
else
error "Unknown host: $LOCAL_HOSTNAME"
exit 1
fi
declare -A SSH_KEYS
SSH_KEYS["$HOST1|$HOST2"]="$HOST1_SSH_KEY"
SSH_KEYS["$HOST2|$HOST1"]="$HOST2_SSH_KEY"
SSH_KEY="${SSH_KEYS[$LOCAL_SERVER_NAME|$REMOTE_SERVER_NAME]}"
[[ -z "$SSH_KEY" ]] && error "Missing SSH key mapping" && exit 1
info "Host: $LOCAL_SERVER_NAME$REMOTE_SERVER_NAME"
}
# REMOTE
resolve_remote_ip() {
log "Resolving remote IP..."
REMOTE_SERVER=$(tailscale ip -4 "$REMOTE_SERVER_NAME" 2>/dev/null)
[[ -z "$REMOTE_SERVER" ]] && error "Failed to resolve remote IP" && exit 1
info "Remote IP: $REMOTE_SERVER"
}
# CONTAINERS
RUNNING_CONTAINERS=()
stop_containers() {
if [[ ${#CRITICAL_CONTAINER_NAMES[@]} -eq 0 ]]; then
log "No containers defined to stop"
return
fi
info "Stopping containers..."
RUNNING_CONTAINERS=()
for c in "${CRITICAL_CONTAINER_NAMES[@]}"; do
log "Checking container: $c"
STATUS=$(ssh -i "$SSH_KEY" root@"$REMOTE_SERVER" \
"docker inspect -f '{{.State.Running}}' $c 2>/dev/null" || echo "false")
if [[ "$STATUS" == "true" ]]; then
warn "Stopping $c"
RUNNING_CONTAINERS+=("$c")
ssh -i "$SSH_KEY" root@"$REMOTE_SERVER" "docker stop $c"
else
log "$c already stopped"
fi
done
}
start_containers() {
if [[ ${#RUNNING_CONTAINERS[@]} -eq 0 ]]; then
log "No containers to restart"
return
fi
info "Starting containers..."
for c in "${RUNNING_CONTAINERS[@]}"; do
info "Starting $c"
ssh -i "$SSH_KEY" root@"$REMOTE_SERVER" "docker start $c"
done
}
# RSYNC LIMITER (FIXED FINAL)
wait_for_rsync() {
: "${RETRY_COUNT:=5}"
: "${MAX_RSYNC_PROCS:=2}"
: "${SLEEP:=2}"
for i in $(seq 1 "$RETRY_COUNT"); do
# ONLY COUNT LOCAL INITIATED RSYNC COMMANDS
COUNT=$(ps -eo pid,cmd | grep "[r]sync .*${REMOTE_SERVER:-}" | wc -l || true)
# fallback if REMOTE_SERVER not set yet
if [[ -z "$REMOTE_SERVER" ]]; then
COUNT=$(pgrep -x rsync | wc -l || true)
fi
if [[ "$COUNT" -ge "$MAX_RSYNC_PROCS" ]]; then
warn "Waiting rsync slot ($COUNT/$MAX_RSYNC_PROCS)"
sleep "$SLEEP"
else
return 0
fi
done
error "Too many rsync processes"
exit 1
}
# RSYNC OPTIONS
get_rsync_opts() {
if [[ -n "${PROFILE_RSYNC_OPTS[$PROFILE_NAME]:-}" ]]; then
read -r -a RSYNC_OPTS <<< "${PROFILE_RSYNC_OPTS[$PROFILE_NAME]}"
else
RSYNC_OPTS=("${DEFAULT_RSYNC_OPTS[@]}")
fi
}
# STATUS
show_status() {
echo "===== STATUS ====="
echo "Local: $LOCAL_SERVER_NAME"
echo "Remote: $REMOTE_SERVER_NAME"
echo "IP: $REMOTE_SERVER"
echo "Profile: $PROFILE_NAME"
echo "DryRun: $DRY_RUN"
echo "Logging: $ENABLE_LOGGING"
echo "=================="
}