Add build copy.func and update build.func

Added new 'build copy.func' script for LXC container build and configuration in Proxmox VE, including variable initialization, storage management, resource allocation, and advanced interactive configuration. Updated 'build.func' to support new features and improved logic for container setup, storage selection, and app-specific defaults management.
This commit is contained in:
CanbiZ 2025-11-24 09:34:35 +01:00
parent 6a2928ca47
commit f866c1cbef
2 changed files with 3918 additions and 133 deletions

3783
misc/build copy.func Normal file

File diff suppressed because it is too large Load Diff

View File

@ -542,29 +542,6 @@ base_settings() {
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
var_os="debian"
@ -1795,16 +1772,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
@ -2298,26 +2266,24 @@ 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}")
# Build FEATURES string with advanced settings
# Start with nesting (almost always enabled for Proxmox CTs)
FEATURES="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")
FEATURES="$FEATURES,keyctl=1"
fi
# mknod: allow device node creation (requires kernel 5.3+, experimental)
if [ "$ENABLE_MKNOD" == "1" ]; then
FEATURES_ARRAY+=("mknod=1")
FEATURES="$FEATURES,mknod=1"
fi
# FUSE: required for rclone, mergerfs, AppImage, etc.
if [ "$ENABLE_FUSE" == "1" ]; then
FEATURES_ARRAY+=("fuse=1")
if [ "$ENABLE_FUSE" == "yes" ]; then
FEATURES="$FEATURES,fuse=1"
fi
# mount: allow specific filesystems (e.g., nfs, ext4, etc.)
@ -2325,7 +2291,7 @@ build_container() {
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")
FEATURES="$FEATURES,mount=$ALLOW_MOUNT_FS_FORMATTED"
fi
TEMP_DIR=$(mktemp -d)
@ -2370,50 +2336,33 @@ build_container() {
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)
# Build protection flag if enabled
_PROT_FLAG=""
if [ "$PROTECT_CT" == "yes" ]; then
_PROT_FLAG="-protection 1"
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
# Build timezone flag if set
_TZ_FLAG=""
if [ -n "$CT_TIMEZONE" ]; then
PCT_OPTIONS+=("-timezone" "$CT_TIMEZONE")
_TZ_FLAG="-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
$_PROT_FLAG
$_TZ_FLAG
$PW
"
export TEMPLATE_STORAGE="${var_template_storage:-}"
export CONTAINER_STORAGE="${var_container_storage:-}"
create_lxc_container || exit $?
@ -2588,13 +2537,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 +2563,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 +2688,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,6 +2704,21 @@ 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
@ -2793,8 +2771,8 @@ EOF'
# 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}"
[[ $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}"
fi
# Dev mode: Keep container or open breakpoint shell
@ -2830,18 +2808,6 @@ EOF'
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
elif [[ "$response" =~ ^[Nn]$ ]]; then
echo -e "\n${TAB}${YW}Container ${CTID} kept for debugging${CL}"
# Dev mode: Setup MOTD/SSH for debugging access to broken container
# if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
# echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}"
# if pct exec "$CTID" -- bash -c "
# source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func)
# declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true
# " >/dev/null 2>&1; then
# local ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
# echo -e "${BFR}${CM}${GN}MOTD/SSH ready - SSH into container: ssh root@${ct_ip}${CL}"
# fi
# fi
fi
else
# Timeout - auto-remove
@ -2934,40 +2900,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})"
# Stoppe Container für Config-Update
pct stop "$CTID" >/dev/null 2>&1
# For privileged containers: also fix permissions inside container
# 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
@ -3133,7 +3138,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"
@ -3578,7 +3583,7 @@ 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"
@ -3635,7 +3640,7 @@ 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
@ -3667,7 +3672,7 @@ 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
@ -3691,9 +3696,6 @@ create_lxc_container() {
}
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
# Report container creation to API
post_to_api
}
# ==============================================================================