mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-06-27 17:54:58 +02:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7c1f30373 | |||
| 5b252892e1 | |||
| 8b99d3b1cc | |||
| 039470965b | |||
| 8e4a9829cf | |||
| f1eee5f5ed | |||
| fb14e6ae8b | |||
| 4142c5c2d3 | |||
| d85914530f | |||
| 3d9e67292b | |||
| ae60dc138b | |||
| 14a85a8591 | |||
| 1be64c1994 | |||
| 340695b9bd | |||
| ba31c925e3 | |||
| 868b405082 | |||
| 60266b9c17 | |||
| ea8b87fd7f | |||
| 58145d5bd3 | |||
| 9fbe2de1cb | |||
| c918dee5fe | |||
| 0774772b87 | |||
| dc26b8358e | |||
| 01a6c1ddec | |||
| 3e544b750d | |||
| 681924cb1a | |||
| 6ea04b7602 | |||
| b2d20799d8 | |||
| 324fa33d8c | |||
| 5aed3bdde5 |
@@ -486,6 +486,42 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## 2026-06-27
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- fix(endurain): replace Poetry/uv-pip backend setup with uv sync --frozen --no-dev [@Copilot](https://github.com/Copilot) ([#15429](https://github.com/community-scripts/ProxmoxVE/pull/15429))
|
||||||
|
|
||||||
|
## 2026-06-26
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Termix: Update Nginx configuration file paths [@xyzulu](https://github.com/xyzulu) ([#15397](https://github.com/community-scripts/ProxmoxVE/pull/15397))
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Docuseal: use real SECRET_KEY_BASE for db:migrate on update [@MickLesk](https://github.com/MickLesk) ([#15411](https://github.com/community-scripts/ProxmoxVE/pull/15411))
|
||||||
|
- bun: correct install for degoog [@MickLesk](https://github.com/MickLesk) ([#15412](https://github.com/community-scripts/ProxmoxVE/pull/15412))
|
||||||
|
- fix databasus update/install errors [@asylumexp](https://github.com/asylumexp) ([#15403](https://github.com/community-scripts/ProxmoxVE/pull/15403))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- tools.func: fix setup_docker - don't abort update on docker pull failure [@MickLesk](https://github.com/MickLesk) ([#15410](https://github.com/community-scripts/ProxmoxVE/pull/15410))
|
||||||
|
- fix(build.func): set /dev/kfd GID in fix_gpu_gids for AMD ROCm [@jamiej](https://github.com/jamiej) ([#15401](https://github.com/community-scripts/ProxmoxVE/pull/15401))
|
||||||
|
- fix alpine mktmp error [@asylumexp](https://github.com/asylumexp) ([#15398](https://github.com/community-scripts/ProxmoxVE/pull/15398))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: reduce IP-Tag resource usage and clean up ShellCheck findings [@MickLesk](https://github.com/MickLesk) ([#15418](https://github.com/community-scripts/ProxmoxVE/pull/15418))
|
||||||
|
- QoL: kernel-clean: Validate kernel selection input [@MickLesk](https://github.com/MickLesk) ([#15414](https://github.com/community-scripts/ProxmoxVE/pull/15414))
|
||||||
|
- QoL: clean-lxcs exclude matching and set -e cancel handling [@MickLesk](https://github.com/MickLesk) ([#15413](https://github.com/community-scripts/ProxmoxVE/pull/15413))
|
||||||
|
- QoL: Harden microcode download/install in microcode and pbs-microcode [@MickLesk](https://github.com/MickLesk) ([#15415](https://github.com/community-scripts/ProxmoxVE/pull/15415))
|
||||||
|
- QoL: scaling-governor extend selection and guard missing cpufreq [@MickLesk](https://github.com/MickLesk) ([#15416](https://github.com/community-scripts/ProxmoxVE/pull/15416))
|
||||||
|
|
||||||
## 2026-06-25
|
## 2026-06-25
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|||||||
+3
-3
@@ -52,11 +52,11 @@ function update_script() {
|
|||||||
[[ "$MONGO_ARCH" == "arm64" ]] && MONGO_DIST="ubuntu2204"
|
[[ "$MONGO_ARCH" == "arm64" ]] && MONGO_DIST="ubuntu2204"
|
||||||
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-${MONGO_ARCH}-100.16.1.deb"
|
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-${MONGO_ARCH}-100.16.1.deb"
|
||||||
fi
|
fi
|
||||||
|
ensure_dependencies mariadb-client
|
||||||
|
mkdir -p /usr/local/mariadb-{10.6,12.1}/bin /usr/local/mysql-{5.7,8.0,8.4,9}/bin /usr/local/mongodb-database-tools/bin
|
||||||
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
|
[[ -f /usr/bin/mongodump ]] && ln -sf /usr/bin/mongodump /usr/local/mongodb-database-tools/bin/mongodump
|
||||||
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
|
[[ -f /usr/bin/mongorestore ]] && ln -sf /usr/bin/mongorestore /usr/local/mongodb-database-tools/bin/mongorestore
|
||||||
# Create MariaDB and MySQL client symlinks for compatibility
|
# Create MariaDB and MySQL client symlinks for compatibility
|
||||||
ensure_dependencies mariadb-client
|
|
||||||
mkdir -p /usr/local/mariadb-{10.6,12.1}/bin /usr/local/mysql-{5.7,8.0,8.4,9}/bin /usr/local/mongodb-database-tools/bin
|
|
||||||
for dir in /usr/local/mariadb-{10.6,12.1}/bin; do
|
for dir in /usr/local/mariadb-{10.6,12.1}/bin; do
|
||||||
ln -sf /usr/bin/mariadb-dump "$dir/mariadb-dump"
|
ln -sf /usr/bin/mariadb-dump "$dir/mariadb-dump"
|
||||||
ln -sf /usr/bin/mariadb "$dir/mariadb"
|
ln -sf /usr/bin/mariadb "$dir/mariadb"
|
||||||
@@ -79,7 +79,7 @@ function update_script() {
|
|||||||
cd /opt/databasus/backend
|
cd /opt/databasus/backend
|
||||||
$STD go mod download
|
$STD go mod download
|
||||||
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
||||||
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=$(arch_resolve) go build -o databasus ./cmd/main.go
|
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=$(arch_resolve) go build -o databasus ./cmd
|
||||||
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
||||||
mkdir -p /opt/databasus/ui/build
|
mkdir -p /opt/databasus/ui/build
|
||||||
cp -r /opt/databasus/frontend/dist/* /opt/databasus/ui/build/
|
cp -r /opt/databasus/frontend/dist/* /opt/databasus/ui/build/
|
||||||
|
|||||||
+2
-2
@@ -38,7 +38,7 @@ function update_script() {
|
|||||||
create_backup /opt/degoog/.env \
|
create_backup /opt/degoog/.env \
|
||||||
/opt/degoog/data
|
/opt/degoog/data
|
||||||
|
|
||||||
if ! command -v bun >/dev/null 2>&1; then
|
if [[ ! -x /root/.bun/bin/bun ]]; then
|
||||||
msg_info "Installing Bun"
|
msg_info "Installing Bun"
|
||||||
export BUN_INSTALL="/root/.bun"
|
export BUN_INSTALL="/root/.bun"
|
||||||
curl -fsSL https://bun.sh/install | $STD bash
|
curl -fsSL https://bun.sh/install | $STD bash
|
||||||
@@ -52,7 +52,7 @@ function update_script() {
|
|||||||
msg_ok "Updated Valkey"
|
msg_ok "Updated Valkey"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "degoog" "fccview/degoog" "prebuild" "latest" "/opt/degoog" "degoog_*_prebuild.tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "degoog" "fccview/degoog" "prebuild" "latest" "/opt/degoog" "degoog_*_prebuild.tar.gz"
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "curl-impersonate" "lexiforest/curl-impersonate" "prebuild" "latest" "/usr/local/bin" "curl-impersonate-v*.$(uname -m)-linux-gnu.tar.gz"
|
fetch_and_deploy_gh_release "curl-impersonate" "lexiforest/curl-impersonate" "prebuild" "latest" "/usr/local/bin" "curl-impersonate-v*.$(uname -m)-linux-gnu.tar.gz"
|
||||||
|
|
||||||
restore_backup
|
restore_backup
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ function update_script() {
|
|||||||
eval "$(rbenv init - bash)" 2>/dev/null || true
|
eval "$(rbenv init - bash)" 2>/dev/null || true
|
||||||
export RAILS_ENV=production
|
export RAILS_ENV=production
|
||||||
export NODE_ENV=production
|
export NODE_ENV=production
|
||||||
export SECRET_KEY_BASE_DUMMY=1
|
mkdir -p /opt/docuseal/tmp
|
||||||
set -a
|
set -a
|
||||||
source /opt/docuseal/.env
|
source /opt/docuseal/.env
|
||||||
set +a
|
set +a
|
||||||
|
|||||||
+1
-4
@@ -63,10 +63,7 @@ function update_script() {
|
|||||||
cd /opt/endurain/backend
|
cd /opt/endurain/backend
|
||||||
UV_VERSION=$(grep -Po 'required-version\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null || echo "0.11.18")
|
UV_VERSION=$(grep -Po 'required-version\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null || echo "0.11.18")
|
||||||
UV_VERSION="$UV_VERSION" setup_uv
|
UV_VERSION="$UV_VERSION" setup_uv
|
||||||
$STD poetry export -f requirements.txt --output requirements.txt --without-hashes
|
$STD uv sync --frozen --no-dev
|
||||||
$STD uv venv --clear
|
|
||||||
$STD uv pip install -r requirements.txt
|
|
||||||
$STD uv pip install pytz
|
|
||||||
msg_ok "Backend Updated"
|
msg_ok "Backend Updated"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
+1
-1
@@ -200,7 +200,7 @@ EOF
|
|||||||
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
|
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
|
||||||
curl -fsSL "https://raw.githubusercontent.com/Termix-SSH/Termix/main/docker/nginx.conf" -o /etc/nginx/nginx.conf
|
curl -fsSL "https://raw.githubusercontent.com/Termix-SSH/Termix/main/docker/nginx.conf" -o /etc/nginx/nginx.conf
|
||||||
sed -i '/^master_process/d' /etc/nginx/nginx.conf
|
sed -i '/^master_process/d' /etc/nginx/nginx.conf
|
||||||
sed -i 's|pid /tmp/nginx/nginx.pid;|pid /run/nginx.pid;|' /etc/nginx/nginx.conf
|
sed -i '/^pid \/app\/nginx/d' /etc/nginx/nginx.conf
|
||||||
sed -i 's|error_log /tmp/nginx/error.log|error_log /var/log/nginx/error.log|' /etc/nginx/nginx.conf
|
sed -i 's|error_log /tmp/nginx/error.log|error_log /var/log/nginx/error.log|' /etc/nginx/nginx.conf
|
||||||
sed -i 's|access_log /tmp/nginx/access.log|access_log /var/log/nginx/access.log|' /etc/nginx/nginx.conf
|
sed -i 's|access_log /tmp/nginx/access.log|access_log /var/log/nginx/access.log|' /etc/nginx/nginx.conf
|
||||||
sed -i 's|/app/html|/opt/termix/html|g' /etc/nginx/nginx.conf
|
sed -i 's|/app/html|/opt/termix/html|g' /etc/nginx/nginx.conf
|
||||||
|
|||||||
+2
-7
@@ -33,17 +33,12 @@ function update_script() {
|
|||||||
systemctl stop tunarr
|
systemctl stop tunarr
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Creating Backup"
|
create_backup /root/.local/share/tunarr
|
||||||
if [ -d "/root/.local/share/tunarr" ]; then
|
|
||||||
tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /root/.local/share/tunarr $STD
|
|
||||||
msg_ok "Backup Created"
|
|
||||||
else
|
|
||||||
msg_error "Backup failed: /root/.local/share/tunarr does not exist"
|
|
||||||
fi
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tunarr" "chrisbenincasa/tunarr" "prebuild" "latest" "/opt/tunarr" "*linux-$(arch_resolve "x64" "arm64").tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tunarr" "chrisbenincasa/tunarr" "prebuild" "latest" "/opt/tunarr" "*linux-$(arch_resolve "x64" "arm64").tar.gz"
|
||||||
cd /opt/tunarr
|
cd /opt/tunarr
|
||||||
mv tunarr* tunarr
|
mv tunarr* tunarr
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start tunarr
|
systemctl start tunarr
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ done
|
|||||||
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
|
# Install MongoDB Database Tools via direct .deb (no APT repo for Debian 13)
|
||||||
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
|
[[ "$(get_os_info id)" == "ubuntu" ]] && MONGO_DIST="ubuntu2204" || MONGO_DIST="debian12"
|
||||||
# MongoDB only publishes arm64 builds for Ubuntu
|
# MongoDB only publishes arm64 builds for Ubuntu
|
||||||
[[ "$MONGO_ARCH" == "arm64" ]] && MONGO_DIST="ubuntu2204"
|
[[ "$(arch_resolve "x86_64" "arm64")" == "arm64" ]] && MONGO_DIST="ubuntu2204"
|
||||||
MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools" "100." || echo "100.16.1")
|
MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools" "100." || echo "100.16.1")
|
||||||
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-$(arch_resolve "x86_64" "arm64")-${MONGO_VERSION}.deb" ""
|
fetch_and_deploy_from_url "https://fastdl.mongodb.org/tools/db/mongodb-database-tools-${MONGO_DIST}-$(arch_resolve "x86_64" "arm64")-${MONGO_VERSION}.deb" ""
|
||||||
mkdir -p /usr/local/mongodb-database-tools/bin
|
mkdir -p /usr/local/mongodb-database-tools/bin
|
||||||
@@ -65,7 +65,7 @@ $STD go mod tidy
|
|||||||
$STD go mod download
|
$STD go mod download
|
||||||
$STD go install github.com/swaggo/swag/cmd/swag@latest
|
$STD go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
||||||
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=$(arch_resolve) go build -o databasus ./cmd/main.go
|
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=$(arch_resolve) go build -o databasus ./cmd
|
||||||
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
||||||
mkdir -p /databasus-data/{pgdata,temp,backups,data,logs}
|
mkdir -p /databasus-data/{pgdata,temp,backups,data,logs}
|
||||||
mkdir -p /opt/databasus/ui/build
|
mkdir -p /opt/databasus/ui/build
|
||||||
|
|||||||
@@ -83,14 +83,7 @@ msg_info "Setting up Backend"
|
|||||||
cd /opt/endurain/backend
|
cd /opt/endurain/backend
|
||||||
UV_VERSION=$(grep -Po 'required-version\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null || echo "0.11.18")
|
UV_VERSION=$(grep -Po 'required-version\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null || echo "0.11.18")
|
||||||
UV_VERSION="$UV_VERSION" setup_uv
|
UV_VERSION="$UV_VERSION" setup_uv
|
||||||
$STD uv tool install poetry
|
$STD uv sync --frozen --no-dev
|
||||||
$STD uv tool update-shell
|
|
||||||
export PATH="/root/.local/bin:$PATH"
|
|
||||||
$STD poetry self add poetry-plugin-export
|
|
||||||
$STD poetry export -f requirements.txt --output requirements.txt --without-hashes
|
|
||||||
$STD uv venv --clear
|
|
||||||
$STD uv pip install -r requirements.txt
|
|
||||||
$STD uv pip install pytz
|
|
||||||
msg_ok "Setup Backend"
|
msg_ok "Setup Backend"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -5430,6 +5430,7 @@ fix_gpu_gids() {
|
|||||||
# Update dev entries with correct GIDs
|
# Update dev entries with correct GIDs
|
||||||
sed -i.bak -E "s|(dev[0-9]+: /dev/dri/renderD[0-9]+),gid=[0-9]+|\1,gid=${render_gid}|g" "$LXC_CONFIG"
|
sed -i.bak -E "s|(dev[0-9]+: /dev/dri/renderD[0-9]+),gid=[0-9]+|\1,gid=${render_gid}|g" "$LXC_CONFIG"
|
||||||
sed -i -E "s|(dev[0-9]+: /dev/dri/card[0-9]+),gid=[0-9]+|\1,gid=${video_gid}|g" "$LXC_CONFIG"
|
sed -i -E "s|(dev[0-9]+: /dev/dri/card[0-9]+),gid=[0-9]+|\1,gid=${video_gid}|g" "$LXC_CONFIG"
|
||||||
|
sed -i -E "s|(dev[0-9]+: /dev/kfd),gid=[0-9]+|\1,gid=${render_gid}|g" "$LXC_CONFIG"
|
||||||
|
|
||||||
# Restart container
|
# Restart container
|
||||||
pct start "$CTID" >/dev/null 2>&1
|
pct start "$CTID" >/dev/null 2>&1
|
||||||
@@ -5451,6 +5452,10 @@ fix_gpu_gids() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
if [ -e /dev/kfd ]; then
|
||||||
|
chgrp ${render_gid} /dev/kfd 2>/dev/null || true
|
||||||
|
chmod 660 /dev/kfd 2>/dev/null || true
|
||||||
|
fi
|
||||||
" >/dev/null 2>&1
|
" >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -2607,7 +2607,7 @@ check_for_gh_release() {
|
|||||||
ensure_dependencies jq
|
ensure_dependencies jq
|
||||||
|
|
||||||
local gh_check_json
|
local gh_check_json
|
||||||
gh_check_json=$(mktemp /tmp/tools-gh-check-XXXXXX.json) || return 7
|
gh_check_json=$(mktemp /tmp/tools-gh-check-XXXXXX) || return 73
|
||||||
trap 'rm -f "$gh_check_json"' RETURN
|
trap 'rm -f "$gh_check_json"' RETURN
|
||||||
|
|
||||||
# Build auth header if token is available
|
# Build auth header if token is available
|
||||||
@@ -3257,7 +3257,7 @@ fetch_and_deploy_codeberg_release() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local codeberg_rel_json
|
local codeberg_rel_json
|
||||||
codeberg_rel_json=$(mktemp /tmp/tools-codeberg-rel-XXXXXX.json) || return 7
|
codeberg_rel_json=$(mktemp /tmp/tools-codeberg-rel-XXXXXX) || return 73
|
||||||
trap 'rm -f "$codeberg_rel_json"' RETURN
|
trap 'rm -f "$codeberg_rel_json"' RETURN
|
||||||
|
|
||||||
local attempt=0 success=false resp http_code
|
local attempt=0 success=false resp http_code
|
||||||
@@ -3744,7 +3744,7 @@ fetch_and_deploy_gh_release() {
|
|||||||
rm -f "$TOOLS_GH_REL_JSON"
|
rm -f "$TOOLS_GH_REL_JSON"
|
||||||
fi
|
fi
|
||||||
local gh_rel_json
|
local gh_rel_json
|
||||||
gh_rel_json=$(mktemp /tmp/tools-gh-rel-XXXXXX.json) || return 7
|
gh_rel_json=$(mktemp /tmp/tools-gh-rel-XXXXXX) || return 73
|
||||||
TOOLS_GH_REL_JSON="$gh_rel_json"
|
TOOLS_GH_REL_JSON="$gh_rel_json"
|
||||||
|
|
||||||
local api_url="https://api.github.com/repos/$repo/releases"
|
local api_url="https://api.github.com/repos/$repo/releases"
|
||||||
@@ -4614,11 +4614,11 @@ EOF
|
|||||||
local image=$(echo "$container" | awk '{print $2}')
|
local image=$(echo "$container" | awk '{print $2}')
|
||||||
local current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
local current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
||||||
|
|
||||||
# Pull latest image digest
|
# Pull latest image digest (ignore failures, e.g. local-only images or registry/permission issues)
|
||||||
docker pull "$image" >/dev/null 2>&1
|
docker pull "$image" >/dev/null 2>&1 || true
|
||||||
local latest_digest=$(docker inspect "$image" --format='{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
local latest_digest=$(docker inspect "$image" --format='{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
||||||
|
|
||||||
if [ "$current_digest" != "$latest_digest" ]; then
|
if [ -n "$latest_digest" ] && [ "$current_digest" != "$latest_digest" ]; then
|
||||||
containers_with_updates+=("$name")
|
containers_with_updates+=("$name")
|
||||||
container_info+=("${index}) ${name} (${image})")
|
container_info+=("${index}) ${name} (${image})")
|
||||||
((index++))
|
((index++))
|
||||||
@@ -7561,8 +7561,8 @@ setup_nodejs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Install global Node modules
|
# Install global Node modules
|
||||||
if [[ -n "$NODE_MODULE" ]] || (( node_major >= 25 )); then
|
if [[ -n "$NODE_MODULE" ]] || ((node_major >= 25)); then
|
||||||
if (( node_major >= 25 )) && [[ ",${NODE_MODULE}," != *",corepack,"* ]] && [[ "$NODE_MODULE" != corepack* ]]; then
|
if ((node_major >= 25)) && [[ ",${NODE_MODULE}," != *",corepack,"* ]] && [[ "$NODE_MODULE" != corepack* ]]; then
|
||||||
NODE_MODULE="${NODE_MODULE:+$NODE_MODULE,}corepack"
|
NODE_MODULE="${NODE_MODULE:+$NODE_MODULE,}corepack"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -7624,12 +7624,12 @@ setup_nodejs() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if (( failed_modules > 0 )); then
|
if ((failed_modules > 0)); then
|
||||||
msg_warn "$failed_modules Node.js module(s) failed: $NODE_MODULE"
|
msg_warn "$failed_modules Node.js module(s) failed: $NODE_MODULE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$NODE_COREPACK_ENABLE" == "1" ]] && (( wants_corepack )) && command -v corepack >/dev/null 2>&1; then
|
if [[ "$NODE_COREPACK_ENABLE" == "1" ]] && ((wants_corepack)) && command -v corepack >/dev/null 2>&1; then
|
||||||
msg_info "Enabling corepack"
|
msg_info "Enabling corepack"
|
||||||
if $STD corepack enable 2>/dev/null; then
|
if $STD corepack enable 2>/dev/null; then
|
||||||
msg_ok "Enabled corepack"
|
msg_ok "Enabled corepack"
|
||||||
@@ -9172,7 +9172,7 @@ check_for_gl_release() {
|
|||||||
ensure_dependencies jq
|
ensure_dependencies jq
|
||||||
|
|
||||||
local gl_check_json
|
local gl_check_json
|
||||||
gl_check_json=$(mktemp /tmp/tools-gl-check-XXXXXX.json) || return 7
|
gl_check_json=$(mktemp /tmp/tools-gl-check-XXXXXX) || return 73
|
||||||
trap 'rm -f "$gl_check_json"' RETURN
|
trap 'rm -f "$gl_check_json"' RETURN
|
||||||
|
|
||||||
local repo_encoded
|
local repo_encoded
|
||||||
@@ -9452,7 +9452,7 @@ fetch_and_deploy_gl_release() {
|
|||||||
ensure_dependencies jq
|
ensure_dependencies jq
|
||||||
|
|
||||||
local gl_rel_json
|
local gl_rel_json
|
||||||
gl_rel_json=$(mktemp /tmp/tools-gl-rel-XXXXXX.json) || return 7
|
gl_rel_json=$(mktemp /tmp/tools-gl-rel-XXXXXX) || return 73
|
||||||
trap 'rm -f "$gl_rel_json"' RETURN
|
trap 'rm -f "$gl_rel_json"' RETURN
|
||||||
|
|
||||||
local repo_encoded
|
local repo_encoded
|
||||||
@@ -9902,7 +9902,7 @@ setup_nltk() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "${target_dir}/${subdir}"
|
mkdir -p "${target_dir}/${subdir}"
|
||||||
tmp_zip=$(mktemp --suffix=.zip)
|
tmp_zip=$(mktemp)
|
||||||
|
|
||||||
if CURL_TIMEOUT=120 curl_with_retry "$pkg_url" "$tmp_zip"; then
|
if CURL_TIMEOUT=120 curl_with_retry "$pkg_url" "$tmp_zip"; then
|
||||||
if [[ "$do_unzip" == "1" ]]; then
|
if [[ "$do_unzip" == "1" ]]; then
|
||||||
|
|||||||
+72
-32
@@ -22,10 +22,10 @@ APP="IP-Tag"
|
|||||||
hostname=$(hostname)
|
hostname=$(hostname)
|
||||||
|
|
||||||
# Color variables
|
# Color variables
|
||||||
YW=$(echo "\033[33m")
|
YW="\033[33m"
|
||||||
GN=$(echo "\033[1;92m")
|
GN="\033[1;92m"
|
||||||
RD=$(echo "\033[01;31m")
|
RD="\033[01;31m"
|
||||||
CL=$(echo "\033[m")
|
CL="\033[m"
|
||||||
BFR="\\r\\033[K"
|
BFR="\\r\\033[K"
|
||||||
HOLD=" "
|
HOLD=" "
|
||||||
CM="${GN}✓${CL} "
|
CM="${GN}✓${CL} "
|
||||||
@@ -127,7 +127,7 @@ update_installation() {
|
|||||||
echo -e "\n${YW}Configuration file already exists.${CL}"
|
echo -e "\n${YW}Configuration file already exists.${CL}"
|
||||||
echo -e "${YW}Note: No critical changes were made in this version.${CL}"
|
echo -e "${YW}Note: No critical changes were made in this version.${CL}"
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Do you want to replace it with defaults? (y/n): " yn
|
read -rp "Do you want to replace it with defaults? (y/n): " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
interactive_config_setup
|
interactive_config_setup
|
||||||
@@ -176,7 +176,7 @@ export FORCE_SINGLE_RUN=true
|
|||||||
exec "$SCRIPT_FILE"
|
exec "$SCRIPT_FILE"
|
||||||
EOF
|
EOF
|
||||||
chmod +x /usr/local/bin/iptag-run
|
chmod +x /usr/local/bin/iptag-run
|
||||||
msg_ok "Created iptag-run executable - You can execute this manually by entering “iptag-run” in the Proxmox host, so the script is executed by hand."
|
msg_ok "Created iptag-run executable - You can execute this manually by entering 'iptag-run' in the Proxmox host, so the script is executed by hand."
|
||||||
|
|
||||||
msg_info "Restarting service"
|
msg_info "Restarting service"
|
||||||
systemctl daemon-reload &>/dev/null
|
systemctl daemon-reload &>/dev/null
|
||||||
@@ -208,7 +208,7 @@ install_command_only() {
|
|||||||
else
|
else
|
||||||
stop_spinner
|
stop_spinner
|
||||||
echo -e "\n${YW}Configuration file already exists.${CL}"
|
echo -e "\n${YW}Configuration file already exists.${CL}"
|
||||||
read -p "Do you want to reconfigure tag format? (y/n): " reconfigure
|
read -rp "Do you want to reconfigure tag format? (y/n): " reconfigure
|
||||||
case $reconfigure in
|
case $reconfigure in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
interactive_config_setup_command
|
interactive_config_setup_command
|
||||||
@@ -285,7 +285,7 @@ interactive_config_setup_command() {
|
|||||||
echo -e "${GN}3)${CL} full - Show full IP address (e.g., 192.168.0.100)"
|
echo -e "${GN}3)${CL} full - Show full IP address (e.g., 192.168.0.100)"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Enter your choice (1-3) [1]: " tag_choice
|
read -rp "Enter your choice (1-3) [1]: " tag_choice
|
||||||
case ${tag_choice:-1} in
|
case ${tag_choice:-1} in
|
||||||
1)
|
1)
|
||||||
TAG_FORMAT="last_two_octets"
|
TAG_FORMAT="last_two_octets"
|
||||||
@@ -323,7 +323,7 @@ interactive_config_setup() {
|
|||||||
echo -e "${GN}3)${CL} full - Show full IP address (e.g., 192.168.0.100)"
|
echo -e "${GN}3)${CL} full - Show full IP address (e.g., 192.168.0.100)"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Enter your choice (1-3) [1]: " tag_choice
|
read -rp "Enter your choice (1-3) [1]: " tag_choice
|
||||||
case ${tag_choice:-1} in
|
case ${tag_choice:-1} in
|
||||||
1)
|
1)
|
||||||
TAG_FORMAT="last_two_octets"
|
TAG_FORMAT="last_two_octets"
|
||||||
@@ -352,7 +352,7 @@ interactive_config_setup() {
|
|||||||
echo -e "${YW}Recommended range: 300-3600 seconds${CL}"
|
echo -e "${YW}Recommended range: 300-3600 seconds${CL}"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Enter interval in seconds [300]: " interval_input
|
read -rp "Enter interval in seconds [300]: " interval_input
|
||||||
interval_input=${interval_input:-300}
|
interval_input=${interval_input:-300}
|
||||||
|
|
||||||
if [[ $interval_input =~ ^[0-9]+$ ]] && [ $interval_input -ge 300 ] && [ $interval_input -le 7200 ]; then
|
if [[ $interval_input =~ ^[0-9]+$ ]] && [ $interval_input -ge 300 ] && [ $interval_input -le 7200 ]; then
|
||||||
@@ -563,9 +563,10 @@ get_vm_ips() {
|
|||||||
|
|
||||||
debug_log "vm $vmid: starting IP detection"
|
debug_log "vm $vmid: starting IP detection"
|
||||||
|
|
||||||
# Check if VM is running first
|
# Check if VM is running first (status comes from the cached `qm list`,
|
||||||
local vm_status=""
|
# falling back to `qm status` only when called outside the normal cycle).
|
||||||
if command -v qm >/dev/null 2>&1; then
|
local vm_status="${STATUS_CACHE[vm_${vmid}]:-}"
|
||||||
|
if [[ -z "$vm_status" ]] && command -v qm >/dev/null 2>&1; then
|
||||||
vm_status=$(qm status "$vmid" 2>/dev/null | awk '{print $2}')
|
vm_status=$(qm status "$vmid" 2>/dev/null | awk '{print $2}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -578,33 +579,43 @@ get_vm_ips() {
|
|||||||
local mac_addresses=$(grep -E "^net[0-9]+:" "$vm_config" | grep -oE "([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}" | head -3)
|
local mac_addresses=$(grep -E "^net[0-9]+:" "$vm_config" | grep -oE "([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}" | head -3)
|
||||||
debug_log "vm $vmid: found MACs: $mac_addresses"
|
debug_log "vm $vmid: found MACs: $mac_addresses"
|
||||||
|
|
||||||
# Method 1: QM guest agent (most reliable for current IP)
|
# Method 1: QEMU guest agent (most reliable for current IP). Only query it
|
||||||
if command -v qm >/dev/null 2>&1; then
|
# when the agent is actually enabled in the VM config, otherwise the call
|
||||||
debug_log "vm $vmid: trying qm guest agent first"
|
# blocks until the timeout on every VM without an agent.
|
||||||
local qm_ips=$(timeout 8 qm guest cmd "$vmid" network-get-interfaces 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v "127.0.0.1" | head -3)
|
local agent_enabled=0
|
||||||
|
if [[ "$(grep -E '^agent:' "$vm_config" 2>/dev/null)" =~ (^agent:[[:space:]]*1|enabled=1) ]]; then
|
||||||
|
agent_enabled=1
|
||||||
|
fi
|
||||||
|
if [[ "$agent_enabled" == "1" ]] && command -v qm >/dev/null 2>&1; then
|
||||||
|
debug_log "vm $vmid: querying guest agent"
|
||||||
|
local qm_ips=$(timeout 5 qm guest cmd "$vmid" network-get-interfaces 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v "127.0.0.1" | head -3)
|
||||||
for qm_ip in $qm_ips; do
|
for qm_ip in $qm_ips; do
|
||||||
if [[ "$qm_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
if [[ "$qm_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
debug_log "vm $vmid: found IP $qm_ip via qm guest cmd"
|
debug_log "vm $vmid: found IP $qm_ip via qm guest cmd"
|
||||||
ips+="$qm_ip "
|
ips+="$qm_ip "
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
else
|
||||||
|
debug_log "vm $vmid: guest agent not enabled, skipping qm guest cmd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Method 2: Fresh ARP table lookup (force refresh)
|
# Method 2: ARP table lookup (only if the guest agent gave us nothing).
|
||||||
if [[ -n "$mac_addresses" ]]; then
|
if [[ -z "$ips" && -n "$mac_addresses" ]]; then
|
||||||
debug_log "vm $vmid: refreshing ARP table and checking"
|
debug_log "vm $vmid: checking ARP table"
|
||||||
# Try to refresh ARP table by pinging network ranges
|
# Snapshot the neighbor table once instead of per MAC
|
||||||
|
local neigh_table
|
||||||
|
neigh_table=$(ip neighbor show 2>/dev/null)
|
||||||
for mac in $mac_addresses; do
|
for mac in $mac_addresses; do
|
||||||
local mac_lower=$(echo "$mac" | tr '[:upper:]' '[:lower:]')
|
local mac_lower=$(echo "$mac" | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
# First check current ARP table
|
# Check current ARP table
|
||||||
local current_ip=$(ip neighbor show | grep "$mac_lower" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
|
local current_ip=$(echo "$neigh_table" | grep "$mac_lower" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
|
||||||
|
|
||||||
# If found in ARP, verify it's still valid by trying to ping
|
# If found in ARP, verify it's still valid by trying to ping
|
||||||
if [[ -n "$current_ip" && "$current_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
if [[ -n "$current_ip" && "$current_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
debug_log "vm $vmid: found IP $current_ip in ARP table for MAC $mac_lower, verifying..."
|
debug_log "vm $vmid: found IP $current_ip in ARP table for MAC $mac_lower, verifying..."
|
||||||
# Quick ping test to verify IP is still active
|
# Quick ping test to verify IP is still active
|
||||||
if timeout 2 ping -c 1 "$current_ip" >/dev/null 2>&1; then
|
if timeout 1 ping -c 1 -W 1 "$current_ip" >/dev/null 2>&1; then
|
||||||
debug_log "vm $vmid: verified IP $current_ip is active via ping"
|
debug_log "vm $vmid: verified IP $current_ip is active via ping"
|
||||||
ips+="$current_ip "
|
ips+="$current_ip "
|
||||||
else
|
else
|
||||||
@@ -628,7 +639,7 @@ get_vm_ips() {
|
|||||||
if [[ -n "$dhcp_ip" && "$dhcp_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
if [[ -n "$dhcp_ip" && "$dhcp_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
debug_log "vm $vmid: found IP $dhcp_ip via DHCP leases"
|
debug_log "vm $vmid: found IP $dhcp_ip via DHCP leases"
|
||||||
# Verify this IP responds
|
# Verify this IP responds
|
||||||
if timeout 2 ping -c 1 "$dhcp_ip" >/dev/null 2>&1; then
|
if timeout 1 ping -c 1 -W 1 "$dhcp_ip" >/dev/null 2>&1; then
|
||||||
debug_log "vm $vmid: verified DHCP IP $dhcp_ip is active"
|
debug_log "vm $vmid: verified DHCP IP $dhcp_ip is active"
|
||||||
ips+="$dhcp_ip "
|
ips+="$dhcp_ip "
|
||||||
break 2
|
break 2
|
||||||
@@ -652,6 +663,9 @@ get_vm_ips() {
|
|||||||
# Cache for configs to avoid repeated reads
|
# Cache for configs to avoid repeated reads
|
||||||
declare -A CONFIG_CACHE
|
declare -A CONFIG_CACHE
|
||||||
declare -A IP_CACHE
|
declare -A IP_CACHE
|
||||||
|
# Status cache populated once per check from `pct list` / `qm list` to avoid
|
||||||
|
# spawning an expensive `pct status` / `qm status` (Perl) per guest each cycle.
|
||||||
|
declare -A STATUS_CACHE
|
||||||
|
|
||||||
# Update tags for container or VM
|
# Update tags for container or VM
|
||||||
update_tags() {
|
update_tags() {
|
||||||
@@ -836,7 +850,16 @@ update_all_tags() {
|
|||||||
|
|
||||||
# Get list of all containers/VMs
|
# Get list of all containers/VMs
|
||||||
if [[ "$type" == "lxc" ]]; then
|
if [[ "$type" == "lxc" ]]; then
|
||||||
vmids=($(pct list 2>/dev/null | grep -v VMID | awk '{print $1}'))
|
# A single `pct list` call yields both the VMID list and the running
|
||||||
|
# status, so we never need a per-container `pct status` afterwards.
|
||||||
|
local pct_list_output
|
||||||
|
pct_list_output=$(pct list 2>/dev/null)
|
||||||
|
vmids=($(echo "$pct_list_output" | awk 'NR>1 {print $1}'))
|
||||||
|
local _vmid _status _rest
|
||||||
|
while read -r _vmid _status _rest; do
|
||||||
|
[[ "$_vmid" == "VMID" || -z "$_vmid" ]] && continue
|
||||||
|
STATUS_CACHE["lxc_${_vmid}"]="$_status"
|
||||||
|
done <<<"$pct_list_output"
|
||||||
else
|
else
|
||||||
# More efficient: direct file listing instead of ls+sed
|
# More efficient: direct file listing instead of ls+sed
|
||||||
vmids=()
|
vmids=()
|
||||||
@@ -845,6 +868,15 @@ update_all_tags() {
|
|||||||
local basename="${conf##*/}"
|
local basename="${conf##*/}"
|
||||||
vmids+=("${basename%.conf}")
|
vmids+=("${basename%.conf}")
|
||||||
done
|
done
|
||||||
|
# A single `qm list` call yields the status for all VMs, avoiding a
|
||||||
|
# per-VM `qm status`.
|
||||||
|
if command -v qm >/dev/null 2>&1; then
|
||||||
|
local _vmid _name _status _rest
|
||||||
|
while read -r _vmid _name _status _rest; do
|
||||||
|
[[ "$_vmid" == "VMID" || -z "$_vmid" ]] && continue
|
||||||
|
STATUS_CACHE["vm_${_vmid}"]="$_status"
|
||||||
|
done <<<"$(qm list 2>/dev/null)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
count=${#vmids[@]}
|
count=${#vmids[@]}
|
||||||
@@ -881,6 +913,7 @@ check() {
|
|||||||
# Clear caches before each run
|
# Clear caches before each run
|
||||||
CONFIG_CACHE=()
|
CONFIG_CACHE=()
|
||||||
IP_CACHE=()
|
IP_CACHE=()
|
||||||
|
STATUS_CACHE=()
|
||||||
|
|
||||||
# Update LXC containers
|
# Update LXC containers
|
||||||
update_all_tags "lxc"
|
update_all_tags "lxc"
|
||||||
@@ -925,8 +958,12 @@ get_lxc_ips() {
|
|||||||
|
|
||||||
debug_log "lxc $vmid: starting IP detection"
|
debug_log "lxc $vmid: starting IP detection"
|
||||||
|
|
||||||
# Check if LXC is running
|
# Check if LXC is running (status comes from the cached `pct list`,
|
||||||
local lxc_status=$(pct status "${vmid}" 2>/dev/null | awk '{print $2}')
|
# falling back to `pct status` only when called outside the normal cycle).
|
||||||
|
local lxc_status="${STATUS_CACHE[lxc_${vmid}]:-}"
|
||||||
|
if [[ -z "$lxc_status" ]]; then
|
||||||
|
lxc_status=$(pct status "${vmid}" 2>/dev/null | awk '{print $2}')
|
||||||
|
fi
|
||||||
if [[ "$lxc_status" != "running" ]]; then
|
if [[ "$lxc_status" != "running" ]]; then
|
||||||
debug_log "lxc $vmid: not running (status: $lxc_status)"
|
debug_log "lxc $vmid: not running (status: $lxc_status)"
|
||||||
return
|
return
|
||||||
@@ -952,9 +989,12 @@ get_lxc_ips() {
|
|||||||
if [[ -z "$ips" && -f "$pve_lxc_config" ]]; then
|
if [[ -z "$ips" && -f "$pve_lxc_config" ]]; then
|
||||||
local mac_addrs=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | cut -d'=' -f2)
|
local mac_addrs=$(grep -Eo 'hwaddr=([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$pve_lxc_config" | cut -d'=' -f2)
|
||||||
if [[ -n "$mac_addrs" ]]; then
|
if [[ -n "$mac_addrs" ]]; then
|
||||||
|
# Snapshot the neighbor table once instead of per MAC
|
||||||
|
local neigh_table
|
||||||
|
neigh_table=$(ip neighbor show 2>/dev/null)
|
||||||
while IFS= read -r mac_addr; do
|
while IFS= read -r mac_addr; do
|
||||||
[[ -z "$mac_addr" ]] && continue
|
[[ -z "$mac_addr" ]] && continue
|
||||||
local arp_ip=$(ip neighbor show | grep -i "$mac_addr" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
|
local arp_ip=$(echo "$neigh_table" | grep -i "$mac_addr" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1)
|
||||||
if [[ -n "$arp_ip" && "$arp_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
if [[ -n "$arp_ip" && "$arp_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
debug_log "lxc $vmid: found IP $arp_ip via ARP table for MAC $mac_addr"
|
debug_log "lxc $vmid: found IP $arp_ip via ARP table for MAC $mac_addr"
|
||||||
ips="${ips}${ips:+ }${arp_ip}"
|
ips="${ips}${ips:+ }${arp_ip}"
|
||||||
@@ -996,7 +1036,7 @@ echo -e "${GN}3)${CL} Update existing installation"
|
|||||||
echo -e "${RD}4)${CL} Cancel"
|
echo -e "${RD}4)${CL} Cancel"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Enter your choice (1-4): " choice
|
read -rp "Enter your choice (1-4): " choice
|
||||||
case $choice in
|
case $choice in
|
||||||
1)
|
1)
|
||||||
INSTALL_MODE="service"
|
INSTALL_MODE="service"
|
||||||
@@ -1025,7 +1065,7 @@ done
|
|||||||
|
|
||||||
echo -e "\n${YW}This will install ${APP} on ${hostname} in $INSTALL_MODE mode.${CL}"
|
echo -e "\n${YW}This will install ${APP} on ${hostname} in $INSTALL_MODE mode.${CL}"
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Proceed? (y/n): " yn
|
read -rp "Proceed? (y/n): " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
break
|
break
|
||||||
@@ -1072,7 +1112,7 @@ if [[ "$INSTALL_MODE" == "service" ]]; then
|
|||||||
else
|
else
|
||||||
stop_spinner
|
stop_spinner
|
||||||
echo -e "\n${YW}Configuration file already exists.${CL}"
|
echo -e "\n${YW}Configuration file already exists.${CL}"
|
||||||
read -p "Do you want to reconfigure tag format and loop interval? (y/n): " reconfigure
|
read -rp "Do you want to reconfigure tag format and loop interval? (y/n): " reconfigure
|
||||||
case $reconfigure in
|
case $reconfigure in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
interactive_config_setup
|
interactive_config_setup
|
||||||
|
|||||||
+15
-8
@@ -30,7 +30,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "clean-lxcs" "
|
|||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
|
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This will clean logs, cache and update package lists on selected LXC Containers. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This will clean logs, cache and update package lists on selected LXC Containers. Proceed?" 10 58 || exit 0
|
||||||
|
|
||||||
NODE=$(hostname)
|
NODE=$(hostname)
|
||||||
EXCLUDE_MENU=()
|
EXCLUDE_MENU=()
|
||||||
@@ -42,17 +42,17 @@ while read -r TAG ITEM; do
|
|||||||
EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF")
|
EXCLUDE_MENU+=("$TAG" "$ITEM " "OFF")
|
||||||
done < <(pct list | awk 'NR>1')
|
done < <(pct list | awk 'NR>1')
|
||||||
|
|
||||||
excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from cleaning:\n" \
|
# Capture the selection; abort cleanly if the user cancels the dialog
|
||||||
16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
# (set -e would otherwise terminate on the failing command substitution).
|
||||||
|
if ! excluded_containers=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --checklist "\nSelect containers to skip from cleaning:\n" \
|
||||||
if [ $? -ne 0 ]; then
|
16 $((MSG_MAX_LENGTH + 23)) 6 "${EXCLUDE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"'); then
|
||||||
exit
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function run_lxc_clean() {
|
function run_lxc_clean() {
|
||||||
local container=$1
|
local container=$1
|
||||||
header_info
|
header_info
|
||||||
name=$(pct exec "$container" hostname)
|
name=$(pct exec "$container" -- hostname)
|
||||||
|
|
||||||
pct exec "$container" -- bash -c '
|
pct exec "$container" -- bash -c '
|
||||||
BL="\033[36m"; GN="\033[1;92m"; CL="\033[m"
|
BL="\033[36m"; GN="\033[1;92m"; CL="\033[m"
|
||||||
@@ -84,7 +84,14 @@ function run_lxc_clean() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for container in $(pct list | awk '{if(NR>1) print $1}'); do
|
for container in $(pct list | awk '{if(NR>1) print $1}'); do
|
||||||
if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then
|
excluded=0
|
||||||
|
for ex in $excluded_containers; do
|
||||||
|
if [[ "$ex" == "$container" ]]; then
|
||||||
|
excluded=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$excluded" -eq 1 ]]; then
|
||||||
header_info
|
header_info
|
||||||
echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}"
|
echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|||||||
@@ -55,12 +55,23 @@ read -r selected
|
|||||||
selected_indices=()
|
selected_indices=()
|
||||||
IFS=',' read -r -a tokens <<<"$selected"
|
IFS=',' read -r -a tokens <<<"$selected"
|
||||||
for token in "${tokens[@]}"; do
|
for token in "${tokens[@]}"; do
|
||||||
|
# Strip surrounding whitespace and skip empty tokens
|
||||||
|
token="${token//[[:space:]]/}"
|
||||||
|
[ -z "$token" ] && continue
|
||||||
if [[ "$token" =~ ^([0-9]+)-([0-9]+)$ ]]; then
|
if [[ "$token" =~ ^([0-9]+)-([0-9]+)$ ]]; then
|
||||||
for ((i = BASH_REMATCH[1]; i <= BASH_REMATCH[2]; i++)); do
|
start=${BASH_REMATCH[1]}
|
||||||
|
end=${BASH_REMATCH[2]}
|
||||||
|
if ((start > end)); then
|
||||||
|
echo -e "${RD}Ignoring invalid range '${token}' (start greater than end).${CL}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
for ((i = start; i <= end; i++)); do
|
||||||
selected_indices+=("$i")
|
selected_indices+=("$i")
|
||||||
done
|
done
|
||||||
else
|
elif [[ "$token" =~ ^[0-9]+$ ]]; then
|
||||||
selected_indices+=("$token")
|
selected_indices+=("$token")
|
||||||
|
else
|
||||||
|
echo -e "${RD}Ignoring invalid selection '${token}'.${CL}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -101,8 +112,7 @@ for kernel in "${kernels_to_remove[@]}"; do
|
|||||||
remaining=$(dpkg --list |
|
remaining=$(dpkg --list |
|
||||||
awk '/^ii/ {print $2}' |
|
awk '/^ii/ {print $2}' |
|
||||||
grep -E "^proxmox-kernel-${minor_version}\." |
|
grep -E "^proxmox-kernel-${minor_version}\." |
|
||||||
grep -v "^${kernel}$" |
|
grep -cv "^${kernel}$")
|
||||||
wc -l)
|
|
||||||
if [ "$remaining" -eq 0 ]; then
|
if [ "$remaining" -eq 0 ]; then
|
||||||
pkgs_to_remove+=("$meta")
|
pkgs_to_remove+=("$meta")
|
||||||
fi
|
fi
|
||||||
|
|||||||
+11
-11
@@ -16,10 +16,10 @@ function header_info {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
RD=$(echo "\033[01;31m")
|
RD="\033[01;31m"
|
||||||
YW=$(echo "\033[33m")
|
YW="\033[33m"
|
||||||
GN=$(echo "\033[1;92m")
|
GN="\033[1;92m"
|
||||||
CL=$(echo "\033[m")
|
CL="\033[m"
|
||||||
BFR="\\r\\033[K"
|
BFR="\\r\\033[K"
|
||||||
HOLD="-"
|
HOLD="-"
|
||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
@@ -47,7 +47,7 @@ intel() {
|
|||||||
sleep 1
|
sleep 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
intel_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode//" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//')
|
intel_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//')
|
||||||
[ -z "$intel_microcode" ] && {
|
[ -z "$intel_microcode" ] && {
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68
|
||||||
msg_info "Exiting"
|
msg_info "Exiting"
|
||||||
@@ -80,17 +80,17 @@ intel() {
|
|||||||
msg_ok "Downloaded the Intel Processor Microcode Package $microcode"
|
msg_ok "Downloaded the Intel Processor Microcode Package $microcode"
|
||||||
|
|
||||||
msg_info "Installing $microcode (Patience)"
|
msg_info "Installing $microcode (Patience)"
|
||||||
dpkg -i $microcode &>/dev/null
|
dpkg -i "$microcode" &>/dev/null
|
||||||
msg_ok "Installed $microcode"
|
msg_ok "Installed $microcode"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
msg_info "Cleaning up"
|
||||||
rm $microcode
|
rm -f "$microcode"
|
||||||
msg_ok "Cleaned"
|
msg_ok "Cleaned"
|
||||||
echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n"
|
echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
amd() {
|
amd() {
|
||||||
amd_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode///" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//')
|
amd_microcode=$(curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/" | grep -o 'href="[^"]*amd64.deb"' | sed 's/href="//;s/"//')
|
||||||
|
|
||||||
[ -z "$amd_microcode" ] && {
|
[ -z "$amd_microcode" ] && {
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Microcode Found" --msgbox "It appears there were no microcode packages found\n Try again later." 10 68
|
||||||
@@ -120,15 +120,15 @@ amd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg_info "Downloading the AMD Processor Microcode Package $microcode"
|
msg_info "Downloading the AMD Processor Microcode Package $microcode"
|
||||||
curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode" -o $(basename "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode")
|
curl -fsSL --proto '=https' "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode" -o "$microcode"
|
||||||
msg_ok "Downloaded the AMD Processor Microcode Package $microcode"
|
msg_ok "Downloaded the AMD Processor Microcode Package $microcode"
|
||||||
|
|
||||||
msg_info "Installing $microcode (Patience)"
|
msg_info "Installing $microcode (Patience)"
|
||||||
dpkg -i $microcode &>/dev/null
|
dpkg -i "$microcode" &>/dev/null
|
||||||
msg_ok "Installed $microcode"
|
msg_ok "Installed $microcode"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
msg_info "Cleaning up"
|
||||||
rm $microcode
|
rm -f "$microcode"
|
||||||
msg_ok "Cleaned"
|
msg_ok "Cleaned"
|
||||||
echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n"
|
echo -e "\nIn order to apply the changes, a system reboot will be necessary.\n"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ EOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Color definitions
|
# Color definitions
|
||||||
RD=$(echo "\033[01;31m")
|
RD="\033[01;31m"
|
||||||
YW=$(echo "\033[33m")
|
YW="\033[33m"
|
||||||
GN=$(echo "\033[1;92m")
|
GN="\033[1;92m"
|
||||||
CL=$(echo "\033[m")
|
CL="\033[m"
|
||||||
BFR="\\r\\033[K"
|
BFR="\\r\\033[K"
|
||||||
HOLD="-"
|
HOLD="-"
|
||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
@@ -94,11 +94,11 @@ intel() {
|
|||||||
msg_ok "Downloaded Intel processor microcode package $microcode"
|
msg_ok "Downloaded Intel processor microcode package $microcode"
|
||||||
|
|
||||||
msg_info "Installing $microcode (this might take a while)"
|
msg_info "Installing $microcode (this might take a while)"
|
||||||
dpkg -i $microcode &>/dev/null
|
dpkg -i "$microcode" &>/dev/null
|
||||||
msg_ok "Installed $microcode"
|
msg_ok "Installed $microcode"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
msg_info "Cleaning up"
|
||||||
rm $microcode
|
rm -f "$microcode"
|
||||||
msg_ok "Clean up complete"
|
msg_ok "Clean up complete"
|
||||||
echo -e "\nA system reboot is required to apply the changes.\n"
|
echo -e "\nA system reboot is required to apply the changes.\n"
|
||||||
}
|
}
|
||||||
@@ -137,15 +137,15 @@ amd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg_info "Downloading AMD processor microcode package $microcode"
|
msg_info "Downloading AMD processor microcode package $microcode"
|
||||||
curl -fsSL "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode" -o $(basename "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode")
|
curl -fsSL --proto '=https' "https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode" -o "$microcode"
|
||||||
msg_ok "Downloaded AMD processor microcode package $microcode"
|
msg_ok "Downloaded AMD processor microcode package $microcode"
|
||||||
|
|
||||||
msg_info "Installing $microcode (this might take a while)"
|
msg_info "Installing $microcode (this might take a while)"
|
||||||
dpkg -i $microcode &>/dev/null
|
dpkg -i "$microcode" &>/dev/null
|
||||||
msg_ok "Installed $microcode"
|
msg_ok "Installed $microcode"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
msg_info "Cleaning up"
|
||||||
rm $microcode
|
rm -f "$microcode"
|
||||||
msg_ok "Clean up complete"
|
msg_ok "Clean up complete"
|
||||||
echo -e "\nA system reboot is required to apply the changes.\n"
|
echo -e "\nA system reboot is required to apply the changes.\n"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,26 @@ header_info() {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
header_info
|
header_info
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling Governors" --yesno "View/Change CPU Scaling Governors. Proceed?" 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling Governors" --yesno "View/Change CPU Scaling Governors. Proceed?" 10 58 || exit 0
|
||||||
current_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)
|
|
||||||
|
GOV_BASE="/sys/devices/system/cpu/cpu0/cpufreq"
|
||||||
|
if [[ ! -r "$GOV_BASE/scaling_governor" || ! -r "$GOV_BASE/scaling_available_governors" ]]; then
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU Scaling Not Available" \
|
||||||
|
--msgbox "CPU frequency scaling is not available on this system.\n\nThis is normal when no cpufreq driver is active (e.g. CPU power management handled by the BIOS, or certain virtualized hosts)." 12 70
|
||||||
|
clear
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_governor=$(cat "$GOV_BASE/scaling_governor")
|
||||||
GOVERNORS_MENU=()
|
GOVERNORS_MENU=()
|
||||||
MSG_MAX_LENGTH=0
|
MSG_MAX_LENGTH=0
|
||||||
while read -r TAG ITEM; do
|
while read -r TAG ITEM; do
|
||||||
OFFSET=2
|
OFFSET=2
|
||||||
((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET
|
((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET
|
||||||
GOVERNORS_MENU+=("$TAG" "$ITEM " "OFF")
|
GOVERNORS_MENU+=("$TAG" "$ITEM " "OFF")
|
||||||
done < <(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | tr ' ' '\n' | grep -v "$current_governor")
|
done < <(tr ' ' '\n' <"$GOV_BASE/scaling_available_governors" | sed '/^$/d' | grep -vxF "$current_governor")
|
||||||
scaling_governor=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current CPU Scaling Governor is set to $current_governor" --checklist "\nSelect the Scaling Governor to use:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${GOVERNORS_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
# A radiolist is used on purpose: only a single governor can be active at a time.
|
||||||
|
scaling_governor=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Current CPU Scaling Governor is set to $current_governor" --radiolist "\nSelect the Scaling Governor to use:\n" 16 $((MSG_MAX_LENGTH + 58)) 6 "${GOVERNORS_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
||||||
[ -z "$scaling_governor" ] && {
|
[ -z "$scaling_governor" ] && {
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No CPU Scaling Governor Selected" --msgbox "It appears that no CPU Scaling Governor was selected" 10 68
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No CPU Scaling Governor Selected" --msgbox "It appears that no CPU Scaling Governor was selected" 10 68
|
||||||
clear
|
clear
|
||||||
@@ -49,7 +59,7 @@ yes)
|
|||||||
EXISTING_CRONTAB=$(crontab -l 2>/dev/null)
|
EXISTING_CRONTAB=$(crontab -l 2>/dev/null)
|
||||||
if [[ -n "$EXISTING_CRONTAB" ]]; then
|
if [[ -n "$EXISTING_CRONTAB" ]]; then
|
||||||
TEMP_CRONTAB_FILE=$(mktemp)
|
TEMP_CRONTAB_FILE=$(mktemp)
|
||||||
echo "$EXISTING_CRONTAB" | grep -v "@reboot (sleep 60 && echo*" >"$TEMP_CRONTAB_FILE"
|
echo "$EXISTING_CRONTAB" | grep -vF "@reboot (sleep 60 && echo" >"$TEMP_CRONTAB_FILE"
|
||||||
crontab "$TEMP_CRONTAB_FILE"
|
crontab "$TEMP_CRONTAB_FILE"
|
||||||
rm "$TEMP_CRONTAB_FILE"
|
rm "$TEMP_CRONTAB_FILE"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user