diff --git a/deploy/install.sh b/deploy/install.sh index f2fc35b..a87c7a5 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -33,6 +33,172 @@ # set -euo pipefail +# ---- style helpers ----------------------------------------------------- +# Identical block across proxmox-install.sh, install.sh, pxe-setup.sh. +# Inlined (not sourced) so the curl|bash entrypoint renders without a +# prior fetch. Respects NO_COLOR, non-TTY, and non-UTF-8 locales. +_color=0; _unicode=0 +if [[ -t 2 && -z "${NO_COLOR:-}" && "${TERM:-dumb}" != "dumb" ]]; then + _color=1 +fi +case "${LC_ALL:-}${LANG:-}" in + *UTF-8*|*utf8*|*UTF8*) _unicode=1 ;; +esac +if (( _color )); then + _B=$'\033[1m'; _D=$'\033[2m'; _R=$'\033[0m' + _C=$'\033[1;36m'; _G=$'\033[32m'; _Y=$'\033[33m'; _E=$'\033[31m' +else + _B=""; _D=""; _R=""; _C=""; _G=""; _Y=""; _E="" +fi +if (( _unicode )); then + _S_STEP="▸"; _S_OK="✓"; _S_WARN="⚠"; _S_FAIL="✗"; _S_INFO="·" + _B_TL="╭"; _B_TR="╮"; _B_BL="╰"; _B_BR="╯"; _B_H="─"; _B_V="│" +else + _S_STEP="-->"; _S_OK="[ok]"; _S_WARN="[!]"; _S_FAIL="[x]"; _S_INFO="*" + _B_TL="+"; _B_TR="+"; _B_BL="+"; _B_BR="+"; _B_H="-"; _B_V="|" +fi +_start_epoch="$(date +%s)"; _step_epoch=""; _quiet_log=""; _spin_pid="" +_fmt_dur() { + local s=$1 + if (( s < 60 )); then printf '%ds' "$s" + elif (( s < 3600 )); then printf '%dm %ds' "$((s/60))" "$((s%60))" + else printf '%dh %dm' "$((s/3600))" "$(((s%3600)/60))" + fi +} +banner() { + local inner=" $1 " w line="" i=0 + w=${#inner} + while (( i < w )); do line+="${_B_H}"; i=$((i+1)); done + printf '\n %s%s%s%s%s\n' "${_C}" "${_B_TL}" "${line}" "${_B_TR}" "${_R}" >&2 + printf ' %s%s%s%s%s%s%s%s%s\n' "${_C}" "${_B_V}" "${_R}" "${_B}" "${inner}" "${_R}" "${_C}" "${_B_V}" "${_R}" >&2 + printf ' %s%s%s%s%s\n\n' "${_C}" "${_B_BL}" "${line}" "${_B_BR}" "${_R}" >&2 +} +step() { + _step_epoch="$(date +%s)" + printf '%s%s%s %s%s%s\n' "${_C}" "${_S_STEP}" "${_R}" "${_B}" "$1" "${_R}" >&2 +} +ok() { + local tail="" + if [[ -n "${_step_epoch}" ]]; then + tail=" ${_D}($(_fmt_dur $(( $(date +%s) - _step_epoch ))))${_R}" + fi + printf ' %s%s%s %s%s\n' "${_G}" "${_S_OK}" "${_R}" "$1" "${tail}" >&2 + _step_epoch="" +} +info() { printf ' %s%s %s%s\n' "${_D}" "${_S_INFO}" "$1" "${_R}" >&2; } +warn() { printf ' %s%s %s%s\n' "${_Y}" "${_S_WARN}" "$1" "${_R}" >&2; } +die() { + printf '\n%s%s %s%s\n' "${_E}" "${_S_FAIL}" "$1" "${_R}" >&2 + if [[ -n "${_quiet_log:-}" && -s "${_quiet_log}" ]]; then + printf ' %s── last 40 lines of output ──%s\n' "${_D}" "${_R}" >&2 + tail -n 40 "${_quiet_log}" | sed 's/^/ /' >&2 + printf ' %sfull log: %s%s\n' "${_D}" "${_quiet_log}" "${_R}" >&2 + fi + exit 1 +} +_SPIN=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") +_start_spin() { + (( _color && _unicode )) || return 0 + local label="$1" + ( + local i=0 + while :; do + printf '\r %s%s%s %s ' "${_C}" "${_SPIN[i]}" "${_R}" "${label}" >&2 + i=$(( (i+1) % ${#_SPIN[@]} )) + sleep 0.1 + done + ) & + _spin_pid=$! +} +_stop_spin() { + [[ -n "${_spin_pid}" ]] || return 0 + kill "${_spin_pid}" 2>/dev/null || true + wait "${_spin_pid}" 2>/dev/null || true + _spin_pid="" + printf '\r\033[2K' >&2 +} +# run_quiet "