mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-18 03:03:25 +01:00
Compare commits
1 Commits
feature/ex
...
fix/immich
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcd0a6faaa |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -422,21 +422,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- core: call get_lxc_ip in start() before updates [@MickLesk](https://github.com/MickLesk) ([#12015](https://github.com/community-scripts/ProxmoxVE/pull/12015))
|
- core: call get_lxc_ip in start() before updates [@MickLesk](https://github.com/MickLesk) ([#12015](https://github.com/community-scripts/ProxmoxVE/pull/12015))
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools/pve: add data analytics / formatting / linting [@MickLesk](https://github.com/MickLesk) ([#12034](https://github.com/community-scripts/ProxmoxVE/pull/12034))
|
|
||||||
- core: smart recovery for failed installs | extend exit_codes [@MickLesk](https://github.com/MickLesk) ([#11221](https://github.com/community-scripts/ProxmoxVE/pull/11221))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: error-handler improvements | better exit_code handling | better tools.func source check [@MickLesk](https://github.com/MickLesk) ([#12019](https://github.com/community-scripts/ProxmoxVE/pull/12019))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Immich Public Proxy: centralize and fix systemd service creation [@MickLesk](https://github.com/MickLesk) ([#12025](https://github.com/community-scripts/ProxmoxVE/pull/12025))
|
|
||||||
|
|
||||||
## 2026-02-16
|
## 2026-02-16
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-02-17T12:14:18Z",
|
"generated": "2026-02-17T06:22:06Z",
|
||||||
"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.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T11:44:48Z"
|
"date": "2026-01-29T15:29:25Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "byparr",
|
"slug": "byparr",
|
||||||
@@ -207,9 +207,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "comfyui",
|
"slug": "comfyui",
|
||||||
"repo": "comfyanonymous/ComfyUI",
|
"repo": "comfyanonymous/ComfyUI",
|
||||||
"version": "v0.14.0",
|
"version": "v0.13.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T06:29:10Z"
|
"date": "2026-02-10T20:27:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "commafeed",
|
"slug": "commafeed",
|
||||||
@@ -253,13 +253,6 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-11T15:39:05Z"
|
"date": "2026-02-11T15:39:05Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "databasus",
|
|
||||||
"repo": "databasus/databasus",
|
|
||||||
"version": "v3.12.2",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-02-14T22:28:59Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "dawarich",
|
"slug": "dawarich",
|
||||||
"repo": "Freika/dawarich",
|
"repo": "Freika/dawarich",
|
||||||
@@ -557,9 +550,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "huntarr",
|
"slug": "huntarr",
|
||||||
"repo": "plexguide/Huntarr.io",
|
"repo": "plexguide/Huntarr.io",
|
||||||
"version": "9.3.0",
|
"version": "9.2.4.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T06:34:38Z"
|
"date": "2026-02-12T22:17:47Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "immich-public-proxy",
|
"slug": "immich-public-proxy",
|
||||||
@@ -788,9 +781,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "mail-archiver",
|
"slug": "mail-archiver",
|
||||||
"repo": "s1t5/mail-archiver",
|
"repo": "s1t5/mail-archiver",
|
||||||
"version": "2602.2",
|
"version": "2602.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T09:46:52Z"
|
"date": "2026-02-11T06:23:11Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "managemydamnlife",
|
"slug": "managemydamnlife",
|
||||||
@@ -1110,9 +1103,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pocketbase",
|
"slug": "pocketbase",
|
||||||
"repo": "pocketbase/pocketbase",
|
"repo": "pocketbase/pocketbase",
|
||||||
"version": "v0.36.4",
|
"version": "v0.36.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T08:02:51Z"
|
"date": "2026-02-13T18:38:58Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pocketid",
|
"slug": "pocketid",
|
||||||
@@ -1488,9 +1481,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",
|
||||||
|
|||||||
@@ -11,35 +11,9 @@ 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
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# post_progress_to_api()
|
|
||||||
#
|
|
||||||
# - Lightweight progress ping from inside the container
|
|
||||||
# - Updates the existing telemetry record status from "installing" 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
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
post_progress_to_api() {
|
|
||||||
command -v curl &>/dev/null || return 0
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
|
||||||
|
|
||||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-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
|
||||||
verb_ip6() {
|
verb_ip6() {
|
||||||
set_std_mode # Set STD mode based on VERBOSE
|
set_std_mode # Set STD mode based on VERBOSE
|
||||||
@@ -79,7 +53,6 @@ setting_up_container() {
|
|||||||
fi
|
fi
|
||||||
msg_ok "Set up Container OS"
|
msg_ok "Set up Container OS"
|
||||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
||||||
@@ -112,18 +85,8 @@ network_check() {
|
|||||||
update_os() {
|
update_os() {
|
||||||
msg_info "Updating Container OS"
|
msg_info "Updating Container OS"
|
||||||
$STD apk -U upgrade
|
$STD apk -U upgrade
|
||||||
local tools_content
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
|
||||||
msg_error "Failed to download tools.func"
|
|
||||||
exit 6
|
|
||||||
}
|
|
||||||
source /dev/stdin <<<"$tools_content"
|
|
||||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
|
||||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
|
||||||
exit 6
|
|
||||||
fi
|
|
||||||
msg_ok "Updated Container OS"
|
msg_ok "Updated Container OS"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function modifies the message of the day (motd) and SSH settings
|
# This function modifies the message of the day (motd) and SSH settings
|
||||||
|
|||||||
115
misc/api.func
115
misc/api.func
@@ -117,17 +117,16 @@ detect_repo_source
|
|||||||
# - Canonical source of truth for ALL exit code mappings
|
# - Canonical source of truth for ALL exit code mappings
|
||||||
# - Used by both api.func (telemetry) and error_handler.func (error display)
|
# - Used by both api.func (telemetry) and error_handler.func (error display)
|
||||||
# - Supports:
|
# - Supports:
|
||||||
# * Generic/Shell errors (1-3, 10, 124-132, 134, 137, 139, 141, 143-146)
|
# * Generic/Shell errors (1, 2, 124, 126-130, 134, 137, 139, 141, 143)
|
||||||
# * curl/wget errors (4-8, 16, 18, 22-28, 30, 32-36, 39, 44-48, 51-52, 55-57, 59, 61, 63, 75, 78-79, 92, 95)
|
# * curl/wget errors (6, 7, 22, 28, 35)
|
||||||
# * Package manager errors (APT, DPKG: 100-102, 255)
|
# * Package manager errors (APT, DPKG: 100-102, 255)
|
||||||
# * BSD sysexits (64-78)
|
|
||||||
# * Systemd/Service errors (150-154)
|
# * Systemd/Service errors (150-154)
|
||||||
# * Python/pip/uv errors (160-162)
|
# * Python/pip/uv errors (160-162)
|
||||||
# * PostgreSQL errors (170-173)
|
# * PostgreSQL errors (170-173)
|
||||||
# * MySQL/MariaDB errors (180-183)
|
# * MySQL/MariaDB errors (180-183)
|
||||||
# * MongoDB errors (190-193)
|
# * MongoDB errors (190-193)
|
||||||
# * Proxmox custom codes (200-231)
|
# * Proxmox custom codes (200-231)
|
||||||
# * Node.js/npm errors (239, 243, 245-249)
|
# * Node.js/npm errors (243, 245-249)
|
||||||
# - Returns description string for given exit code
|
# - Returns description string for given exit code
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
explain_exit_code() {
|
explain_exit_code() {
|
||||||
@@ -136,7 +135,6 @@ explain_exit_code() {
|
|||||||
# --- Generic / Shell ---
|
# --- Generic / Shell ---
|
||||||
1) echo "General error / Operation not permitted" ;;
|
1) echo "General error / Operation not permitted" ;;
|
||||||
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
||||||
3) echo "General syntax or argument error" ;;
|
|
||||||
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
||||||
|
|
||||||
# --- curl / wget errors (commonly seen in downloads) ---
|
# --- curl / wget errors (commonly seen in downloads) ---
|
||||||
@@ -144,41 +142,16 @@ explain_exit_code() {
|
|||||||
5) echo "curl: Could not resolve proxy" ;;
|
5) echo "curl: Could not resolve proxy" ;;
|
||||||
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
||||||
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
||||||
8) echo "curl: Server reply error (FTP/SFTP or apk untrusted key)" ;;
|
8) echo "curl: FTP server reply error" ;;
|
||||||
16) echo "curl: HTTP/2 framing layer error" ;;
|
|
||||||
18) echo "curl: Partial file (transfer not completed)" ;;
|
|
||||||
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
||||||
23) echo "curl: Write error (disk full or permissions)" ;;
|
23) echo "curl: Write error (disk full or permissions)" ;;
|
||||||
24) echo "curl: Write to local file failed" ;;
|
|
||||||
25) echo "curl: Upload failed" ;;
|
25) echo "curl: Upload failed" ;;
|
||||||
26) echo "curl: Read error on local file (I/O)" ;;
|
|
||||||
27) echo "curl: Out of memory (memory allocation failed)" ;;
|
|
||||||
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
||||||
30) echo "curl: FTP port command failed" ;;
|
30) echo "curl: FTP port command failed" ;;
|
||||||
32) echo "curl: FTP SIZE command failed" ;;
|
|
||||||
33) echo "curl: HTTP range error" ;;
|
|
||||||
34) echo "curl: HTTP post error" ;;
|
|
||||||
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
||||||
36) echo "curl: FTP bad download resume" ;;
|
|
||||||
39) echo "curl: LDAP search failed" ;;
|
|
||||||
44) echo "curl: Internal error (bad function call order)" ;;
|
|
||||||
45) echo "curl: Interface error (failed to bind to specified interface)" ;;
|
|
||||||
46) echo "curl: Bad password entered" ;;
|
|
||||||
47) echo "curl: Too many redirects" ;;
|
|
||||||
48) echo "curl: Unknown command line option specified" ;;
|
|
||||||
51) echo "curl: SSL peer certificate or SSH host key verification failed" ;;
|
|
||||||
52) echo "curl: Empty reply from server (got nothing)" ;;
|
|
||||||
55) echo "curl: Failed sending network data" ;;
|
|
||||||
56) echo "curl: Receive error (connection reset by peer)" ;;
|
56) echo "curl: Receive error (connection reset by peer)" ;;
|
||||||
57) echo "curl: Unrecoverable poll/select error (system I/O failure)" ;;
|
|
||||||
59) echo "curl: Couldn't use specified SSL cipher" ;;
|
|
||||||
61) echo "curl: Bad/unrecognized transfer encoding" ;;
|
|
||||||
63) echo "curl: Maximum file size exceeded" ;;
|
|
||||||
75) echo "Temporary failure (retry later)" ;;
|
75) echo "Temporary failure (retry later)" ;;
|
||||||
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
||||||
79) echo "curl: SSH session error (key exchange/auth failed)" ;;
|
|
||||||
92) echo "curl: HTTP/2 stream error (protocol violation)" ;;
|
|
||||||
95) echo "curl: HTTP/3 layer error" ;;
|
|
||||||
|
|
||||||
# --- Package manager / APT / DPKG ---
|
# --- Package manager / APT / DPKG ---
|
||||||
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
||||||
@@ -202,21 +175,15 @@ explain_exit_code() {
|
|||||||
|
|
||||||
# --- Common shell/system errors ---
|
# --- Common shell/system errors ---
|
||||||
124) echo "Command timed out (timeout command)" ;;
|
124) echo "Command timed out (timeout command)" ;;
|
||||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
|
||||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||||
127) echo "Command not found" ;;
|
127) echo "Command not found" ;;
|
||||||
128) echo "Invalid argument to exit" ;;
|
128) echo "Invalid argument to exit" ;;
|
||||||
129) echo "Killed by SIGHUP (terminal closed / hangup)" ;;
|
|
||||||
130) echo "Aborted by user (SIGINT)" ;;
|
130) echo "Aborted by user (SIGINT)" ;;
|
||||||
131) echo "Killed by SIGQUIT (core dumped)" ;;
|
|
||||||
132) echo "Killed by SIGILL (illegal CPU instruction)" ;;
|
|
||||||
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
||||||
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
||||||
139) echo "Segmentation fault (core dumped)" ;;
|
139) echo "Segmentation fault (core dumped)" ;;
|
||||||
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
||||||
143) echo "Terminated (SIGTERM)" ;;
|
143) echo "Terminated (SIGTERM)" ;;
|
||||||
144) echo "Killed by signal 16 (SIGUSR1 / SIGSTKFLT)" ;;
|
|
||||||
146) echo "Killed by signal 18 (SIGTSTP)" ;;
|
|
||||||
|
|
||||||
# --- Systemd / Service errors (150-154) ---
|
# --- Systemd / Service errors (150-154) ---
|
||||||
150) echo "Systemd: Service failed to start" ;;
|
150) echo "Systemd: Service failed to start" ;;
|
||||||
@@ -224,6 +191,7 @@ explain_exit_code() {
|
|||||||
152) echo "Permission denied (EACCES)" ;;
|
152) echo "Permission denied (EACCES)" ;;
|
||||||
153) echo "Build/compile failed (make/gcc/cmake)" ;;
|
153) echo "Build/compile failed (make/gcc/cmake)" ;;
|
||||||
154) echo "Node.js: Native addon build failed (node-gyp)" ;;
|
154) echo "Node.js: Native addon build failed (node-gyp)" ;;
|
||||||
|
|
||||||
# --- Python / pip / uv (160-162) ---
|
# --- Python / pip / uv (160-162) ---
|
||||||
160) echo "Python: Virtualenv / uv environment missing or broken" ;;
|
160) echo "Python: Virtualenv / uv environment missing or broken" ;;
|
||||||
161) echo "Python: Dependency resolution failed" ;;
|
161) echo "Python: Dependency resolution failed" ;;
|
||||||
@@ -274,8 +242,7 @@ explain_exit_code() {
|
|||||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||||
|
|
||||||
# --- Node.js / npm / pnpm / yarn (239-249) ---
|
# --- Node.js / npm / pnpm / yarn (243-249) ---
|
||||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
|
||||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||||
245) echo "Node.js: Invalid command-line option" ;;
|
245) echo "Node.js: Invalid command-line option" ;;
|
||||||
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
||||||
@@ -552,7 +519,6 @@ 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",
|
||||||
@@ -657,7 +623,6 @@ 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",
|
||||||
@@ -790,7 +755,6 @@ 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}",
|
||||||
@@ -833,7 +797,6 @@ 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}",
|
||||||
@@ -876,7 +839,6 @@ 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}",
|
||||||
@@ -913,9 +875,6 @@ categorize_error() {
|
|||||||
# Network errors (curl/wget)
|
# Network errors (curl/wget)
|
||||||
6 | 7 | 22 | 35) echo "network" ;;
|
6 | 7 | 22 | 35) echo "network" ;;
|
||||||
|
|
||||||
# Docker / Privileged mode required
|
|
||||||
10) echo "config" ;;
|
|
||||||
|
|
||||||
# Timeout errors
|
# Timeout errors
|
||||||
28 | 124 | 211) echo "timeout" ;;
|
28 | 124 | 211) echo "timeout" ;;
|
||||||
|
|
||||||
@@ -990,63 +949,6 @@ get_install_duration() {
|
|||||||
echo $((now - INSTALL_START_TIME))
|
echo $((now - INSTALL_START_TIME))
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _telemetry_report_exit()
|
|
||||||
#
|
|
||||||
# - Internal handler called by EXIT trap set in init_tool_telemetry()
|
|
||||||
# - Determines success/failure from exit code and reports via appropriate API
|
|
||||||
# - Arguments:
|
|
||||||
# * $1: exit_code from the script
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
_telemetry_report_exit() {
|
|
||||||
local ec="${1:-0}"
|
|
||||||
local status="success"
|
|
||||||
[[ "$ec" -ne 0 ]] && status="failed"
|
|
||||||
|
|
||||||
# Lazy name resolution: use explicit name, fall back to $APP, then "unknown"
|
|
||||||
local name="${TELEMETRY_TOOL_NAME:-${APP:-unknown}}"
|
|
||||||
|
|
||||||
if [[ "${TELEMETRY_TOOL_TYPE:-pve}" == "addon" ]]; then
|
|
||||||
post_addon_to_api "$name" "$status" "$ec"
|
|
||||||
else
|
|
||||||
post_tool_to_api "$name" "$status" "$ec"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# init_tool_telemetry()
|
|
||||||
#
|
|
||||||
# - One-line telemetry setup for tools/addon scripts
|
|
||||||
# - 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
|
|
||||||
# - Sets EXIT trap to automatically report success/failure on script exit
|
|
||||||
# - Arguments:
|
|
||||||
# * $1: tool_name (optional, falls back to $APP at exit time)
|
|
||||||
# * $2: type ("pve" for PVE host scripts, "addon" for container addons)
|
|
||||||
# - Usage:
|
|
||||||
# source <(curl -fsSL .../misc/api.func) 2>/dev/null || true
|
|
||||||
# init_tool_telemetry "post-pve-install" "pve"
|
|
||||||
# init_tool_telemetry "" "addon" # uses $APP at exit time
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
init_tool_telemetry() {
|
|
||||||
local name="${1:-}"
|
|
||||||
local type="${2:-pve}"
|
|
||||||
|
|
||||||
[[ -n "$name" ]] && TELEMETRY_TOOL_NAME="$name"
|
|
||||||
TELEMETRY_TOOL_TYPE="$type"
|
|
||||||
|
|
||||||
# Read diagnostics opt-in/opt-out
|
|
||||||
if [[ -f /usr/local/community-scripts/diagnostics ]]; then
|
|
||||||
DIAGNOSTICS=$(grep -i "^DIAGNOSTICS=" /usr/local/community-scripts/diagnostics 2>/dev/null | awk -F'=' '{print $2}') || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
start_install_timer
|
|
||||||
|
|
||||||
# EXIT trap: automatically report telemetry when script ends
|
|
||||||
trap '_telemetry_report_exit "$?"' EXIT
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# post_tool_to_api()
|
# post_tool_to_api()
|
||||||
#
|
#
|
||||||
@@ -1094,8 +996,7 @@ post_tool_to_api() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
{
|
{
|
||||||
"random_id": "${uuid}",
|
"random_id": "${uuid}",
|
||||||
"execution_id": "${EXECUTION_ID:-${uuid}}",
|
"type": "tool",
|
||||||
"type": "pve",
|
|
||||||
"nsapp": "${tool_name}",
|
"nsapp": "${tool_name}",
|
||||||
"status": "${status}",
|
"status": "${status}",
|
||||||
"exit_code": ${exit_code},
|
"exit_code": ${exit_code},
|
||||||
@@ -1162,7 +1063,6 @@ 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}",
|
||||||
@@ -1254,7 +1154,6 @@ 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}",
|
||||||
|
|||||||
479
misc/build.func
479
misc/build.func
@@ -42,10 +42,9 @@ 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="no" # Safe default: no telemetry until user consents via diagnostics_check()
|
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.
|
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
|
||||||
@@ -2788,85 +2787,93 @@ 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 (first run only)
|
# - Asks user whether to send anonymous diagnostic data
|
||||||
# - Saves DIAGNOSTICS=yes/no in the config file
|
# - Saves DIAGNOSTICS=yes/no in the config file
|
||||||
# - Reads current diagnostics setting from existing file
|
# - Creates file if missing with default DIAGNOSTICS=yes
|
||||||
|
# - 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() {
|
||||||
local config_dir="/usr/local/community-scripts"
|
if ! [ -d "/usr/local/community-scripts" ]; then
|
||||||
local config_file="${config_dir}/diagnostics"
|
mkdir -p /usr/local/community-scripts
|
||||||
|
|
||||||
mkdir -p "$config_dir"
|
|
||||||
|
|
||||||
if [[ -f "$config_file" ]]; then
|
|
||||||
DIAGNOSTICS=$(awk -F '=' '/^DIAGNOSTICS/ {print $2}' "$config_file") || true
|
|
||||||
DIAGNOSTICS="${DIAGNOSTICS:-no}"
|
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local result
|
if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then
|
||||||
result=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
|
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
|
||||||
--title "TELEMETRY & DIAGNOSTICS" \
|
cat <<EOF >/usr/local/community-scripts/diagnostics
|
||||||
--ok-button "Confirm" --cancel-button "Exit" \
|
DIAGNOSTICS=yes
|
||||||
--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"
|
|
||||||
|
|
||||||
DIAGNOSTICS="${result:-no}"
|
#This file is used to store the diagnostics settings for the Community-Scripts API.
|
||||||
|
#https://github.com/community-scripts/ProxmoxVE/discussions/1836
|
||||||
cat <<EOF >"$config_file"
|
#Your diagnostics will be sent to the Community-Scripts API for troubleshooting/statistical purposes.
|
||||||
DIAGNOSTICS=${DIAGNOSTICS}
|
#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.
|
||||||
# Community-Scripts Telemetry Configuration
|
#This will disable the diagnostics feature.
|
||||||
# https://telemetry.community-scripts.org
|
#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.
|
||||||
# This file stores your telemetry preference.
|
#The following information will be sent:
|
||||||
# Set DIAGNOSTICS=yes to share anonymous installation data.
|
#"disk_size"
|
||||||
# Set DIAGNOSTICS=no to disable telemetry.
|
#"core_count"
|
||||||
#
|
#"ram_size"
|
||||||
# You can also change this via the Settings menu during installation.
|
#"os_type"
|
||||||
#
|
#"os_version"
|
||||||
# Data collected (when enabled):
|
#"nsapp"
|
||||||
# disk_size, core_count, ram_size, os_type, os_version,
|
#"method"
|
||||||
# nsapp, method, pve_version, status, exit_code
|
#"pve_version"
|
||||||
#
|
#"status"
|
||||||
# No personal data (IPs, hostnames, passwords) is ever collected.
|
#If you have any concerns, please review the source code at /misc/build.func
|
||||||
# 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() {
|
||||||
local current="${DIAGNOSTICS:-no}"
|
if [ "${DIAGNOSTICS:-no}" = "yes" ]; then
|
||||||
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 "TELEMETRY SETTINGS" \
|
--title "DIAGNOSTIC SETTINGS" \
|
||||||
--yesno "${dialog_text[*]}" 14 64 \
|
--yesno "Send Diagnostics?\n\nCurrent: ${DIAGNOSTICS}" 10 58 \
|
||||||
--yes-button "Disable" --no-button "Keep enabled"; then
|
--yes-button "No" --no-button "Back"; 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 "Telemetry disabled.\n\nNote: Existing containers keep their current setting.\nNew containers will inherit this choice." 10 58
|
whiptail --msgbox "Diagnostics set to ${DIAGNOSTICS}." 8 58
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if whiptail --backtitle "Proxmox VE Helper Scripts" \
|
if whiptail --backtitle "Proxmox VE Helper Scripts" \
|
||||||
--title "TELEMETRY SETTINGS" \
|
--title "DIAGNOSTIC SETTINGS" \
|
||||||
--yesno "${dialog_text[*]}" 14 64 \
|
--yesno "Send Diagnostics?\n\nCurrent: ${DIAGNOSTICS}" 10 58 \
|
||||||
--yes-button "Enable" --no-button "Keep disabled"; then
|
--yes-button "Yes" --no-button "Back"; 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 "Telemetry enabled.\n\nNote: Existing containers keep their current setting.\nNew containers will inherit this choice." 10 58
|
whiptail --msgbox "Diagnostics set to ${DIAGNOSTICS}." 8 58
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -3554,7 +3561,6 @@ 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"
|
||||||
@@ -4034,13 +4040,6 @@ EOF'
|
|||||||
|
|
||||||
msg_ok "Customized LXC Container"
|
msg_ok "Customized LXC Container"
|
||||||
|
|
||||||
# Optional DNS override for retry scenarios (inside LXC, never on host)
|
|
||||||
if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then
|
|
||||||
msg_info "Applying DNS retry override in LXC (8.8.8.8, 1.1.1.1)"
|
|
||||||
pct exec "$CTID" -- bash -c "printf 'nameserver 8.8.8.8\nnameserver 1.1.1.1\n' >/etc/resolv.conf" >/dev/null 2>&1 || true
|
|
||||||
msg_ok "DNS override applied in LXC"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install SSH keys
|
# Install SSH keys
|
||||||
install_ssh_keys_into_ct
|
install_ssh_keys_into_ct
|
||||||
|
|
||||||
@@ -4153,322 +4152,32 @@ EOF'
|
|||||||
|
|
||||||
# Prompt user for cleanup with 60s timeout
|
# Prompt user for cleanup with 60s timeout
|
||||||
echo ""
|
echo ""
|
||||||
|
echo -en "${TAB}❓${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||||
# Detect error type for smart recovery options
|
|
||||||
local is_oom=false
|
|
||||||
local is_network_issue=false
|
|
||||||
local is_apt_issue=false
|
|
||||||
local is_cmd_not_found=false
|
|
||||||
local error_explanation=""
|
|
||||||
if declare -f explain_exit_code >/dev/null 2>&1; then
|
|
||||||
error_explanation="$(explain_exit_code "$install_exit_code")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# OOM detection: exit codes 134 (SIGABRT/heap), 137 (SIGKILL/OOM), 243 (Node.js heap)
|
|
||||||
if [[ $install_exit_code -eq 134 || $install_exit_code -eq 137 || $install_exit_code -eq 243 ]]; then
|
|
||||||
is_oom=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# APT/DPKG detection: exit codes 100-102 (APT), 255 (DPKG with log evidence)
|
|
||||||
case "$install_exit_code" in
|
|
||||||
100 | 101 | 102) is_apt_issue=true ;;
|
|
||||||
255)
|
|
||||||
if [[ -f "$combined_log" ]] && grep -qiE 'dpkg|apt-get|apt\.conf|broken packages|unmet dependencies|E: Sub-process|E: Failed' "$combined_log"; then
|
|
||||||
is_apt_issue=true
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Command not found detection
|
|
||||||
if [[ $install_exit_code -eq 127 ]]; then
|
|
||||||
is_cmd_not_found=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Network-related detection (curl/apt/git fetch failures and transient network issues)
|
|
||||||
case "$install_exit_code" in
|
|
||||||
6 | 7 | 22 | 28 | 35 | 52 | 56 | 57 | 75 | 78) is_network_issue=true ;;
|
|
||||||
100)
|
|
||||||
# APT can fail due to network (Failed to fetch)
|
|
||||||
if [[ -f "$combined_log" ]] && grep -qiE 'Failed to fetch|Could not resolve|Connection failed|Network is unreachable|Temporary failure resolving' "$combined_log"; then
|
|
||||||
is_network_issue=true
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
128)
|
|
||||||
if [[ -f "$combined_log" ]] && grep -qiE 'RPC failed|early EOF|fetch-pack|HTTP/2 stream|Could not resolve host|Temporary failure resolving|Failed to fetch|Connection reset|Network is unreachable' "$combined_log"; then
|
|
||||||
is_network_issue=true
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Exit 1 subclassification: analyze logs to identify actual root cause
|
|
||||||
# Many exit 1 errors are actually APT, OOM, network, or command-not-found issues
|
|
||||||
if [[ $install_exit_code -eq 1 && -f "$combined_log" ]]; then
|
|
||||||
if grep -qiE 'E: Unable to|E: Package|E: Failed to fetch|dpkg.*error|broken packages|unmet dependencies|dpkg --configure -a' "$combined_log"; then
|
|
||||||
is_apt_issue=true
|
|
||||||
fi
|
|
||||||
if grep -qiE 'Cannot allocate memory|Out of memory|oom-killer|Killed process|JavaScript heap' "$combined_log"; then
|
|
||||||
is_oom=true
|
|
||||||
fi
|
|
||||||
if grep -qiE 'Could not resolve|DNS|Connection refused|Network is unreachable|No route to host|Temporary failure resolving|Failed to fetch' "$combined_log"; then
|
|
||||||
is_network_issue=true
|
|
||||||
fi
|
|
||||||
if grep -qiE ': command not found|No such file or directory.*/s?bin/' "$combined_log"; then
|
|
||||||
is_cmd_not_found=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show error explanation if available
|
|
||||||
if [[ -n "$error_explanation" ]]; then
|
|
||||||
echo -e "${TAB}${RD}Error: ${error_explanation}${CL}"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show specific hints for known error types
|
|
||||||
if [[ $install_exit_code -eq 10 ]]; then
|
|
||||||
echo -e "${TAB}${INFO} This error usually means the container needs ${GN}privileged${CL} mode or Docker/nesting support."
|
|
||||||
echo -e "${TAB}${INFO} Recreate with: Advanced Install → Container Type: ${GN}Privileged${CL}"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $install_exit_code -eq 125 || $install_exit_code -eq 126 ]]; then
|
|
||||||
echo -e "${TAB}${INFO} The command exists but cannot be executed. This may be a ${GN}permission${CL} issue."
|
|
||||||
echo -e "${TAB}${INFO} If using Docker, ensure the container is ${GN}privileged${CL} or has correct permissions."
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$is_cmd_not_found" == true ]]; then
|
|
||||||
local missing_cmd=""
|
|
||||||
if [[ -f "$combined_log" ]]; then
|
|
||||||
missing_cmd=$(grep -oiE '[a-zA-Z0-9_.-]+: command not found' "$combined_log" | tail -1 | sed 's/: command not found//')
|
|
||||||
fi
|
|
||||||
if [[ -n "$missing_cmd" ]]; then
|
|
||||||
echo -e "${TAB}${INFO} Missing command: ${GN}${missing_cmd}${CL}"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build recovery menu based on error type
|
|
||||||
echo -e "${YW}What would you like to do?${CL}"
|
|
||||||
echo ""
|
|
||||||
echo -e " ${GN}1)${CL} Remove container and exit"
|
|
||||||
echo -e " ${GN}2)${CL} Keep container for debugging"
|
|
||||||
echo -e " ${GN}3)${CL} Retry with verbose mode (full rebuild)"
|
|
||||||
|
|
||||||
local next_option=4
|
|
||||||
local APT_OPTION="" OOM_OPTION="" DNS_OPTION=""
|
|
||||||
|
|
||||||
if [[ "$is_apt_issue" == true ]]; then
|
|
||||||
if [[ "$var_os" == "alpine" ]]; then
|
|
||||||
echo -e " ${GN}${next_option})${CL} Repair APK state and re-run install (in-place)"
|
|
||||||
else
|
|
||||||
echo -e " ${GN}${next_option})${CL} Repair APT/DPKG state and re-run install (in-place)"
|
|
||||||
fi
|
|
||||||
APT_OPTION=$next_option
|
|
||||||
next_option=$((next_option + 1))
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$is_oom" == true ]]; then
|
|
||||||
local recovery_attempt="${RECOVERY_ATTEMPT:-0}"
|
|
||||||
if [[ $recovery_attempt -lt 2 ]]; then
|
|
||||||
local new_ram=$((RAM_SIZE * 2))
|
|
||||||
local new_cpu=$((CORE_COUNT * 2))
|
|
||||||
echo -e " ${GN}${next_option})${CL} Retry with more resources (RAM: ${RAM_SIZE}→${new_ram} MiB, CPU: ${CORE_COUNT}→${new_cpu} cores)"
|
|
||||||
OOM_OPTION=$next_option
|
|
||||||
next_option=$((next_option + 1))
|
|
||||||
else
|
|
||||||
echo -e " ${DGN}-)${CL} ${DGN}OOM retry exhausted (already retried ${recovery_attempt}x)${CL}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$is_network_issue" == true ]]; then
|
|
||||||
echo -e " ${GN}${next_option})${CL} Retry with DNS override in LXC (8.8.8.8 / 1.1.1.1)"
|
|
||||||
DNS_OPTION=$next_option
|
|
||||||
next_option=$((next_option + 1))
|
|
||||||
fi
|
|
||||||
|
|
||||||
local max_option=$((next_option - 1))
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -en "${YW}Select option [1-${max_option}] (default: 1, auto-remove in 60s): ${CL}"
|
|
||||||
|
|
||||||
if read -t 60 -r response; then
|
if read -t 60 -r response; then
|
||||||
case "${response:-1}" in
|
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||||
1)
|
|
||||||
# Remove container
|
# Remove container
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID}${CL}"
|
echo ""
|
||||||
|
msg_info "Removing container ${CTID}"
|
||||||
pct stop "$CTID" &>/dev/null || true
|
pct stop "$CTID" &>/dev/null || true
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
pct destroy "$CTID" &>/dev/null || true
|
||||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
msg_ok "Container ${CTID} removed"
|
||||||
;;
|
elif [[ "$response" =~ ^[Nn]$ ]]; then
|
||||||
2)
|
echo ""
|
||||||
echo -e "\n${TAB}${YW}Container ${CTID} kept for debugging${CL}"
|
msg_warn "Container ${CTID} kept for debugging"
|
||||||
|
|
||||||
# Dev mode: Setup MOTD/SSH for debugging access to broken container
|
# Dev mode: Setup MOTD/SSH for debugging access to broken container
|
||||||
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
|
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
|
||||||
echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}"
|
echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}"
|
||||||
if pct exec "$CTID" -- bash -c "
|
if pct exec "$CTID" -- bash -c "
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/install.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/install.func)
|
||||||
declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true
|
declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true
|
||||||
" >/dev/null 2>&1; then
|
" >/dev/null 2>&1; then
|
||||||
local ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
|
local ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
|
||||||
echo -e "${BFR}${CM}${GN}MOTD/SSH ready - SSH into container: ssh root@${ct_ip}${CL}"
|
echo -e "${BFR}${CM}${GN}MOTD/SSH ready - SSH into container: ssh root@${ct_ip}${CL}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
exit $install_exit_code
|
fi
|
||||||
;;
|
|
||||||
3)
|
|
||||||
# Retry with verbose mode (full rebuild)
|
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID} for rebuild...${CL}"
|
|
||||||
pct stop "$CTID" &>/dev/null || true
|
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
|
||||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
|
||||||
echo ""
|
|
||||||
# Get new container ID
|
|
||||||
local old_ctid="$CTID"
|
|
||||||
export CTID=$(get_valid_container_id "$CTID")
|
|
||||||
export VERBOSE="yes"
|
|
||||||
export var_verbose="yes"
|
|
||||||
|
|
||||||
# Show rebuild summary
|
|
||||||
echo -e "${YW}Rebuilding with preserved settings:${CL}"
|
|
||||||
echo -e " Container ID: ${old_ctid} → ${CTID}"
|
|
||||||
echo -e " RAM: ${RAM_SIZE} MiB | CPU: ${CORE_COUNT} cores | Disk: ${DISK_SIZE} GB"
|
|
||||||
echo -e " Network: ${NET:-dhcp} | Bridge: ${BRG:-vmbr0}"
|
|
||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
|
||||||
echo ""
|
|
||||||
msg_info "Restarting installation..."
|
|
||||||
# Re-run build_container
|
|
||||||
build_container
|
|
||||||
return $?
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Handle dynamic smart recovery options via named option variables
|
|
||||||
local handled=false
|
|
||||||
|
|
||||||
if [[ -n "${APT_OPTION}" && "${response}" == "${APT_OPTION}" ]]; then
|
|
||||||
# Package manager in-place repair: fix broken state and re-run install script
|
|
||||||
handled=true
|
|
||||||
if [[ "$var_os" == "alpine" ]]; then
|
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Repairing APK state in container ${CTID}...${CL}"
|
|
||||||
pct exec "$CTID" -- ash -c "
|
|
||||||
apk fix 2>/dev/null || true
|
|
||||||
apk cache clean 2>/dev/null || true
|
|
||||||
apk update 2>/dev/null || true
|
|
||||||
" >/dev/null 2>&1 || true
|
|
||||||
echo -e "${BFR}${CM}${GN}APK state repaired in container ${CTID}${CL}"
|
|
||||||
else
|
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Repairing APT/DPKG state in container ${CTID}...${CL}"
|
|
||||||
pct exec "$CTID" -- bash -c "
|
|
||||||
DEBIAN_FRONTEND=noninteractive dpkg --configure -a 2>/dev/null || true
|
|
||||||
apt-get -f install -y 2>/dev/null || true
|
|
||||||
apt-get clean 2>/dev/null
|
|
||||||
apt-get update 2>/dev/null || true
|
|
||||||
" >/dev/null 2>&1 || true
|
|
||||||
echo -e "${BFR}${CM}${GN}APT/DPKG state repaired in container ${CTID}${CL}"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
export VERBOSE="yes"
|
|
||||||
export var_verbose="yes"
|
|
||||||
|
|
||||||
echo -e "${YW}Re-running installation in existing container ${CTID}:${CL}"
|
|
||||||
echo -e " RAM: ${RAM_SIZE} MiB | CPU: ${CORE_COUNT} cores | Disk: ${DISK_SIZE} GB"
|
|
||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
|
||||||
echo ""
|
|
||||||
msg_info "Re-running installation script..."
|
|
||||||
|
|
||||||
# Re-run install script in existing container (don't destroy/recreate)
|
|
||||||
set +Eeuo pipefail
|
|
||||||
trap - ERR
|
|
||||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
|
|
||||||
local apt_retry_exit=$?
|
|
||||||
set -Eeuo pipefail
|
|
||||||
trap 'error_handler' ERR
|
|
||||||
|
|
||||||
# Check for error flag from retry
|
|
||||||
local apt_retry_code=0
|
|
||||||
if [[ -n "${SESSION_ID:-}" ]]; then
|
|
||||||
local retry_error_flag="/root/.install-${SESSION_ID}.failed"
|
|
||||||
if pct exec "$CTID" -- test -f "$retry_error_flag" 2>/dev/null; then
|
|
||||||
apt_retry_code=$(pct exec "$CTID" -- cat "$retry_error_flag" 2>/dev/null || echo "1")
|
|
||||||
pct exec "$CTID" -- rm -f "$retry_error_flag" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $apt_retry_code -eq 0 && $apt_retry_exit -ne 0 ]]; then
|
|
||||||
apt_retry_code=$apt_retry_exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $apt_retry_code -eq 0 ]]; then
|
|
||||||
msg_ok "Installation completed successfully after APT repair!"
|
|
||||||
post_update_to_api "done" "0" "force"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
msg_error "Installation still failed after APT repair (exit code: ${apt_retry_code})"
|
|
||||||
install_exit_code=$apt_retry_code
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "${OOM_OPTION}" && "${response}" == "${OOM_OPTION}" ]]; then
|
|
||||||
# Retry with doubled resources
|
|
||||||
handled=true
|
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID} for rebuild with more resources...${CL}"
|
|
||||||
pct stop "$CTID" &>/dev/null || true
|
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
|
||||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
|
||||||
echo ""
|
|
||||||
local old_ctid="$CTID"
|
|
||||||
local old_ram="$RAM_SIZE"
|
|
||||||
local old_cpu="$CORE_COUNT"
|
|
||||||
export CTID=$(get_valid_container_id "$CTID")
|
|
||||||
export RAM_SIZE=$((RAM_SIZE * 2))
|
|
||||||
export CORE_COUNT=$((CORE_COUNT * 2))
|
|
||||||
export var_ram="$RAM_SIZE"
|
|
||||||
export var_cpu="$CORE_COUNT"
|
|
||||||
export VERBOSE="yes"
|
|
||||||
export var_verbose="yes"
|
|
||||||
export RECOVERY_ATTEMPT=$((${RECOVERY_ATTEMPT:-0} + 1))
|
|
||||||
|
|
||||||
echo -e "${YW}Rebuilding with increased resources (attempt ${RECOVERY_ATTEMPT}/2):${CL}"
|
|
||||||
echo -e " Container ID: ${old_ctid} → ${CTID}"
|
|
||||||
echo -e " RAM: ${old_ram} → ${GN}${RAM_SIZE}${CL} MiB (x2)"
|
|
||||||
echo -e " CPU: ${old_cpu} → ${GN}${CORE_COUNT}${CL} cores (x2)"
|
|
||||||
echo -e " Disk: ${DISK_SIZE} GB | Network: ${NET:-dhcp} | Bridge: ${BRG:-vmbr0}"
|
|
||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
|
||||||
echo ""
|
|
||||||
msg_info "Restarting installation..."
|
|
||||||
build_container
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "${DNS_OPTION}" && "${response}" == "${DNS_OPTION}" ]]; then
|
|
||||||
# Retry with DNS override in LXC
|
|
||||||
handled=true
|
|
||||||
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID} for rebuild with DNS override...${CL}"
|
|
||||||
pct stop "$CTID" &>/dev/null || true
|
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
|
||||||
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
|
|
||||||
echo ""
|
|
||||||
local old_ctid="$CTID"
|
|
||||||
export CTID=$(get_valid_container_id "$CTID")
|
|
||||||
export DNS_RETRY_OVERRIDE="true"
|
|
||||||
export VERBOSE="yes"
|
|
||||||
export var_verbose="yes"
|
|
||||||
|
|
||||||
echo -e "${YW}Rebuilding with DNS override in LXC:${CL}"
|
|
||||||
echo -e " Container ID: ${old_ctid} → ${CTID}"
|
|
||||||
echo -e " DNS: ${GN}8.8.8.8, 1.1.1.1${CL} (inside LXC only)"
|
|
||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
|
||||||
echo ""
|
|
||||||
msg_info "Restarting installation..."
|
|
||||||
build_container
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$handled" == false ]]; then
|
|
||||||
echo -e "\n${TAB}${YW}Invalid option. Container ${CTID} kept.${CL}"
|
|
||||||
exit $install_exit_code
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
else
|
||||||
# Timeout - auto-remove
|
# Timeout - auto-remove
|
||||||
echo ""
|
echo ""
|
||||||
@@ -5546,8 +5255,6 @@ 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
|
||||||
# - For signal exits (>128): sends telemetry FIRST before log collection
|
|
||||||
# to prevent pct pull hangs from blocking status updates
|
|
||||||
# - 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
|
||||||
@@ -5556,26 +5263,18 @@ 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
|
||||||
if [ $exit_code -gt 128 ]; then
|
ensure_log_on_host
|
||||||
# Signal exit: send telemetry IMMEDIATELY (container may be dying)
|
post_update_to_api "failed" "$exit_code"
|
||||||
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
|
||||||
ensure_log_on_host 2>/dev/null || true
|
|
||||||
else
|
|
||||||
# Normal error: collect logs first for better error details
|
|
||||||
ensure_log_on_host 2>/dev/null || true
|
|
||||||
post_update_to_api "failed" "$exit_code"
|
|
||||||
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
|
# This catches edge cases like early returns after post_to_api()
|
||||||
post_update_to_api "done" "0"
|
post_update_to_api "failed" "1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
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 2>/dev/null || true; post_update_to_api "failed" "$_ec"; fi' ERR
|
trap 'ensure_log_on_host; post_update_to_api "failed" "$?"' ERR
|
||||||
trap 'post_update_to_api "failed" "129" 2>/dev/null || true; 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; 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; ensure_log_on_host 2>/dev/null || true; exit 143' SIGTERM
|
|
||||||
|
|||||||
@@ -37,47 +37,21 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
case "$code" in
|
case "$code" in
|
||||||
1) echo "General error / Operation not permitted" ;;
|
1) echo "General error / Operation not permitted" ;;
|
||||||
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
||||||
3) echo "General syntax or argument error" ;;
|
|
||||||
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
||||||
4) echo "curl: Feature not supported or protocol error" ;;
|
4) echo "curl: Feature not supported or protocol error" ;;
|
||||||
5) echo "curl: Could not resolve proxy" ;;
|
5) echo "curl: Could not resolve proxy" ;;
|
||||||
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
||||||
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
||||||
8) echo "curl: Server reply error (FTP/SFTP or apk untrusted key)" ;;
|
8) echo "curl: FTP server reply error" ;;
|
||||||
16) echo "curl: HTTP/2 framing layer error" ;;
|
|
||||||
18) echo "curl: Partial file (transfer not completed)" ;;
|
|
||||||
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
||||||
23) echo "curl: Write error (disk full or permissions)" ;;
|
23) echo "curl: Write error (disk full or permissions)" ;;
|
||||||
24) echo "curl: Write to local file failed" ;;
|
|
||||||
25) echo "curl: Upload failed" ;;
|
25) echo "curl: Upload failed" ;;
|
||||||
26) echo "curl: Read error on local file (I/O)" ;;
|
|
||||||
27) echo "curl: Out of memory (memory allocation failed)" ;;
|
|
||||||
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
||||||
30) echo "curl: FTP port command failed" ;;
|
30) echo "curl: FTP port command failed" ;;
|
||||||
32) echo "curl: FTP SIZE command failed" ;;
|
|
||||||
33) echo "curl: HTTP range error" ;;
|
|
||||||
34) echo "curl: HTTP post error" ;;
|
|
||||||
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
||||||
36) echo "curl: FTP bad download resume" ;;
|
|
||||||
39) echo "curl: LDAP search failed" ;;
|
|
||||||
44) echo "curl: Internal error (bad function call order)" ;;
|
|
||||||
45) echo "curl: Interface error (failed to bind to specified interface)" ;;
|
|
||||||
46) echo "curl: Bad password entered" ;;
|
|
||||||
47) echo "curl: Too many redirects" ;;
|
|
||||||
48) echo "curl: Unknown command line option specified" ;;
|
|
||||||
51) echo "curl: SSL peer certificate or SSH host key verification failed" ;;
|
|
||||||
52) echo "curl: Empty reply from server (got nothing)" ;;
|
|
||||||
55) echo "curl: Failed sending network data" ;;
|
|
||||||
56) echo "curl: Receive error (connection reset by peer)" ;;
|
56) echo "curl: Receive error (connection reset by peer)" ;;
|
||||||
57) echo "curl: Unrecoverable poll/select error (system I/O failure)" ;;
|
|
||||||
59) echo "curl: Couldn't use specified SSL cipher" ;;
|
|
||||||
61) echo "curl: Bad/unrecognized transfer encoding" ;;
|
|
||||||
63) echo "curl: Maximum file size exceeded" ;;
|
|
||||||
75) echo "Temporary failure (retry later)" ;;
|
75) echo "Temporary failure (retry later)" ;;
|
||||||
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
||||||
79) echo "curl: SSH session error (key exchange/auth failed)" ;;
|
|
||||||
92) echo "curl: HTTP/2 stream error (protocol violation)" ;;
|
|
||||||
95) echo "curl: HTTP/3 layer error" ;;
|
|
||||||
64) echo "Usage error (wrong arguments)" ;;
|
64) echo "Usage error (wrong arguments)" ;;
|
||||||
65) echo "Data format error (bad input data)" ;;
|
65) echo "Data format error (bad input data)" ;;
|
||||||
66) echo "Input file not found (cannot open input)" ;;
|
66) echo "Input file not found (cannot open input)" ;;
|
||||||
@@ -95,21 +69,15 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||||
124) echo "Command timed out (timeout command)" ;;
|
124) echo "Command timed out (timeout command)" ;;
|
||||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
|
||||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||||
127) echo "Command not found" ;;
|
127) echo "Command not found" ;;
|
||||||
128) echo "Invalid argument to exit" ;;
|
128) echo "Invalid argument to exit" ;;
|
||||||
129) echo "Killed by SIGHUP (terminal closed / hangup)" ;;
|
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
|
||||||
130) echo "Aborted by user (SIGINT)" ;;
|
|
||||||
131) echo "Killed by SIGQUIT (core dumped)" ;;
|
|
||||||
132) echo "Killed by SIGILL (illegal CPU instruction)" ;;
|
|
||||||
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
||||||
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
||||||
139) echo "Segmentation fault (core dumped)" ;;
|
139) echo "Segmentation fault (core dumped)" ;;
|
||||||
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
||||||
143) echo "Terminated (SIGTERM)" ;;
|
143) echo "Terminated (SIGTERM)" ;;
|
||||||
144) echo "Killed by signal 16 (SIGUSR1 / SIGSTKFLT)" ;;
|
|
||||||
146) echo "Killed by signal 18 (SIGTSTP)" ;;
|
|
||||||
150) echo "Systemd: Service failed to start" ;;
|
150) echo "Systemd: Service failed to start" ;;
|
||||||
151) echo "Systemd: Service unit not found" ;;
|
151) echo "Systemd: Service unit not found" ;;
|
||||||
152) echo "Permission denied (EACCES)" ;;
|
152) echo "Permission denied (EACCES)" ;;
|
||||||
@@ -155,7 +123,6 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
|
||||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||||
245) echo "Node.js: Invalid command-line option" ;;
|
245) echo "Node.js: Invalid command-line option" ;;
|
||||||
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
||||||
@@ -329,8 +296,6 @@ 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=$?
|
||||||
@@ -339,24 +304,14 @@ 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
|
||||||
if [[ $exit_code -gt 128 ]]; then
|
# Ensure log is accessible on host before reporting
|
||||||
# Signal exit: send telemetry IMMEDIATELY (container may be dying, pct pull could hang)
|
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
||||||
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
ensure_log_on_host
|
||||||
# Then try log collection (non-critical, best-effort)
|
fi
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
if [[ $exit_code -ne 0 ]]; then
|
||||||
ensure_log_on_host 2>/dev/null || true
|
post_update_to_api "failed" "$exit_code"
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
# Normal exit: collect logs first for better error details
|
post_update_to_api "failed" "1"
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
|
||||||
ensure_log_on_host 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
|
||||||
post_update_to_api "failed" "$exit_code"
|
|
||||||
else
|
|
||||||
# exit_code=0 is never an error — report as success
|
|
||||||
post_update_to_api "done" "0"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -368,26 +323,22 @@ 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() {
|
||||||
# CRITICAL: Send telemetry FIRST before any cleanup or output
|
# Ensure log is accessible on host before reporting
|
||||||
# If ensure_log_on_host hangs (e.g. pct pull on dying container),
|
|
||||||
# the status update would never be sent, leaving records stuck in "installing"
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
post_update_to_api "failed" "130" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
# Best-effort log collection (non-critical after telemetry is sent)
|
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
||||||
ensure_log_on_host 2>/dev/null || true
|
ensure_log_on_host
|
||||||
|
fi
|
||||||
|
# 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
|
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)" 2>/dev/null || true
|
msg_error "Interrupted by user (SIGINT)"
|
||||||
else
|
else
|
||||||
echo -e "\n${RD}Interrupted by user (SIGINT)${CL}" 2>/dev/null || true
|
echo -e "\n${RD}Interrupted by user (SIGINT)${CL}"
|
||||||
fi
|
fi
|
||||||
exit 130
|
exit 130
|
||||||
}
|
}
|
||||||
@@ -396,27 +347,23 @@ 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() {
|
||||||
# CRITICAL: Send telemetry FIRST before any cleanup or output
|
# Ensure log is accessible on host before reporting
|
||||||
# Same rationale as on_interrupt: ensure status gets reported even if
|
|
||||||
# ensure_log_on_host hangs or terminal is already closed
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
post_update_to_api "failed" "143" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
# Best-effort log collection (non-critical after telemetry is sent)
|
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
||||||
ensure_log_on_host 2>/dev/null || true
|
ensure_log_on_host
|
||||||
|
fi
|
||||||
|
# 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
|
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)" 2>/dev/null || true
|
msg_error "Terminated by signal (SIGTERM)"
|
||||||
else
|
else
|
||||||
echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}" 2>/dev/null || true
|
echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}"
|
||||||
fi
|
fi
|
||||||
exit 143
|
exit 143
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,35 +37,9 @@ 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
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# post_progress_to_api()
|
|
||||||
#
|
|
||||||
# - Lightweight progress ping from inside the container
|
|
||||||
# - Updates the existing telemetry record status from "installing" 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
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
post_progress_to_api() {
|
|
||||||
command -v curl &>/dev/null || return 0
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
|
||||||
|
|
||||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: NETWORK & CONNECTIVITY
|
# SECTION 2: NETWORK & CONNECTIVITY
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -129,7 +103,6 @@ setting_up_container() {
|
|||||||
msg_ok "Set up Container OS"
|
msg_ok "Set up Container OS"
|
||||||
#msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
|
#msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
|
||||||
msg_ok "Network Connected: ${BL}$(hostname -I)"
|
msg_ok "Network Connected: ${BL}$(hostname -I)"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -233,18 +206,8 @@ EOF
|
|||||||
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
||||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||||
msg_ok "Updated Container OS"
|
msg_ok "Updated Container OS"
|
||||||
post_progress_to_api
|
|
||||||
|
|
||||||
local tools_content
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
|
||||||
msg_error "Failed to download tools.func"
|
|
||||||
exit 6
|
|
||||||
}
|
|
||||||
source /dev/stdin <<<"$tools_content"
|
|
||||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
|
||||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
|
||||||
exit 6
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
@@ -19,11 +19,6 @@ EOF
|
|||||||
}
|
}
|
||||||
header_info
|
header_info
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "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
|
||||||
case $yn in
|
case $yn in
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ function msg_info() { echo -e " \e[1;36m➤\e[0m $1"; }
|
|||||||
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
|
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
|
||||||
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
|
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "addon"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
if ! command -v pveversion &>/dev/null; then
|
if ! command -v pveversion &>/dev/null; then
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=8080
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ function msg() {
|
|||||||
local TEXT="$1"
|
local TEXT="$1"
|
||||||
echo -e "$TEXT"
|
echo -e "$TEXT"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "addon"
|
|
||||||
|
|
||||||
function validate_container_id() {
|
function validate_container_id() {
|
||||||
local ctid="$1"
|
local ctid="$1"
|
||||||
# Check if ID is numeric
|
# Check if ID is numeric
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="Coder Code Server"
|
APP="Coder Code Server"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "coder-code-server" "addon"
|
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o errtrace
|
set -o errtrace
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="CrowdSec"
|
APP="CrowdSec"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "crowdsec" "addon"
|
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o errtrace
|
set -o errtrace
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ DEFAULT_PORT=8080
|
|||||||
SRC_DIR="/"
|
SRC_DIR="/"
|
||||||
TMP_BIN="/tmp/filebrowser.$$"
|
TMP_BIN="/tmp/filebrowser.$$"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "filebrowser-quantum" "addon"
|
|
||||||
|
|
||||||
# Get primary IP
|
# Get primary IP
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
function header_info {
|
function header_info {
|
||||||
clear
|
clear
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
_______ __ ____
|
_______ __ ____
|
||||||
/ ____(_) /__ / __ )_________ _ __________ _____
|
/ ____(_) /__ / __ )_________ _ __________ _____
|
||||||
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
|
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
|
||||||
@@ -29,10 +29,6 @@ INSTALL_PATH="/usr/local/bin/filebrowser"
|
|||||||
DB_PATH="/usr/local/community-scripts/filebrowser.db"
|
DB_PATH="/usr/local/community-scripts/filebrowser.db"
|
||||||
DEFAULT_PORT=8080
|
DEFAULT_PORT=8080
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "filebrowser" "addon"
|
|
||||||
|
|
||||||
# Get first non-loopback IP & Detect primary network interface dynamically
|
# Get first non-loopback IP & Detect primary network interface dynamically
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
@@ -42,65 +38,65 @@ IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n
|
|||||||
|
|
||||||
# Detect OS
|
# Detect OS
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
if [[ -f "/etc/alpine-release" ]]; then
|
||||||
OS="Alpine"
|
OS="Alpine"
|
||||||
SERVICE_PATH="/etc/init.d/filebrowser"
|
SERVICE_PATH="/etc/init.d/filebrowser"
|
||||||
PKG_MANAGER="apk add --no-cache"
|
PKG_MANAGER="apk add --no-cache"
|
||||||
elif [[ -f "/etc/debian_version" ]]; then
|
elif [[ -f "/etc/debian_version" ]]; then
|
||||||
OS="Debian"
|
OS="Debian"
|
||||||
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
|
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
|
||||||
PKG_MANAGER="apt-get install -y"
|
PKG_MANAGER="apt-get install -y"
|
||||||
else
|
else
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${INFO} ${YW}${msg}...${CL}"
|
echo -e "${INFO} ${YW}${msg}...${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function msg_ok() {
|
function msg_ok() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${CM} ${GN}${msg}${CL}"
|
echo -e "${CM} ${GN}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function msg_error() {
|
function msg_error() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${CROSS} ${RD}${msg}${CL}"
|
echo -e "${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -f "$INSTALL_PATH" ]; then
|
if [ -f "$INSTALL_PATH" ]; then
|
||||||
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
||||||
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
|
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
|
||||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Uninstalling ${APP}"
|
msg_info "Uninstalling ${APP}"
|
||||||
if [[ "$OS" == "Debian" ]]; then
|
if [[ "$OS" == "Debian" ]]; then
|
||||||
systemctl disable --now filebrowser.service &>/dev/null
|
systemctl disable --now filebrowser.service &>/dev/null
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
else
|
else
|
||||||
rc-service filebrowser stop &>/dev/null
|
rc-service filebrowser stop &>/dev/null
|
||||||
rc-update del filebrowser &>/dev/null
|
rc-update del filebrowser &>/dev/null
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
|
fi
|
||||||
|
rm -f "$INSTALL_PATH" "$DB_PATH"
|
||||||
|
msg_ok "${APP} has been uninstalled."
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
rm -f "$INSTALL_PATH" "$DB_PATH"
|
|
||||||
msg_ok "${APP} has been uninstalled."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
|
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
|
||||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Updating ${APP}"
|
msg_info "Updating ${APP}"
|
||||||
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
||||||
chmod +x "$INSTALL_PATH"
|
chmod +x "$INSTALL_PATH"
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Updated ${APP}"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
||||||
@@ -109,43 +105,43 @@ PORT=${PORT:-$DEFAULT_PORT}
|
|||||||
|
|
||||||
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
|
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
|
||||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Installing ${APP} on ${OS}"
|
msg_info "Installing ${APP} on ${OS}"
|
||||||
$PKG_MANAGER wget tar curl &>/dev/null
|
$PKG_MANAGER wget tar curl &>/dev/null
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
||||||
chmod +x "$INSTALL_PATH"
|
chmod +x "$INSTALL_PATH"
|
||||||
msg_ok "Installed ${APP}"
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
msg_info "Creating FileBrowser directory"
|
msg_info "Creating FileBrowser directory"
|
||||||
mkdir -p /usr/local/community-scripts
|
mkdir -p /usr/local/community-scripts
|
||||||
chown root:root /usr/local/community-scripts
|
chown root:root /usr/local/community-scripts
|
||||||
chmod 755 /usr/local/community-scripts
|
chmod 755 /usr/local/community-scripts
|
||||||
touch "$DB_PATH"
|
touch "$DB_PATH"
|
||||||
chown root:root "$DB_PATH"
|
chown root:root "$DB_PATH"
|
||||||
chmod 644 "$DB_PATH"
|
chmod 644 "$DB_PATH"
|
||||||
msg_ok "Directory created successfully"
|
msg_ok "Directory created successfully"
|
||||||
|
|
||||||
read -r -p "Would you like to use No Authentication? (y/N): " auth_prompt
|
read -r -p "Would you like to use No Authentication? (y/N): " auth_prompt
|
||||||
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Configuring No Authentication"
|
msg_info "Configuring No Authentication"
|
||||||
cd /usr/local/community-scripts
|
cd /usr/local/community-scripts
|
||||||
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config init --auth.method=noauth &>/dev/null
|
filebrowser config init --auth.method=noauth &>/dev/null
|
||||||
filebrowser config set --auth.method=noauth &>/dev/null
|
filebrowser config set --auth.method=noauth &>/dev/null
|
||||||
filebrowser users add ID 1 --perm.admin &>/dev/null
|
filebrowser users add ID 1 --perm.admin &>/dev/null
|
||||||
msg_ok "No Authentication configured"
|
msg_ok "No Authentication configured"
|
||||||
else
|
else
|
||||||
msg_info "Setting up default authentication"
|
msg_info "Setting up default authentication"
|
||||||
cd /usr/local/community-scripts
|
cd /usr/local/community-scripts
|
||||||
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
||||||
msg_ok "Default authentication configured (admin:helper-scripts.com)"
|
msg_ok "Default authentication configured (admin:helper-scripts.com)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Creating service"
|
msg_info "Creating service"
|
||||||
if [[ "$OS" == "Debian" ]]; then
|
if [[ "$OS" == "Debian" ]]; then
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
cat <<EOF >"$SERVICE_PATH"
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Filebrowser
|
Description=Filebrowser
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
@@ -161,9 +157,9 @@ Restart=always
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
systemctl enable -q --now filebrowser
|
systemctl enable -q --now filebrowser
|
||||||
else
|
else
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
cat <<EOF >"$SERVICE_PATH"
|
||||||
#!/sbin/openrc-run
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
command="/usr/local/bin/filebrowser"
|
command="/usr/local/bin/filebrowser"
|
||||||
@@ -176,14 +172,14 @@ depend() {
|
|||||||
need net
|
need net
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$SERVICE_PATH"
|
chmod +x "$SERVICE_PATH"
|
||||||
rc-update add filebrowser default &>/dev/null
|
rc-update add filebrowser default &>/dev/null
|
||||||
rc-service filebrowser start &>/dev/null
|
rc-service filebrowser start &>/dev/null
|
||||||
fi
|
fi
|
||||||
msg_ok "Service created successfully"
|
msg_ok "Service created successfully"
|
||||||
|
|
||||||
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
|
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -30,10 +30,6 @@ function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
|
|||||||
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
||||||
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "glances" "addon"
|
|
||||||
|
|
||||||
get_lxc_ip() {
|
get_lxc_ip() {
|
||||||
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
|
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
|
||||||
hostname -I | awk '{print $1}'
|
hostname -I | awk '{print $1}'
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=3000
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=3000
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ BFR="\\r\\033[K"
|
|||||||
HOLD="-"
|
HOLD="-"
|
||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
silent() { "$@" >/dev/null 2>&1; }
|
silent() { "$@" >/dev/null 2>&1; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "addon"
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="OliveTin"
|
APP="OliveTin"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "olivetin" "addon"
|
|
||||||
|
|
||||||
set-e
|
set-e
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ APP="phpMyAdmin"
|
|||||||
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
|
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
|
||||||
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
|
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "phpmyadmin" "addon"
|
|
||||||
|
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -8,13 +8,11 @@
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ function msg_error() {
|
|||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "pyenv" "addon"
|
|
||||||
|
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
msg_error "Can't Install on Proxmox "
|
msg_error "Can't Install on Proxmox "
|
||||||
exit
|
exit
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ msg_ok() {
|
|||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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 "webmin" "addon"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Webmin Installer" --yesno "This Will Install Webmin on this LXC Container. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Webmin Installer" --yesno "This Will Install Webmin on this LXC Container. Proceed?" 10 58
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ HOLD=" "
|
|||||||
CM="${GN}✓${CL} "
|
CM="${GN}✓${CL} "
|
||||||
CROSS="${RD}✗${CL} "
|
CROSS="${RD}✗${CL} "
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
# Stop any running spinner
|
# Stop any running spinner
|
||||||
stop_spinner() {
|
stop_spinner() {
|
||||||
if [ -n "$SPINNER_PID" ] && kill -0 "$SPINNER_PID" 2>/dev/null; then
|
if [ -n "$SPINNER_PID" ] && kill -0 "$SPINNER_PID" 2>/dev/null; then
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ CM='\xE2\x9C\x94\033'
|
|||||||
GN="\033[1;92m"
|
GN="\033[1;92m"
|
||||||
CL="\033[m"
|
CL="\033[m"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
function header_info {
|
function header_info {
|
||||||
clear
|
clear
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
____ ________ ____ __ __ __ _ ____ ___
|
____ ________ ____ __ __ __ _ ____ ___
|
||||||
/ __ \_________ _ ______ ___ ____ _ __ / ____/ /__ ____ _____ / __ \_________ / /_ ____ _____ ___ ____/ / / /| | / / |/ /____
|
/ __ \_________ _ ______ ___ ____ _ __ / ____/ /__ ____ _____ / __ \_________ / /_ ____ _____ ___ ____/ / / /| | / / |/ /____
|
||||||
/ /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / / / / _ \/ __ `/ __ \ / / / / ___/ __ \/ __ \/ __ `/ __ \/ _ \/ __ / / / | | / / /|_/ / ___/
|
/ /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/ / / / / _ \/ __ `/ __ \ / / / / ___/ __ \/ __ \/ __ `/ __ \/ _ \/ __ / / / | | / / /|_/ / ___/
|
||||||
@@ -16,66 +16,62 @@ function header_info {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
# Function to check for orphaned LVM volumes
|
# Function to check for orphaned LVM volumes
|
||||||
function find_orphaned_lvm {
|
function find_orphaned_lvm {
|
||||||
echo -e "\n🔍 Scanning for orphaned LVM volumes...\n"
|
echo -e "\n🔍 Scanning for orphaned LVM volumes...\n"
|
||||||
|
|
||||||
orphaned_volumes=()
|
orphaned_volumes=()
|
||||||
while read -r lv vg size seg_type; do
|
while read -r lv vg size seg_type; do
|
||||||
# Exclude system-critical LVs and Ceph OSDs
|
# Exclude system-critical LVs and Ceph OSDs
|
||||||
if [[ "$lv" == "data" || "$lv" == "root" || "$lv" == "swap" || "$lv" =~ ^osd-block- ]]; then
|
if [[ "$lv" == "data" || "$lv" == "root" || "$lv" == "swap" || "$lv" =~ ^osd-block- ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exclude thin pools (any name)
|
# Exclude thin pools (any name)
|
||||||
if [[ "$seg_type" == "thin-pool" ]]; then
|
if [[ "$seg_type" == "thin-pool" ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
container_id=$(echo "$lv" | grep -oE "[0-9]+" | head -1)
|
container_id=$(echo "$lv" | grep -oE "[0-9]+" | head -1)
|
||||||
# Check if the ID exists as a VM or LXC container
|
# Check if the ID exists as a VM or LXC container
|
||||||
if [ -f "/etc/pve/lxc/${container_id}.conf" ] || [ -f "/etc/pve/qemu-server/${container_id}.conf" ]; then
|
if [ -f "/etc/pve/lxc/${container_id}.conf" ] || [ -f "/etc/pve/qemu-server/${container_id}.conf" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
orphaned_volumes+=("$lv" "$vg" "$size")
|
orphaned_volumes+=("$lv" "$vg" "$size")
|
||||||
done < <(lvs --noheadings -o lv_name,vg_name,lv_size,seg_type --separator ' ' 2>/dev/null | awk '{print $1, $2, $3, $4}')
|
done < <(lvs --noheadings -o lv_name,vg_name,lv_size,seg_type --separator ' ' 2>/dev/null | awk '{print $1, $2, $3, $4}')
|
||||||
|
|
||||||
# Display orphaned volumes
|
# Display orphaned volumes
|
||||||
echo -e "❗ The following orphaned LVM volumes were found:\n"
|
echo -e "❗ The following orphaned LVM volumes were found:\n"
|
||||||
printf "%-25s %-10s %-10s\n" "LV Name" "VG" "Size"
|
printf "%-25s %-10s %-10s\n" "LV Name" "VG" "Size"
|
||||||
printf "%-25s %-10s %-10s\n" "-------------------------" "----------" "----------"
|
printf "%-25s %-10s %-10s\n" "-------------------------" "----------" "----------"
|
||||||
|
|
||||||
for ((i = 0; i < ${#orphaned_volumes[@]}; i += 3)); do
|
for ((i = 0; i < ${#orphaned_volumes[@]}; i += 3)); do
|
||||||
printf "%-25s %-10s %-10s\n" "${orphaned_volumes[i]}" "${orphaned_volumes[i + 1]}" "${orphaned_volumes[i + 2]}"
|
printf "%-25s %-10s %-10s\n" "${orphaned_volumes[i]}" "${orphaned_volumes[i + 1]}" "${orphaned_volumes[i + 2]}"
|
||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to delete selected volumes
|
# Function to delete selected volumes
|
||||||
function delete_orphaned_lvm {
|
function delete_orphaned_lvm {
|
||||||
for ((i = 0; i < ${#orphaned_volumes[@]}; i += 3)); do
|
for ((i = 0; i < ${#orphaned_volumes[@]}; i += 3)); do
|
||||||
lv="${orphaned_volumes[i]}"
|
lv="${orphaned_volumes[i]}"
|
||||||
vg="${orphaned_volumes[i + 1]}"
|
vg="${orphaned_volumes[i + 1]}"
|
||||||
size="${orphaned_volumes[i + 2]}"
|
size="${orphaned_volumes[i + 2]}"
|
||||||
|
|
||||||
read -p "❓ Do you want to delete $lv (VG: $vg, Size: $size)? [y/N]: " confirm
|
read -p "❓ Do you want to delete $lv (VG: $vg, Size: $size)? [y/N]: " confirm
|
||||||
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
echo -e "🗑️ Deleting $lv from $vg..."
|
echo -e "🗑️ Deleting $lv from $vg..."
|
||||||
lvremove -f "$vg/$lv"
|
lvremove -f "$vg/$lv"
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo -e "✅ Successfully deleted $lv.\n"
|
echo -e "✅ Successfully deleted $lv.\n"
|
||||||
else
|
else
|
||||||
echo -e "❌ Failed to delete $lv.\n"
|
echo -e "❌ Failed to delete $lv.\n"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "⚠️ Skipping $lv.\n"
|
echo -e "⚠️ Skipping $lv.\n"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run script
|
# Run script
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
clear
|
clear
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
echo -e "⚠️ Can't Run from the Proxmox Shell"
|
echo -e "⚠️ Can't Run from the Proxmox Shell"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
YW=$(echo "\033[33m")
|
YW=$(echo "\033[33m")
|
||||||
BL=$(echo "\033[36m")
|
BL=$(echo "\033[36m")
|
||||||
@@ -23,16 +23,16 @@ CM="${GN}✓${CL}"
|
|||||||
CROSS="${RD}✗${CL}"
|
CROSS="${RD}✗${CL}"
|
||||||
APP="Home Assistant Container"
|
APP="Home Assistant Container"
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn
|
read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
*) echo "Please answer yes or no." ;;
|
*) echo "Please answer yes or no." ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
clear
|
clear
|
||||||
function header_info {
|
function header_info {
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
__ __ ___ _ __ __
|
__ __ ___ _ __ __
|
||||||
/ / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_
|
/ / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_
|
||||||
/ /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/
|
/ /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/
|
||||||
@@ -44,39 +44,35 @@ EOF
|
|||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -ne " ${HOLD} ${YW}${msg}..."
|
echo -ne " ${HOLD} ${YW}${msg}..."
|
||||||
}
|
}
|
||||||
function msg_ok() {
|
function msg_ok() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
||||||
}
|
}
|
||||||
function msg_error() {
|
function msg_error() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then
|
if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then
|
||||||
msg_error "No backups found! \n"
|
msg_error "No backups found! \n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
DIR=/var/lib/docker/volumes/hass_config/_data/restore
|
DIR=/var/lib/docker/volumes/hass_config/_data/restore
|
||||||
if [ -d "$DIR" ]; then
|
if [ -d "$DIR" ]; then
|
||||||
msg_ok "Restore Directory Exists."
|
msg_ok "Restore Directory Exists."
|
||||||
else
|
else
|
||||||
mkdir -p /var/lib/docker/volumes/hass_config/_data/restore
|
mkdir -p /var/lib/docker/volumes/hass_config/_data/restore
|
||||||
msg_ok "Created Restore Directory."
|
msg_ok "Created Restore Directory."
|
||||||
fi
|
fi
|
||||||
cd /var/lib/docker/volumes/hass_config/_data/backups/
|
cd /var/lib/docker/volumes/hass_config/_data/backups/
|
||||||
PS3="Please enter your choice: "
|
PS3="Please enter your choice: "
|
||||||
files="$(ls -A .)"
|
files="$(ls -A .)"
|
||||||
select filename in ${files}; do
|
select filename in ${files}; do
|
||||||
msg_ok "You selected ${BL}${filename}${CL}"
|
msg_ok "You selected ${BL}${filename}${CL}"
|
||||||
break
|
break
|
||||||
done
|
done
|
||||||
msg_info "Stopping Home Assistant"
|
msg_info "Stopping Home Assistant"
|
||||||
docker stop homeassistant &>/dev/null
|
docker stop homeassistant &>/dev/null
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
clear
|
clear
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
echo -e "⚠️ Can't Run from the Proxmox Shell"
|
echo -e "⚠️ Can't Run from the Proxmox Shell"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
YW=$(echo "\033[33m")
|
YW=$(echo "\033[33m")
|
||||||
BL=$(echo "\033[36m")
|
BL=$(echo "\033[36m")
|
||||||
@@ -23,16 +23,16 @@ CM="${GN}✓${CL}"
|
|||||||
CROSS="${RD}✗${CL}"
|
CROSS="${RD}✗${CL}"
|
||||||
APP="Home Assistant Core"
|
APP="Home Assistant Core"
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn
|
read -p "This will restore ${APP} from a backup. Proceed(y/n)?" yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
*) echo "Please answer yes or no." ;;
|
*) echo "Please answer yes or no." ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
clear
|
clear
|
||||||
function header_info {
|
function header_info {
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
__ __ ___ _ __ __ ______
|
__ __ ___ _ __ __ ______
|
||||||
/ / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___ ________
|
/ / / /___ ____ ___ ___ / | __________(_)____/ /_____ _____ / /_ / ____/___ ________
|
||||||
/ /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \
|
/ /_/ / __ \/ __ `__ \/ _ \ / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ / / / __ \/ ___/ _ \
|
||||||
@@ -44,39 +44,35 @@ EOF
|
|||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -ne " ${HOLD} ${YW}${msg}..."
|
echo -ne " ${HOLD} ${YW}${msg}..."
|
||||||
}
|
}
|
||||||
function msg_ok() {
|
function msg_ok() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
||||||
}
|
}
|
||||||
function msg_error() {
|
function msg_error() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then
|
if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then
|
||||||
msg_error "No backups found! \n"
|
msg_error "No backups found! \n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
DIR=/root/.homeassistant/restore
|
DIR=/root/.homeassistant/restore
|
||||||
if [ -d "$DIR" ]; then
|
if [ -d "$DIR" ]; then
|
||||||
msg_ok "Restore Directory Exists."
|
msg_ok "Restore Directory Exists."
|
||||||
else
|
else
|
||||||
mkdir -p /root/.homeassistant/restore
|
mkdir -p /root/.homeassistant/restore
|
||||||
msg_ok "Created Restore Directory."
|
msg_ok "Created Restore Directory."
|
||||||
fi
|
fi
|
||||||
cd /root/.homeassistant/backups/
|
cd /root/.homeassistant/backups/
|
||||||
PS3="Please enter your choice: "
|
PS3="Please enter your choice: "
|
||||||
files="$(ls -A .)"
|
files="$(ls -A .)"
|
||||||
select filename in ${files}; do
|
select filename in ${files}; do
|
||||||
msg_ok "You selected ${BL}${filename}${CL}"
|
msg_ok "You selected ${BL}${filename}${CL}"
|
||||||
break
|
break
|
||||||
done
|
done
|
||||||
msg_info "Stopping Home Assistant"
|
msg_info "Stopping Home Assistant"
|
||||||
sudo service homeassistant stop
|
sudo service homeassistant stop
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ RD=$(echo "\033[01;31m")
|
|||||||
CM='\xE2\x9C\x94\033'
|
CM='\xE2\x9C\x94\033'
|
||||||
GN=$(echo "\033[1;92m")
|
GN=$(echo "\033[1;92m")
|
||||||
CL=$(echo "\033[m")
|
CL=$(echo "\033[m")
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Execute" --yesno "This will execute a command inside selected LXC Containers. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Execute" --yesno "This will execute a command inside selected LXC Containers. Proceed?" 10 58
|
||||||
@@ -45,6 +40,7 @@ if [ $? -ne 0 ]; then
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
read -r -p "Enter here command for inside the containers: " custom_command
|
read -r -p "Enter here command for inside the containers: " custom_command
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
@@ -54,11 +50,12 @@ function execute_in() {
|
|||||||
container=$1
|
container=$1
|
||||||
name=$(pct exec "$container" hostname)
|
name=$(pct exec "$container" hostname)
|
||||||
echo -e "${BL}[Info]${GN} Execute inside${BL} ${name}${GN} with output: ${CL}"
|
echo -e "${BL}[Info]${GN} Execute inside${BL} ${name}${GN} with output: ${CL}"
|
||||||
if ! pct exec "$container" -- bash -c "command ${custom_command} >/dev/null 2>&1"; then
|
if ! pct exec "$container" -- bash -c "command ${custom_command} >/dev/null 2>&1"
|
||||||
echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container has no command: ${custom_command}"
|
then
|
||||||
else
|
echo -e "${BL}[Info]${GN} Skipping ${name} ${RD}$container has no command: ${custom_command}"
|
||||||
pct exec "$container" -- bash -c "${custom_command}" | tee
|
else
|
||||||
fi
|
pct exec "$container" -- bash -c "${custom_command}" | tee
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
for container in $(pct list | awk '{if(NR>1) print $1}'); do
|
for container in $(pct list | awk '{if(NR>1) print $1}'); do
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ function header_info {
|
|||||||
/___/ /_/ /_/
|
/___/ /_/ /_/
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will Prepare a LXC Container for Frigate. Proceed (y/n)?" yn
|
read -p "This will Prepare a LXC Container for Frigate. Proceed (y/n)?" yn
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ RD="\033[01;31m"
|
|||||||
GN="\033[1;92m"
|
GN="\033[1;92m"
|
||||||
CL="\033[m"
|
CL="\033[m"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
LOGFILE="/var/log/fstrim.log"
|
LOGFILE="/var/log/fstrim.log"
|
||||||
touch "$LOGFILE"
|
touch "$LOGFILE"
|
||||||
chmod 600 "$LOGFILE"
|
chmod 600 "$LOGFILE"
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ function header_info {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
# Function to perform backup
|
# Function to perform backup
|
||||||
function perform_backup {
|
function perform_backup {
|
||||||
local BACKUP_PATH
|
local BACKUP_PATH
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ BFR="\\r\\033[K"
|
|||||||
HOLD="-"
|
HOLD="-"
|
||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ GN="\033[1;92m"
|
|||||||
RD="\033[01;31m"
|
RD="\033[01;31m"
|
||||||
CL="\033[m"
|
CL="\033[m"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
# Detect current kernel
|
# Detect current kernel
|
||||||
current_kernel=$(uname -r)
|
current_kernel=$(uname -r)
|
||||||
available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V)
|
available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v "$current_kernel" | sort -V)
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
current_kernel=$(uname -r)
|
current_kernel=$(uname -r)
|
||||||
available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 16, length($2)-22)}')
|
available_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 16, length($2)-22)}')
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
|
|||||||
@@ -38,10 +38,6 @@ CL=$(echo "\033[m")
|
|||||||
TAB=" "
|
TAB=" "
|
||||||
CM="${TAB}✔️${TAB}${CL}"
|
CM="${TAB}✔️${TAB}${CL}"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Deletion" --yesno "This will delete LXC containers. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Deletion" --yesno "This will delete LXC containers. Proceed?" 10 58
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
|
|||||||
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}"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "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]+')
|
||||||
[ -z "$current_microcode" ] && current_microcode="Not found."
|
[ -z "$current_microcode" ] && current_microcode="Not found."
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ cat <<"EOF"
|
|||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
echo -e "\n IMPORTANT: Tag-Based Monitoring Enabled"
|
echo -e "\n IMPORTANT: Tag-Based Monitoring Enabled"
|
||||||
echo "Only VMs and containers with the tag 'mon-restart' will be automatically restarted by this service."
|
echo "Only VMs and containers with the tag 'mon-restart' will be automatically restarted by this service."
|
||||||
@@ -32,9 +28,9 @@ add() {
|
|||||||
while true; do
|
while true; do
|
||||||
read -p "This script will add Monitor All to Proxmox VE. Proceed (y/n)? " yn
|
read -p "This script will add Monitor All to Proxmox VE. Proceed (y/n)? " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
*) echo "Please answer yes or no." ;;
|
*) echo "Please answer yes or no." ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -179,8 +175,5 @@ CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Monitor-All f
|
|||||||
case $CHOICE in
|
case $CHOICE in
|
||||||
"Add") add ;;
|
"Add") add ;;
|
||||||
"Remove") remove ;;
|
"Remove") remove ;;
|
||||||
*)
|
*) echo "Exiting..."; exit 0 ;;
|
||||||
echo "Exiting..."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ INFO="${TAB}ℹ️${TAB}${CL}"
|
|||||||
WARN="${TAB}⚠️${TAB}${CL}"
|
WARN="${TAB}⚠️${TAB}${CL}"
|
||||||
|
|
||||||
function header_info {
|
function header_info {
|
||||||
clear
|
clear
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
|
|
||||||
_ ____________ ____ __________ ___ ____ _ __ __
|
_ ____________ ____ __________ ___ ____ _ __ __
|
||||||
/ | / / _/ ____/ / __ \/ __/ __/ /___ ____ _____/ (_)___ ____ _ / __ \(_)________ _/ /_ / /__ _____
|
/ | / / _/ ____/ / __ \/ __/ __/ /___ ____ _____/ (_)___ ____ _ / __ \(_)________ _/ /_ / /__ _____
|
||||||
@@ -33,10 +33,6 @@ Enhanced version supporting both e1000e and e1000 drivers
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
function msg_info() { echo -e "${INFO} ${YW}${1}...${CL}"; }
|
function msg_info() { echo -e "${INFO} ${YW}${1}...${CL}"; }
|
||||||
@@ -46,18 +42,15 @@ function msg_warn() { echo -e "${WARN} ${YWB}${1}"; }
|
|||||||
|
|
||||||
# Check for root privileges
|
# Check for root privileges
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
msg_error "Error: This script must be run as root."
|
msg_error "Error: This script must be run as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v ethtool >/dev/null 2>&1; then
|
if ! command -v ethtool >/dev/null 2>&1; then
|
||||||
msg_info "Installing ethtool"
|
msg_info "Installing ethtool"
|
||||||
apt-get update &>/dev/null
|
apt-get update &>/dev/null
|
||||||
apt-get install -y ethtool &>/dev/null || {
|
apt-get install -y ethtool &>/dev/null || { msg_error "Failed to install ethtool. Exiting."; exit 1; }
|
||||||
msg_error "Failed to install ethtool. Exiting."
|
msg_ok "ethtool installed successfully"
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
msg_ok "ethtool installed successfully"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get list of network interfaces using Intel e1000e or e1000 drivers
|
# Get list of network interfaces using Intel e1000e or e1000 drivers
|
||||||
@@ -67,95 +60,95 @@ COUNT=0
|
|||||||
msg_info "Searching for Intel e1000e and e1000 interfaces"
|
msg_info "Searching for Intel e1000e and e1000 interfaces"
|
||||||
|
|
||||||
for device in /sys/class/net/*; do
|
for device in /sys/class/net/*; do
|
||||||
interface="$(basename "$device")" # or adjust the rest of the usages below, as mostly you'll use the path anyway
|
interface="$(basename "$device")" # or adjust the rest of the usages below, as mostly you'll use the path anyway
|
||||||
# Skip loopback interface and virtual interfaces
|
# Skip loopback interface and virtual interfaces
|
||||||
if [[ "$interface" != "lo" ]] && [[ ! "$interface" =~ ^(tap|fwbr|veth|vmbr|bonding_masters) ]]; then
|
if [[ "$interface" != "lo" ]] && [[ ! "$interface" =~ ^(tap|fwbr|veth|vmbr|bonding_masters) ]]; then
|
||||||
# Check if the interface uses the e1000e or e1000 driver
|
# Check if the interface uses the e1000e or e1000 driver
|
||||||
driver=$(basename $(readlink -f /sys/class/net/$interface/device/driver 2>/dev/null) 2>/dev/null)
|
driver=$(basename $(readlink -f /sys/class/net/$interface/device/driver 2>/dev/null) 2>/dev/null)
|
||||||
|
|
||||||
if [[ "$driver" == "e1000e" ]] || [[ "$driver" == "e1000" ]]; then
|
if [[ "$driver" == "e1000e" ]] || [[ "$driver" == "e1000" ]]; then
|
||||||
# Get MAC address for additional identification
|
# Get MAC address for additional identification
|
||||||
mac=$(cat /sys/class/net/$interface/address 2>/dev/null)
|
mac=$(cat /sys/class/net/$interface/address 2>/dev/null)
|
||||||
INTERFACES+=("$interface" "Intel $driver NIC ($mac)")
|
INTERFACES+=("$interface" "Intel $driver NIC ($mac)")
|
||||||
((COUNT++))
|
((COUNT++))
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# Check if any Intel e1000e/e1000 interfaces were found
|
# Check if any Intel e1000e/e1000 interfaces were found
|
||||||
if [ ${#INTERFACES[@]} -eq 0 ]; then
|
if [ ${#INTERFACES[@]} -eq 0 ]; then
|
||||||
whiptail --title "Error" --msgbox "No Intel e1000e or e1000 network interfaces found!" 10 60
|
whiptail --title "Error" --msgbox "No Intel e1000e or e1000 network interfaces found!" 10 60
|
||||||
msg_error "No Intel e1000e or e1000 network interfaces found! Exiting."
|
msg_error "No Intel e1000e or e1000 network interfaces found! Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_ok "Found ${BL}$COUNT${GN} Intel e1000e/e1000 interfaces"
|
msg_ok "Found ${BL}$COUNT${GN} Intel e1000e/e1000 interfaces"
|
||||||
|
|
||||||
# Create a checklist for interface selection with all interfaces initially checked
|
# Create a checklist for interface selection with all interfaces initially checked
|
||||||
INTERFACES_CHECKLIST=()
|
INTERFACES_CHECKLIST=()
|
||||||
for ((i = 0; i < ${#INTERFACES[@]}; i += 2)); do
|
for ((i=0; i<${#INTERFACES[@]}; i+=2)); do
|
||||||
INTERFACES_CHECKLIST+=("${INTERFACES[i]}" "${INTERFACES[i + 1]}" "ON")
|
INTERFACES_CHECKLIST+=("${INTERFACES[i]}" "${INTERFACES[i+1]}" "ON")
|
||||||
done
|
done
|
||||||
|
|
||||||
# Show interface selection checklist
|
# Show interface selection checklist
|
||||||
SELECTED_INTERFACES=$(whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --title "Network Interfaces" \
|
SELECTED_INTERFACES=$(whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --title "Network Interfaces" \
|
||||||
--separate-output --checklist "Select Intel e1000e/e1000 network interfaces\n(Space to toggle, Enter to confirm):" 15 80 6 \
|
--separate-output --checklist "Select Intel e1000e/e1000 network interfaces\n(Space to toggle, Enter to confirm):" 15 80 6 \
|
||||||
"${INTERFACES_CHECKLIST[@]}" 3>&1 1>&2 2>&3)
|
"${INTERFACES_CHECKLIST[@]}" 3>&1 1>&2 2>&3)
|
||||||
|
|
||||||
exitstatus=$?
|
exitstatus=$?
|
||||||
if [ $exitstatus != 0 ]; then
|
if [ $exitstatus != 0 ]; then
|
||||||
msg_info "User canceled. Exiting."
|
msg_info "User canceled. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if any interfaces were selected
|
# Check if any interfaces were selected
|
||||||
if [ -z "$SELECTED_INTERFACES" ]; then
|
if [ -z "$SELECTED_INTERFACES" ]; then
|
||||||
msg_error "No interfaces selected. Exiting."
|
msg_error "No interfaces selected. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Convert the selected interfaces into an array
|
# Convert the selected interfaces into an array
|
||||||
readarray -t INTERFACE_ARRAY <<<"$SELECTED_INTERFACES"
|
readarray -t INTERFACE_ARRAY <<< "$SELECTED_INTERFACES"
|
||||||
|
|
||||||
# Show the number of selected interfaces
|
# Show the number of selected interfaces
|
||||||
INTERFACE_COUNT=${#INTERFACE_ARRAY[@]}
|
INTERFACE_COUNT=${#INTERFACE_ARRAY[@]}
|
||||||
|
|
||||||
# Print selected interfaces with their driver types
|
# Print selected interfaces with their driver types
|
||||||
for iface in "${INTERFACE_ARRAY[@]}"; do
|
for iface in "${INTERFACE_ARRAY[@]}"; do
|
||||||
driver=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
driver=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
||||||
msg_ok "Selected interface: ${BL}$iface${GN} (${BL}$driver${GN})"
|
msg_ok "Selected interface: ${BL}$iface${GN} (${BL}$driver${GN})"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Ask for confirmation with the list of selected interfaces
|
# Ask for confirmation with the list of selected interfaces
|
||||||
CONFIRMATION_MSG="You have selected the following interface(s):\n\n"
|
CONFIRMATION_MSG="You have selected the following interface(s):\n\n"
|
||||||
for iface in "${INTERFACE_ARRAY[@]}"; do
|
for iface in "${INTERFACE_ARRAY[@]}"; do
|
||||||
SPEED=$(cat /sys/class/net/$iface/speed 2>/dev/null || echo "Unknown")
|
SPEED=$(cat /sys/class/net/$iface/speed 2>/dev/null || echo "Unknown")
|
||||||
MAC=$(cat /sys/class/net/$iface/address 2>/dev/null)
|
MAC=$(cat /sys/class/net/$iface/address 2>/dev/null)
|
||||||
DRIVER=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
DRIVER=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
||||||
CONFIRMATION_MSG+="- $iface (Driver: $DRIVER, MAC: $MAC, Speed: ${SPEED}Mbps)\n"
|
CONFIRMATION_MSG+="- $iface (Driver: $DRIVER, MAC: $MAC, Speed: ${SPEED}Mbps)\n"
|
||||||
done
|
done
|
||||||
CONFIRMATION_MSG+="\nThis will create systemd service(s) to disable offloading features.\n\nProceed?"
|
CONFIRMATION_MSG+="\nThis will create systemd service(s) to disable offloading features.\n\nProceed?"
|
||||||
|
|
||||||
if ! whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --title "Confirmation" \
|
if ! whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --title "Confirmation" \
|
||||||
--yesno "$CONFIRMATION_MSG" 20 80; then
|
--yesno "$CONFIRMATION_MSG" 20 80; then
|
||||||
msg_info "User canceled. Exiting."
|
msg_info "User canceled. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Loop through all selected interfaces and create services for each
|
# Loop through all selected interfaces and create services for each
|
||||||
for SELECTED_INTERFACE in "${INTERFACE_ARRAY[@]}"; do
|
for SELECTED_INTERFACE in "${INTERFACE_ARRAY[@]}"; do
|
||||||
# Get the driver type for this specific interface
|
# Get the driver type for this specific interface
|
||||||
DRIVER=$(basename $(readlink -f /sys/class/net/$SELECTED_INTERFACE/device/driver 2>/dev/null) 2>/dev/null)
|
DRIVER=$(basename $(readlink -f /sys/class/net/$SELECTED_INTERFACE/device/driver 2>/dev/null) 2>/dev/null)
|
||||||
|
|
||||||
# Create service name for this interface
|
# Create service name for this interface
|
||||||
SERVICE_NAME="disable-nic-offload-$SELECTED_INTERFACE.service"
|
SERVICE_NAME="disable-nic-offload-$SELECTED_INTERFACE.service"
|
||||||
SERVICE_PATH="/etc/systemd/system/$SERVICE_NAME"
|
SERVICE_PATH="/etc/systemd/system/$SERVICE_NAME"
|
||||||
|
|
||||||
# Create the service file with driver-specific optimizations
|
# Create the service file with driver-specific optimizations
|
||||||
msg_info "Creating systemd service for interface: ${BL}$SELECTED_INTERFACE${YW} (${BL}$DRIVER${YW})"
|
msg_info "Creating systemd service for interface: ${BL}$SELECTED_INTERFACE${YW} (${BL}$DRIVER${YW})"
|
||||||
|
|
||||||
# Start with the common part of the service file
|
# Start with the common part of the service file
|
||||||
cat >"$SERVICE_PATH" <<EOF
|
cat > "$SERVICE_PATH" << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Disable NIC offloading for Intel $DRIVER interface $SELECTED_INTERFACE
|
Description=Disable NIC offloading for Intel $DRIVER interface $SELECTED_INTERFACE
|
||||||
After=network.target
|
After=network.target
|
||||||
@@ -170,49 +163,45 @@ RemainAfterExit=true
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Check if service file was created successfully
|
# Check if service file was created successfully
|
||||||
if [ ! -f "$SERVICE_PATH" ]; then
|
if [ ! -f "$SERVICE_PATH" ]; then
|
||||||
whiptail --title "Error" --msgbox "Failed to create service file for $SELECTED_INTERFACE!" 10 50
|
whiptail --title "Error" --msgbox "Failed to create service file for $SELECTED_INTERFACE!" 10 50
|
||||||
msg_error "Failed to create service file for $SELECTED_INTERFACE! Skipping to next interface."
|
msg_error "Failed to create service file for $SELECTED_INTERFACE! Skipping to next interface."
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure this service
|
# Configure this service
|
||||||
{
|
{
|
||||||
echo "25"
|
echo "25"; sleep 0.2
|
||||||
sleep 0.2
|
# Reload systemd to recognize the new service
|
||||||
# Reload systemd to recognize the new service
|
systemctl daemon-reload
|
||||||
systemctl daemon-reload
|
echo "50"; sleep 0.2
|
||||||
echo "50"
|
# Start the service
|
||||||
sleep 0.2
|
systemctl start "$SERVICE_NAME"
|
||||||
# Start the service
|
echo "75"; sleep 0.2
|
||||||
systemctl start "$SERVICE_NAME"
|
# Enable the service to start on boot
|
||||||
echo "75"
|
systemctl enable "$SERVICE_NAME"
|
||||||
sleep 0.2
|
echo "100"; sleep 0.2
|
||||||
# Enable the service to start on boot
|
} | whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --gauge "Configuring service for $SELECTED_INTERFACE..." 10 80 0
|
||||||
systemctl enable "$SERVICE_NAME"
|
|
||||||
echo "100"
|
|
||||||
sleep 0.2
|
|
||||||
} | whiptail --backtitle "Intel e1000e/e1000 NIC Offloading Disabler" --gauge "Configuring service for $SELECTED_INTERFACE..." 10 80 0
|
|
||||||
|
|
||||||
# Individual service status
|
# Individual service status
|
||||||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
SERVICE_STATUS="Active"
|
SERVICE_STATUS="Active"
|
||||||
else
|
else
|
||||||
SERVICE_STATUS="Inactive"
|
SERVICE_STATUS="Inactive"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
|
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
|
||||||
BOOT_STATUS="Enabled"
|
BOOT_STATUS="Enabled"
|
||||||
else
|
else
|
||||||
BOOT_STATUS="Disabled"
|
BOOT_STATUS="Disabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show individual service results
|
# Show individual service results
|
||||||
msg_ok "Service for ${BL}$SELECTED_INTERFACE${GN} (${BL}$DRIVER${GN}) created and enabled!"
|
msg_ok "Service for ${BL}$SELECTED_INTERFACE${GN} (${BL}$DRIVER${GN}) created and enabled!"
|
||||||
msg_info "${TAB}Service: ${BL}$SERVICE_NAME${YW}"
|
msg_info "${TAB}Service: ${BL}$SERVICE_NAME${YW}"
|
||||||
msg_info "${TAB}Status: ${BL}$SERVICE_STATUS${YW}"
|
msg_info "${TAB}Status: ${BL}$SERVICE_STATUS${YW}"
|
||||||
msg_info "${TAB}Start on boot: ${BL}$BOOT_STATUS${YW}"
|
msg_info "${TAB}Start on boot: ${BL}$BOOT_STATUS${YW}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Prepare summary of all interfaces
|
# Prepare summary of all interfaces
|
||||||
@@ -220,22 +209,22 @@ SUMMARY_MSG="Services created successfully!\n\n"
|
|||||||
SUMMARY_MSG+="Configured Interfaces:\n"
|
SUMMARY_MSG+="Configured Interfaces:\n"
|
||||||
|
|
||||||
for iface in "${INTERFACE_ARRAY[@]}"; do
|
for iface in "${INTERFACE_ARRAY[@]}"; do
|
||||||
SERVICE_NAME="disable-nic-offload-$iface.service"
|
SERVICE_NAME="disable-nic-offload-$iface.service"
|
||||||
DRIVER=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
DRIVER=$(basename $(readlink -f /sys/class/net/$iface/device/driver 2>/dev/null) 2>/dev/null)
|
||||||
|
|
||||||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
SVC_STATUS="Active"
|
SVC_STATUS="Active"
|
||||||
else
|
else
|
||||||
SVC_STATUS="Inactive"
|
SVC_STATUS="Inactive"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
|
if systemctl is-enabled --quiet "$SERVICE_NAME"; then
|
||||||
BOOT_SVC_STATUS="Enabled"
|
BOOT_SVC_STATUS="Enabled"
|
||||||
else
|
else
|
||||||
BOOT_SVC_STATUS="Disabled"
|
BOOT_SVC_STATUS="Disabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SUMMARY_MSG+="- $iface ($DRIVER): $SVC_STATUS, Boot: $BOOT_SVC_STATUS\n"
|
SUMMARY_MSG+="- $iface ($DRIVER): $SVC_STATUS, Boot: $BOOT_SVC_STATUS\n"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Show summary results
|
# Show summary results
|
||||||
@@ -247,8 +236,8 @@ msg_ok "Intel e1000e/e1000 optimization complete for ${#INTERFACE_ARRAY[@]} inte
|
|||||||
echo ""
|
echo ""
|
||||||
msg_info "Verification commands:"
|
msg_info "Verification commands:"
|
||||||
for iface in "${INTERFACE_ARRAY[@]}"; do
|
for iface in "${INTERFACE_ARRAY[@]}"; do
|
||||||
echo -e "${TAB}${BL}ethtool -k $iface${CL} ${YW}# Check offloading status${CL}"
|
echo -e "${TAB}${BL}ethtool -k $iface${CL} ${YW}# Check offloading status${CL}"
|
||||||
echo -e "${TAB}${BL}systemctl status disable-nic-offload-$iface.service${CL} ${YW}# Check service status${CL}"
|
echo -e "${TAB}${BL}systemctl status disable-nic-offload-$iface.service${CL} ${YW}# Check service status${CL}"
|
||||||
done
|
done
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ msg_error() {
|
|||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
start_routines() {
|
start_routines() {
|
||||||
header_info
|
header_info
|
||||||
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 14 58 2 \
|
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 2 BACKUP" --menu "\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?" 14 58 2 \
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
|
|||||||
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}"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
start_routines() {
|
start_routines() {
|
||||||
header_info
|
header_info
|
||||||
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 3 BACKUP" --menu \
|
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "PBS 3 BACKUP" --menu \
|
||||||
|
|||||||
@@ -28,10 +28,6 @@ CM="${GN}✓${CL}"
|
|||||||
CROSS="${RD}✗${CL}"
|
CROSS="${RD}✗${CL}"
|
||||||
|
|
||||||
msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
|
msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "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}"; }
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ msg_info() { echo -ne " ${HOLD} ${YW}$1..."; }
|
|||||||
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}"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
# ---- helpers ----
|
# ---- helpers ----
|
||||||
get_pbs_codename() {
|
get_pbs_codename() {
|
||||||
awk -F'=' '/^VERSION_CODENAME=/{print $2}' /etc/os-release
|
awk -F'=' '/^VERSION_CODENAME=/{print $2}' /etc/os-release
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ msg_error() {
|
|||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "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"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ msg_error() {
|
|||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
get_pve_version() {
|
get_pve_version() {
|
||||||
local pve_ver
|
local pve_ver
|
||||||
pve_ver="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
pve_ver="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ if ! command -v curl >/dev/null 2>&1; then
|
|||||||
apt-get install -y curl >/dev/null 2>&1
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
fi
|
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
|
|
||||||
load_functions
|
load_functions
|
||||||
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
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ msg_error() {
|
|||||||
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
start_routines() {
|
start_routines() {
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
# License: MIT
|
# License: MIT
|
||||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info() {
|
header_info() {
|
||||||
clear
|
clear
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
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
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "update-apps" "pve"
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# CONFIGURATION VARIABLES
|
# CONFIGURATION VARIABLES
|
||||||
@@ -100,14 +98,14 @@ EOF
|
|||||||
|
|
||||||
# Handle command line arguments
|
# Handle command line arguments
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
--help | -h)
|
--help|-h)
|
||||||
print_usage
|
print_usage
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
--export-config)
|
--export-config)
|
||||||
export_config_json
|
export_config_json
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -204,40 +202,40 @@ msg_ok "Loaded ${#menu_items[@]} containers"
|
|||||||
# Determine container selection based on var_container
|
# Determine container selection based on var_container
|
||||||
if [[ -n "$var_container" ]]; then
|
if [[ -n "$var_container" ]]; then
|
||||||
case "$var_container" in
|
case "$var_container" in
|
||||||
all)
|
all)
|
||||||
# Select all containers with matching tags
|
# Select all containers with matching tags
|
||||||
CHOICE=""
|
CHOICE=""
|
||||||
for ((i = 0; i < ${#menu_items[@]}; i += 3)); do
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
CHOICE="$CHOICE ${menu_items[$i]}"
|
CHOICE="$CHOICE ${menu_items[$i]}"
|
||||||
done
|
done
|
||||||
CHOICE=$(echo "$CHOICE" | xargs)
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
;;
|
;;
|
||||||
all_running)
|
all_running)
|
||||||
# Select only running containers with matching tags
|
# Select only running containers with matching tags
|
||||||
CHOICE=""
|
CHOICE=""
|
||||||
for ((i = 0; i < ${#menu_items[@]}; i += 3)); do
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
cid="${menu_items[$i]}"
|
cid="${menu_items[$i]}"
|
||||||
if pct status "$cid" 2>/dev/null | grep -q "running"; then
|
if pct status "$cid" 2>/dev/null | grep -q "running"; then
|
||||||
CHOICE="$CHOICE $cid"
|
CHOICE="$CHOICE $cid"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
CHOICE=$(echo "$CHOICE" | xargs)
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
;;
|
;;
|
||||||
all_stopped)
|
all_stopped)
|
||||||
# Select only stopped containers with matching tags
|
# Select only stopped containers with matching tags
|
||||||
CHOICE=""
|
CHOICE=""
|
||||||
for ((i = 0; i < ${#menu_items[@]}; i += 3)); do
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
cid="${menu_items[$i]}"
|
cid="${menu_items[$i]}"
|
||||||
if pct status "$cid" 2>/dev/null | grep -q "stopped"; then
|
if pct status "$cid" 2>/dev/null | grep -q "stopped"; then
|
||||||
CHOICE="$CHOICE $cid"
|
CHOICE="$CHOICE $cid"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
CHOICE=$(echo "$CHOICE" | xargs)
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Assume comma-separated list of container IDs
|
# Assume comma-separated list of container IDs
|
||||||
CHOICE=$(echo "$var_container" | tr ',' ' ')
|
CHOICE=$(echo "$var_container" | tr ',' ' ')
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ -z "$CHOICE" ]]; then
|
if [[ -z "$CHOICE" ]]; then
|
||||||
|
|||||||
@@ -24,11 +24,6 @@ RD=$(echo "\033[01;31m")
|
|||||||
CM='\xE2\x9C\x94\033'
|
CM='\xE2\x9C\x94\033'
|
||||||
GN=$(echo "\033[1;92m")
|
GN=$(echo "\033[1;92m")
|
||||||
CL=$(echo "\033[m")
|
CL=$(echo "\033[m")
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ RD=$(echo "\033[01;31m")
|
|||||||
GN=$(echo "\033[1;92m")
|
GN=$(echo "\033[1;92m")
|
||||||
CL=$(echo "\033[m")
|
CL=$(echo "\033[m")
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
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" "pve"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
NODE=$(hostname)
|
NODE=$(hostname)
|
||||||
|
|||||||
Reference in New Issue
Block a user