introduce dev_mode

Introduces granular dev_mode flags (motd, keep, trace, pause, breakpoint, logs, dryrun) with a parser and exports for container builds. Enables persistent log directories when logs mode is active, supports dryrun and trace modes, and adds MOTD/SSH setup and breakpoint shell for debugging. Refactors related logic in build.func, core.func, and install.func for improved developer experience and debugging.
This commit is contained in:
CanbiZ 2025-11-17 12:53:26 +01:00
parent c2b7f4e298
commit 916293d98d
3 changed files with 283 additions and 125 deletions

View File

@ -48,7 +48,16 @@ variables() {
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files
BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log
CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"} CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"
# Parse dev_mode early
parse_dev_mode
# Setup persistent log directory if logs mode active
if [[ "${DEV_MODE_LOGS:-false}" == "true" ]]; then
mkdir -p /var/log/community-scripts
BUILD_LOG="/var/log/community-scripts/create-lxc-${SESSION_ID}-$(date +%Y%m%d_%H%M%S).log"
fi
# Get Proxmox VE version and kernel version # Get Proxmox VE version and kernel version
if command -v pveversion >/dev/null 2>&1; then if command -v pveversion >/dev/null 2>&1; then
@ -2209,6 +2218,14 @@ build_container() {
export SESSION_ID="$SESSION_ID" export SESSION_ID="$SESSION_ID"
export BUILD_LOG="$BUILD_LOG" export BUILD_LOG="$BUILD_LOG"
export INSTALL_LOG="/root/.install-${SESSION_ID}.log" export INSTALL_LOG="/root/.install-${SESSION_ID}.log"
export dev_mode="${dev_mode:-}"
export DEV_MODE_MOTD="${DEV_MODE_MOTD:-false}"
export DEV_MODE_KEEP="${DEV_MODE_KEEP:-false}"
export DEV_MODE_TRACE="${DEV_MODE_TRACE:-false}"
export DEV_MODE_PAUSE="${DEV_MODE_PAUSE:-false}"
export DEV_MODE_BREAKPOINT="${DEV_MODE_BREAKPOINT:-false}"
export DEV_MODE_LOGS="${DEV_MODE_LOGS:-false}"
export DEV_MODE_DRYRUN="${DEV_MODE_DRYRUN:-false}"
export CACHER="$APT_CACHER" export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP" export CACHER_IP="$APT_CACHER_IP"
export tz="$timezone" export tz="$timezone"
@ -2579,6 +2596,20 @@ EOF'
# Install SSH keys # Install SSH keys
install_ssh_keys_into_ct install_ssh_keys_into_ct
# Dev mode: Setup MOTD/SSH before installation for debugging
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
msg_info "[DEV] Setting up MOTD and SSH before installation"
pct exec "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)" <<'MOTD_SETUP'
# Only run motd_ssh function if it exists
if declare -f motd_ssh >/dev/null 2>&1; then
motd_ssh
else
msg_warn "motd_ssh function not found in ${var_install}.sh"
fi
MOTD_SETUP
msg_ok "[DEV] MOTD/SSH ready - container accessible"
fi
# Run application installer (disable ERR trap to handle errors manually) # Run application installer (disable ERR trap to handle errors manually)
set +e set +e
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)" lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
@ -2625,6 +2656,26 @@ EOF'
[[ $install_log_copied == true ]] && echo -e "${GN}✔${CL} Installation log: ${BL}/tmp/install-lxc-${CTID}-${SESSION_ID}.log${CL}" [[ $install_log_copied == true ]] && echo -e "${GN}✔${CL} Installation log: ${BL}/tmp/install-lxc-${CTID}-${SESSION_ID}.log${CL}"
fi fi
# Dev mode: Keep container or open breakpoint shell
if [[ "${DEV_MODE_KEEP:-false}" == "true" ]]; then
msg_custom "🔧" "${YWB}" "[DEV] Keep mode active - container ${CTID} preserved"
return 0
elif [[ "${DEV_MODE_BREAKPOINT:-false}" == "true" ]]; then
msg_custom "🐛" "${RD}" "[DEV] Breakpoint mode - opening shell in container ${CTID}"
echo -e "${YW}Type 'exit' to return to host${CL}"
pct enter "$CTID"
echo ""
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
if read -r response && [[ "$response" =~ ^[Yy]$ ]]; then
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
msg_ok "Container ${CTID} removed"
else
msg_custom "🔧" "${YW}" "Container ${CTID} kept for debugging"
fi
exit $install_exit_code
fi
# Prompt user for cleanup with 60s timeout (plain echo - no msg_info to avoid spinner) # Prompt user for cleanup with 60s timeout (plain echo - no msg_info to avoid spinner)
echo "" echo ""
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}" echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"

View File

