Update build.func
This commit is contained in:
parent
cb2c3fab96
commit
7455f8195c
499
misc/build.func
499
misc/build.func
@ -47,17 +47,7 @@ variables() {
|
||||
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.
|
||||
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
|
||||
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
|
||||
CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"}
|
||||
|
||||
# Get Proxmox VE version and kernel version
|
||||
if command -v pveversion >/dev/null 2>&1; then
|
||||
@ -535,35 +525,6 @@ base_settings() {
|
||||
TAGS="community-script,${var_tags:-}"
|
||||
ENABLE_FUSE=${var_fuse:-"${1:-no}"}
|
||||
ENABLE_TUN=${var_tun:-"${1:-no}"}
|
||||
ENABLE_NESTING=${var_nesting:-"${1:-1}"}
|
||||
ENABLE_KEYCTL=${var_keyctl:-"${1:-0}"}
|
||||
ALLOW_MOUNT_FS=${var_mount_fs:-""}
|
||||
ENABLE_MKNOD=${var_mknod:-"${1:-0}"}
|
||||
PROTECT_CT=${var_protection:-"${1:-no}"}
|
||||
CT_TIMEZONE=${var_timezone:-""}
|
||||
|
||||
# Normalize feature flags to 0/1 immediately (pct requires numeric values, not yes/no)
|
||||
# This must happen here before any usage of these variables
|
||||
case "${ENABLE_NESTING,,}" in
|
||||
yes | true) ENABLE_NESTING="1" ;;
|
||||
no | false) ENABLE_NESTING="0" ;;
|
||||
esac
|
||||
case "${ENABLE_KEYCTL,,}" in
|
||||
yes | true) ENABLE_KEYCTL="1" ;;
|
||||
no | false) ENABLE_KEYCTL="0" ;;
|
||||
esac
|
||||
case "${ENABLE_MKNOD,,}" in
|
||||
yes | true) ENABLE_MKNOD="1" ;;
|
||||
no | false) ENABLE_MKNOD="0" ;;
|
||||
esac
|
||||
case "${ENABLE_FUSE,,}" in
|
||||
yes | true) ENABLE_FUSE="1" ;;
|
||||
no | false) ENABLE_FUSE="0" ;;
|
||||
esac
|
||||
case "${PROTECT_CT,,}" in
|
||||
yes | true) PROTECT_CT="1" ;;
|
||||
no | false) PROTECT_CT="0" ;;
|
||||
esac
|
||||
|
||||
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
|
||||
if [ -z "$var_os" ]; then
|
||||
@ -587,9 +548,9 @@ default_var_settings() {
|
||||
# Allowed var_* keys (alphabetically sorted)
|
||||
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
|
||||
local VAR_WHITELIST=(
|
||||
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_keyctl
|
||||
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
|
||||
var_net var_nesting var_ns var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
|
||||
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse
|
||||
var_gateway var_hostname var_ipv6_method var_mac var_mtu
|
||||
var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged
|
||||
var_verbose var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
|
||||
)
|
||||
|
||||
@ -667,14 +628,6 @@ var_ssh=no
|
||||
# Features/Tags/verbosity
|
||||
var_fuse=no
|
||||
var_tun=no
|
||||
|
||||
# Advanced Settings (Proxmox-official features)
|
||||
var_nesting=1 # Allow nesting (required for Docker/LXC in CT)
|
||||
var_keyctl=0 # Allow keyctl() - needed for Docker (systemd-networkd workaround)
|
||||
var_mknod=0 # Allow device node creation (requires kernel 5.3+, experimental)
|
||||
var_mount_fs= # Allow specific filesystems: nfs,fuse,ext4,etc (leave empty for defaults)
|
||||
var_protection=no # Prevent accidental deletion of container
|
||||
var_timezone= # Container timezone (e.g. Europe/Berlin, leave empty for host timezone)
|
||||
var_tags=community-script
|
||||
var_verbose=no
|
||||
|
||||
@ -941,12 +894,6 @@ _build_current_app_vars_tmp() {
|
||||
_apt_cacher_ip="${APT_CACHER_IP:-}"
|
||||
_fuse="${ENABLE_FUSE:-no}"
|
||||
_tun="${ENABLE_TUN:-no}"
|
||||
_nesting="${ENABLE_NESTING:-1}"
|
||||
_keyctl="${ENABLE_KEYCTL:-0}"
|
||||
_mknod="${ENABLE_MKNOD:-0}"
|
||||
_mount_fs="${ALLOW_MOUNT_FS:-}"
|
||||
_protect="${PROTECT_CT:-no}"
|
||||
_timezone="${CT_TIMEZONE:-}"
|
||||
_tags="${TAGS:-}"
|
||||
_verbose="${VERBOSE:-no}"
|
||||
|
||||
@ -990,12 +937,6 @@ _build_current_app_vars_tmp() {
|
||||
|
||||
[ -n "$_fuse" ] && echo "var_fuse=$(_sanitize_value "$_fuse")"
|
||||
[ -n "$_tun" ] && echo "var_tun=$(_sanitize_value "$_tun")"
|
||||
[ -n "$_nesting" ] && echo "var_nesting=$(_sanitize_value "$_nesting")"
|
||||
[ -n "$_keyctl" ] && echo "var_keyctl=$(_sanitize_value "$_keyctl")"
|
||||
[ -n "$_mknod" ] && echo "var_mknod=$(_sanitize_value "$_mknod")"
|
||||
[ -n "$_mount_fs" ] && echo "var_mount_fs=$(_sanitize_value "$_mount_fs")"
|
||||
[ -n "$_protect" ] && echo "var_protection=$(_sanitize_value "$_protect")"
|
||||
[ -n "$_timezone" ] && echo "var_timezone=$(_sanitize_value "$_timezone")"
|
||||
[ -n "$_tags" ] && echo "var_tags=$(_sanitize_value "$_tags")"
|
||||
[ -n "$_verbose" ] && echo "var_verbose=$(_sanitize_value "$_verbose")"
|
||||
|
||||
@ -1578,51 +1519,6 @@ advanced_settings() {
|
||||
configure_ssh_settings
|
||||
export SSH_KEYS_FILE
|
||||
echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
|
||||
|
||||
# Advanced Settings - Proxmox Features
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS" --yesno "Configure Advanced Proxmox Features?" 10 58); then
|
||||
# keyctl: for Docker support
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "Enable keyctl()" --yesno "Allow keyctl() system calls?\n\nNeeded for: Docker inside container, systemd-networkd\nDefault: No (not needed for most applications)" 10 58); then
|
||||
ENABLE_KEYCTL="1"
|
||||
else
|
||||
ENABLE_KEYCTL="0"
|
||||
fi
|
||||
echo -e "${SEARCH}${BOLD}${DGN}Allow keyctl(): ${BGN}$ENABLE_KEYCTL${CL}"
|
||||
|
||||
# mknod: device node creation
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "Enable mknod()" --yesno "Allow device node creation?\n\nNeeded for: Complex device management (experimental, kernel 5.3+)\nDefault: No (rarely needed)" 10 58); then
|
||||
ENABLE_MKNOD="1"
|
||||
else
|
||||
ENABLE_MKNOD="0"
|
||||
fi
|
||||
echo -e "${SEARCH}${BOLD}${DGN}Allow mknod(): ${BGN}$ENABLE_MKNOD${CL}"
|
||||
|
||||
# mount: specific filesystems
|
||||
if MOUNT_FS=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allow specific filesystems (e.g., nfs,fuse,ext4)\nLeave blank for defaults" 8 58 "$ALLOW_MOUNT_FS" --title "Mount Filesystems" 3>&1 1>&2 2>&3); then
|
||||
ALLOW_MOUNT_FS="$MOUNT_FS"
|
||||
[ -z "$ALLOW_MOUNT_FS" ] && ALLOW_MOUNT_FS="(defaults)"
|
||||
else
|
||||
exit_script
|
||||
fi
|
||||
echo -e "${SEARCH}${BOLD}${DGN}Mount Filesystems: ${BGN}$ALLOW_MOUNT_FS${CL}"
|
||||
|
||||
# Container protection
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "Protection Flag" --yesno "Prevent accidental deletion?\n\nIf enabled, container cannot be deleted or its disk modified\nDefault: No" 10 58); then
|
||||
PROTECT_CT="yes"
|
||||
else
|
||||
PROTECT_CT="no"
|
||||
fi
|
||||
echo -e "${SEARCH}${BOLD}${DGN}Container Protection: ${BGN}$PROTECT_CT${CL}"
|
||||
|
||||
# Container timezone
|
||||
if CT_TIMEZONE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set container timezone (e.g., Europe/Berlin)\nLeave blank to use host timezone" 8 58 "$CT_TIMEZONE" --title "Container Timezone" 3>&1 1>&2 2>&3); then
|
||||
[ -z "$CT_TIMEZONE" ] && CT_TIMEZONE="(host)"
|
||||
else
|
||||
exit_script
|
||||
fi
|
||||
echo -e "${SEARCH}${BOLD}${DGN}Container Timezone: ${BGN}$CT_TIMEZONE${CL}"
|
||||
fi
|
||||
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then
|
||||
ENABLE_FUSE="yes"
|
||||
else
|
||||
@ -1795,16 +1691,7 @@ install_script() {
|
||||
fi
|
||||
|
||||
NEXTID=$(pvesh get /cluster/nextid)
|
||||
|
||||
# Get timezone using timedatectl (Debian 13+ compatible)
|
||||
# Fallback to /etc/timezone for older systems
|
||||
if command -v timedatectl >/dev/null 2>&1; then
|
||||
timezone=$(timedatectl show --value --property=Timezone 2>/dev/null || echo "UTC")
|
||||
elif [ -f /etc/timezone ]; then
|
||||
timezone=$(cat /etc/timezone)
|
||||
else
|
||||
timezone="UTC"
|
||||
fi
|
||||
timezone=$(cat /etc/timezone)
|
||||
|
||||
# Show APP Header
|
||||
header_info
|
||||
@ -1932,12 +1819,13 @@ settings_menu() {
|
||||
local settings_items=(
|
||||
"1" "Manage API-Diagnostic Setting"
|
||||
"2" "Edit Default.vars"
|
||||
"3" "Edit Default Storage"
|
||||
)
|
||||
if [ -f "$(get_app_defaults_path)" ]; then
|
||||
settings_items+=("3" "Edit App.vars for ${APP}")
|
||||
settings_items+=("4" "Exit")
|
||||
settings_items+=("4" "Edit App.vars for ${APP}")
|
||||
settings_items+=("5" "Exit")
|
||||
else
|
||||
settings_items+=("3" "Exit")
|
||||
settings_items+=("4" "Exit")
|
||||
fi
|
||||
|
||||
local choice
|
||||
@ -2298,34 +2186,14 @@ build_container() {
|
||||
none) ;;
|
||||
esac
|
||||
|
||||
# Build FEATURES array with advanced settings
|
||||
# Note: All feature flags are already normalized to 0/1 in default_settings()
|
||||
# Proxmox requires each feature as a separate parameter, not comma-separated string
|
||||
FEATURES_ARRAY=()
|
||||
FEATURES_ARRAY+=("nesting=${ENABLE_NESTING}")
|
||||
|
||||
# keyctl: needed for Docker inside containers (systemd-networkd workaround)
|
||||
# Typically needed for unprivileged containers with Docker
|
||||
if [ "$CT_TYPE" == "1" ] || [ "$ENABLE_KEYCTL" == "1" ]; then
|
||||
FEATURES_ARRAY+=("keyctl=1")
|
||||
if [ "$CT_TYPE" == "1" ]; then
|
||||
FEATURES="keyctl=1,nesting=1"
|
||||
else
|
||||
FEATURES="nesting=1"
|
||||
fi
|
||||
|
||||
# mknod: allow device node creation (requires kernel 5.3+, experimental)
|
||||
if [ "$ENABLE_MKNOD" == "1" ]; then
|
||||
FEATURES_ARRAY+=("mknod=1")
|
||||
fi
|
||||
|
||||
# FUSE: required for rclone, mergerfs, AppImage, etc.
|
||||
if [ "$ENABLE_FUSE" == "1" ]; then
|
||||
FEATURES_ARRAY+=("fuse=1")
|
||||
fi
|
||||
|
||||
# mount: allow specific filesystems (e.g., nfs, ext4, etc.)
|
||||
# Format: mount=fstype1;fstype2;fstype3 (semicolon-separated, not comma!)
|
||||
if [ -n "$ALLOW_MOUNT_FS" ]; then
|
||||
# Replace commas with semicolons for proper pct syntax
|
||||
ALLOW_MOUNT_FS_FORMATTED="${ALLOW_MOUNT_FS//,/;}"
|
||||
FEATURES_ARRAY+=("mount=$ALLOW_MOUNT_FS_FORMATTED")
|
||||
if [ "$ENABLE_FUSE" == "yes" ]; then
|
||||
FEATURES="$FEATURES,fuse=1"
|
||||
fi
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
@ -2338,16 +2206,6 @@ build_container() {
|
||||
export DIAGNOSTICS="$DIAGNOSTICS"
|
||||
export RANDOM_UUID="$RANDOM_UUID"
|
||||
export SESSION_ID="$SESSION_ID"
|
||||
export BUILD_LOG="$BUILD_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_IP="$APT_CACHER_IP"
|
||||
export tz="$timezone"
|
||||
@ -2361,59 +2219,22 @@ build_container() {
|
||||
export CTTYPE="$CT_TYPE"
|
||||
export ENABLE_FUSE="$ENABLE_FUSE"
|
||||
export ENABLE_TUN="$ENABLE_TUN"
|
||||
export ENABLE_NESTING="$ENABLE_NESTING"
|
||||
export ENABLE_KEYCTL="$ENABLE_KEYCTL"
|
||||
export ENABLE_MKNOD="$ENABLE_MKNOD"
|
||||
export ALLOW_MOUNT_FS="$ALLOW_MOUNT_FS"
|
||||
export PROTECT_CT="$PROTECT_CT"
|
||||
export CT_TIMEZONE="$CT_TIMEZONE"
|
||||
export PCT_OSTYPE="$var_os"
|
||||
export PCT_OSVERSION="$var_version"
|
||||
export PCT_DISK_SIZE="$DISK_SIZE"
|
||||
|
||||
# Build PCT_OPTIONS array (not string) for proper parameter handling
|
||||
PCT_OPTIONS=()
|
||||
|
||||
# Add features - each as separate -features parameter
|
||||
for feature in "${FEATURES_ARRAY[@]}"; do
|
||||
PCT_OPTIONS+=("-features" "$feature")
|
||||
done
|
||||
|
||||
PCT_OPTIONS+=("-hostname" "$HN")
|
||||
PCT_OPTIONS+=("-tags" "$TAGS")
|
||||
|
||||
if [ -n "$SD" ]; then
|
||||
PCT_OPTIONS+=($SD) # Storage device flags (already formatted)
|
||||
fi
|
||||
|
||||
if [ -n "$NS" ]; then
|
||||
PCT_OPTIONS+=($NS) # Nameserver flags (already formatted)
|
||||
fi
|
||||
|
||||
# Network configuration (single string with all network parameters)
|
||||
PCT_OPTIONS+=($NET_STRING)
|
||||
|
||||
PCT_OPTIONS+=("-onboot" "1")
|
||||
PCT_OPTIONS+=("-cores" "$CORE_COUNT")
|
||||
PCT_OPTIONS+=("-memory" "$RAM_SIZE")
|
||||
PCT_OPTIONS+=("-unprivileged" "$CT_TYPE")
|
||||
|
||||
# Protection flag
|
||||
if [ "$PROTECT_CT" == "1" ]; then
|
||||
PCT_OPTIONS+=("-protection" "1")
|
||||
fi
|
||||
|
||||
# Timezone flag
|
||||
if [ -n "$CT_TIMEZONE" ]; then
|
||||
PCT_OPTIONS+=("-timezone" "$CT_TIMEZONE")
|
||||
fi
|
||||
|
||||
# Password flag (already formatted as "-password xxx")
|
||||
if [ -n "$PW" ]; then
|
||||
PCT_OPTIONS+=($PW)
|
||||
fi
|
||||
|
||||
export PCT_OPTIONS
|
||||
export PCT_OPTIONS="
|
||||
-features $FEATURES
|
||||
-hostname $HN
|
||||
-tags $TAGS
|
||||
$SD
|
||||
$NS
|
||||
$NET_STRING
|
||||
-onboot 1
|
||||
-cores $CORE_COUNT
|
||||
-memory $RAM_SIZE
|
||||
-unprivileged $CT_TYPE
|
||||
$PW
|
||||
"
|
||||
export TEMPLATE_STORAGE="${var_template_storage:-}"
|
||||
export CONTAINER_STORAGE="${var_container_storage:-}"
|
||||
create_lxc_container || exit $?
|
||||
@ -2588,13 +2409,20 @@ EOF
|
||||
[[ "$selected_gpu" == "INTEL" ]] && devices=("${INTEL_DEVICES[@]}")
|
||||
[[ "$selected_gpu" == "AMD" ]] && devices=("${AMD_DEVICES[@]}")
|
||||
|
||||
# Use pct set to add devices with proper dev0/dev1 format
|
||||
# GIDs will be detected and set after container starts
|
||||
local dev_index=0
|
||||
# Add lxc.mount.entry for each device
|
||||
for dev in "${devices[@]}"; do
|
||||
# Add to config using pct set (will be visible in GUI)
|
||||
echo "dev${dev_index}: ${dev},gid=44" >>"$LXC_CONFIG"
|
||||
dev_index=$((dev_index + 1))
|
||||
echo "lxc.mount.entry: $dev $dev none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
# Privileged container - also add cgroup allows
|
||||
local major minor
|
||||
major=$(stat -c '%t' "$dev" 2>/dev/null || echo "0")
|
||||
minor=$(stat -c '%T' "$dev" 2>/dev/null || echo "0")
|
||||
|
||||
if [[ "$major" != "0" && "$minor" != "0" ]]; then
|
||||
echo "lxc.cgroup2.devices.allow: c $((0x$major)):$((0x$minor)) rwm" >>"$LXC_CONFIG"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
export GPU_TYPE="$selected_gpu"
|
||||
@ -2607,11 +2435,20 @@ EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Use pct set for NVIDIA devices
|
||||
local dev_index=0
|
||||
# Add lxc.mount.entry for each NVIDIA device
|
||||
for dev in "${NVIDIA_DEVICES[@]}"; do
|
||||
echo "dev${dev_index}: ${dev},gid=44" >>"$LXC_CONFIG"
|
||||
dev_index=$((dev_index + 1))
|
||||
echo "lxc.mount.entry: $dev $dev none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
# Privileged container - also add cgroup allows
|
||||
local major minor
|
||||
major=$(stat -c '%t' "$dev" 2>/dev/null || echo "0")
|
||||
minor=$(stat -c '%T' "$dev" 2>/dev/null || echo "0")
|
||||
|
||||
if [[ "$major" != "0" && "$minor" != "0" ]]; then
|
||||
echo "lxc.cgroup2.devices.allow: c $((0x$major)):$((0x$minor)) rwm" >>"$LXC_CONFIG"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
export GPU_TYPE="NVIDIA"
|
||||
@ -2723,9 +2560,7 @@ EOF'
|
||||
fi
|
||||
|
||||
if pct exec "$CTID" -- test -e "/usr/share/zoneinfo/$tz"; then
|
||||
# Set timezone using symlink (Debian 13+ compatible)
|
||||
# Create /etc/timezone for backwards compatibility with older scripts
|
||||
pct exec "$CTID" -- bash -c "tz='$tz'; ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime && echo \"\$tz\" >/etc/timezone || true"
|
||||
pct exec "$CTID" -- bash -c "tz='$tz'; echo \"\$tz\" >/etc/timezone && ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime"
|
||||
else
|
||||
msg_warn "Skipping timezone setup – zone '$tz' not found in container"
|
||||
fi
|
||||
@ -2741,121 +2576,14 @@ EOF'
|
||||
# Install SSH keys
|
||||
install_ssh_keys_into_ct
|
||||
|
||||
# Dev mode: Setup MOTD/SSH AFTER network is ready and before installation
|
||||
# This ensures the container is fully booted and accessible via SSH
|
||||
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
|
||||
msg_dev "Setting up MOTD and SSH for debugging access"
|
||||
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_dev "MOTD/SSH ready - container accessible via SSH (IP: $ip_in_lxc)"
|
||||
fi
|
||||
|
||||
# Run application installer
|
||||
# NOTE: We disable error handling here because:
|
||||
# 1. Container errors are caught by error_handler INSIDE container
|
||||
# 2. Container creates flag file with exit code
|
||||
# 3. We read flag file and handle cleanup manually below
|
||||
# 4. We DON'T want host error_handler to fire for lxc-attach command itself
|
||||
|
||||
set +Eeuo pipefail # Disable ALL error handling temporarily
|
||||
trap - ERR # Remove ERR trap completely
|
||||
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
|
||||
local lxc_exit=$?
|
||||
|
||||
set -Eeuo pipefail # Re-enable error handling
|
||||
trap 'error_handler' ERR # Restore ERR trap
|
||||
|
||||
# Check for error flag file in container (more reliable than lxc-attach exit code)
|
||||
local install_exit_code=0
|
||||
if [[ -n "${SESSION_ID:-}" ]]; then
|
||||
local error_flag="/root/.install-${SESSION_ID}.failed"
|
||||
if pct exec "$CTID" -- test -f "$error_flag" 2>/dev/null; then
|
||||
install_exit_code=$(pct exec "$CTID" -- cat "$error_flag" 2>/dev/null || echo "1")
|
||||
pct exec "$CTID" -- rm -f "$error_flag" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fallback to lxc-attach exit code if no flag file
|
||||
if [[ $install_exit_code -eq 0 && $lxc_exit -ne 0 ]]; then
|
||||
install_exit_code=$lxc_exit
|
||||
fi
|
||||
|
||||
# Installation failed?
|
||||
if [[ $install_exit_code -ne 0 ]]; then
|
||||
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
|
||||
|
||||
# Copy both logs from container before potential deletion
|
||||
local build_log_copied=false
|
||||
local install_log_copied=false
|
||||
|
||||
if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"; then
|
||||
local exit_code=$?
|
||||
# Try to copy installation log from container before exiting
|
||||
if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then
|
||||
# Copy BUILD_LOG (creation log) if it exists
|
||||
if [[ -f "${BUILD_LOG}" ]]; then
|
||||
cp "${BUILD_LOG}" "/tmp/create-lxc-${CTID}-${SESSION_ID}.log" 2>/dev/null && build_log_copied=true
|
||||
fi
|
||||
|
||||
# Copy INSTALL_LOG from container
|
||||
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "/tmp/install-lxc-${CTID}-${SESSION_ID}.log" 2>/dev/null; then
|
||||
install_log_copied=true
|
||||
fi
|
||||
|
||||
# Show available logs
|
||||
echo ""
|
||||
[[ $build_log_copied == true ]] && echo -e "${GN}✔${CL} Container creation log: ${BL}/tmp/create-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}"
|
||||
pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "/tmp/install-${SESSION_ID}.log" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Dev mode: Keep container or open breakpoint shell
|
||||
if [[ "${DEV_MODE_KEEP:-false}" == "true" ]]; then
|
||||
msg_dev "Keep mode active - container ${CTID} preserved"
|
||||
return 0
|
||||
elif [[ "${DEV_MODE_BREAKPOINT:-false}" == "true" ]]; then
|
||||
msg_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_dev "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)
|
||||
echo ""
|
||||
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||
|
||||
if read -t 60 -r response; then
|
||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||
# Remove container
|
||||
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID}${CL}"
|
||||
pct stop "$CTID" &>/dev/null || true
|
||||
pct destroy "$CTID" &>/dev/null || true
|
||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
||||
elif [[ "$response" =~ ^[Nn]$ ]]; then
|
||||
echo -e "\n${TAB}${YW}Container ${CTID} kept for debugging${CL}"
|
||||
fi
|
||||
else
|
||||
# Timeout - auto-remove
|
||||
echo -e "\n${YW}No response - auto-removing container${CL}"
|
||||
echo -e "${TAB}${HOLD}${YW}Removing container ${CTID}${CL}"
|
||||
pct stop "$CTID" &>/dev/null || true
|
||||
pct destroy "$CTID" &>/dev/null || true
|
||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
||||
fi
|
||||
|
||||
exit $install_exit_code
|
||||
exit $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
@ -2937,40 +2665,79 @@ fix_gpu_gids() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Silent operation to avoid spinner conflicts
|
||||
msg_custom "🔧" "${BL}" "Detecting and setting correct GPU group IDs"
|
||||
|
||||
# Get actual GIDs from container
|
||||
# Ermittle die tatsächlichen GIDs aus dem Container
|
||||
local video_gid=$(pct exec "$CTID" -- sh -c "getent group video 2>/dev/null | cut -d: -f3")
|
||||
local render_gid=$(pct exec "$CTID" -- sh -c "getent group render 2>/dev/null | cut -d: -f3")
|
||||
|
||||
# Create groups if they don't exist
|
||||
# Fallbacks wenn Gruppen nicht existieren
|
||||
if [[ -z "$video_gid" ]]; then
|
||||
pct exec "$CTID" -- sh -c "groupadd -r video 2>/dev/null || true" >/dev/null 2>&1
|
||||
# Versuche die video Gruppe zu erstellen
|
||||
pct exec "$CTID" -- sh -c "groupadd -r video 2>/dev/null || true"
|
||||
video_gid=$(pct exec "$CTID" -- sh -c "getent group video 2>/dev/null | cut -d: -f3")
|
||||
[[ -z "$video_gid" ]] && video_gid="44"
|
||||
[[ -z "$video_gid" ]] && video_gid="44" # Ultimate fallback
|
||||
fi
|
||||
|
||||
if [[ -z "$render_gid" ]]; then
|
||||
pct exec "$CTID" -- sh -c "groupadd -r render 2>/dev/null || true" >/dev/null 2>&1
|
||||
# Versuche die render Gruppe zu erstellen
|
||||
pct exec "$CTID" -- sh -c "groupadd -r render 2>/dev/null || true"
|
||||
render_gid=$(pct exec "$CTID" -- sh -c "getent group render 2>/dev/null | cut -d: -f3")
|
||||
[[ -z "$render_gid" ]] && render_gid="104"
|
||||
[[ -z "$render_gid" ]] && render_gid="104" # Ultimate fallback
|
||||
fi
|
||||
|
||||
# Stop container to update config
|
||||
pct stop "$CTID" >/dev/null 2>&1
|
||||
sleep 1
|
||||
msg_custom "ℹ️" "${DGN}" "Container GIDs detected - video:${video_gid}, render:${render_gid}"
|
||||
|
||||
# Update dev entries with correct GIDs
|
||||
sed -i.bak -E "s|(dev[0-9]+: /dev/dri/renderD[0-9]+),gid=[0-9]+|\1,gid=${render_gid}|g" "$LXC_CONFIG"
|
||||
sed -i -E "s|(dev[0-9]+: /dev/dri/card[0-9]+),gid=[0-9]+|\1,gid=${video_gid}|g" "$LXC_CONFIG"
|
||||
# Prüfe ob die GIDs von den Defaults abweichen
|
||||
local need_update=0
|
||||
if [[ "$video_gid" != "44" ]] || [[ "$render_gid" != "104" ]]; then
|
||||
need_update=1
|
||||
fi
|
||||
|
||||
# Restart container
|
||||
pct start "$CTID" >/dev/null 2>&1
|
||||
sleep 2
|
||||
if [[ $need_update -eq 1 ]]; then
|
||||
msg_custom "🔄" "${YW}" "Updating device GIDs in container config"
|
||||
|
||||
msg_ok "GPU passthrough configured (video:${video_gid}, render:${render_gid})"
|
||||
|
||||
# For privileged containers: also fix permissions inside container
|
||||
# Stoppe Container für Config-Update
|
||||
pct stop "$CTID" >/dev/null 2>&1
|
||||
|
||||
# Update die dev Einträge mit korrekten GIDs
|
||||
# Backup der Config
|
||||
cp "$LXC_CONFIG" "${LXC_CONFIG}.bak"
|
||||
|
||||
# Parse und update jeden dev Eintrag
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" =~ ^dev[0-9]+: ]]; then
|
||||
# Extract device path
|
||||
local device_path=$(echo "$line" | sed -E 's/^dev[0-9]+: ([^,]+).*/\1/')
|
||||
local dev_num=$(echo "$line" | sed -E 's/^(dev[0-9]+):.*/\1/')
|
||||
|
||||
if [[ "$device_path" =~ renderD ]]; then
|
||||
# RenderD device - use render GID
|
||||
echo "${dev_num}: ${device_path},gid=${render_gid}"
|
||||
elif [[ "$device_path" =~ card ]]; then
|
||||
# Card device - use video GID
|
||||
echo "${dev_num}: ${device_path},gid=${video_gid}"
|
||||
else
|
||||
# Keep original line
|
||||
echo "$line"
|
||||
fi
|
||||
else
|
||||
# Keep non-dev lines
|
||||
echo "$line"
|
||||
fi
|
||||
done <"$LXC_CONFIG" >"${LXC_CONFIG}.new"
|
||||
|
||||
mv "${LXC_CONFIG}.new" "$LXC_CONFIG"
|
||||
|
||||
# Starte Container wieder
|
||||
pct start "$CTID" >/dev/null 2>&1
|
||||
sleep 3
|
||||
|
||||
msg_ok "Device GIDs updated successfully"
|
||||
else
|
||||
msg_ok "Device GIDs are already correct"
|
||||
fi
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
pct exec "$CTID" -- bash -c "
|
||||
if [ -d /dev/dri ]; then
|
||||
@ -3136,7 +2903,7 @@ create_lxc_container() {
|
||||
case "${_ans,,}" in
|
||||
y | yes)
|
||||
msg_info "Upgrading Proxmox LXC stack (pve-container, lxc-pve)"
|
||||
if $STD apt-get update && $STD apt-get install -y --only-upgrade pve-container lxc-pve; then
|
||||
if apt-get update -qq >/dev/null && apt-get install -y --only-upgrade pve-container lxc-pve >/dev/null; then
|
||||
msg_ok "LXC stack upgraded."
|
||||
if [[ "$do_retry" == "yes" ]]; then
|
||||
msg_info "Retrying container creation after upgrade"
|
||||
@ -3581,13 +3348,13 @@ create_lxc_container() {
|
||||
exit 211
|
||||
}
|
||||
|
||||
LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log"
|
||||
LOGFILE="/tmp/pct_create_${CTID}.log"
|
||||
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
|
||||
msg_debug "Logfile: $LOGFILE"
|
||||
|
||||
# First attempt
|
||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >"$LOGFILE" 2>&1; then
|
||||
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Validating template..."
|
||||
msg_error "Container creation failed on ${TEMPLATE_STORAGE}. Checking template..."
|
||||
|
||||
# Validate template file
|
||||
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
|
||||
@ -3606,16 +3373,18 @@ create_lxc_container() {
|
||||
|
||||
# Retry after repair
|
||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
|
||||
# Fallback to local storage if not already on local
|
||||
# Fallback to local storage
|
||||
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
|
||||
msg_info "Retrying container creation with fallback to local storage..."
|
||||
msg_warn "Retrying container creation with fallback to local storage..."
|
||||
LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
|
||||
if [[ ! -f "$LOCAL_TEMPLATE_PATH" ]]; then
|
||||
msg_info "Downloading template to local..."
|
||||
pveam download local "$TEMPLATE" >/dev/null 2>&1
|
||||
fi
|
||||
if ! pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
|
||||
# Local fallback also failed - check for LXC stack version issue
|
||||
if pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
|
||||
msg_ok "Container successfully created using local fallback."
|
||||
else
|
||||
# --- Dynamic stack upgrade + auto-retry on the well-known error pattern ---
|
||||
if grep -qiE 'unsupported .* version' "$LOGFILE"; then
|
||||
echo
|
||||
echo "pct reported 'unsupported ... version' – your LXC stack might be too old for this template."
|
||||
@ -3635,19 +3404,18 @@ create_lxc_container() {
|
||||
;;
|
||||
esac
|
||||
else
|
||||
msg_error "Container creation failed. See $LOGFILE"
|
||||
msg_error "Container creation failed even with local fallback. See $LOGFILE"
|
||||
if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
|
||||
set -x
|
||||
pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" 2>&1 | tee -a "$LOGFILE"
|
||||
bash -x -c "pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}" 2>&1 | tee -a "$LOGFILE"
|
||||
set +x
|
||||
fi
|
||||
exit 209
|
||||
fi
|
||||
else
|
||||
msg_ok "Container successfully created using local fallback."
|
||||
fi
|
||||
else
|
||||
# Already on local storage and still failed - check LXC stack version
|
||||
msg_error "Container creation failed on local storage. See $LOGFILE"
|
||||
# --- Dynamic stack upgrade + auto-retry on the well-known error pattern ---
|
||||
if grep -qiE 'unsupported .* version' "$LOGFILE"; then
|
||||
echo
|
||||
echo "pct reported 'unsupported ... version' – your LXC stack might be too old for this template."
|
||||
@ -3670,14 +3438,12 @@ create_lxc_container() {
|
||||
msg_error "Container creation failed. See $LOGFILE"
|
||||
if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
|
||||
set -x
|
||||
pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" 2>&1 | tee -a "$LOGFILE"
|
||||
bash -x -c "pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}" 2>&1 | tee -a "$LOGFILE"
|
||||
set +x
|
||||
fi
|
||||
exit 209
|
||||
fi
|
||||
fi
|
||||
else
|
||||
msg_ok "Container successfully created after template repair."
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -3694,9 +3460,6 @@ create_lxc_container() {
|
||||
}
|
||||
|
||||
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
|
||||
|
||||
# Report container creation to API
|
||||
post_to_api
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user