fix: Multi-distro LXC container fixes for autologin and package installation

- Rocky/AlmaLinux 10 (EL10): Version detection for DNF 5 with correct packages (langpacks-en instead of glibc-langpack-en), makecache refresh, fallback to minimal install
- openSUSE: Install ncurses-utils and terminfo-base, set TERM in /etc/profile.d and /etc/environment to fix 'unknown terminal type'
- Gentoo: Fixed template pattern to use underscore (-openrc_) instead of dash, special version handling
- openEuler: Set privileged container (var_unprivileged=0) to workaround PVE setup hook limitation
- Devuan: Enhanced sysvinit autologin with multiple inittab patterns, fallback console entry, telinit reload
- CentOS/all: Updated URLs from raw.githubusercontent.com to git.community-scripts.org
- General: Better error handling and removed duplicate code blocks
This commit is contained in:
MickLesk 2026-01-12 21:34:58 +01:00
parent 021a4c612a
commit b8afdab106
3 changed files with 3406 additions and 3307 deletions

View File

@ -5,6 +5,11 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://www.openeuler.org/ # Source: https://www.openeuler.org/
# NOTE: openEuler requires privileged container due to PVE limitation
# PVE's post_create_hook expects /etc/redhat-release which openEuler doesn't have
# This causes "unable to create CT - error in setup task PVE::LXC::Setup::post_create_hook"
# Setting var_unprivileged=0 creates privileged container which bypasses this check
APP="openEuler" APP="openEuler"
var_tags="${var_tags:-os}" var_tags="${var_tags:-os}"
var_cpu="${var_cpu:-1}" var_cpu="${var_cpu:-1}"
@ -12,7 +17,7 @@ var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}" var_disk="${var_disk:-4}"
var_os="${var_os:-openeuler}" var_os="${var_os:-openeuler}"
var_version="${var_version:-25.03}" var_version="${var_version:-25.03}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-0}"
header_info "$APP" header_info "$APP"
variables variables

View File