@ -146,6 +146,7 @@ default_vars() {
# - Sets default verbose mode for script and OS execution # - Sets default verbose mode for script and OS execution
# - If VERBOSE=yes: STD="" (show all output) # - If VERBOSE=yes: STD="" (show all output)
# - If VERBOSE=no: STD="silent" (suppress output via silent() wrapper) # - If VERBOSE=no: STD="silent" (suppress output via silent() wrapper)
# - If DEV_MODE_TRACE=true: Enables bash tracing (set -x)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
set_std_mode() { set_std_mode() {
if [ "${VERBOSE:-no}" = "yes" ]; then if [ "${VERBOSE:-no}" = "yes" ]; then
@ -153,6 +154,80 @@ set_std_mode() {
else else
STD="silent" STD="silent"
fi fi
# Enable bash tracing if trace mode active
if [[ "${DEV_MODE_TRACE:-false}" == "true" ]]; then
set -x
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
fi
}
# ------------------------------------------------------------------------------
# parse_dev_mode()
#
# - Parses comma-separated dev_mode variable (e.g., "motd,keep,trace")
# - Sets global flags for each mode:
# * DEV_MODE_MOTD: Setup SSH/MOTD before installation
# * DEV_MODE_KEEP: Never delete container on failure
# * DEV_MODE_TRACE: Enable bash set -x tracing
# * DEV_MODE_PAUSE: Pause after each msg_info step
# * DEV_MODE_BREAKPOINT: Open shell on error instead of cleanup
# * DEV_MODE_LOGS: Persist all logs to /var/log/community-scripts/
# * DEV_MODE_DRYRUN: Show commands without executing
# - Call this early in script execution
# ------------------------------------------------------------------------------
parse_dev_mode() {
local mode
# Initialize all flags to false
export DEV_MODE_MOTD=false
export DEV_MODE_KEEP=false
export DEV_MODE_TRACE=false
export DEV_MODE_PAUSE=false
export DEV_MODE_BREAKPOINT=false
export DEV_MODE_LOGS=false
export DEV_MODE_DRYRUN=false
# Parse comma-separated modes
if [[ -n "${dev_mode:-}" ]]; then
IFS=',' read -ra MODES <<<"$dev_mode"
for mode in "${MODES[@]}"; do
mode="$(echo "$mode" | xargs)" # Trim whitespace
case "$mode" in
motd) export DEV_MODE_MOTD=true ;;
keep) export DEV_MODE_KEEP=true ;;
trace) export DEV_MODE_TRACE=true ;;
pause) export DEV_MODE_PAUSE=true ;;
breakpoint) export DEV_MODE_BREAKPOINT=true ;;
logs) export DEV_MODE_LOGS=true ;;
dryrun) export DEV_MODE_DRYRUN=true ;;
*)
if declare -f msg_warn >/dev/null 2>&1; then
msg_warn "Unknown dev_mode: '$mode' (ignored)"
else
echo "[WARN] Unknown dev_mode: '$mode' (ignored)" >&2
fi
;;
esac
done
# Show active dev modes
local active_modes=()
[[ $DEV_MODE_MOTD == true ]] && active_modes+=("motd")
[[ $DEV_MODE_KEEP == true ]] && active_modes+=("keep")
[[ $DEV_MODE_TRACE == true ]] && active_modes+=("trace")
[[ $DEV_MODE_PAUSE == true ]] && active_modes+=("pause")
[[ $DEV_MODE_BREAKPOINT == true ]] && active_modes+=("breakpoint")
[[ $DEV_MODE_LOGS == true ]] && active_modes+=("logs")
[[ $DEV_MODE_DRYRUN == true ]] && active_modes+=("dryrun")
if [[ ${#active_modes[@]} -gt 0 ]]; then
if declare -f msg_custom >/dev/null 2>&1; then
msg_custom "🔧" "${YWB}" "Dev modes active: ${active_modes[*]}"
else
echo "[DEV] Active modes: ${active_modes[*]}" >&2
fi
fi
fi
} }
# ============================================================================== # ==============================================================================
@ -322,6 +397,16 @@ silent() {
local caller_line="${BASH_LINENO[0]:-unknown}" local caller_line="${BASH_LINENO[0]:-unknown}"
local logfile="$(get_active_logfile)" local logfile="$(get_active_logfile)"
# Dryrun mode: Show command without executing
if [[ "${DEV_MODE_DRYRUN:-false}" == "true" ]]; then
if declare -f msg_custom >/dev/null 2>&1; then
msg_custom "🔍" "${BL}" "[DRYRUN] $cmd"
else
echo "[DRYRUN] $cmd" >&2
fi
return 0
fi
set +Eeuo pipefail set +Eeuo pipefail
trap - ERR trap - ERR
@ -447,6 +532,12 @@ msg_info() {
if is_verbose_mode || is_alpine; then if is_verbose_mode || is_alpine; then
local HOURGLASS="${TAB}⏳${TAB}" local HOURGLASS="${TAB}⏳${TAB}"
printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2
# Pause mode: Wait for Enter after each step
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
read -r
fi
return return
fi fi
@ -455,6 +546,13 @@ msg_info() {
SPINNER_PID=$! SPINNER_PID=$!
echo "$SPINNER_PID" >/tmp/.spinner.pid echo "$SPINNER_PID" >/tmp/.spinner.pid
disown "$SPINNER_PID" 2>/dev/null || true disown "$SPINNER_PID" 2>/dev/null || true
# Pause mode: Stop spinner and wait
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
stop_spinner
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
read -r
fi
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -33,6 +33,12 @@ if [[ -z "${INSTALL_LOG:-}" ]]; then
INSTALL_LOG="/root/.install-${SESSION_ID:-unknown}.log" INSTALL_LOG="/root/.install-${SESSION_ID:-unknown}.log"
fi fi
# Dev mode: Persistent logs directory
if [[ "${DEV_MODE_LOGS:-false}" == "true" ]]; then
mkdir -p /var/log/community-scripts
INSTALL_LOG="/var/log/community-scripts/install-${SESSION_ID:-unknown}-$(date +%Y%m%d_%H%M%S).log"
fi
if ! command -v curl >/dev/null 2>&1; then if ! command -v curl >/dev/null 2>&1; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 apt-get update >/dev/null 2>&1
@ -43,6 +49,9 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV
load_functions load_functions
catch_errors catch_errors
# Re-parse dev_mode in container context (flags exported from host)
parse_dev_mode
# ============================================================================== # ==============================================================================
# SECTION 2: NETWORK & CONNECTIVITY # SECTION 2: NETWORK & CONNECTIVITY
# ============================================================================== # ==============================================================================