Compare commits

...

19 Commits

Author SHA1 Message Date
github-actions[bot]
6dcc7c6b8d Update CHANGELOG.md 2026-02-19 00:23:00 +00:00
community-scripts-pr-app[bot]
9b2275c980 chore: update github-versions.json (#12069)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-19 00:22:45 +00:00
CanbiZ (MickLesk)
b6a4e6a2a6 OPNSense: add disk space check | increase disk space (#12058)
* Fix: Add disk space checking for OPNsense VM FreeBSD image decompression

- Add check_disk_space() function to verify available storage
- Check for 20GB before download and 15GB before decompression
- Provide clear error messages showing available vs required space
- Add proper error handling for unxz decompression failures
- Clean up compressed .xz file after decompression to save space
- Add progress messages for download and decompression steps

Fixes issue where script fails at line 611 with 'No space left on device'
when /tmp directory lacks sufficient space for ~10-15GB decompressed image.

* Increase OPNsense VM disk size from 10GB to 20GB

- Provides more space for system updates, logs, and package installations
- 20GB is a more appropriate size for OPNsense production use
2026-02-18 22:06:04 +01:00
community-scripts-pr-app[bot]
96c056ea4e chore: update github-versions.json (#12067)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 18:17:12 +00:00
CanbiZ (MickLesk)
491081ffbf Add post_progress_to_api lightweight telemetry ping
Introduce post_progress_to_api() in misc/api.func — a non-blocking, fire-and-forget curl ping (gated by DIAGNOSTICS and RANDOM_UUID) that updates telemetry status to "configuring". Wire this progress ping into multiple scripts (alpine-install.func, install.func, build.func, core.func) at key milestones (container start, network ready, customization, creation, cleanup) and replace/deduplicate some earlier post_to_api calls. Also update error_handler.func to always report failures immediately via post_update_to_api to ensure failures are captured even before/after container lifecycle.
2026-02-18 16:19:19 +01:00
community-scripts-pr-app[bot]
1123fdca14 Update CHANGELOG.md (#12064)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 12:53:37 +00:00
Chris
a3a383361d [Fix] PatchMon: use SERVER_PORT in Nginx config if set in env (#12053)
- This PR will add the ability to change the PatchMon listen port in the
Nginx config during update, if the `SERVER_PORT` env var is set in
`/opt/patchmon/backend.env` and if the port is not 443
- If not set, or if set and the port is 443, then no changes are made to
the listen port in the Nginx config
2026-02-18 13:53:08 +01:00
CanbiZ (MickLesk)
6cc8877852 Add timeouts and prioritize telemetry on exit
Prevent hangs when pulling logs from containers by wrapping pct pull calls with timeout (8s) and running ensure_log_on_host under timeout (10s). Always send telemetry (post_update_to_api) before attempting best-effort log collection so status is reported even if log retrieval blocks. Update EXIT/ERR/SIGHUP/SIGINT/SIGTERM traps and consolidate error/interrupt handlers to use the new timeouted log collection. Changes in misc/build.func and misc/error_handler.func.
2026-02-18 13:14:59 +01:00
community-scripts-pr-app[bot]
845b89f975 chore: update github-versions.json (#12061)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 12:13:39 +00:00
community-scripts-pr-app[bot]
be26dc33dd Update CHANGELOG.md (#12057)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 09:24:29 +00:00
CanbiZ (MickLesk)
b439960222 core: Execution ID & Telemetry Improvements (#12041)
* fix: send telemetry BEFORE log collection in signal handlers

- Swap ensure_log_on_host/post_update_to_api order in on_interrupt, on_terminate, api_exit_script, and inline SIGHUP/SIGINT/SIGTERM traps
- For signal exits (>128): send telemetry immediately, then best-effort log collection
- Add 2>/dev/null || true to all I/O in signal handlers to prevent SIGPIPE
- Fix on_exit: exit_code=0 now reports 'done' instead of 'failed 1'
- Root cause: pct pull hangs on dying containers blocked telemetry updates, leaving 595+ records stuck in 'installing' daily

* feat: add execution_id to all telemetry payloads

- Generate EXECUTION_ID from RANDOM_UUID in variables()
- Export EXECUTION_ID to container environment
- Add execution_id field to all 8 API payloads in api.func
- Add execution_id to post_progress_to_api in install.func and alpine-install.func
- Fallback to RANDOM_UUID when EXECUTION_ID not set (backward compat)

* fix: correct telemetry type values for PVE and addon scripts

- PVE scripts (tools/pve/*): change type 'tool' -> 'pve'
- Addon scripts (tools/addon/*): fix 4 scripts that wrongly used 'tool' -> 'addon'
  (netdata, add-tailscale-lxc, add-netbird-lxc, all-templates)
- api.func: post_tool_to_api sends type='pve', default fallback 'pve'
- Aligns with PocketBase categories: lxc, vm, pve, addon

* fix: persist diagnostics opt-in inside containers for addon telemetry

- install.func + alpine-install.func: create /usr/local/community-scripts/diagnostics
  inside the container when DIAGNOSTICS=yes (from build.func export)
- Enables addon scripts running later inside containers to find the opt-in
- Update init_tool_telemetry default type from 'tool' to 'pve'

* refactor: clean up diagnostics/telemetry opt-in system

- diagnostics_check(): deduplicate heredoc (was 2x 22 lines), improve whiptail
  text with clear what/what-not collected, add telemetry + privacy links
- diagnostics_menu(): better UX with current status, clear enable/disable
  buttons, note about existing containers
- variables(): change DIAGNOSTICS default from 'yes' to 'no' (safe: no
  telemetry before user consents via diagnostics_check)
- install.func + alpine-install.func: persist BOTH yes AND no in container
  so opt-out is explicit (not just missing file = no)
- Fix typo 'menue' -> 'menu' in config file comments

* fix: no pre-selection in telemetry dialog, link to telemetry-service README

- Add --defaultno so 'No, opt out' is focused by default (user must Tab to Yes)
- Change privacy link from discussions/1836 to telemetry-service#privacy--compliance

* fix: use radiolist for telemetry dialog (no pre-selection)

- Replace --yesno with --radiolist: user must actively SPACE-select an option
- Both options start as OFF (no pre-selection)
- Cancel/Exit defaults to 'no' (opt-out)

* simplify: inline telemetry dialog text like other whiptail dialogs

* improve: telemetry dialog with more detail, link to PRIVACY.md

- Add what we collect / don't collect sections back to dialog
- Link to telemetry-service/docs/PRIVACY.md instead of README anchor
- Update config file comment with same link
2026-02-18 10:24:06 +01:00
community-scripts-pr-app[bot]
b4a5d28957 chore: update github-versions.json (#12054)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 06:25:12 +00:00
community-scripts-pr-app[bot]
eaa69d58be Update CHANGELOG.md (#12052)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 00:22:33 +00:00
community-scripts-pr-app[bot]
3ffff334a0 chore: update github-versions.json (#12051)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-18 00:22:12 +00:00
community-scripts-pr-app[bot]
38f04f4dcc Update CHANGELOG.md (#12048)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-17 20:14:36 +00:00
Andreas Abeck
fdbcee3a93 fix according to issue #12045 (#12047) 2026-02-17 21:14:12 +01:00
community-scripts-pr-app[bot]
ce11ba8f27 Update CHANGELOG.md (#12046)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-17 19:18:03 +00:00
Chris
43a0a078f5 [Hotfix] Cleanuparr: backup config before update (#12039) 2026-02-17 20:17:22 +01:00
community-scripts-pr-app[bot]
646dabf0f0 chore: update github-versions.json (#12043)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-17 18:20:21 +00:00
44 changed files with 352 additions and 206 deletions

View File

@@ -404,6 +404,22 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details> </details>
## 2026-02-19
## 2026-02-18
### 🚀 Updated Scripts
- #### 💥 Breaking Changes
- [Fix] PatchMon: use `SERVER_PORT` in Nginx config if set in env [@vhsdream](https://github.com/vhsdream) ([#12053](https://github.com/community-scripts/ProxmoxVE/pull/12053))
### 💾 Core
- #### ✨ New Features
- core: Execution ID & Telemetry Improvements [@MickLesk](https://github.com/MickLesk) ([#12041](https://github.com/community-scripts/ProxmoxVE/pull/12041))
## 2026-02-17 ## 2026-02-17
### 🆕 New Scripts ### 🆕 New Scripts
@@ -414,6 +430,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- [Hotfix] Cleanuparr: backup config before update [@vhsdream](https://github.com/vhsdream) ([#12039](https://github.com/community-scripts/ProxmoxVE/pull/12039))
- fix: pterodactyl-panel add symlink [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11997](https://github.com/community-scripts/ProxmoxVE/pull/11997)) - fix: pterodactyl-panel add symlink [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11997](https://github.com/community-scripts/ProxmoxVE/pull/11997))
### 💾 Core ### 💾 Core
@@ -437,6 +454,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- Immich Public Proxy: centralize and fix systemd service creation [@MickLesk](https://github.com/MickLesk) ([#12025](https://github.com/community-scripts/ProxmoxVE/pull/12025)) - Immich Public Proxy: centralize and fix systemd service creation [@MickLesk](https://github.com/MickLesk) ([#12025](https://github.com/community-scripts/ProxmoxVE/pull/12025))
### 📚 Documentation
- fix contribution/setup-fork [@andreasabeck](https://github.com/andreasabeck) ([#12047](https://github.com/community-scripts/ProxmoxVE/pull/12047))
## 2026-02-16 ## 2026-02-16
### 🆕 New Scripts ### 🆕 New Scripts

View File

@@ -32,8 +32,17 @@ function update_script() {
systemctl stop cleanuparr systemctl stop cleanuparr
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Backing up config"
cp -r /opt/cleanuparr/config /opt/cleanuparr_config_backup
msg_ok "Backed up config"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-amd64.zip" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-amd64.zip"
msg_info "Restoring config"
[[ -d /opt/cleanuparr/config ]] && rm -rf /opt/cleanuparr/config
mv /opt/cleanuparr_config_backup /opt/cleanuparr/config
msg_ok "Restored config"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start cleanuparr systemctl start cleanuparr
msg_ok "Started Service" msg_ok "Started Service"

View File

@@ -46,6 +46,7 @@ function update_script() {
VERSION=$(get_latest_github_release "PatchMon/PatchMon") VERSION=$(get_latest_github_release "PatchMon/PatchMon")
PROTO="$(sed -n '/SERVER_PROTOCOL/s/[^=]*=//p' /opt/backend.env)" PROTO="$(sed -n '/SERVER_PROTOCOL/s/[^=]*=//p' /opt/backend.env)"
HOST="$(sed -n '/SERVER_HOST/s/[^=]*=//p' /opt/backend.env)" HOST="$(sed -n '/SERVER_HOST/s/[^=]*=//p' /opt/backend.env)"
SERVER_PORT="$(sed -n '/SERVER_PORT/s/[^=]*=//p' /opt/backend.env)"
[[ "${PROTO:-http}" == "http" ]] && PORT=":3001" [[ "${PROTO:-http}" == "http" ]] && PORT=":3001"
sed -i 's/PORT=3399/PORT=3001/' /opt/backend.env sed -i 's/PORT=3399/PORT=3001/' /opt/backend.env
sed -i -e "s/VERSION=.*/VERSION=$VERSION/" \ sed -i -e "s/VERSION=.*/VERSION=$VERSION/" \
@@ -66,6 +67,9 @@ function update_script() {
-e '\|try_files |i\ root /opt/patchmon/frontend/dist;' \ -e '\|try_files |i\ root /opt/patchmon/frontend/dist;' \
-e 's|alias.*|alias /opt/patchmon/frontend/dist/assets;|' \ -e 's|alias.*|alias /opt/patchmon/frontend/dist/assets;|' \
-e '\|expires 1y|i\ root /opt/patchmon/frontend/dist;' /etc/nginx/sites-available/patchmon.conf -e '\|expires 1y|i\ root /opt/patchmon/frontend/dist;' /etc/nginx/sites-available/patchmon.conf
if [[ -n "$SERVER_PORT" ]] && [[ "$SERVER_PORT" != "443" ]]; then
sed -i "s/listen [[:digit:]]/listen ${SERVER_PORT};/" /etc/nginx/sites-available/patchmon.conf
fi
ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/ ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default rm -f /etc/nginx/sites-enabled/default
$STD nginx -t $STD nginx -t

View File

@@ -134,7 +134,7 @@ update_links() {
# Find all files containing the old repo reference # Find all files containing the old repo reference
while IFS= read -r file; do while IFS= read -r file; do
# Count occurrences # Count occurrences
local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0) local count=$(grep -E -c "(github.com|githubusercontent.com)/$old_repo/$old_name" "$file" 2>/dev/null || echo 0)
if [[ $count -gt 0 ]]; then if [[ $count -gt 0 ]]; then
# Backup original # Backup original
@@ -143,16 +143,16 @@ update_links() {
# Replace links - use different sed syntax for BSD/macOS vs GNU sed # Replace links - use different sed syntax for BSD/macOS vs GNU sed
if sed --version &>/dev/null 2>&1; then if sed --version &>/dev/null 2>&1; then
# GNU sed # GNU sed
sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" sed -E -i "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
else else
# BSD sed (macOS) # BSD sed (macOS)
sed -i '' "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" sed -E -i '' "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
fi fi
((files_updated++)) ((files_updated++))
print_success "Updated $file ($count links)" print_success "Updated $file ($count links)"
fi fi
done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -l "github.com/$old_repo/$old_name" 2>/dev/null) done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -E -l "(github.com|githubusercontent.com)/$old_repo/$old_name" 2>/dev/null)
return $files_updated return $files_updated
} }

View File

@@ -1,5 +1,5 @@
{ {
"generated": "2026-02-17T12:14:18Z", "generated": "2026-02-19T00:22:36Z",
"versions": [ "versions": [
{ {
"slug": "2fauth", "slug": "2fauth",
@@ -158,9 +158,9 @@
{ {
"slug": "bookstack", "slug": "bookstack",
"repo": "BookStackApp/BookStack", "repo": "BookStackApp/BookStack",
"version": "v25.12.4", "version": "v25.12.6",
"pinned": false, "pinned": false,
"date": "2026-02-17T11:44:48Z" "date": "2026-02-18T19:53:07Z"
}, },
{ {
"slug": "byparr", "slug": "byparr",
@@ -207,9 +207,9 @@
{ {
"slug": "comfyui", "slug": "comfyui",
"repo": "comfyanonymous/ComfyUI", "repo": "comfyanonymous/ComfyUI",
"version": "v0.14.0", "version": "v0.14.2",
"pinned": false, "pinned": false,
"date": "2026-02-17T06:29:10Z" "date": "2026-02-18T06:12:02Z"
}, },
{ {
"slug": "commafeed", "slug": "commafeed",
@@ -221,9 +221,9 @@
{ {
"slug": "configarr", "slug": "configarr",
"repo": "raydak-labs/configarr", "repo": "raydak-labs/configarr",
"version": "v1.20.0", "version": "v1.21.0",
"pinned": false, "pinned": false,
"date": "2026-01-10T21:25:47Z" "date": "2026-02-17T22:59:07Z"
}, },
{ {
"slug": "convertx", "slug": "convertx",
@@ -256,9 +256,9 @@
{ {
"slug": "databasus", "slug": "databasus",
"repo": "databasus/databasus", "repo": "databasus/databasus",
"version": "v3.12.2", "version": "v3.14.1",
"pinned": false, "pinned": false,
"date": "2026-02-14T22:28:59Z" "date": "2026-02-18T10:43:45Z"
}, },
{ {
"slug": "dawarich", "slug": "dawarich",
@@ -270,9 +270,9 @@
{ {
"slug": "discopanel", "slug": "discopanel",
"repo": "nickheyer/discopanel", "repo": "nickheyer/discopanel",
"version": "v1.0.36", "version": "v1.0.37",
"pinned": false, "pinned": false,
"date": "2026-02-09T21:15:44Z" "date": "2026-02-18T08:53:43Z"
}, },
{ {
"slug": "dispatcharr", "slug": "dispatcharr",
@@ -417,9 +417,9 @@
{ {
"slug": "ghostfolio", "slug": "ghostfolio",
"repo": "ghostfolio/ghostfolio", "repo": "ghostfolio/ghostfolio",
"version": "2.239.0", "version": "2.240.0",
"pinned": false, "pinned": false,
"date": "2026-02-15T09:51:16Z" "date": "2026-02-18T20:08:56Z"
}, },
{ {
"slug": "gitea", "slug": "gitea",
@@ -557,9 +557,9 @@
{ {
"slug": "huntarr", "slug": "huntarr",
"repo": "plexguide/Huntarr.io", "repo": "plexguide/Huntarr.io",
"version": "9.3.0", "version": "9.3.5",
"pinned": false, "pinned": false,
"date": "2026-02-17T06:34:38Z" "date": "2026-02-18T16:25:07Z"
}, },
{ {
"slug": "immich-public-proxy", "slug": "immich-public-proxy",
@@ -585,16 +585,16 @@
{ {
"slug": "invoiceninja", "slug": "invoiceninja",
"repo": "invoiceninja/invoiceninja", "repo": "invoiceninja/invoiceninja",
"version": "v5.12.62", "version": "v5.12.64",
"pinned": false, "pinned": false,
"date": "2026-02-17T03:23:48Z" "date": "2026-02-18T07:59:44Z"
}, },
{ {
"slug": "jackett", "slug": "jackett",
"repo": "Jackett/Jackett", "repo": "Jackett/Jackett",
"version": "v0.24.1140", "version": "v0.24.1147",
"pinned": false, "pinned": false,
"date": "2026-02-17T05:54:25Z" "date": "2026-02-18T05:54:19Z"
}, },
{ {
"slug": "jellystat", "slug": "jellystat",
@@ -704,9 +704,9 @@
{ {
"slug": "leantime", "slug": "leantime",
"repo": "Leantime/leantime", "repo": "Leantime/leantime",
"version": "v3.6.2", "version": "v3.7.0",
"pinned": false, "pinned": false,
"date": "2026-01-29T16:37:00Z" "date": "2026-02-18T00:02:31Z"
}, },
{ {
"slug": "librenms", "slug": "librenms",
@@ -746,9 +746,9 @@
{ {
"slug": "linkstack", "slug": "linkstack",
"repo": "linkstackorg/linkstack", "repo": "linkstackorg/linkstack",
"version": "v4.8.4", "version": "v4.8.6",
"pinned": false, "pinned": false,
"date": "2024-12-10T15:14:34Z" "date": "2026-02-17T16:53:47Z"
}, },
{ {
"slug": "linkwarden", "slug": "linkwarden",
@@ -893,9 +893,9 @@
{ {
"slug": "netbox", "slug": "netbox",
"repo": "netbox-community/netbox", "repo": "netbox-community/netbox",
"version": "v4.5.2", "version": "v4.5.3",
"pinned": false, "pinned": false,
"date": "2026-02-03T13:54:26Z" "date": "2026-02-17T15:39:18Z"
}, },
{ {
"slug": "nextcloud-exporter", "slug": "nextcloud-exporter",
@@ -1061,9 +1061,9 @@
{ {
"slug": "pelican-panel", "slug": "pelican-panel",
"repo": "pelican-dev/panel", "repo": "pelican-dev/panel",
"version": "v1.0.0-beta32", "version": "v1.0.0-beta33",
"pinned": false, "pinned": false,
"date": "2026-02-09T22:15:44Z" "date": "2026-02-18T21:37:11Z"
}, },
{ {
"slug": "pelican-wings", "slug": "pelican-wings",
@@ -1096,9 +1096,9 @@
{ {
"slug": "planka", "slug": "planka",
"repo": "plankanban/planka", "repo": "plankanban/planka",
"version": "v2.0.0", "version": "v2.0.1",
"pinned": false, "pinned": false,
"date": "2026-02-11T13:50:10Z" "date": "2026-02-17T15:26:55Z"
}, },
{ {
"slug": "plant-it", "slug": "plant-it",
@@ -1187,9 +1187,9 @@
{ {
"slug": "pulse", "slug": "pulse",
"repo": "rcourtman/Pulse", "repo": "rcourtman/Pulse",
"version": "v5.1.9", "version": "v5.1.10",
"pinned": false, "pinned": false,
"date": "2026-02-11T15:34:40Z" "date": "2026-02-18T14:00:51Z"
}, },
{ {
"slug": "pve-scripts-local", "slug": "pve-scripts-local",
@@ -1243,9 +1243,9 @@
{ {
"slug": "rclone", "slug": "rclone",
"repo": "rclone/rclone", "repo": "rclone/rclone",
"version": "v1.73.0", "version": "v1.73.1",
"pinned": false, "pinned": false,
"date": "2026-01-30T22:12:03Z" "date": "2026-02-17T18:27:21Z"
}, },
{ {
"slug": "rdtclient", "slug": "rdtclient",
@@ -1313,9 +1313,9 @@
{ {
"slug": "scanopy", "slug": "scanopy",
"repo": "scanopy/scanopy", "repo": "scanopy/scanopy",
"version": "v0.14.4", "version": "v0.14.6",
"pinned": false, "pinned": false,
"date": "2026-02-10T03:57:28Z" "date": "2026-02-18T16:54:14Z"
}, },
{ {
"slug": "scraparr", "slug": "scraparr",
@@ -1341,9 +1341,9 @@
{ {
"slug": "semaphore", "slug": "semaphore",
"repo": "semaphoreui/semaphore", "repo": "semaphoreui/semaphore",
"version": "v2.17.2", "version": "v2.17.8",
"pinned": false, "pinned": false,
"date": "2026-02-16T10:27:40Z" "date": "2026-02-18T19:46:43Z"
}, },
{ {
"slug": "shelfmark", "slug": "shelfmark",
@@ -1418,9 +1418,9 @@
{ {
"slug": "stirling-pdf", "slug": "stirling-pdf",
"repo": "Stirling-Tools/Stirling-PDF", "repo": "Stirling-Tools/Stirling-PDF",
"version": "v2.5.0", "version": "v2.5.1",
"pinned": false, "pinned": false,
"date": "2026-02-16T22:58:17Z" "date": "2026-02-18T11:05:34Z"
}, },
{ {
"slug": "streamlink-webui", "slug": "streamlink-webui",
@@ -1488,9 +1488,9 @@
{ {
"slug": "threadfin", "slug": "threadfin",
"repo": "threadfin/threadfin", "repo": "threadfin/threadfin",
"version": "delete", "version": "1.2.37",
"pinned": false, "pinned": false,
"date": "" "date": "2025-09-11T16:13:41Z"
}, },
{ {
"slug": "tianji", "slug": "tianji",
@@ -1551,9 +1551,9 @@
{ {
"slug": "tunarr", "slug": "tunarr",
"repo": "chrisbenincasa/tunarr", "repo": "chrisbenincasa/tunarr",
"version": "v1.1.13", "version": "v1.1.14",
"pinned": false, "pinned": false,
"date": "2026-02-16T16:16:17Z" "date": "2026-02-17T18:26:17Z"
}, },
{ {
"slug": "uhf", "slug": "uhf",
@@ -1607,9 +1607,9 @@
{ {
"slug": "victoriametrics", "slug": "victoriametrics",
"repo": "VictoriaMetrics/VictoriaMetrics", "repo": "VictoriaMetrics/VictoriaMetrics",
"version": "v1.135.0", "version": "v1.136.0",
"pinned": false, "pinned": false,
"date": "2026-02-02T14:20:15Z" "date": "2026-02-16T13:17:50Z"
}, },
{ {
"slug": "vikunja", "slug": "vikunja",
@@ -1726,9 +1726,9 @@
{ {
"slug": "yubal", "slug": "yubal",
"repo": "guillevc/yubal", "repo": "guillevc/yubal",
"version": "v0.6.0", "version": "v0.6.1",
"pinned": false, "pinned": false,
"date": "2026-02-15T17:47:56Z" "date": "2026-02-18T23:24:16Z"
}, },
{ {
"slug": "zigbee2mqtt", "slug": "zigbee2mqtt",

View File

@@ -11,6 +11,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
load_functions load_functions
catch_errors catch_errors
# Persist diagnostics setting inside container (exported from build.func)
# so addon scripts running later can find the user's choice
if [[ ! -f /usr/local/community-scripts/diagnostics ]]; then
mkdir -p /usr/local/community-scripts
echo "DIAGNOSTICS=${DIAGNOSTICS:-no}" >/usr/local/community-scripts/diagnostics
fi
# Get LXC IP address (must be called INSIDE container, after network is up) # Get LXC IP address (must be called INSIDE container, after network is up)
get_lxc_ip get_lxc_ip
@@ -30,7 +37,7 @@ post_progress_to_api() {
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \ curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true -d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
} }
# This function enables IPv6 if it's not disabled and sets verbose mode # This function enables IPv6 if it's not disabled and sets verbose mode
@@ -141,6 +148,7 @@ motd_ssh() {
# Start the sshd service # Start the sshd service
$STD /etc/init.d/sshd start $STD /etc/init.d/sshd start
fi fi
post_progress_to_api
} }
# Validate Timezone for some LXC's # Validate Timezone for some LXC's
@@ -177,5 +185,5 @@ EOF
echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)\"" >/usr/bin/update echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update chmod +x /usr/bin/update
post_progress_to_api
} }

View File

@@ -552,6 +552,7 @@ post_to_api() {
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "lxc", "type": "lxc",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "installing", "status": "installing",
@@ -656,6 +657,7 @@ post_to_api_vm() {
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "vm", "type": "vm",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "installing", "status": "installing",
@@ -686,6 +688,29 @@ EOF
POST_TO_API_DONE=true POST_TO_API_DONE=true
} }
# ------------------------------------------------------------------------------
# post_progress_to_api()
#
# - Lightweight progress ping from host or container
# - Updates the existing telemetry record status to "configuring"
# - Signals that the installation is actively progressing (not stuck)
# - Fire-and-forget: never blocks or fails the script
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
# - Can be called multiple times safely
# ------------------------------------------------------------------------------
post_progress_to_api() {
command -v curl &>/dev/null || return 0
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
local app_name="${NSAPP:-${app:-unknown}}"
local telemetry_type="${TELEMETRY_TYPE:-lxc}"
curl -fsS -m 5 -X POST "${TELEMETRY_URL:-https://telemetry.community-scripts.org/telemetry}" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${telemetry_type}\",\"nsapp\":\"${app_name}\",\"status\":\"configuring\"}" &>/dev/null || true
}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# post_update_to_api() # post_update_to_api()
# #
@@ -788,6 +813,7 @@ post_update_to_api() {
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "${TELEMETRY_TYPE:-lxc}", "type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}", "status": "${pb_status}",
@@ -830,6 +856,7 @@ EOF
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "${TELEMETRY_TYPE:-lxc}", "type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}", "status": "${pb_status}",
@@ -872,6 +899,7 @@ EOF
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "${TELEMETRY_TYPE:-lxc}", "type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}", "status": "${pb_status}",
@@ -1001,7 +1029,7 @@ _telemetry_report_exit() {
# Lazy name resolution: use explicit name, fall back to $APP, then "unknown" # Lazy name resolution: use explicit name, fall back to $APP, then "unknown"
local name="${TELEMETRY_TOOL_NAME:-${APP:-unknown}}" local name="${TELEMETRY_TOOL_NAME:-${APP:-unknown}}"
if [[ "${TELEMETRY_TOOL_TYPE:-tool}" == "addon" ]]; then if [[ "${TELEMETRY_TOOL_TYPE:-pve}" == "addon" ]]; then
post_addon_to_api "$name" "$status" "$ec" post_addon_to_api "$name" "$status" "$ec"
else else
post_tool_to_api "$name" "$status" "$ec" post_tool_to_api "$name" "$status" "$ec"
@@ -1013,19 +1041,20 @@ _telemetry_report_exit() {
# #
# - One-line telemetry setup for tools/addon scripts # - One-line telemetry setup for tools/addon scripts
# - Reads DIAGNOSTICS from /usr/local/community-scripts/diagnostics # - Reads DIAGNOSTICS from /usr/local/community-scripts/diagnostics
# (persisted on PVE host during first build, and inside containers by install.func)
# - Starts install timer for duration tracking # - Starts install timer for duration tracking
# - Sets EXIT trap to automatically report success/failure on script exit # - Sets EXIT trap to automatically report success/failure on script exit
# - Arguments: # - Arguments:
# * $1: tool_name (optional, falls back to $APP at exit time) # * $1: tool_name (optional, falls back to $APP at exit time)
# * $2: type ("tool" for PVE host scripts, "addon" for container addons) # * $2: type ("pve" for PVE host scripts, "addon" for container addons)
# - Usage: # - Usage:
# source <(curl -fsSL .../misc/api.func) 2>/dev/null || true # source <(curl -fsSL .../misc/api.func) 2>/dev/null || true
# init_tool_telemetry "post-pve-install" "tool" # init_tool_telemetry "post-pve-install" "pve"
# init_tool_telemetry "" "addon" # uses $APP at exit time # init_tool_telemetry "" "addon" # uses $APP at exit time
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
init_tool_telemetry() { init_tool_telemetry() {
local name="${1:-}" local name="${1:-}"
local type="${2:-tool}" local type="${2:-pve}"
[[ -n "$name" ]] && TELEMETRY_TOOL_NAME="$name" [[ -n "$name" ]] && TELEMETRY_TOOL_NAME="$name"
TELEMETRY_TOOL_TYPE="$type" TELEMETRY_TOOL_TYPE="$type"
@@ -1088,7 +1117,8 @@ post_tool_to_api() {
cat <<EOF cat <<EOF
{ {
"random_id": "${uuid}", "random_id": "${uuid}",
"type": "tool", "execution_id": "${EXECUTION_ID:-${uuid}}",
"type": "pve",
"nsapp": "${tool_name}", "nsapp": "${tool_name}",
"status": "${status}", "status": "${status}",
"exit_code": ${exit_code}, "exit_code": ${exit_code},
@@ -1155,6 +1185,7 @@ post_addon_to_api() {
cat <<EOF cat <<EOF
{ {
"random_id": "${uuid}", "random_id": "${uuid}",
"execution_id": "${EXECUTION_ID:-${uuid}}",
"type": "addon", "type": "addon",
"nsapp": "${addon_name}", "nsapp": "${addon_name}",
"status": "${status}", "status": "${status}",
@@ -1246,6 +1277,7 @@ post_update_to_api_extended() {
cat <<EOF cat <<EOF
{ {
"random_id": "${RANDOM_UUID}", "random_id": "${RANDOM_UUID}",
"execution_id": "${EXECUTION_ID:-${RANDOM_UUID}}",
"type": "${TELEMETRY_TYPE:-lxc}", "type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}", "nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}", "status": "${pb_status}",

View File

@@ -42,9 +42,10 @@ variables() {
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. 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. INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern.
PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase 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. DIAGNOSTICS="no" # Safe default: no telemetry until user consents via diagnostics_check()
METHOD="default" # sets the METHOD variable to "default", 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. RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
EXECUTION_ID="${RANDOM_UUID}" # Unique execution ID for telemetry record identification (unique-indexed in PocketBase)
SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files 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 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 combined_log="/tmp/install-${SESSION_ID}-combined.log" # Combined log (build + install) for failed installations
@@ -2787,93 +2788,85 @@ Advanced:
# diagnostics_check() # diagnostics_check()
# #
# - Ensures diagnostics config file exists at /usr/local/community-scripts/diagnostics # - Ensures diagnostics config file exists at /usr/local/community-scripts/diagnostics
# - Asks user whether to send anonymous diagnostic data # - Asks user whether to send anonymous diagnostic data (first run only)
# - Saves DIAGNOSTICS=yes/no in the config file # - Saves DIAGNOSTICS=yes/no in the config file
# - Creates file if missing with default DIAGNOSTICS=yes # - Reads current diagnostics setting from existing file
# - Reads current diagnostics setting from file
# - Sets global DIAGNOSTICS variable for API telemetry opt-in/out # - Sets global DIAGNOSTICS variable for API telemetry opt-in/out
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
diagnostics_check() { diagnostics_check() {
if ! [ -d "/usr/local/community-scripts" ]; then local config_dir="/usr/local/community-scripts"
mkdir -p /usr/local/community-scripts local config_file="${config_dir}/diagnostics"
mkdir -p "$config_dir"
if [[ -f "$config_file" ]]; then
DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' "$config_file") || true
DIAGNOSTICS="${DIAGNOSTICS:-no}"
return
fi fi
if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then local result
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then result=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
cat <<EOF >/usr/local/community-scripts/diagnostics --title "TELEMETRY & DIAGNOSTICS" \
DIAGNOSTICS=yes --ok-button "Confirm" --cancel-button "Exit" \
--radiolist "\nHelp improve Community-Scripts by sharing anonymous data.\n\nWhat we collect:\n - Container resources (CPU, RAM, disk), OS & PVE version\n - Application name, install method and status\n\nWhat we DON'T collect:\n - No IP addresses, hostnames, or personal data\n\nYou can change this anytime in the Settings menu.\nPrivacy: https://github.com/community-scripts/telemetry-service/blob/main/docs/PRIVACY.md\n\nUse SPACE to select, ENTER to confirm." 22 76 2 \
"yes" "Yes, share anonymous data" OFF \
"no" "No, opt out" OFF \
3>&1 1>&2 2>&3) || result="no"
#This file is used to store the diagnostics settings for the Community-Scripts API. DIAGNOSTICS="${result:-no}"
#https://github.com/community-scripts/ProxmoxVE/discussions/1836
#Your diagnostics will be sent to the Community-Scripts API for troubleshooting/statistical purposes. cat <<EOF >"$config_file"
#You can review the data at https://community-scripts.github.io/ProxmoxVE/data DIAGNOSTICS=${DIAGNOSTICS}
#If you do not wish to send diagnostics, please set the variable 'DIAGNOSTICS' to "no" in /usr/local/community-scripts/diagnostics, or use the menue.
#This will disable the diagnostics feature. # Community-Scripts Telemetry Configuration
#To send diagnostics, set the variable 'DIAGNOSTICS' to "yes" in /usr/local/community-scripts/diagnostics, or use the menue. # https://telemetry.community-scripts.org
#This will enable the diagnostics feature. #
#The following information will be sent: # This file stores your telemetry preference.
#"disk_size" # Set DIAGNOSTICS=yes to share anonymous installation data.
#"core_count" # Set DIAGNOSTICS=no to disable telemetry.
#"ram_size" #
#"os_type" # You can also change this via the Settings menu during installation.
#"os_version" #
#"nsapp" # Data collected (when enabled):
#"method" # disk_size, core_count, ram_size, os_type, os_version,
#"pve_version" # nsapp, method, pve_version, status, exit_code
#"status" #
#If you have any concerns, please review the source code at /misc/build.func # No personal data (IPs, hostnames, passwords) is ever collected.
# Privacy: https://github.com/community-scripts/telemetry-service/blob/main/docs/PRIVACY.md
EOF EOF
DIAGNOSTICS="yes"
else
cat <<EOF >/usr/local/community-scripts/diagnostics
DIAGNOSTICS=no
#This file is used to store the diagnostics settings for the Community-Scripts API.
#https://github.com/community-scripts/ProxmoxVE/discussions/1836
#Your diagnostics will be sent to the Community-Scripts API for troubleshooting/statistical purposes.
#You can review the data at https://community-scripts.github.io/ProxmoxVE/data
#If you do not wish to send diagnostics, please set the variable 'DIAGNOSTICS' to "no" in /usr/local/community-scripts/diagnostics, or use the menue.
#This will disable the diagnostics feature.
#To send diagnostics, set the variable 'DIAGNOSTICS' to "yes" in /usr/local/community-scripts/diagnostics, or use the menue.
#This will enable the diagnostics feature.
#The following information will be sent:
#"disk_size"
#"core_count"
#"ram_size"
#"os_type"
#"os_version"
#"nsapp"
#"method"
#"pve_version"
#"status"
#If you have any concerns, please review the source code at /misc/build.func
EOF
DIAGNOSTICS="no"
fi
else
DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' /usr/local/community-scripts/diagnostics)
fi
} }
diagnostics_menu() { diagnostics_menu() {
if [ "${DIAGNOSTICS:-no}" = "yes" ]; then local current="${DIAGNOSTICS:-no}"
local status_text="DISABLED"
[[ "$current" == "yes" ]] && status_text="ENABLED"
local dialog_text=(
"Telemetry is currently: ${status_text}\n\n"
"Anonymous data helps us improve scripts and track issues.\n"
"No personal data is ever collected.\n\n"
"More info: https://telemetry.community-scripts.org\n\n"
"Do you want to ${current:+change this setting}?"
)
if [[ "$current" == "yes" ]]; then
if whiptail --backtitle "Proxmox VE Helper Scripts" \ if whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "DIAGNOSTIC SETTINGS" \ --title "TELEMETRY SETTINGS" \
--yesno "Send Diagnostics?\n\nCurrent: ${DIAGNOSTICS}" 10 58 \ --yesno "${dialog_text[*]}" 14 64 \
--yes-button "No" --no-button "Back"; then --yes-button "Disable" --no-button "Keep enabled"; then
DIAGNOSTICS="no" DIAGNOSTICS="no"
sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=no/' /usr/local/community-scripts/diagnostics
whiptail --msgbox "Diagnostics set to ${DIAGNOSTICS}." 8 58 whiptail --msgbox "Telemetry disabled.\n\nNote: Existing containers keep their current setting.\nNew containers will inherit this choice." 10 58
fi fi
else else
if whiptail --backtitle "Proxmox VE Helper Scripts" \ if whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "DIAGNOSTIC SETTINGS" \ --title "TELEMETRY SETTINGS" \
--yesno "Send Diagnostics?\n\nCurrent: ${DIAGNOSTICS}" 10 58 \ --yesno "${dialog_text[*]}" 14 64 \
--yes-button "Yes" --no-button "Back"; then --yes-button "Enable" --no-button "Keep disabled"; then
DIAGNOSTICS="yes" DIAGNOSTICS="yes"
sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics sed -i 's/^DIAGNOSTICS=.*/DIAGNOSTICS=yes/' /usr/local/community-scripts/diagnostics
whiptail --msgbox "Diagnostics set to ${DIAGNOSTICS}." 8 58 whiptail --msgbox "Telemetry enabled.\n\nNote: Existing containers keep their current setting.\nNew containers will inherit this choice." 10 58
fi fi
fi fi
} }
@@ -3561,6 +3554,7 @@ build_container() {
# Core exports for install.func # Core exports for install.func
export DIAGNOSTICS="$DIAGNOSTICS" export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID" export RANDOM_UUID="$RANDOM_UUID"
export EXECUTION_ID="$EXECUTION_ID"
export SESSION_ID="$SESSION_ID" export SESSION_ID="$SESSION_ID"
export CACHER="$APT_CACHER" export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP" export CACHER_IP="$APT_CACHER_IP"
@@ -3666,9 +3660,6 @@ $PCT_OPTIONS_STRING"
exit 214 exit 214
fi fi
msg_ok "Storage space validated" msg_ok "Storage space validated"
# Report installation start to API (early - captures failed installs too)
post_to_api
fi fi
create_lxc_container || exit $? create_lxc_container || exit $?
@@ -3914,6 +3905,7 @@ EOF
for i in {1..10}; do for i in {1..10}; do
if pct status "$CTID" | grep -q "status: running"; then if pct status "$CTID" | grep -q "status: running"; then
msg_ok "Started LXC Container" msg_ok "Started LXC Container"
post_progress_to_api # Signal container is running
break break
fi fi
sleep 1 sleep 1
@@ -3968,6 +3960,7 @@ EOF
echo -e "${YW}Container may have limited internet access. Installation will continue...${CL}" echo -e "${YW}Container may have limited internet access. Installation will continue...${CL}"
else else
msg_ok "Network in LXC is reachable (ping)" msg_ok "Network in LXC is reachable (ping)"
post_progress_to_api # Signal network is ready
fi fi
fi fi
# Function to get correct GID inside container # Function to get correct GID inside container
@@ -4039,6 +4032,7 @@ EOF'
fi fi
msg_ok "Customized LXC Container" msg_ok "Customized LXC Container"
post_progress_to_api # Signal ready for app installation
# Optional DNS override for retry scenarios (inside LXC, never on host) # Optional DNS override for retry scenarios (inside LXC, never on host)
if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then
@@ -4112,9 +4106,9 @@ EOF'
build_log_copied=true build_log_copied=true
fi fi
# Copy and append INSTALL_LOG from container # Copy and append INSTALL_LOG from container (with timeout to prevent hangs)
local temp_install_log="/tmp/.install-temp-${SESSION_ID}.log" 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 if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
{ {
echo "================================================================================" echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container)" echo "PHASE 2: APPLICATION INSTALLATION (Container)"
@@ -4894,6 +4888,9 @@ create_lxc_container() {
exit 206 exit 206
fi fi
# Report installation start to API early - captures failures in storage/template/create
post_to_api
# Storage capability check # Storage capability check
check_storage_support "rootdir" || { check_storage_support "rootdir" || {
msg_error "No valid storage found for 'rootdir' [Container]" msg_error "No valid storage found for 'rootdir' [Container]"
@@ -5423,9 +5420,7 @@ create_lxc_container() {
} }
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created." msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
post_progress_to_api # Signal container creation complete
# Report container creation to API
post_to_api
} }
# ============================================================================== # ==============================================================================
@@ -5498,6 +5493,7 @@ EOF
# - If INSTALL_LOG points to a container path (e.g. /root/.install-*), # - If INSTALL_LOG points to a container path (e.g. /root/.install-*),
# tries to pull it from the container and create a combined log # tries to pull it from the container and create a combined log
# - This allows get_error_text() to find actual error output for telemetry # - This allows get_error_text() to find actual error output for telemetry
# - Uses timeout on pct pull to prevent hangs on dead/unresponsive containers
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ensure_log_on_host() { ensure_log_on_host() {
# Already readable on host? Nothing to do. # Already readable on host? Nothing to do.
@@ -5527,9 +5523,9 @@ ensure_log_on_host() {
echo "" echo ""
} >>"$combined_log" } >>"$combined_log"
fi fi
# Pull INSTALL_LOG from container # Pull INSTALL_LOG from container (with timeout to prevent hangs on dead containers)
local temp_log="/tmp/.install-temp-${SESSION_ID}.log" local temp_log="/tmp/.install-temp-${SESSION_ID}.log"
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_log" 2>/dev/null; then if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_log" 2>/dev/null; then
{ {
echo "================================================================================" echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container)" echo "PHASE 2: APPLICATION INSTALLATION (Container)"
@@ -5552,6 +5548,8 @@ ensure_log_on_host() {
# - Exit trap handler for reporting to API telemetry # - Exit trap handler for reporting to API telemetry
# - Captures exit code and reports to PocketBase using centralized error descriptions # - Captures exit code and reports to PocketBase using centralized error descriptions
# - Uses explain_exit_code() from api.func for consistent error messages # - Uses explain_exit_code() from api.func for consistent error messages
# - ALWAYS sends telemetry FIRST before log collection to prevent pct pull
# hangs from blocking status updates (container may be dead/unresponsive)
# - For non-zero exit codes: posts "failed" status # - For non-zero exit codes: posts "failed" status
# - For zero exit codes where post_update_to_api was never called: # - For zero exit codes where post_update_to_api was never called:
# catches orphaned "installing" records (e.g., script exited cleanly # catches orphaned "installing" records (e.g., script exited cleanly
@@ -5560,8 +5558,13 @@ ensure_log_on_host() {
api_exit_script() { api_exit_script() {
local exit_code=$? local exit_code=$?
if [ $exit_code -ne 0 ]; then if [ $exit_code -ne 0 ]; then
ensure_log_on_host # ALWAYS send telemetry FIRST - ensure status is reported even if
post_update_to_api "failed" "$exit_code" # ensure_log_on_host hangs (e.g. pct pull on dead container)
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
# Best-effort log collection with timeout (non-critical after telemetry is sent)
if declare -f ensure_log_on_host >/dev/null 2>&1; then
timeout 10 bash -c 'ensure_log_on_host' 2>/dev/null || true
fi
elif [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then elif [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
# Script exited with 0 but never sent a completion status # Script exited with 0 but never sent a completion status
# exit_code=0 is never an error — report as success # exit_code=0 is never an error — report as success
@@ -5572,7 +5575,7 @@ api_exit_script() {
if command -v pveversion >/dev/null 2>&1; then if command -v pveversion >/dev/null 2>&1; then
trap 'api_exit_script' EXIT trap 'api_exit_script' EXIT
fi fi
trap 'local _ec=$?; if [[ $_ec -ne 0 ]]; then ensure_log_on_host; post_update_to_api "failed" "$_ec"; fi' ERR trap 'local _ec=$?; if [[ $_ec -ne 0 ]]; then post_update_to_api "failed" "$_ec" 2>/dev/null || true; timeout 10 bash -c "ensure_log_on_host" 2>/dev/null || true; fi' ERR
trap 'ensure_log_on_host; post_update_to_api "failed" "129"; exit 129' SIGHUP trap 'post_update_to_api "failed" "129" 2>/dev/null || true; timeout 10 bash -c "ensure_log_on_host" 2>/dev/null || true; exit 129' SIGHUP
trap 'ensure_log_on_host; post_update_to_api "failed" "130"; exit 130' SIGINT trap 'post_update_to_api "failed" "130" 2>/dev/null || true; timeout 10 bash -c "ensure_log_on_host" 2>/dev/null || true; exit 130' SIGINT
trap 'ensure_log_on_host; post_update_to_api "failed" "143"; exit 143' SIGTERM trap 'post_update_to_api "failed" "143" 2>/dev/null || true; timeout 10 bash -c "ensure_log_on_host" 2>/dev/null || true; exit 143' SIGTERM

View File

@@ -1496,6 +1496,11 @@ cleanup_lxc() {
fi fi
msg_ok "Cleaned" msg_ok "Cleaned"
# Send progress ping if available (defined in install.func)
if declare -f post_progress_to_api &>/dev/null; then
post_progress_to_api
fi
} }
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@@ -204,6 +204,12 @@ error_handler() {
printf "\e[?25h" printf "\e[?25h"
# ALWAYS report failure to API immediately - don't wait for container checks
# This ensures we capture failures that occur before/after container exists
if declare -f post_update_to_api &>/dev/null; then
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
fi
# Use msg_error if available, fallback to echo # Use msg_error if available, fallback to echo
if declare -f msg_error >/dev/null 2>&1; then if declare -f msg_error >/dev/null 2>&1; then
msg_error "in line ${line_number}: exit code ${exit_code} (${explanation}): while executing command ${command}" msg_error "in line ${line_number}: exit code ${exit_code} (${explanation}): while executing command ${command}"
@@ -254,11 +260,6 @@ error_handler() {
# Offer to remove container if it exists (build errors after container creation) # Offer to remove container if it exists (build errors after container creation)
if [[ -n "${CTID:-}" ]] && command -v pct &>/dev/null && pct status "$CTID" &>/dev/null; then if [[ -n "${CTID:-}" ]] && command -v pct &>/dev/null && pct status "$CTID" &>/dev/null; then
# Report failure to API before container cleanup
if declare -f post_update_to_api &>/dev/null; then
post_update_to_api "failed" "$exit_code"
fi
echo "" echo ""
if declare -f msg_custom >/dev/null 2>&1; then if declare -f msg_custom >/dev/null 2>&1; then
echo -en "${TAB}${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}" echo -en "${TAB}${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
@@ -329,6 +330,8 @@ error_handler() {
# - Cleans up lock files if lockfile variable is set # - Cleans up lock files if lockfile variable is set
# - Exits with captured exit code # - Exits with captured exit code
# - Always runs on script termination (success or failure) # - Always runs on script termination (success or failure)
# - For signal exits (>128): sends telemetry FIRST before log collection
# to prevent pct pull hangs from blocking status updates
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
on_exit() { on_exit() {
local exit_code=$? local exit_code=$?
@@ -337,14 +340,17 @@ on_exit() {
# post_to_api was called ("installing" sent) but post_update_to_api was never called # 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 [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
if declare -f post_update_to_api >/dev/null 2>&1; then if declare -f post_update_to_api >/dev/null 2>&1; then
# Ensure log is accessible on host before reporting # ALWAYS send telemetry FIRST - ensure status is reported even if
if declare -f ensure_log_on_host >/dev/null 2>&1; then # ensure_log_on_host hangs (e.g. pct pull on dead/unresponsive container)
ensure_log_on_host
fi
if [[ $exit_code -ne 0 ]]; then if [[ $exit_code -ne 0 ]]; then
post_update_to_api "failed" "$exit_code" post_update_to_api "failed" "$exit_code" 2>/dev/null || true
else else
post_update_to_api "failed" "1" # exit_code=0 is never an error — report as success
post_update_to_api "done" "0" 2>/dev/null || true
fi
# Best-effort log collection with timeout (non-critical after telemetry is sent)
if declare -f ensure_log_on_host >/dev/null 2>&1; then
timeout 10 bash -c 'ensure_log_on_host' 2>/dev/null || true
fi fi
fi fi
fi fi
@@ -356,22 +362,26 @@ on_exit() {
# on_interrupt() # on_interrupt()
# #
# - SIGINT (Ctrl+C) trap handler # - SIGINT (Ctrl+C) trap handler
# - Reports to telemetry FIRST (time-critical: container may be dying)
# - Displays "Interrupted by user" message # - Displays "Interrupted by user" message
# - Exits with code 130 (128 + SIGINT=2) # - Exits with code 130 (128 + SIGINT=2)
# - Output redirected to /dev/null fallback to prevent SIGPIPE on closed terminals
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
on_interrupt() { on_interrupt() {
# Ensure log is accessible on host before reporting # CRITICAL: Send telemetry FIRST before any cleanup or output
if declare -f ensure_log_on_host >/dev/null 2>&1; then # If ensure_log_on_host hangs (e.g. pct pull on dying container),
ensure_log_on_host # the status update would never be sent, leaving records stuck in "installing"
fi
# Report interruption to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "130" post_update_to_api "failed" "130" 2>/dev/null || true
fi
# Best-effort log collection with timeout (non-critical after telemetry is sent)
if declare -f ensure_log_on_host >/dev/null 2>&1; then
timeout 10 bash -c 'ensure_log_on_host' 2>/dev/null || true
fi fi
if declare -f msg_error >/dev/null 2>&1; then if declare -f msg_error >/dev/null 2>&1; then
msg_error "Interrupted by user (SIGINT)" msg_error "Interrupted by user (SIGINT)" 2>/dev/null || true
else else
echo -e "\n${RD}Interrupted by user (SIGINT)${CL}" echo -e "\n${RD}Interrupted by user (SIGINT)${CL}" 2>/dev/null || true
fi fi
exit 130 exit 130
} }
@@ -380,23 +390,27 @@ on_interrupt() {
# on_terminate() # on_terminate()
# #
# - SIGTERM trap handler # - SIGTERM trap handler
# - Reports to telemetry FIRST (time-critical: process being killed)
# - Displays "Terminated by signal" message # - Displays "Terminated by signal" message
# - Exits with code 143 (128 + SIGTERM=15) # - Exits with code 143 (128 + SIGTERM=15)
# - Triggered by external process termination # - Triggered by external process termination
# - Output redirected to /dev/null fallback to prevent SIGPIPE on closed terminals
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
on_terminate() { on_terminate() {
# Ensure log is accessible on host before reporting # CRITICAL: Send telemetry FIRST before any cleanup or output
if declare -f ensure_log_on_host >/dev/null 2>&1; then # Same rationale as on_interrupt: ensure status gets reported even if
ensure_log_on_host # ensure_log_on_host hangs or terminal is already closed
fi
# Report termination to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "143" post_update_to_api "failed" "143" 2>/dev/null || true
fi
# Best-effort log collection with timeout (non-critical after telemetry is sent)
if declare -f ensure_log_on_host >/dev/null 2>&1; then
timeout 10 bash -c 'ensure_log_on_host' 2>/dev/null || true
fi fi
if declare -f msg_error >/dev/null 2>&1; then if declare -f msg_error >/dev/null 2>&1; then
msg_error "Terminated by signal (SIGTERM)" msg_error "Terminated by signal (SIGTERM)" 2>/dev/null || true
else else
echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}" echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}" 2>/dev/null || true
fi fi
exit 143 exit 143
} }

View File

@@ -37,6 +37,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
load_functions load_functions
catch_errors catch_errors
# Persist diagnostics setting inside container (exported from build.func)
# so addon scripts running later can find the user's choice
if [[ ! -f /usr/local/community-scripts/diagnostics ]]; then
mkdir -p /usr/local/community-scripts
echo "DIAGNOSTICS=${DIAGNOSTICS:-no}" >/usr/local/community-scripts/diagnostics
fi
# Get LXC IP address (must be called INSIDE container, after network is up) # Get LXC IP address (must be called INSIDE container, after network is up)
get_lxc_ip get_lxc_ip
@@ -56,7 +63,7 @@ post_progress_to_api() {
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \ curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true -d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
} }
# ============================================================================== # ==============================================================================
@@ -278,6 +285,7 @@ motd_ssh() {
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
systemctl restart sshd systemctl restart sshd
fi fi
post_progress_to_api
} }
# ============================================================================== # ==============================================================================
@@ -316,4 +324,5 @@ EOF
chmod 700 /root/.ssh chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys
fi fi
post_progress_to_api
} }

View File

@@ -22,7 +22,7 @@ set -e
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon"
while true; do while true; do
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn

View File

@@ -25,7 +25,7 @@ function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon"
header_info header_info

View File

@@ -45,7 +45,7 @@ function msg() {
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon"
function validate_container_id() { function validate_container_id() {
local ctid="$1" local ctid="$1"

View File

@@ -29,7 +29,7 @@ silent() { "$@" >/dev/null 2>&1; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon"
set -e set -e
header_info header_info

View File

@@ -33,7 +33,7 @@ CROSS="${RD}✗${CL} "
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-iptag" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-iptag" "pve"
# Stop any running spinner # Stop any running spinner
stop_spinner() { stop_spinner() {

View File

@@ -24,7 +24,7 @@ CL="\033[m"
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "clean-lxcs" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "clean-lxcs" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -18,7 +18,7 @@ EOF
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "clean-orphaned-lvm" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "clean-orphaned-lvm" "pve"
# Function to check for orphaned LVM volumes # Function to check for orphaned LVM volumes
function find_orphaned_lvm { function find_orphaned_lvm {

View File

@@ -46,7 +46,7 @@ header_info
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "container-restore" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "container-restore" "pve"
function msg_info() { function msg_info() {
local msg="$1" local msg="$1"

View File

@@ -46,7 +46,7 @@ header_info
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "core-restore" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "core-restore" "pve"
function msg_info() { function msg_info() {
local msg="$1" local msg="$1"

View File

@@ -25,7 +25,7 @@ CL=$(echo "\033[m")
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "execute-lxcs" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "execute-lxcs" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -18,7 +18,7 @@ EOF
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "frigate-support" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "frigate-support" "pve"
header_info header_info
while true; do while true; do

View File

@@ -21,7 +21,7 @@ CL="\033[m"
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "fstrim" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "fstrim" "pve"
LOGFILE="/var/log/fstrim.log" LOGFILE="/var/log/fstrim.log"
touch "$LOGFILE" touch "$LOGFILE"

View File

@@ -18,7 +18,7 @@ EOF
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "host-backup" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "host-backup" "pve"
# Function to perform backup # Function to perform backup
function perform_backup { function perform_backup {

View File

@@ -32,7 +32,7 @@ set -e
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "hw-acceleration" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "hw-acceleration" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -24,7 +24,7 @@ CL="\033[m"
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "kernel-clean" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "kernel-clean" "pve"
# Detect current kernel # Detect current kernel
current_kernel=$(uname -r) current_kernel=$(uname -r)

View File

@@ -28,7 +28,7 @@ available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2,
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "kernel-pin" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "kernel-pin" "pve"
header_info header_info

View File

@@ -40,7 +40,7 @@ CM="${TAB}✔️${TAB}${CL}"
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "lxc-delete" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "lxc-delete" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -31,7 +31,7 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "microcode" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "microcode" "pve"
header_info header_info
current_microcode=$(journalctl -k | grep -i 'microcode: Current revision:' | grep -oP 'Current revision: \K0x[0-9a-f]+') current_microcode=$(journalctl -k | grep -i 'microcode: Current revision:' | grep -oP 'Current revision: \K0x[0-9a-f]+')

View File

@@ -17,7 +17,7 @@ EOF
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "monitor-all" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "monitor-all" "pve"
add() { add() {
echo -e "\n IMPORTANT: Tag-Based Monitoring Enabled" echo -e "\n IMPORTANT: Tag-Based Monitoring Enabled"

View File

@@ -35,7 +35,7 @@ EOF
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "nic-offloading-fix" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "nic-offloading-fix" "pve"
header_info header_info

View File

@@ -46,7 +46,7 @@ msg_error() {
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs3-upgrade" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs3-upgrade" "pve"
start_routines() { start_routines() {
header_info header_info

View File

@@ -34,7 +34,7 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs4-upgrade" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs4-upgrade" "pve"
start_routines() { start_routines() {
header_info header_info

View File

@@ -31,7 +31,7 @@ msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs-microcode" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pbs-microcode" "pve"
msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; } msg_ok() { echo -e "${BFR} ${CM} ${GN}$1${CL}"; }
msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; } msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; }

View File

@@ -34,7 +34,7 @@ msg_error() { echo -e "${BFR} ${CROSS} ${RD}$1${CL}"; }
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pbs-install" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pbs-install" "pve"
# ---- helpers ---- # ---- helpers ----
get_pbs_codename() { get_pbs_codename() {

View File

@@ -45,7 +45,7 @@ msg_error() {
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pmg-install" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pmg-install" "pve"
if ! grep -q "Proxmox Mail Gateway" /etc/issue 2>/dev/null; then if ! grep -q "Proxmox Mail Gateway" /etc/issue 2>/dev/null; then
msg_error "This script is only intended for Proxmox Mail Gateway" msg_error "This script is only intended for Proxmox Mail Gateway"

View File

@@ -46,7 +46,7 @@ msg_error() {
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pve-install" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pve-install" "pve"
get_pve_version() { get_pve_version() {
local pve_ver local pve_ver

View File

@@ -13,7 +13,7 @@ fi
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/core.func) source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
load_functions load_functions
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pve-privilege-converter" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pve-privilege-converter" "pve"
set -euo pipefail set -euo pipefail
shopt -s inherit_errexit nullglob shopt -s inherit_errexit nullglob

View File

@@ -46,7 +46,7 @@ msg_error() {
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pve8-upgrade" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "pve8-upgrade" "pve"
start_routines() { start_routines() {
header_info header_info

View File

@@ -8,7 +8,7 @@ set -e
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "scaling-governor" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "scaling-governor" "pve"
header_info() { header_info() {
clear clear

View File

@@ -6,7 +6,7 @@
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-apps" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-apps" "pve"
# ============================================================================= # =============================================================================
# CONFIGURATION VARIABLES # CONFIGURATION VARIABLES

View File

@@ -27,7 +27,7 @@ CL=$(echo "\033[m")
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-lxcs" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-lxcs" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -25,7 +25,7 @@ CL=$(echo "\033[m")
# Telemetry # Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-repo" "tool" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-repo" "pve"
header_info header_info
echo "Loading..." echo "Loading..."

View File

@@ -91,6 +91,17 @@ function cleanup() {
rm -rf $TEMP_DIR rm -rf $TEMP_DIR
} }
function check_disk_space() {
local path="$1"
local required_gb="$2"
local available_kb=$(df -k "$path" | awk 'NR==2 {print $4}')
local available_gb=$((available_kb / 1024 / 1024))
if [ $available_gb -lt $required_gb ]; then
return 1
fi
return 0
}
TEMP_DIR=$(mktemp -d) TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null pushd $TEMP_DIR >/dev/null
function send_line_to_vm() { function send_line_to_vm() {
@@ -605,11 +616,41 @@ if [ -z "$URL" ]; then
exit 1 exit 1
fi fi
msg_ok "Download URL: ${CL}${BL}${URL}${CL}" msg_ok "Download URL: ${CL}${BL}${URL}${CL}"
# Check available disk space (require at least 20GB for safety)
if ! check_disk_space "$TEMP_DIR" 20; then
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
msg_error "Insufficient disk space in temporary directory ($TEMP_DIR)."
msg_error "Available: ${AVAILABLE_GB}, Required: ~20GB for FreeBSD image decompression."
msg_error "Please free up space or ensure /tmp has sufficient storage."
exit 1
fi
msg_info "Downloading FreeBSD Image"
curl -f#SL -o "$(basename "$URL")" "$URL" curl -f#SL -o "$(basename "$URL")" "$URL"
echo -en "\e[1A\e[0K" echo -en "\e[1A\e[0K"
msg_ok "Downloaded ${CL}${BL}$(basename "$URL")${CL}"
# Check disk space again before decompression
if ! check_disk_space "$TEMP_DIR" 15; then
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
msg_error "Insufficient disk space for decompression."
msg_error "Available: ${AVAILABLE_GB}, Required: ~15GB for decompressed image."
exit 1
fi
msg_info "Decompressing FreeBSD Image (this may take a few minutes)"
FILE=FreeBSD.qcow2 FILE=FreeBSD.qcow2
unxz -cv $(basename $URL) >${FILE} if ! unxz -cv $(basename $URL) >${FILE}; then
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" msg_error "Failed to decompress FreeBSD image."
msg_error "This is usually caused by insufficient disk space."
df -h "$TEMP_DIR"
exit 1
fi
# Remove the compressed file to save space
rm -f "$(basename "$URL")"
msg_ok "Decompressed ${CL}${BL}${FILE}${CL}"
STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')
case $STORAGE_TYPE in case $STORAGE_TYPE in
@@ -649,7 +690,7 @@ qm set $VMID \
-boot order=scsi0 \ -boot order=scsi0 \
-serial0 socket \ -serial0 socket \
-tags community-script >/dev/null -tags community-script >/dev/null
qm resize $VMID scsi0 10G >/dev/null qm resize $VMID scsi0 20G >/dev/null
DESCRIPTION=$( DESCRIPTION=$(
cat <<EOF cat <<EOF
<div align='center'> <div align='center'>