@ -3275,11 +3275,41 @@ EOF'
fedora | rockylinux | almalinux | centos) fedora | rockylinux | almalinux | centos)
# RHEL-based: Fedora, Rocky, AlmaLinux, CentOS # RHEL-based: Fedora, Rocky, AlmaLinux, CentOS
# Install base packages including glibc-langpack for locale support # Detect OS major version for EL10+ compatibility (DNF 5, different packages)
pct exec "$CTID" -- bash -c "dnf install -y curl sudo mc jq procps-ng glibc-langpack-en >/dev/null 2>&1 || yum install -y curl sudo mc jq procps-ng >/dev/null 2>&1" || { local rhel_version
rhel_version=$(pct exec "$CTID" -- bash -c "grep -oP '(?<=VERSION_ID=\")[0-9]+' /etc/os-release 2>/dev/null || echo 9")
# First run makecache to ensure repos are ready (critical for fresh templates)
msg_info "Initializing package manager (this may take a moment)..."
if ! pct exec "$CTID" -- bash -c "dnf makecache --refresh 2>&1 || yum makecache 2>&1" >/dev/null 2>&1; then
msg_warn "Package cache update had issues, continuing anyway..."
fi
# Build package list - EL10+ may not have glibc-langpack-en in same form
local rhel_packages="curl sudo mc jq procps-ng ncurses"
if [[ "$rhel_version" -lt 10 ]]; then
rhel_packages="$rhel_packages glibc-langpack-en"
else
# EL10 uses glibc-all-langpacks or langpacks-en
rhel_packages="$rhel_packages langpacks-en glibc-all-langpacks"
fi
# Install base packages with better error handling
local install_log="/tmp/dnf_install_${CTID}.log"
if ! pct exec "$CTID" -- bash -c "dnf install -y $rhel_packages 2>&1 | tee $install_log; exit \${PIPESTATUS[0]}" >/dev/null 2>&1; then
# Check if it's just missing optional packages
if pct exec "$CTID" -- bash -c "rpm -q curl sudo mc jq procps-ng" >/dev/null 2>&1; then
msg_warn "Some optional packages may have failed, but core packages installed"
else
# Real failure - try minimal install
msg_warn "Full package install failed, trying minimal set..."
if ! pct exec "$CTID" -- bash -c "dnf install -y curl sudo jq 2>&1" >/dev/null 2>&1; then
msg_error "dnf/yum base packages installation failed" msg_error "dnf/yum base packages installation failed"
pct exec "$CTID" -- bash -c "cat $install_log 2>/dev/null" || true
exit 1 exit 1
} fi
fi
fi
# Set locale for RHEL-based systems # Set locale for RHEL-based systems
pct exec "$CTID" -- bash -c "localectl set-locale LANG=en_US.UTF-8 2>/dev/null || echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true pct exec "$CTID" -- bash -c "localectl set-locale LANG=en_US.UTF-8 2>/dev/null || echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true
@ -3295,43 +3325,71 @@ EOF'
;; ;;
opensuse) opensuse)
# openSUSE - add locale package and setup # openSUSE - special handling for terminal/locale issues
pct exec "$CTID" -- bash -c "zypper --non-interactive install curl sudo mc jq glibc-locale >/dev/null" || { msg_info "Initializing package manager for openSUSE..."
pct exec "$CTID" -- bash -c "zypper --non-interactive refresh 2>&1" >/dev/null 2>&1 || true
# Install packages - ncurses and terminfo are CRITICAL for terminal to work
if ! pct exec "$CTID" -- bash -c "zypper --non-interactive install -y curl sudo mc jq glibc-locale ncurses terminfo-base 2>&1" >/dev/null 2>&1; then
# Try without glibc-locale
if ! pct exec "$CTID" -- bash -c "zypper --non-interactive install -y curl sudo mc jq ncurses terminfo-base 2>&1" >/dev/null 2>&1; then
msg_error "zypper base packages installation failed" msg_error "zypper base packages installation failed"
exit 1 exit 1
} fi
# Set locale for openSUSE fi
# Fix 'unknown terminal type' error - set TERM in multiple places
pct exec "$CTID" -- bash -c "localectl set-locale LANG=en_US.UTF-8 2>/dev/null || echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true pct exec "$CTID" -- bash -c "localectl set-locale LANG=en_US.UTF-8 2>/dev/null || echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true
# Set TERM globally for all users
pct exec "$CTID" -- bash -c "cat > /etc/profile.d/term.sh << 'EOFTERM'
# Fix terminal type for LXC containers
if [ -z \"\$TERM\" ] || [ \"\$TERM\" = \"dumb\" ] || [ \"\$TERM\" = \"-\" ]; then
export TERM=xterm-256color
fi
EOFTERM
chmod +x /etc/profile.d/term.sh" || true
# Also set in /etc/environment for non-login shells
pct exec "$CTID" -- bash -c "grep -q '^TERM=' /etc/environment 2>/dev/null || echo 'TERM=xterm-256color' >> /etc/environment" || true
;; ;;
gentoo) gentoo)
# Gentoo - emerge is slow, only install essentials # Gentoo - OpenRC based, emerge is slow
pct exec "$CTID" -- bash -c "emerge --quiet app-misc/jq net-misc/curl app-misc/mc >/dev/null 2>&1" || { # Sync portage first (required for fresh templates)
msg_warn "Gentoo base packages installation incomplete - may need manual setup" msg_info "Syncing Gentoo portage (this may take a while)..."
} pct exec "$CTID" -- bash -c "emerge --sync >/dev/null 2>&1 || emerge-webrsync >/dev/null 2>&1" || true
# Install essentials - emerge can be very slow
if ! pct exec "$CTID" -- bash -c "emerge --quiet --noreplace app-misc/jq net-misc/curl app-misc/mc sys-libs/ncurses 2>&1" >/dev/null 2>&1; then
msg_warn "Gentoo base packages installation incomplete - some packages may need manual setup"
# Try just curl and jq as minimum
pct exec "$CTID" -- bash -c "emerge --quiet --noreplace net-misc/curl app-misc/jq 2>&1" >/dev/null 2>&1 || true
fi
# Set TERM for Gentoo
pct exec "$CTID" -- bash -c "echo 'export TERM=xterm-256color' >> /etc/profile.d/term.sh && chmod +x /etc/profile.d/term.sh" || true
;; ;;
openeuler) openeuler)
# openEuler (RHEL-compatible) # openEuler (RHEL-compatible, uses DNF)
# Note: openEuler may fail pct create due to missing /etc/redhat-release - this is a PVE limitation # Note: openEuler requires privileged container due to PVE limitation with /etc/redhat-release
pct exec "$CTID" -- bash -c "dnf install -y curl sudo mc jq glibc-langpack-en >/dev/null" || { msg_info "Initializing package manager for openEuler..."
pct exec "$CTID" -- bash -c "dnf makecache --refresh 2>&1" >/dev/null 2>&1 || true
# openEuler package names may differ from RHEL
local euler_packages="curl sudo mc jq procps-ng ncurses"
if ! pct exec "$CTID" -- bash -c "dnf install -y $euler_packages 2>&1" >/dev/null 2>&1; then
# Try without procps-ng (might be just 'procps' in openEuler)
if ! pct exec "$CTID" -- bash -c "dnf install -y curl sudo mc jq ncurses 2>&1" >/dev/null 2>&1; then
msg_error "dnf base packages installation failed" msg_error "dnf base packages installation failed"
exit 1 exit 1
} fi
fi
# Set locale # Set locale
pct exec "$CTID" -- bash -c "echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true pct exec "$CTID" -- bash -c "echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true
;; ;;
opensuse)
# openSUSE - add locale package and setup
pct exec "$CTID" -- bash -c "zypper --non-interactive install curl sudo mc jq glibc-locale >/dev/null" || {
msg_error "zypper base packages installation failed"
exit 1
}
# Set locale for openSUSE
pct exec "$CTID" -- bash -c "localectl set-locale LANG=en_US.UTF-8 2>/dev/null || echo 'LANG=en_US.UTF-8' > /etc/locale.conf" || true
;;
*) *)
msg_warn "Unknown OS '$var_os' - skipping core dependency installation" msg_warn "Unknown OS '$var_os' - skipping core dependency installation"
;; ;;
@ -3352,7 +3410,7 @@ EOF'
set +Eeuo pipefail # Disable ALL error handling temporarily set +Eeuo pipefail # Disable ALL error handling temporarily
trap - ERR # Remove ERR trap completely 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)" lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/${var_install}.sh)"
local lxc_exit=$? local lxc_exit=$?
set -Eeuo pipefail # Re-enable error handling set -Eeuo pipefail # Re-enable error handling
@ -3439,7 +3497,7 @@ EOF'
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}" echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}"
if pct exec "$CTID" -- bash -c " if pct exec "$CTID" -- bash -c "
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func) source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)
declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true
" >/dev/null 2>&1; then " >/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) local ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
@ -3879,7 +3937,7 @@ create_lxc_container() {
# Template naming conventions: # Template naming conventions:
# - Debian/Ubuntu/Devuan: <os>-<version>-standard_<date>_<arch>.tar.zst # - Debian/Ubuntu/Devuan: <os>-<version>-standard_<date>_<arch>.tar.zst
# - Alpine/Fedora/Rocky/CentOS/AlmaLinux/openEuler: <os>-<version>-default_<date>_<arch>.tar.xz # - Alpine/Fedora/Rocky/CentOS/AlmaLinux/openEuler: <os>-<version>-default_<date>_<arch>.tar.xz
# - Gentoo: gentoo-current-openrc-<date>_<arch>.tar.xz (version IS 'current') # - Gentoo: gentoo-current-openrc_<date>_<arch>.tar.xz (note: underscore before date!)
# - openSUSE: opensuse-<version>-default_<date>_<arch>.tar.xz # - openSUSE: opensuse-<version>-default_<date>_<arch>.tar.xz
# - CentOS: centos-<version>-stream-default_<date>_<arch>.tar.xz (note: stream in name) # - CentOS: centos-<version>-stream-default_<date>_<arch>.tar.xz (note: stream in name)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -3888,7 +3946,7 @@ create_lxc_container() {
debian | ubuntu | devuan) TEMPLATE_PATTERN="-standard_" ;; debian | ubuntu | devuan) TEMPLATE_PATTERN="-standard_" ;;
alpine | fedora | rockylinux | almalinux | openeuler) TEMPLATE_PATTERN="-default_" ;; alpine | fedora | rockylinux | almalinux | openeuler) TEMPLATE_PATTERN="-default_" ;;
centos) TEMPLATE_PATTERN="-stream-default_" ;; centos) TEMPLATE_PATTERN="-stream-default_" ;;
gentoo) TEMPLATE_PATTERN="-openrc-" ;; # Pattern after gentoo-current gentoo) TEMPLATE_PATTERN="-openrc_" ;; # Pattern: gentoo-current-openrc_<date> (underscore!)
opensuse) TEMPLATE_PATTERN="-default_" ;; opensuse) TEMPLATE_PATTERN="-default_" ;;
*) TEMPLATE_PATTERN="" ;; *) TEMPLATE_PATTERN="" ;;
esac esac
@ -3950,14 +4008,27 @@ create_lxc_container() {
echo "[DEBUG] No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}, searching for alternatives..." echo "[DEBUG] No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}, searching for alternatives..."
# Get all available versions for this OS type # Get all available versions for this OS type
# Special handling for Gentoo which uses 'current' instead of numeric version
if [[ "$PCT_OSTYPE" == "gentoo" ]]; then
mapfile -t AVAILABLE_VERSIONS < <( mapfile -t AVAILABLE_VERSIONS < <(
pveam available -section system 2>/dev/null | pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk -F'\t' '{print $1}' | awk '{print $2}' |
grep "^${PCT_OSTYPE}-" | grep "^gentoo-" |
sed -E "s/.*${PCT_OSTYPE}-([0-9]+(\.[0-9]+)?).*/\1/" | sed -E 's/gentoo-([^-]+)-.*/\1/' |
sort -u -V 2>/dev/null sort -u 2>/dev/null || sort -u
) )
else
mapfile -t AVAILABLE_VERSIONS < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' |
grep "^${PCT_OSTYPE}-" |
sed -E "s/${PCT_OSTYPE}-([0-9]+(\.[0-9]+)?).*/\1/" |
grep -E '^[0-9]' |
sort -u -V 2>/dev/null || sort -u
)
fi
if [[ ${#AVAILABLE_VERSIONS[@]} -gt 0 ]]; then if [[ ${#AVAILABLE_VERSIONS[@]} -gt 0 ]]; then
echo "" echo ""

View File

@ -898,11 +898,34 @@ EOF
;; ;;
sysvinit) sysvinit)
# Devuan/older systems - modify inittab with flexible runlevel matching # Devuan/older systems - modify inittab for auto-login
# Devuan 5 (daedalus) uses SysVinit with various inittab formats
if [[ -f /etc/inittab ]]; then if [[ -f /etc/inittab ]]; then
# Match various runlevel patterns (23, 2345, 12345, etc.) and both getty/agetty # Backup original inittab
sed -i 's|^1:[0-9]*:respawn:/sbin/a\?getty.*|1:2345:respawn:/sbin/agetty --autologin root tty1 38400 linux|' /etc/inittab cp /etc/inittab /etc/inittab.bak 2>/dev/null || true
# Try multiple patterns to catch different inittab formats
# Pattern 1: Standard format "1:2345:respawn:/sbin/getty..."
sed -i -E 's|^1:[0-9]*:respawn:[^ ]*(getty|agetty)[^$]*$|1:2345:respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab
# Pattern 2: With console instead of tty1
sed -i -E 's|^c1:[0-9]*:respawn:[^ ]*(getty|agetty).*console.*$|c1:2345:respawn:/sbin/agetty --autologin root --noclear console 38400 linux|' /etc/inittab
# Pattern 3: Devuan specific "co:2345:respawn:/sbin/getty..."
sed -i -E 's|^co:[0-9]*:respawn:[^ ]*(getty|agetty).*$|co:2345:respawn:/sbin/agetty --autologin root --noclear console 38400 linux|' /etc/inittab
# Pattern 4: LXC console pattern
if ! grep -q 'autologin root' /etc/inittab; then
# If no autologin was set, add a new console entry
if ! grep -qE '^c[o1]:.*autologin' /etc/inittab; then
echo "co:2345:respawn:/sbin/agetty --autologin root --noclear console 38400 linux" >>/etc/inittab
fi fi
fi
# Force a reload of inittab - try multiple methods
telinit q &>/dev/null || init q &>/dev/null || kill -1 1 &>/dev/null || true
fi
touch /root/.hushlogin
;; ;;
esac esac