mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-03 17:35:55 +01:00
Compare commits
1 Commits
preflight_
...
revert-#11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdabc13db1 |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -410,22 +410,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-03-03
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Tinyauth: v5 Support & add Debian Version [@MickLesk](https://github.com/MickLesk) ([#12501](https://github.com/community-scripts/ProxmoxVE/pull/12501))
|
||||
|
||||
### 🗑️ Deleted Scripts
|
||||
|
||||
- Remove Unifi Network Server scripts (dead APT repo) [@Copilot](https://github.com/Copilot) ([#12500](https://github.com/community-scripts/ProxmoxVE/pull/12500))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Revert #11534 PR that messed up search [@BramSuurdje](https://github.com/BramSuurdje) ([#12492](https://github.com/community-scripts/ProxmoxVE/pull/12492))
|
||||
|
||||
## 2026-03-02
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
@@ -35,20 +35,6 @@ function update_script() {
|
||||
$STD service tinyauth stop
|
||||
msg_ok "Service Stopped"
|
||||
|
||||
if [[ -f /opt/tinyauth/.env ]] && ! grep -q "^TINYAUTH_" /opt/tinyauth/.env; then
|
||||
msg_info "Migrating .env to v5 format"
|
||||
sed -i \
|
||||
-e 's/^DATABASE_PATH=/TINYAUTH_DATABASE_PATH=/' \
|
||||
-e 's/^USERS=/TINYAUTH_AUTH_USERS=/' \
|
||||
-e "s/^USERS='/TINYAUTH_AUTH_USERS='/" \
|
||||
-e 's/^APP_URL=/TINYAUTH_APPURL=/' \
|
||||
-e 's/^SECRET=/TINYAUTH_AUTH_SECRET=/' \
|
||||
-e 's/^PORT=/TINYAUTH_SERVER_PORT=/' \
|
||||
-e 's/^ADDRESS=/TINYAUTH_SERVER_ADDRESS=/' \
|
||||
/opt/tinyauth/.env
|
||||
msg_ok "Migrated .env to v5 format"
|
||||
fi
|
||||
|
||||
msg_info "Updating Tinyauth"
|
||||
rm -f /opt/tinyauth/tinyauth
|
||||
curl -fsSL "https://github.com/steveiliop56/tinyauth/releases/download/v${RELEASE}/tinyauth-amd64" -o /opt/tinyauth/tinyauth
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
_______ __ __
|
||||
/_ __(_)___ __ ______ ___ __/ /_/ /_
|
||||
/ / / / __ \/ / / / __ `/ / / / __/ __ \
|
||||
/ / / / / / / /_/ / /_/ / /_/ / /_/ / / /
|
||||
/_/ /_/_/ /_/\__, /\__,_/\__,_/\__/_/ /_/
|
||||
/____/
|
||||
6
ct/headers/unifi
Normal file
6
ct/headers/unifi
Normal file
@@ -0,0 +1,6 @@
|
||||
__ __ _ _____
|
||||
/ / / /___ (_) __(_)
|
||||
/ / / / __ \/ / /_/ /
|
||||
/ /_/ / / / / / __/ /
|
||||
\____/_/ /_/_/_/ /_/
|
||||
|
||||
@@ -1,53 +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/steveiliop56/tinyauth
|
||||
|
||||
APP="Tinyauth"
|
||||
var_tags="${var_tags:-auth}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_disk="${var_disk:-4}"
|
||||
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 [[ ! -d /opt/tinyauth ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "tinyauth" "steveiliop56/tinyauth"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop tinyauth
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
fetch_and_deploy_gh_release "tinyauth" "steveiliop56/tinyauth" "singlefile" "latest" "/opt/tinyauth" "tinyauth-amd64"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start tinyauth
|
||||
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}:3000${CL}"
|
||||
47
ct/unifi.sh
Normal file
47
ct/unifi.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://ui.com/download/unifi
|
||||
|
||||
APP="Unifi"
|
||||
var_tags="${var_tags:-network;unifi}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-12}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /usr/lib/unifi ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
JAVA_VERSION="21" setup_java
|
||||
|
||||
msg_info "Updating ${APP}"
|
||||
$STD apt update --allow-releaseinfo-change
|
||||
ensure_dependencies unifi
|
||||
msg_ok "Updated successfully!"
|
||||
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}https://${IP}:8443${CL}"
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "Tinyauth",
|
||||
"slug": "tinyauth",
|
||||
"name": "Alpine-Tinyauth",
|
||||
"slug": "alpine-tinyauth",
|
||||
"categories": [
|
||||
6
|
||||
],
|
||||
"date_created": "2026-03-03",
|
||||
"date_created": "2025-05-06",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
@@ -17,13 +17,13 @@
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/tinyauth.sh",
|
||||
"script": "ct/alpine-tinyauth.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 512,
|
||||
"hdd": 4,
|
||||
"os": "debian",
|
||||
"version": "13"
|
||||
"ram": 256,
|
||||
"hdd": 2,
|
||||
"os": "alpine",
|
||||
"version": "3.23"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-03-03T06:17:56Z",
|
||||
"generated": "2026-03-02T18:14:19Z",
|
||||
"versions": [
|
||||
{
|
||||
"slug": "2fauth",
|
||||
@@ -291,9 +291,9 @@
|
||||
{
|
||||
"slug": "dispatcharr",
|
||||
"repo": "Dispatcharr/Dispatcharr",
|
||||
"version": "v0.20.2",
|
||||
"version": "v0.20.1",
|
||||
"pinned": false,
|
||||
"date": "2026-03-03T01:40:33Z"
|
||||
"date": "2026-02-26T21:38:19Z"
|
||||
},
|
||||
{
|
||||
"slug": "docmost",
|
||||
@@ -382,9 +382,9 @@
|
||||
{
|
||||
"slug": "firefly",
|
||||
"repo": "firefly-iii/firefly-iii",
|
||||
"version": "v6.5.2",
|
||||
"version": "v6.5.1",
|
||||
"pinned": false,
|
||||
"date": "2026-03-03T05:42:27Z"
|
||||
"date": "2026-02-27T20:55:55Z"
|
||||
},
|
||||
{
|
||||
"slug": "fladder",
|
||||
@@ -585,9 +585,9 @@
|
||||
{
|
||||
"slug": "immich-public-proxy",
|
||||
"repo": "alangrainger/immich-public-proxy",
|
||||
"version": "v1.15.4",
|
||||
"version": "v1.15.3",
|
||||
"pinned": false,
|
||||
"date": "2026-03-02T21:28:06Z"
|
||||
"date": "2026-02-16T22:54:27Z"
|
||||
},
|
||||
{
|
||||
"slug": "inspircd",
|
||||
@@ -613,9 +613,9 @@
|
||||
{
|
||||
"slug": "jackett",
|
||||
"repo": "Jackett/Jackett",
|
||||
"version": "v0.24.1261",
|
||||
"version": "v0.24.1247",
|
||||
"pinned": false,
|
||||
"date": "2026-03-03T05:54:20Z"
|
||||
"date": "2026-03-02T05:56:37Z"
|
||||
},
|
||||
{
|
||||
"slug": "jellystat",
|
||||
@@ -872,9 +872,9 @@
|
||||
{
|
||||
"slug": "metube",
|
||||
"repo": "alexta69/metube",
|
||||
"version": "2026.03.02",
|
||||
"version": "2026.02.27",
|
||||
"pinned": false,
|
||||
"date": "2026-03-02T19:19:10Z"
|
||||
"date": "2026-02-27T11:47:02Z"
|
||||
},
|
||||
{
|
||||
"slug": "miniflux",
|
||||
@@ -1231,7 +1231,7 @@
|
||||
"repo": "rcourtman/Pulse",
|
||||
"version": "v5.1.17",
|
||||
"pinned": false,
|
||||
"date": "2026-03-02T20:15:31Z"
|
||||
"date": "2026-03-02T17:52:12Z"
|
||||
},
|
||||
{
|
||||
"slug": "pve-scripts-local",
|
||||
@@ -1733,9 +1733,9 @@
|
||||
{
|
||||
"slug": "wealthfolio",
|
||||
"repo": "afadil/wealthfolio",
|
||||
"version": "v3.0.2",
|
||||
"version": "v3.0.0",
|
||||
"pinned": false,
|
||||
"date": "2026-03-03T05:01:49Z"
|
||||
"date": "2026-02-24T22:37:05Z"
|
||||
},
|
||||
{
|
||||
"slug": "web-check",
|
||||
|
||||
42
frontend/public/json/unifi.json
Normal file
42
frontend/public/json/unifi.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "UniFi Network Server",
|
||||
"slug": "unifi",
|
||||
"categories": [
|
||||
4
|
||||
],
|
||||
"date_created": "2024-05-02",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8443,
|
||||
"documentation": "https://help.ui.com/hc/en-us/articles/360012282453-Self-Hosting-a-UniFi-Network-Server",
|
||||
"website": "https://www.ui.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ubiquiti-unifi.webp",
|
||||
"config_path": "",
|
||||
"description": "UniFi Network Server is a software that helps manage and monitor UniFi networks (Wi-Fi, Ethernet, etc.) by providing an intuitive user interface and advanced features. It allows network administrators to configure, monitor, and upgrade network devices, as well as view network statistics, client devices, and historical events. The aim of the application is to make the management of UniFi networks easier and more efficient.",
|
||||
"disable": true,
|
||||
"disable_description": "This script is disabled because UniFi no longer delivers APT packages for Debian systems. The installation relies on APT repositories that are no longer maintained or available. For more details, see: https://github.com/community-scripts/ProxmoxVE/issues/11876",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/unifi.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "debian",
|
||||
"version": "12"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "For non-AVX CPUs, MongoDB 4.4 is installed. Please note this is a legacy solution that may present security risks and could become unsupported in future updates.",
|
||||
"type": "warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -36,9 +36,9 @@ msg_ok "Installed Tinyauth"
|
||||
read -r -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url
|
||||
|
||||
cat <<EOF >/opt/tinyauth/.env
|
||||
TINYAUTH_DATABASE_PATH=/opt/tinyauth/database.db
|
||||
TINYAUTH_AUTH_USERS='${USER}'
|
||||
TINYAUTH_APPURL=${app_url}
|
||||
DATABASE_PATH=/opt/tinyauth/database.db
|
||||
USERS='${USER}'
|
||||
APP_URL=${app_url}
|
||||
EOF
|
||||
|
||||
msg_info "Creating Service"
|
||||
|
||||
@@ -1,62 +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/steveiliop56/tinyauth
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
openssl \
|
||||
apache2-utils
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "tinyauth" "steveiliop56/tinyauth" "singlefile" "latest" "/opt/tinyauth" "tinyauth-amd64"
|
||||
|
||||
msg_info "Setting up Tinyauth"
|
||||
PASS=$(openssl rand -base64 8 | tr -dc 'a-zA-Z0-9' | head -c 8)
|
||||
USER=$(htpasswd -Bbn "tinyauth" "${PASS}")
|
||||
cat <<EOF >/opt/tinyauth/credentials.txt
|
||||
Tinyauth Credentials
|
||||
Username: tinyauth
|
||||
Password: ${PASS}
|
||||
EOF
|
||||
msg_ok "Set up Tinyauth"
|
||||
|
||||
read -r -p "${TAB3}Enter your Tinyauth subdomain (e.g. https://tinyauth.example.com): " app_url
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/opt/tinyauth/.env
|
||||
TINYAUTH_DATABASE_PATH=/opt/tinyauth/database.db
|
||||
TINYAUTH_AUTH_USERS='${USER}'
|
||||
TINYAUTH_APPURL=${app_url}
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/tinyauth.service
|
||||
[Unit]
|
||||
Description=Tinyauth Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=/opt/tinyauth/.env
|
||||
ExecStart=/opt/tinyauth/tinyauth
|
||||
WorkingDirectory=/opt/tinyauth
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now tinyauth
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
53
install/unifi-install.sh
Normal file
53
install/unifi-install.sh
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://ui.com/download/unifi
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y apt-transport-https
|
||||
curl -fsSL "https://dl.ui.com/unifi/unifi-repo.gpg" -o "/usr/share/keyrings/unifi-repo.gpg"
|
||||
cat <<EOF | sudo tee /etc/apt/sources.list.d/100-ubnt-unifi.sources >/dev/null
|
||||
Types: deb
|
||||
URIs: https://www.ui.com/downloads/unifi/debian
|
||||
Suites: stable
|
||||
Components: ubiquiti
|
||||
Architectures: amd64
|
||||
Signed-By: /usr/share/keyrings/unifi-repo.gpg
|
||||
EOF
|
||||
$STD apt update
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
JAVA_VERSION="21" setup_java
|
||||
|
||||
if lscpu | grep -q 'avx'; then
|
||||
MONGO_VERSION="8.0" setup_mongodb
|
||||
else
|
||||
msg_error "No AVX detected (CPU-Flag)! We have discontinued support for this. You are welcome to try it manually with a Debian LXC, but due to the many issues with Unifi, we currently only support AVX CPUs."
|
||||
exit 10
|
||||
fi
|
||||
|
||||
if ! dpkg -l | grep -q 'libssl1.1'; then
|
||||
msg_info "Installing libssl (if needed)"
|
||||
curl -fsSL "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u4_amd64.deb" -o "/tmp/libssl.deb"
|
||||
$STD dpkg -i /tmp/libssl.deb
|
||||
rm -f /tmp/libssl.deb
|
||||
msg_ok "Installed libssl1.1"
|
||||
fi
|
||||
|
||||
msg_info "Installing UniFi Network Server"
|
||||
$STD apt install -y unifi
|
||||
msg_ok "Installed UniFi Network Server"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
624
misc/build.func
624
misc/build.func
@@ -100,624 +100,58 @@ fi
|
||||
# ==============================================================================
|
||||
# SECTION 2: PRE-FLIGHT CHECKS & SYSTEM VALIDATION
|
||||
# ==============================================================================
|
||||
#
|
||||
# Runs comprehensive system checks BEFORE container creation to catch common
|
||||
# issues early. This prevents users from going through the entire configuration
|
||||
# menu only to have creation fail due to a system-level problem.
|
||||
#
|
||||
# Checks performed (via run_preflight):
|
||||
# - Kernel: keyring limits (maxkeys/maxbytes for UID 100000)
|
||||
# - Storage: rootdir support, vztmpl support, available space
|
||||
# - Network: bridge availability, DNS resolution
|
||||
# - Repos: enterprise repo subscription validation
|
||||
# - Cluster: quorum status (if clustered)
|
||||
# - Proxmox: LXC stack health, container ID availability
|
||||
# - Template: download server reachability
|
||||
#
|
||||
# Design:
|
||||
# - All checks run and results are collected (no exit on first failure)
|
||||
# - Clear, actionable error messages with suggested fixes
|
||||
# - Reports "aborted" status to telemetry (not "failed")
|
||||
# - Uses existing exit codes for consistency with error_handler/api.func
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
# --- Preflight tracking globals ---
|
||||
PREFLIGHT_PASSED=0
|
||||
PREFLIGHT_FAILED=0
|
||||
PREFLIGHT_WARNINGS=0
|
||||
PREFLIGHT_FAILURES=()
|
||||
PREFLIGHT_EXIT_CODE=0
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_pass() / preflight_fail() / preflight_warn()
|
||||
#
|
||||
# - Track individual check results
|
||||
# - preflight_fail stores message + exit_code for summary
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_pass() {
|
||||
local msg="$1"
|
||||
((PREFLIGHT_PASSED++)) || true
|
||||
echo -e " ${CM} ${GN}${msg}${CL}"
|
||||
}
|
||||
|
||||
preflight_fail() {
|
||||
local msg="$1"
|
||||
local exit_code="${2:-1}"
|
||||
((PREFLIGHT_FAILED++)) || true
|
||||
PREFLIGHT_FAILURES+=("${exit_code}|${msg}")
|
||||
[[ "$PREFLIGHT_EXIT_CODE" -eq 0 ]] && PREFLIGHT_EXIT_CODE="$exit_code"
|
||||
echo -e " ${CROSS} ${RD}${msg}${CL}"
|
||||
}
|
||||
|
||||
preflight_warn() {
|
||||
local msg="$1"
|
||||
((PREFLIGHT_WARNINGS++)) || true
|
||||
echo -e " ${INFO} ${YW}${msg}${CL}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_maxkeys()
|
||||
# maxkeys_check()
|
||||
#
|
||||
# - Reads kernel keyring limits (maxkeys, maxbytes)
|
||||
# - Checks current usage for LXC user (UID 100000)
|
||||
# - Warns if usage is close to limits and suggests sysctl tuning
|
||||
# - https://cleveruptime.com/docs/files/proc-key-users
|
||||
# - https://docs.kernel.org/security/keys/core.html
|
||||
# - Exits if thresholds are exceeded
|
||||
# - https://cleveruptime.com/docs/files/proc-key-users | https://docs.kernel.org/security/keys/core.html
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_maxkeys() {
|
||||
local per_user_maxkeys per_user_maxbytes
|
||||
|
||||
maxkeys_check() {
|
||||
# Read kernel parameters
|
||||
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)
|
||||
|
||||
# Exit if kernel parameters are unavailable
|
||||
if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then
|
||||
preflight_fail "Unable to read kernel key parameters" 107
|
||||
echo -e " ${TAB}${INFO} Ensure proper permissions to /proc/sys/kernel/keys/"
|
||||
return 0
|
||||
msg_error "Unable to read kernel key parameters. Ensure proper permissions."
|
||||
exit 107
|
||||
fi
|
||||
|
||||
local used_lxc_keys used_lxc_bytes
|
||||
# Fetch key usage for user ID 100000 (typical for containers)
|
||||
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)
|
||||
|
||||
local threshold_keys=$((per_user_maxkeys - 100))
|
||||
local threshold_bytes=$((per_user_maxbytes - 1000))
|
||||
local new_limit_keys=$((per_user_maxkeys * 2))
|
||||
local new_limit_bytes=$((per_user_maxbytes * 2))
|
||||
# Calculate thresholds and suggested new limits
|
||||
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))
|
||||
|
||||
local failure=0
|
||||
# Check if key or byte usage is near limits
|
||||
failure=0
|
||||
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
|
||||
|
||||
# Provide next steps if issues are detected
|
||||
if [[ "$failure" -eq 1 ]]; then
|
||||
preflight_fail "Kernel key limits near threshold (keys: ${used_lxc_keys}/${per_user_maxkeys}, bytes: ${used_lxc_bytes}/${per_user_maxbytes})" 108
|
||||
echo -e " ${TAB}${INFO} Set ${GN}kernel.keys.maxkeys=${new_limit_keys}${CL} and ${GN}kernel.keys.maxbytes=${new_limit_bytes}${CL}"
|
||||
echo -e " ${TAB}${INFO} in ${BOLD}/etc/sysctl.d/98-community-scripts.conf${CL}, then run: ${GN}sysctl --system${CL}"
|
||||
return 0
|
||||
msg_error "Kernel key limits exceeded - see suggestions above"
|
||||
exit 108
|
||||
fi
|
||||
|
||||
preflight_pass "Kernel key limits OK (keys: ${used_lxc_keys}/${per_user_maxkeys})"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_storage_rootdir()
|
||||
#
|
||||
# - Verifies at least one storage supports 'rootdir' content type
|
||||
# - Without this, no LXC container can be created
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_storage_rootdir() {
|
||||
local count
|
||||
count=$(pvesm status -content rootdir 2>/dev/null | awk 'NR>1 {count++} END {print count+0}')
|
||||
|
||||
if [[ "$count" -eq 0 ]]; then
|
||||
preflight_fail "No storage with 'rootdir' support found" 119
|
||||
echo -e " ${TAB}${INFO} Enable 'rootdir' content on a storage in Datacenter → Storage"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_pass "Storage with 'rootdir' support available (${count} storage(s))"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_storage_vztmpl()
|
||||
#
|
||||
# - Verifies at least one storage supports 'vztmpl' content type
|
||||
# - Required for downloading and storing OS templates
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_storage_vztmpl() {
|
||||
local count
|
||||
count=$(pvesm status -content vztmpl 2>/dev/null | awk 'NR>1 {count++} END {print count+0}')
|
||||
|
||||
if [[ "$count" -eq 0 ]]; then
|
||||
preflight_fail "No storage with 'vztmpl' support found" 120
|
||||
echo -e " ${TAB}${INFO} Enable 'vztmpl' content on a storage in Datacenter → Storage"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_pass "Storage with 'vztmpl' support available (${count} storage(s))"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_storage_space()
|
||||
#
|
||||
# - Checks if any rootdir-capable storage has enough free space
|
||||
# - Uses the app-declared var_disk as minimum requirement
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_storage_space() {
|
||||
local required_gb="${var_disk:-4}"
|
||||
local required_kb=$((required_gb * 1024 * 1024))
|
||||
local has_enough=0
|
||||
local best_storage=""
|
||||
local best_free=0
|
||||
|
||||
while read -r storage_name _ _ _ _ free_kb _; do
|
||||
[[ -z "$storage_name" || -z "$free_kb" ]] && continue
|
||||
[[ "$free_kb" == "0" ]] && continue
|
||||
|
||||
if [[ "$free_kb" -ge "$required_kb" ]]; then
|
||||
has_enough=1
|
||||
if [[ "$free_kb" -gt "$best_free" ]]; then
|
||||
best_free="$free_kb"
|
||||
best_storage="$storage_name"
|
||||
fi
|
||||
fi
|
||||
done < <(pvesm status -content rootdir 2>/dev/null | awk 'NR>1')
|
||||
|
||||
if [[ "$has_enough" -eq 0 ]]; then
|
||||
preflight_fail "No storage has enough space (need ${required_gb}GB for ${APP})" 214
|
||||
echo -e " ${TAB}${INFO} Free up disk space or add a new storage with sufficient capacity"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local best_free_fmt
|
||||
best_free_fmt=$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$best_free" 2>/dev/null || echo "${best_free}KB")
|
||||
preflight_pass "Sufficient storage space (${best_storage}: ${best_free_fmt} free, need ${required_gb}GB)"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_network_bridge()
|
||||
#
|
||||
# - Checks if at least one network bridge exists (vmbr*)
|
||||
# - Verifies vmbr0 specifically (default bridge used by most scripts)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_network_bridge() {
|
||||
local bridges
|
||||
bridges=$(ip -o link show type bridge 2>/dev/null | grep -oE 'vmbr[0-9]+' | sort -u)
|
||||
|
||||
if [[ -z "$bridges" ]]; then
|
||||
preflight_fail "No network bridge (vmbr*) found" 116
|
||||
echo -e " ${TAB}${INFO} Create a bridge in Network → Create → Linux Bridge"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if echo "$bridges" | grep -qx "vmbr0"; then
|
||||
preflight_pass "Default network bridge vmbr0 available"
|
||||
else
|
||||
local first_bridge
|
||||
first_bridge=$(echo "$bridges" | head -1)
|
||||
preflight_warn "Default bridge vmbr0 not found, but ${first_bridge} is available"
|
||||
echo -e " ${TAB}${INFO} Scripts default to vmbr0 — use Advanced Settings to select ${first_bridge}"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_dns_resolution()
|
||||
#
|
||||
# - Tests if DNS resolution works (required for template downloads)
|
||||
# - Tries multiple hosts to avoid false positives
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_dns_resolution() {
|
||||
local test_hosts=("download.proxmox.com" "raw.githubusercontent.com" "community-scripts.org")
|
||||
local resolved=0
|
||||
|
||||
for host in "${test_hosts[@]}"; do
|
||||
if getent hosts "$host" &>/dev/null; then
|
||||
resolved=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$resolved" -eq 0 ]]; then
|
||||
for host in "${test_hosts[@]}"; do
|
||||
if command -v nslookup &>/dev/null && nslookup "$host" &>/dev/null; then
|
||||
resolved=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "$resolved" -eq 0 ]]; then
|
||||
preflight_fail "DNS resolution failed — cannot reach template servers" 222
|
||||
echo -e " ${TAB}${INFO} Check /etc/resolv.conf and network connectivity"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_pass "DNS resolution working"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_repo_access()
|
||||
#
|
||||
# - Checks if Proxmox enterprise repos are enabled without a valid subscription
|
||||
# - Scans /etc/apt/sources.list.d/ for enterprise.proxmox.com entries
|
||||
# - Tests HTTP access to detect 401 Unauthorized
|
||||
# - Warning only (not a blocker — packages come from no-subscription repo)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_repo_access() {
|
||||
local enterprise_files
|
||||
enterprise_files=$(grep -rlE '^\s*deb\s+https://enterprise\.proxmox\.com' /etc/apt/sources.list.d/ 2>/dev/null || true)
|
||||
|
||||
if [[ -z "$enterprise_files" ]]; then
|
||||
preflight_pass "No enterprise repositories enabled"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Enterprise repo found — test if subscription is valid
|
||||
local http_code
|
||||
http_code=$(curl -sS -o /dev/null -w "%{http_code}" -m 5 "https://enterprise.proxmox.com/debian/pve/dists/" 2>/dev/null) || http_code="000"
|
||||
|
||||
if [[ "$http_code" == "401" || "$http_code" == "403" ]]; then
|
||||
preflight_warn "Enterprise repo enabled without valid subscription (HTTP ${http_code})"
|
||||
echo -e " ${TAB}${INFO} apt-get update will show '401 Unauthorized' errors"
|
||||
echo -e " ${TAB}${INFO} Disable in ${GN}/etc/apt/sources.list.d/${CL} or add a subscription key"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
|
||||
preflight_pass "Enterprise repository accessible (subscription valid)"
|
||||
else
|
||||
preflight_warn "Enterprise repo check inconclusive (HTTP ${http_code})"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_cluster_quorum()
|
||||
#
|
||||
# - Checks cluster quorum status (only if node is part of a cluster)
|
||||
# - Skipped on standalone nodes
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_cluster_quorum() {
|
||||
if [[ ! -f /etc/pve/corosync.conf ]]; then
|
||||
preflight_pass "Standalone node (no cluster quorum needed)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if pvecm status 2>/dev/null | awk -F':' '/^Quorate/ { exit ($2 ~ /Yes/) ? 0 : 1 }'; then
|
||||
preflight_pass "Cluster is quorate"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_fail "Cluster is not quorate — container operations will fail" 210
|
||||
echo -e " ${TAB}${INFO} Ensure all cluster nodes are running, or configure a QDevice"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_lxc_stack()
|
||||
#
|
||||
# - Validates pve-container and lxc-pve packages are installed
|
||||
# - Checks for available updates (informational only)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_lxc_stack() {
|
||||
local pve_container_ver lxc_pve_ver
|
||||
|
||||
pve_container_ver=$(dpkg-query -W -f='${Version}\n' pve-container 2>/dev/null || echo "")
|
||||
lxc_pve_ver=$(dpkg-query -W -f='${Version}\n' lxc-pve 2>/dev/null || echo "")
|
||||
|
||||
if [[ -z "$pve_container_ver" ]]; then
|
||||
preflight_fail "Package 'pve-container' is not installed" 231
|
||||
echo -e " ${TAB}${INFO} Run: apt-get install pve-container"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -z "$lxc_pve_ver" ]]; then
|
||||
preflight_fail "Package 'lxc-pve' is not installed" 231
|
||||
echo -e " ${TAB}${INFO} Run: apt-get install lxc-pve"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local pve_container_cand lxc_pve_cand
|
||||
pve_container_cand=$(apt-cache policy pve-container 2>/dev/null | awk '/Candidate:/ {print $2}') || true
|
||||
lxc_pve_cand=$(apt-cache policy lxc-pve 2>/dev/null | awk '/Candidate:/ {print $2}') || true
|
||||
|
||||
local update_available=0
|
||||
if [[ -n "$pve_container_cand" && "$pve_container_cand" != "none" ]]; then
|
||||
if dpkg --compare-versions "$pve_container_cand" gt "$pve_container_ver" 2>/dev/null; then
|
||||
update_available=1
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$lxc_pve_cand" && "$lxc_pve_cand" != "none" ]]; then
|
||||
if dpkg --compare-versions "$lxc_pve_cand" gt "$lxc_pve_ver" 2>/dev/null; then
|
||||
update_available=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$update_available" -eq 1 ]]; then
|
||||
preflight_warn "LXC stack update available (current: pve-container=${pve_container_ver}, lxc-pve=${lxc_pve_ver})"
|
||||
echo -e " ${TAB}${INFO} An upgrade will be offered during container creation if needed"
|
||||
else
|
||||
preflight_pass "LXC stack is up to date (pve-container=${pve_container_ver})"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_container_id()
|
||||
#
|
||||
# - Verifies that container IDs can be allocated
|
||||
# - Uses pvesh /cluster/nextid (cluster-aware)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_container_id() {
|
||||
local nextid
|
||||
nextid=$(pvesh get /cluster/nextid 2>/dev/null) || true
|
||||
|
||||
if [[ -z "$nextid" || ! "$nextid" =~ ^[0-9]+$ ]]; then
|
||||
preflight_fail "Cannot allocate container ID (pvesh /cluster/nextid failed)" 109
|
||||
echo -e " ${TAB}${INFO} Check Proxmox cluster health and datacenter.cfg ID ranges"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_pass "Container IDs available (next: ${nextid})"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_template_connectivity()
|
||||
#
|
||||
# - Tests connectivity to the Proxmox template download server
|
||||
# - Warns but does not fail (local templates may be available)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_template_connectivity() {
|
||||
local http_code
|
||||
http_code=$(curl -sS -o /dev/null -w "%{http_code}" -m 5 "http://download.proxmox.com/images/system/" 2>/dev/null) || http_code="000"
|
||||
|
||||
if [[ "$http_code" =~ ^2[0-9]{2}$ || "$http_code" =~ ^3[0-9]{2}$ ]]; then
|
||||
preflight_pass "Template server reachable (download.proxmox.com)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local local_count=0
|
||||
while read -r storage_name _; do
|
||||
[[ -z "$storage_name" ]] && continue
|
||||
local count
|
||||
count=$(pveam list "$storage_name" 2>/dev/null | awk 'NR>1' | wc -l)
|
||||
local_count=$((local_count + count))
|
||||
done < <(pvesm status -content vztmpl 2>/dev/null | awk 'NR>1 {print $1}')
|
||||
|
||||
if [[ "$local_count" -gt 0 ]]; then
|
||||
preflight_warn "Template server unreachable, but ${local_count} local template(s) available"
|
||||
return 0
|
||||
fi
|
||||
|
||||
preflight_fail "Template server unreachable and no local templates available" 222
|
||||
echo -e " ${TAB}${INFO} Check internet connectivity or manually upload templates"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_template_available()
|
||||
#
|
||||
# - Validates that a template exists for the configured var_os/var_version
|
||||
# - Checks both local templates and the online pveam catalog
|
||||
# - Fails if no matching template can be found anywhere
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_template_available() {
|
||||
local os="${var_os:-}"
|
||||
local version="${var_version:-}"
|
||||
|
||||
# Skip if os/version not set (e.g. Alpine scripts set them differently)
|
||||
if [[ -z "$os" || -z "$version" ]]; then
|
||||
preflight_pass "Template check skipped (OS/version not configured yet)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local search_pattern="${os}-${version}"
|
||||
|
||||
# Check local templates first
|
||||
local local_match=0
|
||||
while read -r storage_name _; do
|
||||
[[ -z "$storage_name" ]] && continue
|
||||
if pveam list "$storage_name" 2>/dev/null | awk '{print $1}' | grep -qE "^${storage_name}:vztmpl/${search_pattern}"; then
|
||||
local_match=1
|
||||
break
|
||||
fi
|
||||
done < <(pvesm status -content vztmpl 2>/dev/null | awk 'NR>1 {print $1}')
|
||||
|
||||
if [[ "$local_match" -eq 1 ]]; then
|
||||
preflight_pass "Template available locally for ${os} ${version}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check online catalog
|
||||
local online_match=0
|
||||
if pveam available -section system 2>/dev/null | awk '{print $2}' | grep -qE "^${search_pattern}[.-]"; then
|
||||
online_match=1
|
||||
fi
|
||||
|
||||
if [[ "$online_match" -eq 1 ]]; then
|
||||
preflight_pass "Template available online for ${os} ${version}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Gather available versions for the hint
|
||||
local available_versions
|
||||
available_versions=$(
|
||||
pveam available -section system 2>/dev/null |
|
||||
awk '{print $2}' |
|
||||
grep -oE "^${os}-[0-9]+(\.[0-9]+)?" |
|
||||
sed "s/^${os}-//" |
|
||||
sort -uV 2>/dev/null | tr '\n' ', ' | sed 's/,$//' | sed 's/,/, /g'
|
||||
)
|
||||
|
||||
preflight_fail "No template found for ${os} ${version}" 225
|
||||
if [[ -n "$available_versions" ]]; then
|
||||
echo -e " ${TAB}${INFO} Available ${os} versions: ${GN}${available_versions}${CL}"
|
||||
fi
|
||||
echo -e " ${TAB}${INFO} Check var_version in your CT script or use an available version"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# preflight_package_repos()
|
||||
#
|
||||
# - Tests connectivity to OS package repositories from the host
|
||||
# - Selects repos based on var_os (debian, ubuntu, alpine)
|
||||
# - Uses HTTP HEAD requests to verify the repo index is reachable
|
||||
# - Warning only (user may use local mirrors, apt-cacher-ng, etc.)
|
||||
# ------------------------------------------------------------------------------
|
||||
preflight_package_repos() {
|
||||
local os="${var_os:-debian}"
|
||||
local version="${var_version:-}"
|
||||
local -a repo_urls=()
|
||||
local repo_label=""
|
||||
|
||||
case "$os" in
|
||||
debian)
|
||||
repo_label="Debian"
|
||||
repo_urls=(
|
||||
"http://deb.debian.org/debian/dists/${version:-bookworm}/Release"
|
||||
"http://security.debian.org/debian-security/dists/${version:-bookworm}-security/Release"
|
||||
)
|
||||
;;
|
||||
ubuntu)
|
||||
repo_label="Ubuntu"
|
||||
repo_urls=(
|
||||
"http://archive.ubuntu.com/ubuntu/dists/${version:-jammy}/Release"
|
||||
"http://security.ubuntu.com/ubuntu/dists/${version:-jammy}-security/Release"
|
||||
)
|
||||
;;
|
||||
alpine)
|
||||
repo_label="Alpine"
|
||||
# Alpine versions use x.y format (e.g. 3.20)
|
||||
local alpine_branch="v${version:-3.20}"
|
||||
repo_urls=(
|
||||
"https://dl-cdn.alpinelinux.org/alpine/${alpine_branch}/main/x86_64/APKINDEX.tar.gz"
|
||||
)
|
||||
;;
|
||||
*)
|
||||
preflight_pass "Package repo check skipped (OS: ${os})"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
local all_ok=true
|
||||
local failed_urls=()
|
||||
|
||||
for url in "${repo_urls[@]}"; do
|
||||
local http_code
|
||||
http_code=$(curl -sS -o /dev/null -w "%{http_code}" -m 8 --head "$url" 2>/dev/null) || http_code="000"
|
||||
|
||||
# Accept 200, 3xx redirects, and 405 (HEAD not allowed but server is up)
|
||||
if [[ ! "$http_code" =~ ^(2[0-9]{2}|3[0-9]{2}|405)$ ]]; then
|
||||
all_ok=false
|
||||
# Extract hostname for readable output
|
||||
local host
|
||||
host=$(echo "$url" | sed -E 's|https?://([^/]+).*|\1|')
|
||||
failed_urls+=("${host} (HTTP ${http_code})")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$all_ok" == true ]]; then
|
||||
preflight_pass "${repo_label} package repositories reachable"
|
||||
else
|
||||
local fail_summary
|
||||
fail_summary=$(printf '%s, ' "${failed_urls[@]}")
|
||||
fail_summary="${fail_summary%, }"
|
||||
preflight_warn "${repo_label} package repository not fully reachable: ${fail_summary}"
|
||||
echo -e " ${TAB}${INFO} Container may fail during ${GN}apt-get update${CL} / ${GN}apk update${CL}"
|
||||
echo -e " ${TAB}${INFO} Check firewall rules, proxy settings, or DNS from this host"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# run_preflight()
|
||||
#
|
||||
# - Executes all preflight checks and collects results
|
||||
# - Displays a summary with pass/fail/warn counts
|
||||
# - On failure: reports to telemetry with "aborted" status and exits cleanly
|
||||
# - On success: brief pause (2s) then returns (caller shows next screen)
|
||||
# - Called from install_script() after header_info()
|
||||
# ------------------------------------------------------------------------------
|
||||
run_preflight() {
|
||||
# Reset counters
|
||||
PREFLIGHT_PASSED=0
|
||||
PREFLIGHT_FAILED=0
|
||||
PREFLIGHT_WARNINGS=0
|
||||
PREFLIGHT_FAILURES=()
|
||||
PREFLIGHT_EXIT_CODE=0
|
||||
|
||||
echo -e "${INFO}${BOLD}${DGN} Running pre-flight checks...${CL}"
|
||||
echo ""
|
||||
|
||||
# --- Kernel checks ---
|
||||
preflight_maxkeys
|
||||
|
||||
# --- Storage checks ---
|
||||
preflight_storage_rootdir
|
||||
preflight_storage_vztmpl
|
||||
preflight_storage_space
|
||||
|
||||
# --- Network checks ---
|
||||
preflight_network_bridge
|
||||
preflight_dns_resolution
|
||||
|
||||
# --- Repository checks ---
|
||||
preflight_repo_access
|
||||
|
||||
# --- Proxmox/Cluster checks ---
|
||||
preflight_cluster_quorum
|
||||
preflight_lxc_stack
|
||||
preflight_container_id
|
||||
|
||||
# --- Template availability ---
|
||||
preflight_template_connectivity
|
||||
preflight_template_available
|
||||
|
||||
# --- Package repository checks ---
|
||||
preflight_package_repos
|
||||
|
||||
echo ""
|
||||
|
||||
# --- Summary ---
|
||||
if [[ "$PREFLIGHT_FAILED" -gt 0 ]]; then
|
||||
echo -e "${CROSS}${BOLD}${RD} Pre-flight failed: ${PREFLIGHT_FAILED} error(s), ${PREFLIGHT_WARNINGS} warning(s), ${PREFLIGHT_PASSED} passed${CL}"
|
||||
echo ""
|
||||
|
||||
echo -e "${INFO}${BOLD}${DGN} Failure details:${CL}"
|
||||
for failure in "${PREFLIGHT_FAILURES[@]}"; do
|
||||
local code="${failure%%|*}"
|
||||
local msg="${failure#*|}"
|
||||
echo -e " ${CROSS} [Exit ${code}] ${msg}"
|
||||
done
|
||||
echo ""
|
||||
echo -e "${INFO} Please resolve the above issues before creating a container."
|
||||
echo -e "${INFO} Documentation: ${BL}https://community-scripts.github.io/ProxmoxVE/${CL}"
|
||||
|
||||
# Report to telemetry (if consent was given)
|
||||
post_preflight_to_api
|
||||
|
||||
exit "$PREFLIGHT_EXIT_CODE"
|
||||
fi
|
||||
|
||||
# Success — brief pause so user can see results, then clear for next screen
|
||||
if [[ "$PREFLIGHT_WARNINGS" -gt 0 ]]; then
|
||||
echo -e "${CM}${BOLD}${GN} Pre-flight passed with ${PREFLIGHT_WARNINGS} warning(s) (${PREFLIGHT_PASSED} checks passed)${CL}"
|
||||
else
|
||||
echo -e "${CM}${BOLD}${GN} All pre-flight checks passed (${PREFLIGHT_PASSED}/${PREFLIGHT_PASSED})${CL}"
|
||||
fi
|
||||
sleep 2
|
||||
# Silent success - only show errors if they exist
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
@@ -2417,7 +1851,7 @@ advanced_settings() {
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# STEP 2: Root Password
|
||||
# ═════════════════════════════<EFBFBD><EFBFBD><EFBFBD>══════════════════════════════════════════<EFBFBD><EFBFBD><EFBFBD>══
|
||||
# ════════════════════════════════════════════════════════════════════════<EFBFBD><EFBFBD><EFBFBD>══
|
||||
2)
|
||||
if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "ROOT PASSWORD" \
|
||||
@@ -3487,7 +2921,7 @@ echo_default() {
|
||||
# install_script()
|
||||
#
|
||||
# - Main entrypoint for installation mode
|
||||
# - Runs safety checks (pve_check, root_check, diagnostics_check, run_preflight)
|
||||
# - Runs safety checks (pve_check, root_check, maxkeys_check, diagnostics_check)
|
||||
# - Builds interactive menu (Default, Verbose, Advanced, My Defaults, App Defaults, Diagnostics, Storage, Exit)
|
||||
# - Applies chosen settings and triggers container build
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -3497,6 +2931,7 @@ install_script() {
|
||||
root_check
|
||||
arch_check
|
||||
ssh_check
|
||||
maxkeys_check
|
||||
diagnostics_check
|
||||
|
||||
if systemctl is-active -q ping-instances.service; then
|
||||
@@ -3516,9 +2951,8 @@ install_script() {
|
||||
fi
|
||||
[[ "${timezone:-}" == Etc/* ]] && timezone="host" # pct doesn't accept Etc/* zones
|
||||
|
||||
# Show APP Header + run preflight checks
|
||||
# Show APP Header
|
||||
header_info
|
||||
run_preflight
|
||||
|
||||
# --- Support CLI argument as direct preset (default, advanced, …) ---
|
||||
CHOICE="${mode:-${1:-}}"
|
||||
|
||||
Reference in New Issue
Block a user