#!/usr/bin/env bash BLUE='\033[38;5;45m' PURPLE='\033[38;5;127m' GOLD='\033[38;5;178m' RED='\033[38;5;196m' NC='\033[0m' BOLD='\033[1m' BFR='\r\033[K' msg_info() { local msg="$1" echo -e " ${BLUE}ℹ️ ${msg}${NC}" log_msg "[INFO] $msg" } msg_ok() { local msg="$1" echo -e " ${GOLD}✅ ${msg}${NC}" log_msg "[OK] $msg" } msg_error() { local msg="$1" echo -e " ${RED}❌ ${msg}${NC}" >&2 log_msg "[ERROR] $msg" } msg_warn() { local msg="$1" echo -e " ${PURPLE}⚠️ ${msg}${NC}" >&2 log_msg "[WARN] $msg" } get_active_logfile() { local app_designation=$(echo "${APP:-system}" | tr '[:upper:]' '[:lower:]' | tr -d ' ') if [[ -n "${_HOST_LOGFILE:-}" ]]; then echo "$_HOST_LOGFILE" elif [[ -n "${INSTALL_LOG:-}" ]]; then echo "$INSTALL_LOG" else echo "/tmp/INSTALL_LOG_${app_designation}.log" fi } strip_ansi() { if [[ $# -gt 0 ]]; then echo -e "$*" | sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g' else sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g' fi } log_msg() { local msg="$*" local logfile=$(get_active_logfile) [[ -z "$msg" || -z "$logfile" ]] && return mkdir -p "$(dirname "$logfile")" 2>/dev/null || true local clean_msg=$(strip_ansi "$msg") echo "[$(date '+%Y-%m-%d %H:%M:%S')] $clean_msg" >>"$logfile" } manifest_provision() { local logfile=$(get_active_logfile) local _restore_errexit=false [[ "$-" == *e* ]] && _restore_errexit=true set +Eeuo pipefail trap - ERR "$@" 2>&1 | tee -a "$logfile" local rc=${PIPESTATUS[0]} if $_restore_errexit; then set -Eeuo pipefail trap 'error_handler' ERR fi return "$rc" } network_check() { msg_info "Verifying Internet Availability (1.1.1.1 / 1.0.0.1)..." if ping -c 1 -W 2 1.1.1.1 &>/dev/null || ping -c 1 -W 2 1.0.0.1 &>/dev/null; then msg_ok "Network OK." else msg_error "Network Unreachable. Provision Aborted." exit 1 fi } github_api_check() { msg_info "Checking Github API Token..." local api_response=$(curl -s https://api.github.com/rate_limit) local remaining=$(echo "$api_response" | grep -A 2 '"core"' | grep '"remaining"' | tr -dc '0-9') if [[ -n "$remaining" ]]; then msg_ok "Github: Tokens Remaining: ${GOLD}${remaining}${NC}" else msg_warn "Github: Limit Unreadable. Proceeding with caution." fi } apt_update_safe() { msg_info "Refreshing Repositories" if ! manifest_provision apt-get update; then msg_warn "Partial repository refresh. Proceeding with caution." else msg_ok "Repositories Refreshed" fi } apt_update_safe() { msg_info "Refreshing Repositories" if ! manifest_provision apt-get update; then msg_warn "Partial repository refresh. Proceeding with caution." else msg_ok "Repositories Refreshed" fi } dynr_update_menu() { local target_dir="$1" if [[ -n "$target_dir" && -d "$target_dir" ]]; then if command -v whiptail >/dev/null 2>&1; then local choice choice=$(whiptail --backtitle "Dynasty Revolution" --title "UPDATE MANAGER" --radiolist "Select components to update:" 12 58 3 "OS" "Update Operating System" OFF "APP" "Update Application" OFF "BOTH" "Update OS and App" ON 3>&1 1>&2 2>&3) echo "${choice:-NONE}" else echo -e "${PURPLE}Update Manager${NC}" >&2 echo "1) Update OS" >&2 echo "2) Update App" >&2 echo "3) Update Both" >&2 read -p "Select choice [3]: " choice_num < /dev/tty case "$choice_num" in 1) echo "OS" ;; 2) echo "APP" ;; *) echo "BOTH" ;; esac fi else echo "OS" fi } header_info() { clear local app_name="${1:-$APP}" local ascii_target header_info() { clear local app_name="${1:-$APP}" local ascii_target if [[ -n "${MODULE_PATH:-}" ]]; then ascii_target=$(basename "$MODULE_PATH" .sh) else ascii_target=$(echo "$app_name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') fi local ascii_url="https://git.dynastyrevolution.com/DYNR/DynastyRevolution-Scripts/raw/branch/main/core/ascii-art/${ascii_target}" echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" if curl -fsSL --connect-timeout 1 "$ascii_url" &>/dev/null; then echo -e "${BLUE}$(curl -fsSL "$ascii_url")${NC}" else echo -e " ${BLUE}${BOLD}DYNASTY REVOLUTION PROVISIONING${NC}" fi echo -e " ${PURPLE}Install provided by the courtesy of Dynasty Revolution${NC}" echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" [[ -n "$app_name" ]] && echo -e " ${BLUE}Task:${NC} Deployment of ${GOLD}${app_name}${NC}" [[ -n "$app_name" ]] && echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "" } exit_script() { local logfile=$(get_active_logfile) echo -e "\n${GOLD}🐉Provision Complete.${NC}" echo -e "${BLUE}Log Location:${NC} ${GOLD}${logfile}${NC}" exit 0 } parse_dev_mode() { for arg in "$@"; do if [[ "$arg" == "--dev" ]] || [[ "$arg" == "-v" ]] || [[ "$arg" == "--verbose" ]]; then export DEV_MODE_LOGS="true" fi done } pve_check() { command -v pveversion >/dev/null 2>&1 || exit 1; } shell_check() { [[ -n "$BASH_VERSION" ]] || exit 1; } root_check() { [[ "$EUID" -eq 0 ]] || exit 1; } arch_check() { [[ "$(uname -m)" == "x86_64" ]] || exit 1; } load_functions() { :; }