-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathbuild-ui.func
More file actions
233 lines (207 loc) · 10.3 KB
/
Copy pathbuild-ui.func
File metadata and controls
233 lines (207 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# ==============================================================================
# BUILD-UI.FUNC - SHARED LXC BUILD UI (Proxmox VE + Incus)
# ==============================================================================
# Whiptail menus, advanced wizard, validators, preflight helpers, install_script
# and start(). Platform backends override storage/network/create hooks.
# Loaded by core/build.func (PVE) and incus/build.func (Incus).
# ==============================================================================
[[ -n "${_BUILD_UI_FUNC_LOADED:-}" ]] && return
_BUILD_UI_FUNC_LOADED=1
# ==============================================================================
# BUILD.FUNC - LXC CONTAINER BUILD & CONFIGURATION
# ==============================================================================
#
# This file provides the main build functions for creating and configuring
# LXC containers in Proxmox VE. It handles:
#
# - Variable initialization and defaults
# - Container creation and resource allocation
# - Storage selection and management
# - Advanced configuration and customization
# - User interaction menus and prompts
#
# Usage:
# - Sourced automatically by CT creation scripts
# - Requires core.func and error_handler.func to be loaded first
#
# ==============================================================================
# ==============================================================================
# SECTION 1: INITIALIZATION & CORE VARIABLES
# ==============================================================================
# ------------------------------------------------------------------------------
# variables()
#
# - Initializes core variables for container creation
# - Normalizes application name (NSAPP = lowercase, no spaces)
# - Builds installer filename (var_install)
# - Defines regex patterns for validation
# - Fetches Proxmox hostname and version
# - Generates unique session ID for tracking and logging
# - Captures app-declared resource defaults (CPU, RAM, Disk)
# ------------------------------------------------------------------------------
variables() {
# var_os becomes PCT_OSTYPE and then the template search string. Proxmox
# publishes archlinux-base, not "arch linux-base", so a var_os carrying a
# space fails four steps later as "No template found" and again as a pveam
# download with an empty name. Normalise where it enters, and say so.
if [[ -n "${var_os:-}" && "$var_os" =~ [[:space:][:upper:]] ]]; then
local _os_raw="$var_os"
var_os="${var_os,,}"
var_os="${var_os//[[:space:]]/}"
export var_os
msg_warn "var_os was '${_os_raw}', which is not a template name — using '${var_os}'"
fi
NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
EXECUTION_ID="${RANDOM_UUID}" # per-attempt execution ID (regenerated by telemetry_new_attempt on retries)
export RANDOM_UUID EXECUTION_ID
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
combined_log="/tmp/install-${SESSION_ID}-combined.log" # Combined log (build + install) for failed installations
CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"
# ARM64 Template default variables
DEBIAN_DEFAULT_CODENAME="trixie"
UBUNTU_DEFAULT_CODENAME="noble"
ALPINE_DEFAULT_VERSION="3.23"
# 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"
combined_log="/var/log/community-scripts/install-${SESSION_ID}-combined-$(date +%Y%m%d_%H%M%S).log"
fi
# Get Proxmox VE version and kernel version
if command -v pveversion >/dev/null 2>&1; then
PVEVERSION="$(_pve_version)"
else
PVEVERSION="N/A"
fi
KERNEL_VERSION=$(uname -r)
# Capture app-declared defaults (for precedence logic)
# These values are set by the app script BEFORE default.vars is loaded
# If app declares higher values than default.vars, app values take precedence
if [[ -n "${var_cpu:-}" && "${var_cpu}" =~ ^[0-9]+$ ]]; then
export APP_DEFAULT_CPU="${var_cpu}"
fi
if [[ -n "${var_ram:-}" && "${var_ram}" =~ ^[0-9]+$ ]]; then
export APP_DEFAULT_RAM="${var_ram}"
fi
if [[ -n "${var_disk:-}" && "${var_disk}" =~ ^[0-9]+$ ]]; then
export APP_DEFAULT_DISK="${var_disk}"
fi
}
# Configurable base URL for development — override with COMMUNITY_SCRIPTS_URL
# See docs/DEV_MODE.md for details
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main}"
# Repeated per file rather than shared: there is nowhere to put a shared copy
# that does not itself need downloading first. See core/build.func.
_CS_CURL_RETRY=(--retry 3 --retry-delay 1 --retry-connrefused --connect-timeout 10)
# Prefer the dispatcher's resolver; the fallback must use the ENGINE base,
# since every path passed in here is a core file, not a script.
_build_ui_source() {
local rel="$1"
if declare -f _cs_source_func >/dev/null 2>&1; then
_cs_source_func "$rel"
return
fi
local base="${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}"
if command -v curl >/dev/null 2>&1; then
# shellcheck disable=SC1090
source <(curl -fsSL "${_CS_CURL_RETRY[@]}" "$base/$rel")
else
# shellcheck disable=SC1090
source <(wget -qO- "$base/$rel")
fi
}
_build_ui_source "api/api.func"
_build_ui_source "core/core.func"
_build_ui_source "core/error_handler.func"
_build_ui_source "core/dev-mode.func"
load_functions
catch_errors
# ==============================================================================
# SECTION 2: PRE-FLIGHT (disabled — full implementation in host/preflight.func)
# ==============================================================================
# To re-enable: ENABLE_PREFLIGHT=1
# ------------------------------------------------------------------------------
run_preflight() {
if [[ "${ENABLE_PREFLIGHT:-0}" != "1" ]]; then
return 0
fi
if declare -f _cs_source_func >/dev/null 2>&1; then
_cs_source_func "host/preflight.func"
elif declare -f _build_ui_source >/dev/null 2>&1; then
_build_ui_source "host/preflight.func"
else
# shellcheck disable=SC1090
source <(curl -fsSL "${_CS_CURL_RETRY[@]}" "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/host/preflight.func")
fi
if declare -f run_preflight_full >/dev/null 2>&1; then
run_preflight_full
return $?
fi
return 0
}
# ------------------------------------------------------------------------------
# maxkeys_check()
#
# - Checks kernel keyring limits before container creation
# - Warns when the user keyring pool for unprivileged containers is close to
# exhaustion and suggests higher sysctl values
# - Exits with dedicated error codes when limits cannot be read or are exceeded
# ------------------------------------------------------------------------------
maxkeys_check() {
local per_user_maxkeys per_user_maxbytes used_lxc_keys used_lxc_bytes
local threshold_keys threshold_bytes new_limit_keys new_limit_bytes
local failure=0
per_user_maxkeys=$(cat /proc/sys/kernel/keys/maxkeys 2>/dev/null || echo 0)
per_user_maxbytes=$(cat /proc/sys/kernel/keys/maxbytes 2>/dev/null || echo 0)
if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then
msg_error "Unable to read kernel key parameters. Ensure proper permissions."
exit 107
fi
used_lxc_keys=$(awk '/100000:/ {print $2}' /proc/key-users 2>/dev/null || echo 0)
used_lxc_bytes=$(awk '/100000:/ {split($5, a, "/"); print a[1]}' /proc/key-users 2>/dev/null || echo 0)
threshold_keys=$((per_user_maxkeys - 100))
threshold_bytes=$((per_user_maxbytes - 1000))
new_limit_keys=$((per_user_maxkeys * 2))
new_limit_bytes=$((per_user_maxbytes * 2))
if [[ "$used_lxc_keys" -gt "$threshold_keys" ]]; then
msg_warn "Key usage is near the limit (${used_lxc_keys}/${per_user_maxkeys})"
echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}."
failure=1
fi
if [[ "$used_lxc_bytes" -gt "$threshold_bytes" ]]; then
msg_warn "Key byte usage is near the limit (${used_lxc_bytes}/${per_user_maxbytes})"
echo -e "${INFO} Suggested action: Set ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}."
failure=1
fi
if [[ "$failure" -eq 1 ]]; then
msg_error "Kernel key limits exceeded - see suggestions above"
exit 108
fi
}
# ==============================================================================
# The rest of the build UI lives in ui/. Splitting it was a
# maintenance change only -- every function kept its name, body and behaviour.
#
# validate.func container id, hostname, network and IP range validators
# defaults.func storage selection, .vars files, app defaults
# advanced.func the advanced settings wizard
# menu.func settings and diagnostics menus, install_script, start
# ==============================================================================
# Platform-independent value checks; the VM paths load the same file.
_build_ui_source "host/validate.func"
_build_ui_source "ui/validate.func"
_build_ui_source "ui/defaults.func"
_build_ui_source "ui/advanced.func"
_build_ui_source "ui/menu.func"