mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-04-21 17:02:16 -04:00
Compare commits
2 Commits
add-script
...
fix/node-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62498a99de | ||
|
|
ef71bcbbf1 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -447,14 +447,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
## 2026-04-20
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- WhoDB ([#13880](https://github.com/community-scripts/ProxmoxVE/pull/13880))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- pangolin: create migration tables before data transfer to prevent role loss [@MickLesk](https://github.com/MickLesk) ([#13874](https://github.com/community-scripts/ProxmoxVE/pull/13874))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Pangolin: pre-apply schema migrations to prevent data loss [@MickLesk](https://github.com/MickLesk) ([#13861](https://github.com/community-scripts/ProxmoxVE/pull/13861))
|
||||
@@ -464,19 +458,11 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
- #### ✨ New Features
|
||||
|
||||
- Wanderer: add pocketbase CLI wrapper with env [@MickLesk](https://github.com/MickLesk) ([#13863](https://github.com/community-scripts/ProxmoxVE/pull/13863))
|
||||
- feat(homelable): add password reset utility script [@davidsoncabista](https://github.com/davidsoncabista) ([#13798](https://github.com/community-scripts/ProxmoxVE/pull/13798))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Several Scripts: Bump NodeJS to align Node.js versions with upstream for 5 scripts [@MickLesk](https://github.com/MickLesk) ([#13875](https://github.com/community-scripts/ProxmoxVE/pull/13875))
|
||||
- Refactor: PMG Post Install [@MickLesk](https://github.com/MickLesk) ([#13693](https://github.com/community-scripts/ProxmoxVE/pull/13693))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- core: detect Perl breakage after LXC stack upgrade and improve storage validation [@MickLesk](https://github.com/MickLesk) ([#13879](https://github.com/community-scripts/ProxmoxVE/pull/13879))
|
||||
|
||||
## 2026-04-19
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
83
ct/anchor.sh
83
ct/anchor.sh
@@ -1,83 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/ZhFahim/anchor
|
||||
|
||||
APP="Anchor"
|
||||
var_tags="${var_tags:-notes;productivity;sync}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-10}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f ~/.anchor ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "anchor" "ZhFahim/anchor"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop anchor-web anchor-server
|
||||
msg_ok "Stopped Services"
|
||||
|
||||
msg_info "Backing up Configuration"
|
||||
cp /opt/anchor/.env /opt/anchor.env.bak
|
||||
msg_ok "Backed up Configuration"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "anchor" "ZhFahim/anchor" "tarball"
|
||||
|
||||
msg_info "Building Server"
|
||||
cd /opt/anchor/server
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm prisma generate
|
||||
$STD pnpm build
|
||||
[[ -d src/generated ]] && mkdir -p dist/src && cp -R src/generated dist/src/
|
||||
msg_ok "Built Server"
|
||||
|
||||
msg_info "Building Web Interface"
|
||||
cd /opt/anchor/web
|
||||
$STD pnpm install --frozen-lockfile
|
||||
SERVER_URL=http://127.0.0.1:3001 $STD pnpm build
|
||||
cp -r .next/static .next/standalone/.next/static
|
||||
cp -r public .next/standalone/public
|
||||
msg_ok "Built Web Interface"
|
||||
|
||||
cp /opt/anchor.env.bak /opt/anchor/.env
|
||||
rm -f /opt/anchor.env.bak
|
||||
|
||||
msg_info "Running Database Migrations"
|
||||
cd /opt/anchor/server
|
||||
set -a && source /opt/anchor/.env && set +a
|
||||
$STD pnpm prisma migrate deploy
|
||||
msg_ok "Ran Database Migrations"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start anchor-server anchor-web
|
||||
msg_ok "Started Services"
|
||||
msg_ok "Updated ${APP}"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
@@ -1,6 +0,0 @@
|
||||
_ ____ ____ ____
|
||||
| | / / /_ ____ / __ \/ __ )
|
||||
| | /| / / __ \/ __ \/ / / / __ |
|
||||
| |/ |/ / / / / /_/ / /_/ / /_/ /
|
||||
|__/|__/_/ /_/\____/_____/_____/
|
||||
|
||||
@@ -76,23 +76,8 @@ function update_script() {
|
||||
if [[ -f "$DB" ]]; then
|
||||
sqlite3 "$DB" "ALTER TABLE 'orgs' ADD COLUMN 'settingsLogRetentionDaysConnection' integer DEFAULT 0 NOT NULL;" 2>/dev/null || true
|
||||
sqlite3 "$DB" "ALTER TABLE 'clientSitesAssociationsCache' ADD COLUMN 'isJitMode' integer DEFAULT 0 NOT NULL;" 2>/dev/null || true
|
||||
|
||||
# Create new role-mapping tables and migrate data before drizzle-kit
|
||||
# drops the roleId columns from userOrgs and userInvites.
|
||||
sqlite3 "$DB" "CREATE TABLE IF NOT EXISTS 'userOrgRoles' (
|
||||
'userId' text NOT NULL REFERENCES 'user'('id') ON DELETE CASCADE,
|
||||
'orgId' text NOT NULL REFERENCES 'orgs'('orgId') ON DELETE CASCADE,
|
||||
'roleId' integer NOT NULL REFERENCES 'roles'('roleId') ON DELETE CASCADE,
|
||||
UNIQUE('userId', 'orgId', 'roleId')
|
||||
);" 2>/dev/null || true
|
||||
# Migrate roleId from userOrgs → userOrgRoles before the column is dropped
|
||||
sqlite3 "$DB" "INSERT OR IGNORE INTO 'userOrgRoles' (userId, orgId, roleId) SELECT userId, orgId, roleId FROM 'userOrgs' WHERE roleId IS NOT NULL;" 2>/dev/null || true
|
||||
|
||||
sqlite3 "$DB" "CREATE TABLE IF NOT EXISTS 'userInviteRoles' (
|
||||
'inviteId' text NOT NULL REFERENCES 'userInvites'('inviteId') ON DELETE CASCADE,
|
||||
'roleId' integer NOT NULL REFERENCES 'roles'('roleId') ON DELETE CASCADE,
|
||||
PRIMARY KEY('inviteId', 'roleId')
|
||||
);" 2>/dev/null || true
|
||||
sqlite3 "$DB" "INSERT OR IGNORE INTO 'userInviteRoles' (inviteId, roleId) SELECT inviteId, roleId FROM 'userInvites' WHERE roleId IS NOT NULL;" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
ENVIRONMENT=prod $STD npx drizzle-kit push --force --config drizzle.sqlite.config.ts
|
||||
|
||||
54
ct/whodb.sh
54
ct/whodb.sh
@@ -1,54 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://whodb.com/
|
||||
|
||||
APP="WhoDB"
|
||||
var_tags="${var_tags:-database;management;gui}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_disk="${var_disk:-2}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f /opt/whodb/whodb ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "whodb" "clidey/whodb"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop whodb
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
fetch_and_deploy_gh_release "whodb" "clidey/whodb" "singlefile" "latest" "/opt/whodb" "whodb-*-linux-amd64"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start whodb
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||
@@ -1,99 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/ZhFahim/anchor
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="anchor" PG_DB_USER="anchor" setup_postgresql_db
|
||||
|
||||
fetch_and_deploy_gh_release "anchor" "ZhFahim/anchor" "tarball"
|
||||
|
||||
msg_info "Building Server"
|
||||
cd /opt/anchor/server
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm prisma generate
|
||||
$STD pnpm build
|
||||
[[ -d src/generated ]] && mkdir -p dist/src && cp -R src/generated dist/src/
|
||||
msg_ok "Built Server"
|
||||
|
||||
msg_info "Building Web Interface"
|
||||
cd /opt/anchor/web
|
||||
$STD pnpm install --frozen-lockfile
|
||||
SERVER_URL=http://127.0.0.1:3001 $STD pnpm build
|
||||
cp -r .next/static .next/standalone/.next/static
|
||||
cp -r public .next/standalone/public
|
||||
msg_ok "Built Web Interface"
|
||||
|
||||
msg_info "Configuring Application"
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
cat <<EOF >/opt/anchor/.env
|
||||
APP_URL=http://${LOCAL_IP}:3000
|
||||
JWT_SECRET=${JWT_SECRET}
|
||||
DATABASE_URL=postgresql://anchor:${PG_DB_PASS}@localhost:5432/anchor
|
||||
PG_HOST=localhost
|
||||
PG_USER=anchor
|
||||
PG_PASSWORD=${PG_DB_PASS}
|
||||
PG_DATABASE=anchor
|
||||
PG_PORT=5432
|
||||
EOF
|
||||
msg_ok "Configured Application"
|
||||
|
||||
msg_info "Running Database Migrations"
|
||||
cd /opt/anchor/server
|
||||
set -a && source /opt/anchor/.env && set +a
|
||||
$STD pnpm prisma migrate deploy
|
||||
msg_ok "Ran Database Migrations"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<EOF >/etc/systemd/system/anchor-server.service
|
||||
[Unit]
|
||||
Description=Anchor API Server
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/anchor/server
|
||||
EnvironmentFile=/opt/anchor/.env
|
||||
ExecStart=/usr/bin/node dist/src/main.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/anchor-web.service
|
||||
[Unit]
|
||||
Description=Anchor Web Interface
|
||||
After=network.target anchor-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/anchor/web/.next/standalone
|
||||
EnvironmentFile=/opt/anchor/.env
|
||||
Environment=PORT=3000 HOSTNAME=0.0.0.0 NODE_ENV=production
|
||||
ExecStart=/usr/bin/node server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now anchor-server anchor-web
|
||||
msg_ok "Created Services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -45,30 +45,6 @@ STATUS_CHECKER_INTERVAL=60
|
||||
EOF
|
||||
msg_ok "Configured Homelable"
|
||||
|
||||
msg_info "Creating Password Reset Utility"
|
||||
cat <<'EOF' >/root/change_password.sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
NEW_PASS=""
|
||||
|
||||
while [[ -z "$NEW_PASS" ]]; do
|
||||
read -s -p "Enter new password: " NEW_PASS
|
||||
echo ""
|
||||
if [[ -z "$NEW_PASS" ]]; then
|
||||
echo "Error: Password cannot be blank. Try again."
|
||||
fi
|
||||
done
|
||||
|
||||
HASH=$(/opt/homelable/backend/.venv/bin/python -c "from passlib.context import CryptContext; print(CryptContext(schemes=['bcrypt']).hash('${NEW_PASS}'))")
|
||||
|
||||
sed -i "s|^AUTH_PASSWORD_HASH=.*|AUTH_PASSWORD_HASH='${HASH}'|" /opt/homelable/backend/.env
|
||||
|
||||
systemctl restart homelable
|
||||
echo "Password updated and service restarted successfully!"
|
||||
EOF
|
||||
chmod +x /opt/homelable/change_password.sh
|
||||
msg_ok "Created Password Reset Utility"
|
||||
|
||||
msg_info "Building Frontend"
|
||||
cd /opt/homelable/frontend
|
||||
$STD npm ci
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://whodb.com/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "whodb" "clidey/whodb" "singlefile" "latest" "/opt/whodb" "whodb-*-linux-amd64"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/whodb.service
|
||||
[Unit]
|
||||
Description=WhoDB Database Management
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/whodb
|
||||
ExecStart=/opt/whodb/whodb
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now whodb
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
253
misc/build.func
253
misc/build.func
@@ -3658,7 +3658,7 @@ build_container() {
|
||||
local _mount_clean="${ALLOW_MOUNT_FS// /}"
|
||||
_mount_clean="${_mount_clean%%,}"
|
||||
_mount_clean="${_mount_clean##,}"
|
||||
_mount_clean="${_mount_clean%%;}"
|
||||
_mount_clean="${_mount_clean%%;}"
|
||||
_mount_clean="${_mount_clean//,/;}"
|
||||
if [ -n "$_mount_clean" ]; then
|
||||
[ -n "$FEATURES" ] && FEATURES="$FEATURES,"
|
||||
@@ -5250,133 +5250,9 @@ create_lxc_container() {
|
||||
# Extract Debian OS minor from template name: debian-13-standard_13.1-1_amd64.tar.zst => "13.1"
|
||||
parse_template_osver() { sed -n 's/.*_\([0-9][0-9]*\(\.[0-9]\+\)\?\)-.*/\1/p' <<<"$1"; }
|
||||
|
||||
# Switch to the previous OS major version template and retry pct create
|
||||
# Determines the fallback version automatically based on available templates.
|
||||
# Returns: 0 = success, 1 = failed
|
||||
fallback_to_previous_os_version() {
|
||||
local old_template="$TEMPLATE"
|
||||
local os_type="${PCT_OSTYPE:-}"
|
||||
local current_ver="${PCT_OSVERSION:-}"
|
||||
|
||||
# Determine template search pattern based on OS type
|
||||
local tpl_pattern=""
|
||||
case "$os_type" in
|
||||
debian | ubuntu) tpl_pattern="-standard_" ;;
|
||||
alpine | fedora | rocky | centos) tpl_pattern="-default_" ;;
|
||||
*) tpl_pattern="" ;;
|
||||
esac
|
||||
|
||||
msg_info "Searching for an older $os_type template (current: $os_type $current_ver)"
|
||||
|
||||
# Collect all available versions for this OS type (local + online)
|
||||
local -a all_versions=()
|
||||
|
||||
# Local templates
|
||||
mapfile -t _local_vers < <(
|
||||
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
|
||||
awk -v os="$os_type" -v pat="$tpl_pattern" '$1 ~ ("^"os"|/"os) && $1 ~ pat {print $1}' |
|
||||
sed 's|.*/||' |
|
||||
sed -E "s/^${os_type}-([0-9]+(\.[0-9]+)?).*/\1/" |
|
||||
sort -u -V
|
||||
)
|
||||
all_versions+=("${_local_vers[@]}")
|
||||
|
||||
# Online templates (only if needed)
|
||||
if command -v timeout &>/dev/null; then
|
||||
timeout 30 pveam update >/dev/null 2>&1 || true
|
||||
else
|
||||
pveam update >/dev/null 2>&1 || true
|
||||
fi
|
||||
mapfile -t _online_vers < <(
|
||||
pveam available -section system 2>/dev/null |
|
||||
awk '{print $2}' |
|
||||
grep -E "^${os_type}-[0-9]" |
|
||||
{ [[ -n "$tpl_pattern" ]] && grep "$tpl_pattern" || cat; } |
|
||||
sed -E "s/^${os_type}-([0-9]+(\.[0-9]+)?).*/\1/" |
|
||||
sort -u -V 2>/dev/null || true
|
||||
)
|
||||
all_versions+=("${_online_vers[@]}")
|
||||
|
||||
# Deduplicate and sort, find the highest version below current
|
||||
local fallback_ver=""
|
||||
fallback_ver=$(printf '%s\n' "${all_versions[@]}" | sort -u -V | awk -v cur="$current_ver" '{
|
||||
# Compare major versions: extract major part
|
||||
split($0, a, ".")
|
||||
split(cur, b, ".")
|
||||
if (a[1]+0 < b[1]+0) ver=$0
|
||||
} END { if (ver) print ver }')
|
||||
|
||||
if [[ -z "$fallback_ver" ]]; then
|
||||
msg_error "No older $os_type template version found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
msg_ok "Fallback version: $os_type $fallback_ver"
|
||||
|
||||
# Find the actual template file for this version
|
||||
local fallback_search="${os_type}-${fallback_ver}"
|
||||
local fallback_template=""
|
||||
|
||||
# Check local first
|
||||
mapfile -t _fb_local < <(
|
||||
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
|
||||
awk -v search="$fallback_search" -v pat="$tpl_pattern" '$1 ~ search && $1 ~ pat {print $1}' |
|
||||
sed 's|.*/||' | sort -t - -k 2 -V
|
||||
)
|
||||
if [[ ${#_fb_local[@]} -gt 0 ]]; then
|
||||
fallback_template="${_fb_local[-1]}"
|
||||
else
|
||||
# Check online
|
||||
mapfile -t _fb_online < <(
|
||||
pveam available -section system 2>/dev/null |
|
||||
awk '{print $2}' |
|
||||
grep -E "^${fallback_search}.*${tpl_pattern}" |
|
||||
sort -t - -k 2 -V 2>/dev/null || true
|
||||
)
|
||||
[[ ${#_fb_online[@]} -gt 0 ]] && fallback_template="${_fb_online[-1]}"
|
||||
fi
|
||||
|
||||
if [[ -z "$fallback_template" ]]; then
|
||||
msg_error "No template found for $os_type $fallback_ver."
|
||||
return 1
|
||||
fi
|
||||
|
||||
msg_ok "Found template: $fallback_template"
|
||||
|
||||
# Download if needed
|
||||
local fallback_path
|
||||
fallback_path="$(pvesm path "$TEMPLATE_STORAGE:vztmpl/$fallback_template" 2>/dev/null || true)"
|
||||
[[ -z "$fallback_path" ]] && fallback_path="/var/lib/vz/template/cache/$fallback_template"
|
||||
|
||||
if [[ ! -f "$fallback_path" ]]; then
|
||||
msg_info "Downloading $os_type $fallback_ver template"
|
||||
if ! pveam download "$TEMPLATE_STORAGE" "$fallback_template" >>"${BUILD_LOG:-/dev/null}" 2>&1; then
|
||||
msg_error "Failed to download $os_type $fallback_ver template."
|
||||
return 1
|
||||
fi
|
||||
msg_ok "Template downloaded"
|
||||
fi
|
||||
|
||||
# Update variables
|
||||
TEMPLATE="$fallback_template"
|
||||
TEMPLATE_PATH="$fallback_path"
|
||||
PCT_OSVERSION="$fallback_ver"
|
||||
export PCT_OSVERSION
|
||||
|
||||
# Retry pct create
|
||||
msg_info "Retrying container creation with $os_type $fallback_ver"
|
||||
if pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
|
||||
msg_ok "Container created successfully with $os_type $fallback_ver (fallback from $old_template)."
|
||||
return 0
|
||||
else
|
||||
msg_error "Container creation with $os_type $fallback_ver also failed. See $LOGFILE"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Offer upgrade for pve-container/lxc-pve if candidate > installed; optional auto-retry pct create
|
||||
# Returns:
|
||||
# 0 = no upgrade needed / container created after upgrade or fallback
|
||||
# 0 = no upgrade needed
|
||||
# 1 = upgraded (and if do_retry=yes and retry succeeded, creation done)
|
||||
# 2 = user declined
|
||||
# 3 = upgrade attempted but failed OR retry failed
|
||||
@@ -5404,58 +5280,13 @@ create_lxc_container() {
|
||||
echo " pve-container: installed=${_pvec_i:-n/a} candidate=${_pvec_c:-n/a}"
|
||||
echo " lxc-pve : installed=${_lxcp_i:-n/a} candidate=${_lxcp_c:-n/a}"
|
||||
echo
|
||||
|
||||
# Offer older OS version fallback when template version might be too new for LXC stack
|
||||
local _has_fallback_option=false
|
||||
if [[ -n "${PCT_OSTYPE:-}" && -n "${PCT_OSVERSION:-}" ]]; then
|
||||
_has_fallback_option=true
|
||||
echo " [1] Upgrade LXC stack now (recommended)"
|
||||
echo " [2] Use an older ${PCT_OSTYPE} template instead (may not work with all scripts)"
|
||||
echo " [3] Cancel"
|
||||
echo
|
||||
read -rp "Select option [1/2/3]: " _ans </dev/tty
|
||||
else
|
||||
read -rp "Do you want to upgrade now? [y/N] " _ans </dev/tty
|
||||
fi
|
||||
|
||||
if [[ "$_has_fallback_option" == true ]]; then
|
||||
case "$_ans" in
|
||||
1)
|
||||
_ans="y"
|
||||
;;
|
||||
2)
|
||||
if [[ "$do_retry" == "yes" ]]; then
|
||||
if fallback_to_previous_os_version; then
|
||||
return 0
|
||||
else
|
||||
return 3
|
||||
fi
|
||||
else
|
||||
msg_custom "ℹ️" "${YW}" "OS version fallback is only available during container creation."
|
||||
return 2
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
read -rp "Do you want to upgrade now? [y/N] " _ans </dev/tty
|
||||
case "${_ans,,}" in
|
||||
y | yes)
|
||||
msg_info "Upgrading Proxmox LXC stack (pve-container, lxc-pve)"
|
||||
apt_update_safe
|
||||
if $STD apt-get install -y --only-upgrade pve-container lxc-pve; then
|
||||
msg_ok "LXC stack upgraded."
|
||||
# Verify pct binary still works after upgrade (partial upgrades can break Perl modules)
|
||||
if ! pct list &>/dev/null; then
|
||||
msg_error "LXC stack upgrade caused PVE tool breakage (likely Perl module incompatibility)."
|
||||
msg_custom "⚠️" "${YW}" "A partial package upgrade has left the PVE stack in an inconsistent state."
|
||||
msg_custom "🔧" "${YW}" "Please run the following on the Proxmox host, then retry:"
|
||||
echo -e "${TAB} apt update && apt dist-upgrade -y"
|
||||
echo -e "${TAB} reboot"
|
||||
return 3
|
||||
fi
|
||||
if [[ "$do_retry" == "yes" ]]; then
|
||||
msg_info "Retrying container creation after upgrade"
|
||||
if pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
|
||||
@@ -5554,35 +5385,10 @@ create_lxc_container() {
|
||||
fi
|
||||
|
||||
msg_info "Validating storage '$CONTAINER_STORAGE'"
|
||||
# Check if storage.cfg is accessible (pmxcfs must be mounted)
|
||||
if [[ ! -f /etc/pve/storage.cfg ]]; then
|
||||
if ! mountpoint -q /etc/pve 2>/dev/null; then
|
||||
msg_error "Proxmox cluster filesystem (pmxcfs) is not mounted at /etc/pve."
|
||||
msg_custom "🔧" "${YW}" "Try: systemctl restart pve-cluster"
|
||||
else
|
||||
msg_error "/etc/pve/storage.cfg does not exist."
|
||||
msg_custom "🔧" "${YW}" "Check Proxmox cluster filesystem integrity: pvecm status"
|
||||
fi
|
||||
exit 213
|
||||
fi
|
||||
|
||||
STORAGE_TYPE=$(grep -E "^[^:]+:[[:space:]]*$CONTAINER_STORAGE[[:space:]]*$" /etc/pve/storage.cfg | cut -d: -f1 | head -1 || true)
|
||||
|
||||
# Fallback: use pvesm status to determine storage type
|
||||
if [[ -z "$STORAGE_TYPE" ]]; then
|
||||
STORAGE_TYPE=$(pvesm status -storage "$CONTAINER_STORAGE" 2>/dev/null | awk 'NR>1{print $2}')
|
||||
fi
|
||||
STORAGE_TYPE=$(grep -E "^[^:]+: $CONTAINER_STORAGE$" /etc/pve/storage.cfg | cut -d: -f1 | head -1 || true)
|
||||
|
||||
if [[ -z "$STORAGE_TYPE" ]]; then
|
||||
msg_error "Storage '$CONTAINER_STORAGE' not found in /etc/pve/storage.cfg"
|
||||
msg_custom "📋" "${YW}" "Available storages: $(pvesm status 2>/dev/null | awk 'NR>1{printf "%s (%s) ", $1, $2}' || echo 'n/a')"
|
||||
if [[ -r /etc/pve/storage.cfg ]]; then
|
||||
msg_custom "📋" "${YW}" "Storage definitions found in config:"
|
||||
grep -E '^[a-z]+:' /etc/pve/storage.cfg 2>/dev/null | while IFS= read -r _line; do
|
||||
echo "${TAB} $_line"
|
||||
done
|
||||
fi
|
||||
msg_custom "📖" "${YW}" "See https://pve.proxmox.com/wiki/Storage for storage configuration details."
|
||||
exit 213
|
||||
fi
|
||||
|
||||
@@ -6005,17 +5811,6 @@ create_lxc_container() {
|
||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >"$LOGFILE" 2>&1; then
|
||||
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Checking error..."
|
||||
|
||||
# Check for Perl module breakage (partial PVE upgrade)
|
||||
if grep -qiE 'Compilation failed|Bareword.*not allowed' "$LOGFILE"; then
|
||||
msg_error "Container creation failed due to broken Perl modules on the PVE host."
|
||||
msg_custom "⚠️" "${YW}" "This usually happens after a partial PVE package upgrade."
|
||||
msg_custom "🔧" "${YW}" "Please run the following on the Proxmox host, then retry:"
|
||||
echo -e "${TAB} apt update && apt dist-upgrade -y"
|
||||
echo -e "${TAB} reboot"
|
||||
_flush_pct_log
|
||||
exit 232
|
||||
fi
|
||||
|
||||
# Check if CTID collision (race condition: ID claimed between validation and creation)
|
||||
if grep -qiE 'already exists|already in use' "$LOGFILE"; then
|
||||
local old_ctid="$CTID"
|
||||
@@ -6061,16 +5856,15 @@ create_lxc_container() {
|
||||
rc=$?
|
||||
case $rc in
|
||||
0) : ;; # success - container created, continue
|
||||
2 | 3)
|
||||
# Upgrade declined or failed — try older OS version as last resort
|
||||
msg_warn "Attempting older ${PCT_OSTYPE:-} version as last resort"
|
||||
if fallback_to_previous_os_version; then
|
||||
: # success
|
||||
else
|
||||
msg_error "All recovery options exhausted. Please inspect: $LOGFILE"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
fi
|
||||
2)
|
||||
msg_error "Upgrade declined. Please update and re-run: apt update && apt install --only-upgrade pve-container lxc-pve"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
;;
|
||||
3)
|
||||
msg_error "Upgrade and/or retry failed. Please inspect: $LOGFILE"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
;;
|
||||
esac
|
||||
else
|
||||
@@ -6094,16 +5888,15 @@ create_lxc_container() {
|
||||
rc=$?
|
||||
case $rc in
|
||||
0) : ;; # success - container created, continue
|
||||
2 | 3)
|
||||
# Upgrade declined or failed — try older OS version as last resort
|
||||
msg_warn "Attempting older ${PCT_OSTYPE:-} version as last resort"
|
||||
if fallback_to_previous_os_version; then
|
||||
: # success
|
||||
else
|
||||
msg_error "All recovery options exhausted. Please inspect: $LOGFILE"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
fi
|
||||
2)
|
||||
msg_error "Upgrade declined. Please update and re-run: apt update && apt install --only-upgrade pve-container lxc-pve"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
;;
|
||||
3)
|
||||
msg_error "Upgrade and/or retry failed. Please inspect: $LOGFILE"
|
||||
_flush_pct_log
|
||||
exit 231
|
||||
;;
|
||||
esac
|
||||
else
|
||||
@@ -6122,7 +5915,7 @@ create_lxc_container() {
|
||||
fi
|
||||
fi # close CTID collision else-branch
|
||||
fi
|
||||
set +f # re-enable globbing after pct create block
|
||||
set +f # re-enable globbing after pct create block
|
||||
|
||||
# Verify container exists (allow up to 10s for pmxcfs sync in clusters)
|
||||
local _pct_visible=false
|
||||
|
||||
Reference in New Issue
Block a user