Compare commits

..

1 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
da2641e369 fix(emqx): increase disk to 6GB and add optional MQ disable prompt
EMQX 6.1+ preallocates significant disk space for the MQ feature,
causing high CPU/disk usage on small containers (emqx/emqx#16649).

- Increase default disk from 4GB to 6GB
- Add read -rp prompt during install to optionally disable MQ feature
  via mq.enable=false in emqx.conf (reduces disk/CPU overhead)
- Setting is in install script (not CT script) per reviewer feedback

Co-authored-by: sim-san <sim-san@users.noreply.github.com>
2026-02-12 17:32:53 +01:00
38 changed files with 273 additions and 885 deletions

View File

@@ -401,74 +401,26 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-02-13
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- OpenWebUI: pin numba constraint [@MickLesk](https://github.com/MickLesk) ([#11874](https://github.com/community-scripts/ProxmoxVE/pull/11874))
- Planka: add migrate step to update function [@ZimmermannLeon](https://github.com/ZimmermannLeon) ([#11877](https://github.com/community-scripts/ProxmoxVE/pull/11877))
- Pangolin: switch sqlite-specific back to generic [@MickLesk](https://github.com/MickLesk) ([#11868](https://github.com/community-scripts/ProxmoxVE/pull/11868))
- [Hotfix] Jotty: Copy contents of config backup into /opt/jotty/config [@vhsdream](https://github.com/vhsdream) ([#11864](https://github.com/community-scripts/ProxmoxVE/pull/11864))
- #### 🔧 Refactor
- chore(donetick): add config entry for v0.1.73 [@tomfrenzel](https://github.com/tomfrenzel) ([#11872](https://github.com/community-scripts/ProxmoxVE/pull/11872))
- Refactor: Radicale [@vhsdream](https://github.com/vhsdream) ([#11850](https://github.com/community-scripts/ProxmoxVE/pull/11850))
### 💾 Core
- #### 🔧 Refactor
- core: retry reporting with fallback payloads [@MickLesk](https://github.com/MickLesk) ([#11885](https://github.com/community-scripts/ProxmoxVE/pull/11885))
### 📡 API
- #### ✨ New Features
- error-handler: Implement json_escape and enhance error handling [@MickLesk](https://github.com/MickLesk) ([#11875](https://github.com/community-scripts/ProxmoxVE/pull/11875))
### 🌐 Website
- #### 📝 Script Information
- SQLServer-2025: add PVE9/Kernel 6.x incompatibility warning [@MickLesk](https://github.com/MickLesk) ([#11829](https://github.com/community-scripts/ProxmoxVE/pull/11829))
## 2026-02-12
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- EMQX: increase disk to 6GB and add optional MQ disable prompt [@MickLesk](https://github.com/MickLesk) ([#11844](https://github.com/community-scripts/ProxmoxVE/pull/11844))
- Increased the Grafana container default disk size. [@shtefko](https://github.com/shtefko) ([#11840](https://github.com/community-scripts/ProxmoxVE/pull/11840))
- Pangolin: Update database generation command in install script [@tremor021](https://github.com/tremor021) ([#11825](https://github.com/community-scripts/ProxmoxVE/pull/11825))
- Deluge: add python3-setuptools as dep [@MickLesk](https://github.com/MickLesk) ([#11833](https://github.com/community-scripts/ProxmoxVE/pull/11833))
- Dispatcharr: migrate to uv sync [@MickLesk](https://github.com/MickLesk) ([#11831](https://github.com/community-scripts/ProxmoxVE/pull/11831))
- Pangolin: Update database generation command in install script [@tremor021](https://github.com/tremor021) ([#11825](https://github.com/community-scripts/ProxmoxVE/pull/11825))
- #### ✨ New Features
- Archlinux-VM: fix LVM/LVM-thin storage and improve error reporting | VM's add correct exit_code for analytics [@MickLesk](https://github.com/MickLesk) ([#11842](https://github.com/community-scripts/ProxmoxVE/pull/11842))
- Debian13-VM: Optimize First Boot & add noCloud/Cloud Selection [@MickLesk](https://github.com/MickLesk) ([#11810](https://github.com/community-scripts/ProxmoxVE/pull/11810))
### 💾 Core
- #### ✨ New Features
- tools.func: auto-detect binary vs armored GPG keys in setup_deb822_repo [@MickLesk](https://github.com/MickLesk) ([#11841](https://github.com/community-scripts/ProxmoxVE/pull/11841))
- core: remove old Go API and extend misc/api.func with new backend [@MickLesk](https://github.com/MickLesk) ([#11822](https://github.com/community-scripts/ProxmoxVE/pull/11822))
- #### 🔧 Refactor
- error_handler: prevent stuck 'installing' status [@MickLesk](https://github.com/MickLesk) ([#11845](https://github.com/community-scripts/ProxmoxVE/pull/11845))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Tailscale: fix DNS check and keyrings directory issues [@MickLesk](https://github.com/MickLesk) ([#11837](https://github.com/community-scripts/ProxmoxVE/pull/11837))
## 2026-02-11
### 🆕 New Scripts

View File

@@ -9,7 +9,7 @@ APP="Alpine-Grafana"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-2}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"

View File

@@ -42,8 +42,7 @@ function update_script() {
msg_info "Restoring Configurations"
mv /opt/selfhosted.yaml /opt/donetick/config
grep -q 'http://localhost"$' /opt/donetick/config/selfhosted.yaml || sed -i '/https:\/\/localhost"$/a\ - "http://localhost"' /opt/donetick/config/selfhosted.yaml
grep -q 'capacitor://localhost' /opt/donetick/config/selfhosted.yaml || sed -i '/http:\/\/localhost"$/a\ - "capacitor://localhost"' /opt/donetick/config/selfhosted.yaml
sed -i '/capacitor:\/\/localhost/d' /opt/donetick/config/selfhosted.yaml
mv /opt/donetick.db /opt/donetick
msg_ok "Restored Configurations"

View File

@@ -9,7 +9,7 @@ APP="Grafana"
var_tags="${var_tags:-monitoring;visualization}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"

View File

@@ -46,7 +46,7 @@ function update_script() {
msg_info "Restoring configuration & data"
mv /opt/app.env /opt/jotty/.env
[[ -d /opt/data ]] && mv /opt/data /opt/jotty/data
[[ -d /opt/jotty/config ]] && cp -a /opt/config/* /opt/jotty/config && rm -rf /opt/config
[[ -d /opt/jotty/config ]] && mv /opt/config/* /opt/jotty/config
msg_ok "Restored configuration & data"
msg_info "Starting Service"

View File

@@ -44,7 +44,7 @@ function update_script() {
msg_info "Installing uv-based Open-WebUI"
PYTHON_VERSION="3.12" setup_uv
$STD uv tool install --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
$STD uv tool install --python 3.12 open-webui[all]
msg_ok "Installed uv-based Open-WebUI"
msg_info "Restoring data"
@@ -126,7 +126,7 @@ EOF
msg_info "Updating Open WebUI via uv"
PYTHON_VERSION="3.12" setup_uv
$STD uv tool install --force --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
$STD uv tool upgrade --python 3.12 open-webui[all]
systemctl restart open-webui
msg_ok "Updated Open WebUI"
msg_ok "Updated successfully!"

View File

@@ -51,7 +51,7 @@ function update_script() {
$STD npm run db:generate
$STD npm run build
$STD npm run build:cli
$STD npm run db:push
$STD npm run db:sqlite:push
cp -R .next/standalone ./
chmod +x ./dist/cli.mjs
cp server/db/names.json ./dist/names.json

View File

@@ -61,12 +61,6 @@ function update_script() {
rm -rf "$BK"
msg_ok "Restored data"
msg_ok "Migrate Database"
cd /opt/planka
$STD npm run db:upgrade
$STD npm run db:migrate
msg_ok "Migrated Database"
msg_info "Starting Service"
systemctl start planka
msg_ok "Started Service"

View File

@@ -28,55 +28,16 @@ function update_script() {
exit
fi
if check_for_gh_release "Radicale" "Kozea/Radicale"; then
msg_info "Stopping service"
systemctl stop radicale
msg_ok "Stopped service"
msg_info "Updating ${APP}"
$STD python3 -m venv /opt/radicale
source /opt/radicale/bin/activate
$STD python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
msg_ok "Updated ${APP}"
msg_info "Backing up users file"
cp /opt/radicale/users /opt/radicale_users_backup
msg_ok "Backed up users file"
PYTHON_VERSION="3.13" setup_uv
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Radicale" "Kozea/Radicale" "tarball" "latest" "/opt/radicale"
msg_info "Restoring users file"
rm -f /opt/radicale/users
mv /opt/radicale_users_backup /opt/radicale/users
msg_ok "Restored users file"
if grep -q 'start.sh' /etc/systemd/system/radicale.service; then
sed -i -e '/^Description/i[Unit]' \
-e '\|^ExecStart|iWorkingDirectory=/opt/radicale' \
-e 's|^ExecStart=.*|ExecStart=/usr/local/bin/uv run -m radicale --config /etc/radicale/config|' /etc/systemd/system/radicale.service
systemctl daemon-reload
fi
if [[ ! -f /etc/radicale/config ]]; then
msg_info "Migrating to config file (/etc/radicale/config)"
mkdir -p /etc/radicale
cat <<EOF >/etc/radicale/config
[server]
hosts = 0.0.0.0:5232
[auth]
type = htpasswd
htpasswd_filename = /opt/radicale/users
htpasswd_encryption = sha512
[storage]
type = multifilesystem
filesystem_folder = /var/lib/radicale/collections
[web]
type = internal
EOF
msg_ok "Migrated to config (/etc/radicale/config)"
fi
msg_info "Starting service"
systemctl start radicale
msg_ok "Started service"
msg_ok "Updated Successfully!"
fi
msg_info "Starting Service"
systemctl enable -q --now radicale
msg_ok "Started Service"
msg_ok "Updated successfully!"
exit
}

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-13T12:11:36Z",
"generated": "2026-02-12T12:15:15Z",
"versions": [
{
"slug": "2fauth",
@@ -193,9 +193,9 @@
{
"slug": "cleanuparr",
"repo": "Cleanuparr/Cleanuparr",
"version": "v2.6.1",
"version": "v2.5.1",
"pinned": false,
"date": "2026-02-13T10:00:19Z"
"date": "2026-01-11T00:46:17Z"
},
{
"slug": "cloudreve",
@@ -298,9 +298,9 @@
{
"slug": "donetick",
"repo": "donetick/donetick",
"version": "v0.1.73",
"version": "v0.1.71",
"pinned": false,
"date": "2026-02-12T23:42:30Z"
"date": "2026-02-11T06:01:13Z"
},
{
"slug": "drawio",
@@ -403,9 +403,9 @@
{
"slug": "ghostfolio",
"repo": "ghostfolio/ghostfolio",
"version": "2.238.0",
"version": "2.237.0",
"pinned": false,
"date": "2026-02-12T18:28:55Z"
"date": "2026-02-08T13:59:53Z"
},
{
"slug": "gitea",
@@ -543,9 +543,9 @@
{
"slug": "huntarr",
"repo": "plexguide/Huntarr.io",
"version": "9.2.4.1",
"version": "9.2.4",
"pinned": false,
"date": "2026-02-12T22:17:47Z"
"date": "2026-02-12T08:31:23Z"
},
{
"slug": "immich-public-proxy",
@@ -571,16 +571,16 @@
{
"slug": "invoiceninja",
"repo": "invoiceninja/invoiceninja",
"version": "v5.12.59",
"version": "v5.12.57",
"pinned": false,
"date": "2026-02-13T02:26:13Z"
"date": "2026-02-11T23:08:56Z"
},
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1103",
"version": "v0.24.1098",
"pinned": false,
"date": "2026-02-13T05:53:23Z"
"date": "2026-02-12T05:56:25Z"
},
{
"slug": "jellystat",
@@ -823,9 +823,9 @@
{
"slug": "metube",
"repo": "alexta69/metube",
"version": "2026.02.12",
"version": "2026.02.08",
"pinned": false,
"date": "2026-02-12T21:05:49Z"
"date": "2026-02-08T17:01:37Z"
},
{
"slug": "miniflux",
@@ -998,9 +998,9 @@
{
"slug": "pangolin",
"repo": "fosrl/pangolin",
"version": "1.15.4",
"version": "1.15.3",
"pinned": false,
"date": "2026-02-13T00:54:02Z"
"date": "2026-02-12T06:10:19Z"
},
{
"slug": "paperless-ai",
@@ -1026,9 +1026,9 @@
{
"slug": "patchmon",
"repo": "PatchMon/PatchMon",
"version": "v1.4.0",
"version": "v1.3.7",
"pinned": false,
"date": "2026-02-13T10:39:03Z"
"date": "2025-12-25T11:08:14Z"
},
{
"slug": "paymenter",
@@ -1219,13 +1219,6 @@
"pinned": false,
"date": "2025-11-16T22:39:01Z"
},
{
"slug": "radicale",
"repo": "Kozea/Radicale",
"version": "v3.6.0",
"pinned": false,
"date": "2026-01-10T06:56:46Z"
},
{
"slug": "rclone",
"repo": "rclone/rclone",
@@ -1299,9 +1292,9 @@
{
"slug": "scraparr",
"repo": "thecfu/scraparr",
"version": "v3.0.3",
"version": "v3.0.1",
"pinned": false,
"date": "2026-02-12T14:20:56Z"
"date": "2026-02-11T17:42:23Z"
},
{
"slug": "seelf",
@@ -1439,9 +1432,9 @@
{
"slug": "termix",
"repo": "Termix-SSH/Termix",
"version": "release-1.11.1-tag",
"version": "release-1.11.0-tag",
"pinned": false,
"date": "2026-02-13T04:49:16Z"
"date": "2026-01-25T02:09:52Z"
},
{
"slug": "the-lounge",
@@ -1467,9 +1460,9 @@
{
"slug": "tianji",
"repo": "msgbyte/tianji",
"version": "v1.31.12",
"version": "v1.31.10",
"pinned": false,
"date": "2026-02-12T19:06:14Z"
"date": "2026-02-04T17:21:04Z"
},
{
"slug": "traccar",
@@ -1558,9 +1551,9 @@
{
"slug": "upsnap",
"repo": "seriousm4x/UpSnap",
"version": "5.2.8",
"version": "5.2.7",
"pinned": false,
"date": "2026-02-13T00:02:37Z"
"date": "2026-01-07T23:48:00Z"
},
{
"slug": "uptimekuma",

View File

@@ -21,7 +21,7 @@
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 4,
"hdd": 2,
"os": "debian",
"version": "13"
}
@@ -32,7 +32,7 @@
"resources": {
"cpu": 1,
"ram": 256,
"hdd": 2,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}

View File

@@ -12,7 +12,7 @@
"documentation": "https://radicale.org/master.html#documentation-1",
"website": "https://radicale.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/radicale.webp",
"config_path": "/etc/radicale/config",
"config_path": "/etc/radicale/config or ~/.config/radicale/config",
"description": "Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts)",
"install_methods": [
{

View File

@@ -32,10 +32,6 @@
"password": null
},
"notes": [
{
"text": "SQL Server (2025) SQLPAL is incompatible with Proxmox VE 9 (Kernel 6.12+) in LXC containers. Use a VM instead or the SQL-Server 2022 LXC.",
"type": "warning"
},
{
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
"type": "info"

View File

@@ -24,7 +24,7 @@ setup_hwaccel
PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Open WebUI"
$STD uv tool install --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
$STD uv tool install --python 3.12 open-webui[all]
msg_ok "Installed Open WebUI"
read -r -p "${TAB3}Would you like to add Ollama? <y/N> " prompt

View File

@@ -36,7 +36,7 @@ $STD npm ci
$STD npm run set:sqlite
$STD npm run set:oss
rm -rf server/private
$STD npm run db:generate
$STD npm run db:sqlite:generate
$STD npm run build
$STD npm run build:cli
cp -R .next/standalone ./
@@ -178,7 +178,7 @@ http:
servers:
- url: "http://$LOCAL_IP:3000"
EOF
$STD npm run db:push
$STD npm run db:sqlite:push
. /etc/os-release
if [ "$VERSION_CODENAME" = "trixie" ]; then

View File

@@ -14,51 +14,42 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y apache2-utils
$STD apt install -y \
apache2-utils \
python3-pip \
python3-venv
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "Radicale" "Kozea/Radicale" "tarball" "latest" "/opt/radicale"
msg_info "Setting up Radicale"
cd /opt/radicale
python3 -m venv /opt/radicale
source /opt/radicale/bin/activate
$STD python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
RNDPASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD htpasswd -c -b -5 /opt/radicale/users admin "$RNDPASS"
$STD htpasswd -c -b -5 /opt/radicale/users admin $RNDPASS
{
echo "Radicale Credentials"
echo "Admin User: admin"
echo "Admin Password: $RNDPASS"
} >>~/radicale.creds
msg_ok "Done setting up Radicale"
mkdir -p /etc/radicale
cat <<EOF >/etc/radicale/config
[server]
hosts = 0.0.0.0:5232
msg_info "Setup Service"
[auth]
type = htpasswd
htpasswd_filename = /opt/radicale/users
htpasswd_encryption = sha512
[storage]
type = multifilesystem
filesystem_folder = /var/lib/radicale/collections
[web]
type = internal
cat <<EOF >/opt/radicale/start.sh
#!/usr/bin/env bash
source /opt/radicale/bin/activate
python3 -m radicale --storage-filesystem-folder=/var/lib/radicale/collections --hosts 0.0.0.0:5232 --auth-type htpasswd --auth-htpasswd-filename /opt/radicale/users --auth-htpasswd-encryption sha512
EOF
msg_ok "Set up Radicale"
msg_info "Creating Service"
chmod +x /opt/radicale/start.sh
cat <<EOF >/etc/systemd/system/radicale.service
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target
[Service]
WorkingDirectory=/opt/radicale
ExecStart=/usr/local/bin/uv run -m radicale --config /etc/radicale/config
ExecStart=/opt/radicale/start.sh
Restart=on-failure
# User=radicale
# Deny other users access to the calendar data

View File

@@ -15,18 +15,16 @@ 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"
setup_deb822_repo \
"unifi" \
"https://dl.ui.com/unifi/unifi-repo.gpg" \
"https://www.ui.com/downloads/unifi/debian" \
"stable" \
"ubiquiti" \
"amd64"
JAVA_VERSION="21" setup_java
if lscpu | grep -q 'avx'; then

View File

@@ -153,7 +153,7 @@ explain_exit_code() {
126) echo "Command invoked cannot execute (permission problem?)" ;;
127) echo "Command not found" ;;
128) echo "Invalid argument to exit" ;;
130) echo "Aborted by user (SIGINT)" ;;
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
137) echo "Killed (SIGKILL / Out of memory?)" ;;
139) echo "Segmentation fault (core dumped)" ;;
@@ -233,60 +233,6 @@ explain_exit_code() {
esac
}
# ------------------------------------------------------------------------------
# json_escape()
#
# - Escapes a string for safe JSON embedding
# - Handles backslashes, quotes, newlines, tabs, and carriage returns
# ------------------------------------------------------------------------------
json_escape() {
local s="$1"
s=${s//\\/\\\\}
s=${s//"/\\"/}
s=${s//$'\n'/\\n}
s=${s//$'\r'/}
s=${s//$'\t'/\\t}
echo "$s"
}
# ------------------------------------------------------------------------------
# get_error_text()
#
# - Returns last 20 lines of the active log (INSTALL_LOG or BUILD_LOG)
# - Falls back to combined log or BUILD_LOG if primary is not accessible
# - Handles container paths that don't exist on the host
# ------------------------------------------------------------------------------
get_error_text() {
local logfile=""
if declare -f get_active_logfile >/dev/null 2>&1; then
logfile=$(get_active_logfile)
elif [[ -n "${INSTALL_LOG:-}" ]]; then
logfile="$INSTALL_LOG"
elif [[ -n "${BUILD_LOG:-}" ]]; then
logfile="$BUILD_LOG"
fi
# If logfile is inside container (e.g. /root/.install-*), try the host copy
if [[ -n "$logfile" && ! -s "$logfile" ]]; then
# Try combined log: /tmp/<app>-<CTID>-<SESSION_ID>.log
if [[ -n "${CTID:-}" && -n "${SESSION_ID:-}" ]]; then
local combined_log="/tmp/${NSAPP:-lxc}-${CTID}-${SESSION_ID}.log"
if [[ -s "$combined_log" ]]; then
logfile="$combined_log"
fi
fi
fi
# Also try BUILD_LOG as fallback if primary log is empty/missing
if [[ -z "$logfile" || ! -s "$logfile" ]] && [[ -n "${BUILD_LOG:-}" && -s "${BUILD_LOG}" ]]; then
logfile="$BUILD_LOG"
fi
if [[ -n "$logfile" && -s "$logfile" ]]; then
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//'
fi
}
# ==============================================================================
# SECTION 2: TELEMETRY FUNCTIONS
# ==============================================================================
@@ -439,8 +385,7 @@ post_to_api() {
detect_gpu
fi
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_model="${GPU_MODEL:-}"
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Detect CPU if not already set
@@ -448,8 +393,7 @@ post_to_api() {
detect_cpu
fi
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
local cpu_model="${CPU_MODEL:-}"
# Detect RAM if not already set
if [[ -z "${RAM_SPEED:-}" ]]; then
@@ -540,8 +484,7 @@ post_to_api_vm() {
detect_gpu
fi
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_model="${GPU_MODEL:-}"
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Detect CPU if not already set
@@ -549,8 +492,7 @@ post_to_api_vm() {
detect_cpu
fi
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
local cpu_model="${CPU_MODEL:-}"
# Detect RAM if not already set
if [[ -z "${RAM_SPEED:-}" ]]; then
@@ -613,12 +555,9 @@ post_update_to_api() {
# Silent fail - telemetry should never break scripts
command -v curl &>/dev/null || return 0
# Support "force" mode (3rd arg) to bypass duplicate check for retries after cleanup
local force="${3:-}"
# Prevent duplicate submissions
POST_UPDATE_DONE=${POST_UPDATE_DONE:-false}
if [[ "$POST_UPDATE_DONE" == "true" && "$force" != "force" ]]; then
return 0
fi
[[ "$POST_UPDATE_DONE" == "true" ]] && return 0
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
@@ -629,14 +568,12 @@ post_update_to_api() {
# Get GPU info (if detected)
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_model="${GPU_MODEL:-}"
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Get CPU info (if detected)
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
local cpu_model="${CPU_MODEL:-}"
# Get RAM info (if detected)
local ram_speed="${RAM_SPEED:-}"
@@ -658,21 +595,13 @@ post_update_to_api() {
esac
# For failed/unknown status, resolve exit code and error description
local short_error=""
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
exit_code="$raw_exit_code"
else
exit_code=1
fi
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
error=$(explain_exit_code "$exit_code")
error_category=$(categorize_error "$exit_code")
[[ -z "$error" ]] && error="Unknown error"
fi
@@ -689,9 +618,8 @@ post_update_to_api() {
pve_version=$(pveversion 2>/dev/null | awk -F'[/ ]' '{print $2}') || true
fi
local http_code=""
# ── Attempt 1: Full payload with complete error text ──
# Full payload including all fields - allows record creation if initial call failed
# The Go service will find the record by random_id and PATCH, or create if not found
local JSON_PAYLOAD
JSON_PAYLOAD=$(
cat <<EOF
@@ -723,80 +651,11 @@ post_update_to_api() {
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# ── Attempt 2: Short error text (no full log) ──
sleep 1
local RETRY_PAYLOAD
RETRY_PAYLOAD=$(
cat <<EOF
{
"random_id": "${RANDOM_UUID}",
"type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}",
"ct_type": ${CT_TYPE:-1},
"disk_size": ${DISK_SIZE:-0},
"core_count": ${CORE_COUNT:-0},
"ram_size": ${RAM_SIZE:-0},
"os_type": "${var_os:-}",
"os_version": "${var_version:-}",
"pve_version": "${pve_version}",
"method": "${METHOD:-default}",
"exit_code": ${exit_code},
"error": "${short_error}",
"error_category": "${error_category}",
"install_duration": ${duration},
"cpu_vendor": "${cpu_vendor}",
"cpu_model": "${cpu_model}",
"gpu_vendor": "${gpu_vendor}",
"gpu_model": "${gpu_model}",
"gpu_passthrough": "${gpu_passthrough}",
"ram_speed": "${ram_speed}",
"repo_source": "${REPO_SOURCE}"
}
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$RETRY_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# ── Attempt 3: Minimal payload (bare minimum to set status) ──
sleep 2
local MINIMAL_PAYLOAD
MINIMAL_PAYLOAD=$(
cat <<EOF
{
"random_id": "${RANDOM_UUID}",
"type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}",
"exit_code": ${exit_code},
"error": "${short_error}",
"error_category": "${error_category}",
"install_duration": ${duration}
}
EOF
)
# Fire-and-forget: never block, never fail
curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$MINIMAL_PAYLOAD" -o /dev/null 2>/dev/null || true
-d "$JSON_PAYLOAD" -o /dev/null 2>&1 || true
# Tried 3 times - mark as done regardless to prevent infinite loops
POST_UPDATE_DONE=true
}
@@ -832,9 +691,6 @@ categorize_error() {
# Configuration errors
203 | 204 | 205 | 206 | 207 | 208) echo "config" ;;
# Aborted by user
130) echo "aborted" ;;
# Resource errors (OOM, etc)
137 | 134) echo "resource" ;;
@@ -899,13 +755,7 @@ post_tool_to_api() {
if [[ "$status" == "failed" ]]; then
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
error=$(explain_exit_code "$exit_code")
error_category=$(categorize_error "$exit_code")
fi
@@ -966,13 +816,7 @@ post_addon_to_api() {
if [[ "$status" == "failed" ]]; then
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
error=$(explain_exit_code "$exit_code")
error_category=$(categorize_error "$exit_code")
fi
@@ -1065,13 +909,7 @@ post_update_to_api_extended() {
else
exit_code=1
fi
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
error=$(explain_exit_code "$exit_code")
error_category=$(categorize_error "$exit_code")
[[ -z "$error" ]] && error="Unknown error"
fi

View File

@@ -38,16 +38,15 @@
# - Captures app-declared resource defaults (CPU, RAM, Disk)
# ------------------------------------------------------------------------------
variables() {
NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files
BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log
combined_log="/tmp/install-${SESSION_ID}-combined.log" # Combined log (build + install) for failed installations
NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase
DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files
BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log
CTTYPE="${CTTYPE:-${CT_TYPE:-1}}"
# Parse dev_mode early
@@ -218,7 +217,7 @@ update_motd_ip() {
local current_os="$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"') - Version: $(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')"
local current_hostname="$(hostname)"
local current_ip="$(hostname -I | awk '{print $1}')"
# Update only if values actually changed
if ! grep -q "OS:.*$current_os" "$PROFILE_FILE" 2>/dev/null; then
sed -i "s|OS:.*|OS: \${GN}$current_os\${CL}\\\"|" "$PROFILE_FILE"
@@ -386,7 +385,7 @@ validate_hostname() {
# Split by dots and validate each label
local IFS='.'
read -ra labels <<<"$hostname"
read -ra labels <<< "$hostname"
for label in "${labels[@]}"; do
# Each label: 1-63 chars, alphanumeric, hyphens allowed (not at start/end)
if [[ -z "$label" ]] || [[ ${#label} -gt 63 ]]; then
@@ -490,7 +489,7 @@ validate_ipv6_address() {
# Check that no segment exceeds 4 hex chars
local IFS=':'
local -a segments
read -ra segments <<<"$addr"
read -ra segments <<< "$addr"
for seg in "${segments[@]}"; do
if [[ ${#seg} -gt 4 ]]; then
return 1
@@ -540,14 +539,14 @@ validate_gateway_in_subnet() {
# Convert IPs to integers
local IFS='.'
read -r i1 i2 i3 i4 <<<"$ip"
read -r g1 g2 g3 g4 <<<"$gateway"
read -r i1 i2 i3 i4 <<< "$ip"
read -r g1 g2 g3 g4 <<< "$gateway"
local ip_int=$(((i1 << 24) + (i2 << 16) + (i3 << 8) + i4))
local gw_int=$(((g1 << 24) + (g2 << 16) + (g3 << 8) + g4))
local ip_int=$(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))
local gw_int=$(( (g1 << 24) + (g2 << 16) + (g3 << 8) + g4 ))
# Check if both are in same network
if (((ip_int & mask) != (gw_int & mask))); then
if (( (ip_int & mask) != (gw_int & mask) )); then
return 1
fi
@@ -1080,117 +1079,117 @@ load_vars_file() {
# Validate values before setting (skip empty values - they use defaults)
if [[ -n "$var_val" ]]; then
case "$var_key" in
var_mac)
if ! validate_mac_address "$var_val"; then
msg_warn "Invalid MAC address '$var_val' in $file, ignoring"
continue
fi
;;
var_vlan)
if ! validate_vlan_tag "$var_val"; then
msg_warn "Invalid VLAN tag '$var_val' in $file (must be 1-4094), ignoring"
continue
fi
;;
var_mtu)
if ! validate_mtu "$var_val"; then
msg_warn "Invalid MTU '$var_val' in $file (must be 576-65535), ignoring"
continue
fi
;;
var_tags)
if ! validate_tags "$var_val"; then
msg_warn "Invalid tags '$var_val' in $file (alphanumeric, -, _, ; only), ignoring"
continue
fi
;;
var_timezone)
if ! validate_timezone "$var_val"; then
msg_warn "Invalid timezone '$var_val' in $file, ignoring"
continue
fi
;;
var_brg)
if ! validate_bridge "$var_val"; then
msg_warn "Bridge '$var_val' not found in $file, ignoring"
continue
fi
;;
var_gateway)
if ! validate_gateway_ip "$var_val"; then
msg_warn "Invalid gateway IP '$var_val' in $file, ignoring"
continue
fi
;;
var_hostname)
if ! validate_hostname "$var_val"; then
msg_warn "Invalid hostname '$var_val' in $file, ignoring"
continue
fi
;;
var_cpu)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1 || var_val > 128)); then
msg_warn "Invalid CPU count '$var_val' in $file (must be 1-128), ignoring"
continue
fi
;;
var_ram)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 256)); then
msg_warn "Invalid RAM '$var_val' in $file (must be >= 256 MiB), ignoring"
continue
fi
;;
var_disk)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1)); then
msg_warn "Invalid disk size '$var_val' in $file (must be >= 1 GB), ignoring"
continue
fi
;;
var_unprivileged)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid unprivileged value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_nesting)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid nesting value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
# Warn about potential issues with systemd-based OS when nesting is disabled via vars file
if [[ "$var_val" == "0" && "${var_os:-debian}" != "alpine" ]]; then
msg_warn "Nesting disabled in $file - modern systemd-based distributions may require nesting for proper operation"
fi
;;
var_keyctl)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid keyctl value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_net)
# var_net can be: dhcp, static IP/CIDR, or IP range
if [[ "$var_val" != "dhcp" ]]; then
if is_ip_range "$var_val"; then
: # IP range is valid, will be resolved at runtime
elif ! validate_ip_address "$var_val"; then
msg_warn "Invalid network '$var_val' in $file (must be dhcp or IP/CIDR), ignoring"
var_mac)
if ! validate_mac_address "$var_val"; then
msg_warn "Invalid MAC address '$var_val' in $file, ignoring"
continue
fi
fi
;;
var_fuse | var_tun | var_gpu | var_ssh | var_verbose | var_protection)
if [[ "$var_val" != "yes" && "$var_val" != "no" ]]; then
msg_warn "Invalid boolean '$var_val' for $var_key in $file (must be yes/no), ignoring"
continue
fi
;;
var_ipv6_method)
if [[ "$var_val" != "auto" && "$var_val" != "dhcp" && "$var_val" != "static" && "$var_val" != "none" ]]; then
msg_warn "Invalid IPv6 method '$var_val' in $file (must be auto/dhcp/static/none), ignoring"
continue
fi
;;
;;
var_vlan)
if ! validate_vlan_tag "$var_val"; then
msg_warn "Invalid VLAN tag '$var_val' in $file (must be 1-4094), ignoring"
continue
fi
;;
var_mtu)
if ! validate_mtu "$var_val"; then
msg_warn "Invalid MTU '$var_val' in $file (must be 576-65535), ignoring"
continue
fi
;;
var_tags)
if ! validate_tags "$var_val"; then
msg_warn "Invalid tags '$var_val' in $file (alphanumeric, -, _, ; only), ignoring"
continue
fi
;;
var_timezone)
if ! validate_timezone "$var_val"; then
msg_warn "Invalid timezone '$var_val' in $file, ignoring"
continue
fi
;;
var_brg)
if ! validate_bridge "$var_val"; then
msg_warn "Bridge '$var_val' not found in $file, ignoring"
continue
fi
;;
var_gateway)
if ! validate_gateway_ip "$var_val"; then
msg_warn "Invalid gateway IP '$var_val' in $file, ignoring"
continue
fi
;;
var_hostname)
if ! validate_hostname "$var_val"; then
msg_warn "Invalid hostname '$var_val' in $file, ignoring"
continue
fi
;;
var_cpu)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1 || var_val > 128)); then
msg_warn "Invalid CPU count '$var_val' in $file (must be 1-128), ignoring"
continue
fi
;;
var_ram)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 256)); then
msg_warn "Invalid RAM '$var_val' in $file (must be >= 256 MiB), ignoring"
continue
fi
;;
var_disk)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1)); then
msg_warn "Invalid disk size '$var_val' in $file (must be >= 1 GB), ignoring"
continue
fi
;;
var_unprivileged)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid unprivileged value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_nesting)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid nesting value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
# Warn about potential issues with systemd-based OS when nesting is disabled via vars file
if [[ "$var_val" == "0" && "${var_os:-debian}" != "alpine" ]]; then
msg_warn "Nesting disabled in $file - modern systemd-based distributions may require nesting for proper operation"
fi
;;
var_keyctl)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid keyctl value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_net)
# var_net can be: dhcp, static IP/CIDR, or IP range
if [[ "$var_val" != "dhcp" ]]; then
if is_ip_range "$var_val"; then
: # IP range is valid, will be resolved at runtime
elif ! validate_ip_address "$var_val"; then
msg_warn "Invalid network '$var_val' in $file (must be dhcp or IP/CIDR), ignoring"
continue
fi
fi
;;
var_fuse|var_tun|var_gpu|var_ssh|var_verbose|var_protection)
if [[ "$var_val" != "yes" && "$var_val" != "no" ]]; then
msg_warn "Invalid boolean '$var_val' for $var_key in $file (must be yes/no), ignoring"
continue
fi
;;
var_ipv6_method)
if [[ "$var_val" != "auto" && "$var_val" != "dhcp" && "$var_val" != "static" && "$var_val" != "none" ]]; then
msg_warn "Invalid IPv6 method '$var_val' in $file (must be auto/dhcp/static/none), ignoring"
continue
fi
;;
esac
fi
@@ -2765,26 +2764,6 @@ Advanced:
[[ "$APT_CACHER" == "yes" ]] && echo -e "${INFO}${BOLD}${DGN}APT Cacher: ${BGN}$APT_CACHER_IP${CL}"
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}"
echo -e "${CREATING}${BOLD}${RD}Creating an LXC of ${APP} using the above advanced settings${CL}"
# Log settings to file
log_section "CONTAINER SETTINGS (ADVANCED) - ${APP}"
log_msg "Application: ${APP}"
log_msg "PVE Version: ${PVEVERSION} (Kernel: ${KERNEL_VERSION})"
log_msg "Operating System: $var_os ($var_version)"
log_msg "Container Type: $([ "$CT_TYPE" == "1" ] && echo "Unprivileged" || echo "Privileged")"
log_msg "Container ID: $CT_ID"
log_msg "Hostname: $HN"
log_msg "Disk Size: ${DISK_SIZE} GB"
log_msg "CPU Cores: $CORE_COUNT"
log_msg "RAM Size: ${RAM_SIZE} MiB"
log_msg "Bridge: $BRG"
log_msg "IPv4: $NET"
log_msg "IPv6: $IPV6_METHOD"
log_msg "FUSE Support: ${ENABLE_FUSE:-no}"
log_msg "Nesting: $([ "${ENABLE_NESTING:-1}" == "1" ] && echo "Enabled" || echo "Disabled")"
log_msg "GPU Passthrough: ${ENABLE_GPU:-no}"
log_msg "Verbose Mode: $VERBOSE"
log_msg "Session ID: ${SESSION_ID}"
}
# ==============================================================================
@@ -2892,7 +2871,6 @@ diagnostics_menu() {
# - Prints summary of default values (ID, OS, type, disk, RAM, CPU, etc.)
# - Uses icons and formatting for readability
# - Convert CT_TYPE to description
# - Also logs settings to log file for debugging
# ------------------------------------------------------------------------------
echo_default() {
CT_TYPE_DESC="Unprivileged"
@@ -2914,20 +2892,6 @@ echo_default() {
fi
echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}"
echo -e " "
# Log settings to file
log_section "CONTAINER SETTINGS - ${APP}"
log_msg "Application: ${APP}"
log_msg "PVE Version: ${PVEVERSION} (Kernel: ${KERNEL_VERSION})"
log_msg "Container ID: ${CT_ID}"
log_msg "Operating System: $var_os ($var_version)"
log_msg "Container Type: $CT_TYPE_DESC"
log_msg "Disk Size: ${DISK_SIZE} GB"
log_msg "CPU Cores: ${CORE_COUNT}"
log_msg "RAM Size: ${RAM_SIZE} MiB"
[[ -n "${var_gpu:-}" && "${var_gpu}" == "yes" ]] && log_msg "GPU Passthrough: Enabled"
[[ "$VERBOSE" == "yes" ]] && log_msg "Verbose Mode: Enabled"
log_msg "Session ID: ${SESSION_ID}"
}
# ------------------------------------------------------------------------------
@@ -4082,59 +4046,28 @@ EOF'
if [[ $install_exit_code -ne 0 ]]; then
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
# Copy install log from container BEFORE API call so get_error_text() can read it
# Report failure to telemetry API
post_update_to_api "failed" "$install_exit_code"
# Copy both logs from container before potential deletion
local build_log_copied=false
local install_log_copied=false
local combined_log="/tmp/${NSAPP:-lxc}-${CTID}-${SESSION_ID}.log"
if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then
# Create combined log with header
{
echo "================================================================================"
echo "COMBINED INSTALLATION LOG - ${APP:-LXC}"
echo "Container ID: ${CTID}"
echo "Session ID: ${SESSION_ID}"
echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')"
echo "================================================================================"
echo ""
} >"$combined_log"
# Append BUILD_LOG (host-side creation log) if it exists
# Copy BUILD_LOG (creation log) if it exists
if [[ -f "${BUILD_LOG}" ]]; then
{
echo "================================================================================"
echo "PHASE 1: CONTAINER CREATION (Host)"
echo "================================================================================"
cat "${BUILD_LOG}"
echo ""
} >>"$combined_log"
build_log_copied=true
cp "${BUILD_LOG}" "/tmp/create-lxc-${CTID}-${SESSION_ID}.log" 2>/dev/null && build_log_copied=true
fi
# Copy and append INSTALL_LOG from container
local temp_install_log="/tmp/.install-temp-${SESSION_ID}.log"
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
{
echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container)"
echo "================================================================================"
cat "$temp_install_log"
echo ""
} >>"$combined_log"
rm -f "$temp_install_log"
# Copy INSTALL_LOG from container
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "/tmp/install-lxc-${CTID}-${SESSION_ID}.log" 2>/dev/null; then
install_log_copied=true
# Point INSTALL_LOG to combined log so get_error_text() finds it
INSTALL_LOG="$combined_log"
fi
fi
# Report failure to telemetry API (now with log available on host)
post_update_to_api "failed" "$install_exit_code"
# Show combined log location
if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then
# Show available logs
echo ""
echo -e "${GN}${CL} Installation log: ${BL}${combined_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
@@ -4192,10 +4125,6 @@ EOF'
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
fi
# Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
post_update_to_api "failed" "$install_exit_code" "force"
exit $install_exit_code
fi
}
@@ -5199,61 +5128,6 @@ EOF
# SECTION 10: ERROR HANDLING & EXIT TRAPS
# ==============================================================================
# ------------------------------------------------------------------------------
# ensure_log_on_host()
#
# - Ensures INSTALL_LOG points to a readable file on the host
# - If INSTALL_LOG points to a container path (e.g. /root/.install-*),
# tries to pull it from the container and create a combined log
# - This allows get_error_text() to find actual error output for telemetry
# ------------------------------------------------------------------------------
ensure_log_on_host() {
# Already readable on host? Nothing to do.
[[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]] && return 0
# Try pulling from container and creating combined log
if [[ -n "${CTID:-}" && -n "${SESSION_ID:-}" ]] && command -v pct &>/dev/null; then
local combined_log="/tmp/${NSAPP:-lxc}-${CTID}-${SESSION_ID}.log"
if [[ ! -s "$combined_log" ]]; then
# Create combined log
{
echo "================================================================================"
echo "COMBINED INSTALLATION LOG - ${APP:-LXC}"
echo "Container ID: ${CTID}"
echo "Session ID: ${SESSION_ID}"
echo "Timestamp: $(date '+%Y-%m-%d %H:%M:%S')"
echo "================================================================================"
echo ""
} >"$combined_log" 2>/dev/null || return 0
# Append BUILD_LOG if it exists
if [[ -f "${BUILD_LOG:-}" ]]; then
{
echo "================================================================================"
echo "PHASE 1: CONTAINER CREATION (Host)"
echo "================================================================================"
cat "${BUILD_LOG}"
echo ""
} >>"$combined_log"
fi
# Pull INSTALL_LOG from container
local temp_log="/tmp/.install-temp-${SESSION_ID}.log"
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_log" 2>/dev/null; then
{
echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container)"
echo "================================================================================"
cat "$temp_log"
echo ""
} >>"$combined_log"
rm -f "$temp_log"
fi
fi
if [[ -s "$combined_log" ]]; then
INSTALL_LOG="$combined_log"
fi
fi
}
# ------------------------------------------------------------------------------
# api_exit_script()
#
@@ -5266,7 +5140,6 @@ ensure_log_on_host() {
api_exit_script() {
exit_code=$?
if [ $exit_code -ne 0 ]; then
ensure_log_on_host
post_update_to_api "failed" "$exit_code"
fi
}
@@ -5274,6 +5147,6 @@ api_exit_script() {
if command -v pveversion >/dev/null 2>&1; then
trap 'api_exit_script' EXIT
fi
trap 'ensure_log_on_host; post_update_to_api "failed" "$?"' ERR
trap 'ensure_log_on_host; post_update_to_api "failed" "130"' SIGINT
trap 'ensure_log_on_host; post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "$?"' ERR
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM

View File

@@ -413,69 +413,6 @@ get_active_logfile() {
# Legacy compatibility: SILENT_LOGFILE points to active log
SILENT_LOGFILE="$(get_active_logfile)"
# ------------------------------------------------------------------------------
# strip_ansi()
#
# - Removes ANSI escape sequences from input text
# - Used to clean colored output for log files
# - Handles both piped input and arguments
# ------------------------------------------------------------------------------
strip_ansi() {
if [[ $# -gt 0 ]]; then
echo -e "$*" | sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g'
else
sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g'
fi
}
# ------------------------------------------------------------------------------
# log_msg()
#
# - Writes message to active log file without ANSI codes
# - Adds timestamp prefix for log correlation
# - Creates log file if it doesn't exist
# - Arguments: message text (can include ANSI codes, will be stripped)
# ------------------------------------------------------------------------------
log_msg() {
local msg="$*"
local logfile
logfile="$(get_active_logfile)"
[[ -z "$msg" ]] && return
[[ -z "$logfile" ]] && return
# Ensure log directory exists
mkdir -p "$(dirname "$logfile")" 2>/dev/null || true
# Strip ANSI codes and write with timestamp
local clean_msg
clean_msg=$(strip_ansi "$msg")
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $clean_msg" >>"$logfile"
}
# ------------------------------------------------------------------------------
# log_section()
#
# - Writes a section header to the log file
# - Used for separating different phases of installation
# - Arguments: section name
# ------------------------------------------------------------------------------
log_section() {
local section="$1"
local logfile
logfile="$(get_active_logfile)"
[[ -z "$logfile" ]] && return
mkdir -p "$(dirname "$logfile")" 2>/dev/null || true
{
echo ""
echo "================================================================================"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $section"
echo "================================================================================"
} >>"$logfile"
}
# ------------------------------------------------------------------------------
# silent()
#
@@ -618,9 +555,6 @@ msg_info() {
[[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
MSG_INFO_SHOWN["$msg"]=1
# Log to file
log_msg "[INFO] $msg"
stop_spinner
SPINNER_MSG="$msg"
@@ -664,7 +598,6 @@ msg_ok() {
stop_spinner
clear_line
echo -e "$CM ${GN}${msg}${CL}"
log_msg "[OK] $msg"
unset MSG_INFO_SHOWN["$msg"]
}
@@ -680,7 +613,6 @@ msg_error() {
stop_spinner
local msg="$1"
echo -e "${BFR:-}${CROSS:-✖️} ${RD}${msg}${CL}" >&2
log_msg "[ERROR] $msg"
}
# ------------------------------------------------------------------------------
@@ -695,7 +627,6 @@ msg_warn() {
stop_spinner
local msg="$1"
echo -e "${BFR:-}${INFO:-} ${YWB}${msg}${CL}" >&2
log_msg "[WARN] $msg"
}
# ------------------------------------------------------------------------------
@@ -713,7 +644,6 @@ msg_custom() {
[[ -z "$msg" ]] && return
stop_spinner
echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}"
log_msg "$msg"
}
# ------------------------------------------------------------------------------

View File

@@ -222,12 +222,6 @@ error_handler() {
pct destroy "$CTID" &>/dev/null || true
echo -e "${GN}${CL} Container ${CTID} removed"
fi
# Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
if declare -f post_update_to_api &>/dev/null; then
post_update_to_api "failed" "$exit_code" "force"
fi
fi
fi
fi
@@ -249,18 +243,6 @@ error_handler() {
# ------------------------------------------------------------------------------
on_exit() {
local exit_code=$?
# Report orphaned "installing" records to telemetry API
# Catches ALL exit paths: errors (non-zero), signals, AND clean exits where
# post_to_api was called ("installing" sent) but post_update_to_api was never called
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
if declare -f post_update_to_api >/dev/null 2>&1; then
if [[ $exit_code -ne 0 ]]; then
post_update_to_api "failed" "$exit_code"
else
post_update_to_api "failed" "1"
fi
fi
fi
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
exit "$exit_code"
}
@@ -273,10 +255,6 @@ on_exit() {
# - Exits with code 130 (128 + SIGINT=2)
# ------------------------------------------------------------------------------
on_interrupt() {
# Report interruption to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "130"
fi
if declare -f msg_error >/dev/null 2>&1; then
msg_error "Interrupted by user (SIGINT)"
else
@@ -294,10 +272,6 @@ on_interrupt() {
# - Triggered by external process termination
# ------------------------------------------------------------------------------
on_terminate() {
# Report termination to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "143"
fi
if declare -f msg_error >/dev/null 2>&1; then
msg_error "Terminated by signal (SIGTERM)"
else

View File

@@ -465,7 +465,6 @@ manage_tool_repository() {
msg_error "Failed to download MongoDB GPG key"
return 1
fi
chmod 644 "/etc/apt/keyrings/mongodb-server-${version}.gpg"
# Setup repository
local distro_codename
@@ -1295,33 +1294,12 @@ setup_deb822_repo() {
return 1
}
# Import GPG key (auto-detect binary vs ASCII-armored format)
local tmp_gpg
tmp_gpg=$(mktemp) || return 1
curl -fsSL "$gpg_url" -o "$tmp_gpg" || {
msg_error "Failed to download GPG key for ${name}"
rm -f "$tmp_gpg"
# Import GPG
curl -fsSL "$gpg_url" | gpg --dearmor --yes -o "/etc/apt/keyrings/${name}.gpg" || {
msg_error "Failed to import GPG key for ${name}"
return 1
}
if grep -q "BEGIN PGP" "$tmp_gpg" 2>/dev/null; then
# ASCII-armored — dearmor to binary
gpg --dearmor --yes -o "/etc/apt/keyrings/${name}.gpg" < "$tmp_gpg" || {
msg_error "Failed to dearmor GPG key for ${name}"
rm -f "$tmp_gpg"
return 1
}
else
# Already in binary GPG format — copy directly
cp "$tmp_gpg" "/etc/apt/keyrings/${name}.gpg" || {
msg_error "Failed to install GPG key for ${name}"
rm -f "$tmp_gpg"
return 1
}
fi
rm -f "$tmp_gpg"
chmod 644 "/etc/apt/keyrings/${name}.gpg"
# Write deb822
{
echo "Types: deb"

View File

@@ -75,37 +75,14 @@ pct exec "$CTID" -- bash -c '
set -e
export DEBIAN_FRONTEND=noninteractive
# Source os-release properly (handles quoted values)
source /etc/os-release
ID=$(grep "^ID=" /etc/os-release | cut -d"=" -f2)
VER=$(grep "^VERSION_CODENAME=" /etc/os-release | cut -d"=" -f2)
# Fallback if DNS is poisoned or blocked
# fallback if DNS is poisoned or blocked
ORIG_RESOLV="/etc/resolv.conf"
BACKUP_RESOLV="/tmp/resolv.conf.backup"
# Check DNS resolution using multiple methods (dig may not be installed)
dns_check_failed=true
if command -v dig &>/dev/null; then
if dig +short pkgs.tailscale.com 2>/dev/null | grep -qvE "^127\.|^0\.0\.0\.0$|^$"; then
dns_check_failed=false
fi
elif command -v host &>/dev/null; then
if host pkgs.tailscale.com 2>/dev/null | grep -q "has address"; then
dns_check_failed=false
fi
elif command -v nslookup &>/dev/null; then
if nslookup pkgs.tailscale.com 2>/dev/null | grep -q "Address:"; then
dns_check_failed=false
fi
elif command -v getent &>/dev/null; then
if getent hosts pkgs.tailscale.com &>/dev/null; then
dns_check_failed=false
fi
else
# No DNS tools available, try curl directly and assume DNS works
dns_check_failed=false
fi
if $dns_check_failed; then
if ! dig +short pkgs.tailscale.com | grep -qvE "^127\.|^0\.0\.0\.0$"; then
echo "[INFO] DNS resolution for pkgs.tailscale.com failed (blocked or redirected)."
echo "[INFO] Temporarily overriding /etc/resolv.conf with Cloudflare DNS (1.1.1.1)"
cp "$ORIG_RESOLV" "$BACKUP_RESOLV"
@@ -115,22 +92,17 @@ fi
if ! command -v curl &>/dev/null; then
echo "[INFO] curl not found, installing..."
apt-get update -qq
apt update -qq
apt install -y curl >/dev/null
apt-get install -y curl >/dev/null
fi
# Ensure keyrings directory exists
mkdir -p /usr/share/keyrings
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
curl -fsSL https://pkgs.tailscale.com/stable/${ID}/${VER}.noarmor.gpg \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VER} main" \
>/etc/apt/sources.list.d/tailscale.list
apt-get update -qq
apt update -qq
apt install -y tailscale >/dev/null
apt-get install -y tailscale >/dev/null
if [[ -f /tmp/resolv.conf.backup ]]; then
echo "[INFO] Restoring original /etc/resolv.conf"

View File

@@ -70,7 +70,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -203,6 +203,7 @@ function exit-script() {
function default_settings() {
VMID=$(get_valid_nextid)
FORMAT=",efitype=4m"
MACHINE=""
DISK_SIZE="4G"
DISK_CACHE=""
@@ -258,9 +259,11 @@ function advanced_settings() {
3>&1 1>&2 2>&3); then
if [ "$MACH" = q35 ]; then
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
FORMAT=""
MACHINE=" -machine q35"
else
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
FORMAT=",efitype=4m"
MACHINE=""
fi
else
@@ -473,45 +476,31 @@ case $STORAGE_TYPE in
nfs | dir | cifs)
DISK_EXT=".qcow2"
DISK_REF="$VMID/"
DISK_IMPORT="--format qcow2"
DISK_IMPORT="-format qcow2"
THIN=""
;;
btrfs)
DISK_EXT=".raw"
DISK_REF="$VMID/"
DISK_IMPORT="--format raw"
DISK_IMPORT="-format raw"
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="--format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"
eval DISK"${i}"=vm-"${VMID}"-disk-"${i}"${DISK_EXT:-}
eval DISK"${i}"_REF="${STORAGE}":"${DISK_REF:-}"${!disk}
done
msg_info "Creating a Arch Linux VM"
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
if qm disk import --help >/dev/null 2>&1; then
IMPORT_CMD=(qm disk import)
else
IMPORT_CMD=(qm importdisk)
fi
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "${FILE}" "$STORAGE" ${DISK_IMPORT:-} 2>&1 || true)"
DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
[[ -z "$DISK_REF_IMPORTED" ]] && DISK_REF_IMPORTED="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
[[ -z "$DISK_REF_IMPORTED" ]] && {
msg_error "Unable to determine imported disk reference."
echo "$IMPORT_OUT"
exit 1
}
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
qm set $VMID \
-efidisk0 ${STORAGE}:0,efitype=4m \
-scsi0 ${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,} \
-efidisk0 ${DISK0_REF}${FORMAT} \
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
-ide2 ${STORAGE}:cloudinit \
-boot order=scsi0 \
-serial0 socket >/dev/null

View File

@@ -70,7 +70,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -560,11 +560,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -70,7 +70,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -501,11 +501,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -45,7 +45,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}

View File

@@ -74,7 +74,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}

View File

@@ -71,7 +71,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -566,11 +566,6 @@ zfspool)
DISK_REF=""
DISK_IMPORT="-format raw"
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
DISK_VAR="vm-${VMID}-disk-0${DISK_EXT:-}"

View File

@@ -70,7 +70,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -487,11 +487,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1,2}; do
disk="DISK$i"

View File

@@ -74,7 +74,7 @@ function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
post_update_to_api "failed" "$exit_code"
post_update_to_api "failed" "$command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
cleanup_vmid

View File

@@ -48,7 +48,7 @@ function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
post_update_to_api "failed" "$exit_code"
post_update_to_api "failed" "$command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
cleanup_vmid
@@ -619,11 +619,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -71,7 +71,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -500,11 +500,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1,2}; do
disk="DISK$i"

View File

@@ -79,7 +79,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
@@ -402,11 +402,6 @@ nfs | dir)
DISK_REF="$VMID/"
DISK_IMPORT="-format qcow2"
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -66,7 +66,7 @@ function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
post_update_to_api "failed" "$exit_code"
post_update_to_api "failed" "$command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
cleanup_vmid
@@ -482,11 +482,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -69,7 +69,7 @@ function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
post_update_to_api "failed" "$exit_code"
post_update_to_api "failed" "$command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
cleanup_vmid
@@ -484,11 +484,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -68,7 +68,7 @@ function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
post_update_to_api "failed" "$exit_code"
post_update_to_api "failed" "$command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
cleanup_vmid
@@ -483,11 +483,6 @@ btrfs)
FORMAT=",efitype=4m"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="-format raw"
;;
esac
for i in {0,1}; do
disk="DISK$i"

View File

@@ -69,7 +69,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}