Update repository and clean up

This commit is contained in:
MacRimi
2026-03-26 19:03:01 +01:00
parent 12c088c10b
commit d497763e38
19 changed files with 2 additions and 7088 deletions

View File

@@ -1,277 +0,0 @@
#!/bin/bash
# ==========================================================
# Remove Subscription Banner - Proxmox VE (v3 - Minimal Intrusive)
# ==========================================================
# This version makes a surgical change to the checked_command function
# by changing the condition to 'if (false)' and commenting out the banner logic.
# Also patches the mobile UI to remove the subscription dialog.
# ==========================================================
set -euo pipefail
# Source utilities if available
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
# File paths
JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
MOBILE_UI_FILE="/usr/share/pve-yew-mobile-gui/index.html.tpl"
BACKUP_DIR="$BASE_DIR/backups"
APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
PATCH_BIN="/usr/local/bin/pve-remove-nag-v3.sh"
MARK="/* PROXMENUX_NAG_PATCH_V3 */"
MOBILE_MARK="<!-- PROXMENUX_MOBILE_NAG_PATCH -->"
# Ensure tools JSON exists
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
# Register tool in JSON
register_tool() {
command -v jq >/dev/null 2>&1 || return 0
local tool="$1" state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" \
> "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
# Verify JS file integrity
verify_js_integrity() {
local file="$1"
[ -f "$file" ] || return 1
[ -s "$file" ] || return 1
grep -Eq 'Ext|function|var|const|let' "$file" || return 1
if LC_ALL=C grep -qP '\x00' "$file" 2>/dev/null; then
return 1
fi
return 0
}
# Create timestamped backup
create_backup() {
local file="$1"
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="$BACKUP_DIR/$(basename "$file").backup.$timestamp"
mkdir -p "$BACKUP_DIR"
if [ -f "$file" ]; then
rm -f "$BACKUP_DIR"/"$(basename "$file")".backup.* 2>/dev/null || true
cp -a "$file" "$backup_file"
echo "$backup_file"
fi
}
# Create the patch script that will be called by APT hook
create_patch_script() {
cat > "$PATCH_BIN" <<'EOFPATCH'
#!/usr/bin/env bash
# ==========================================================
# Proxmox Subscription Banner Patch (v3 - Minimal)
# ==========================================================
set -euo pipefail
JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
MOBILE_UI_FILE="/usr/share/pve-yew-mobile-gui/index.html.tpl"
BACKUP_DIR="/usr/local/share/proxmenux/backups"
MARK="/* PROXMENUX_NAG_PATCH_V3 */"
MOBILE_MARK="<!-- PROXMENUX_MOBILE_NAG_PATCH -->"
verify_js_integrity() {
local file="$1"
[ -f "$file" ] && [ -s "$file" ] && grep -Eq 'Ext|function' "$file" && ! LC_ALL=C grep -qP '\x00' "$file" 2>/dev/null
}
patch_checked_command() {
[ -f "$JS_FILE" ] || return 0
# Check if already patched
grep -q "$MARK" "$JS_FILE" && return 0
# Create backup
mkdir -p "$BACKUP_DIR"
local backup="$BACKUP_DIR/$(basename "$JS_FILE").backup.$(date +%Y%m%d_%H%M%S)"
cp -a "$JS_FILE" "$backup"
# Set trap to restore on error
trap "cp -a '$backup' '$JS_FILE' 2>/dev/null || true" ERR
# Add patch marker at the beginning
sed -i "1s|^|$MARK\n|" "$JS_FILE"
# Surgical patch: Change the condition in checked_command function
# This changes the if condition to 'if (false)' making the banner never show
if grep -q "res\.data\.status\.toLowerCase() !== 'active'" "$JS_FILE"; then
# Pattern for newer versions (8.4.5+)
sed -i "/checked_command: function/,/},$/s/res === null || res === undefined || !res || res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
elif grep -q "res\.data\.status !== 'Active'" "$JS_FILE"; then
# Pattern for older versions
sed -i "/checked_command: function/,/},$/s/res === null || res === undefined || !res || res\.data\.status !== 'Active'/false/g" "$JS_FILE"
fi
# Also handle the NoMoreNagging pattern if present
if grep -q "res\.data\.status\.toLowerCase() !== 'NoMoreNagging'" "$JS_FILE"; then
sed -i "/checked_command: function/,/},$/s/res === null || res === undefined || !res || res\.data\.status\.toLowerCase() !== 'NoMoreNagging'/false/g" "$JS_FILE"
fi
# Verify integrity after patch
if ! verify_js_integrity "$JS_FILE"; then
cp -a "$backup" "$JS_FILE"
return 1
fi
# Clean up generated files
rm -f "$MIN_JS_FILE" "$GZ_FILE" 2>/dev/null || true
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/cache/nginx/ -type f -delete 2>/dev/null || true
trap - ERR
return 0
}
patch_mobile_ui() {
[ -f "$MOBILE_UI_FILE" ] || return 0
# Check if already patched
grep -q "$MOBILE_MARK" "$MOBILE_UI_FILE" && return 0
# Create backup
mkdir -p "$BACKUP_DIR"
local backup="$BACKUP_DIR/$(basename "$MOBILE_UI_FILE").backup.$(date +%Y%m%d_%H%M%S)"
cp -a "$MOBILE_UI_FILE" "$backup"
# Set trap to restore on error
trap "cp -a '$backup' '$MOBILE_UI_FILE' 2>/dev/null || true" ERR
# Insert the script before </head> tag
sed -i "/<\/head>/i\\
$MOBILE_MARK\\
<!-- Script to remove subscription banner from mobile UI -->\\
<script>\\
function removeNoSubDialog() {\\
const observer = new MutationObserver(() => {\\
const diag = document.querySelector('dialog[aria-label=\"No valid subscription\"]');\\
if (diag) {\\
diag.remove();\\
}\\
});\\
observer.observe(document.body, { childList: true, subtree: true });\\
}\\
window.addEventListener('load', () => {\\
setTimeout(removeNoSubDialog, 200);\\
});\\
</script>" "$MOBILE_UI_FILE"
trap - ERR
return 0
}
reload_services() {
systemctl is-active --quiet pveproxy 2>/dev/null && {
systemctl reload pveproxy 2>/dev/null || systemctl restart pveproxy 2>/dev/null || true
}
systemctl is-active --quiet nginx 2>/dev/null && {
systemctl reload nginx 2>/dev/null || true
}
systemctl is-active --quiet pvedaemon 2>/dev/null && {
systemctl reload pvedaemon 2>/dev/null || true
}
}
main() {
patch_checked_command || return 1
patch_mobile_ui || true
reload_services
}
main
EOFPATCH
chmod 755 "$PATCH_BIN"
}
# Create APT hook to reapply patch after updates
create_apt_hook() {
cat > "$APT_HOOK" <<'EOFAPT'
/* ProxMenux: reapply minimal nag patch after upgrades */
DPkg::Post-Invoke { "/usr/local/bin/pve-remove-nag-v3.sh || true"; };
EOFAPT
chmod 644 "$APT_HOOK"
# Verify APT hook syntax
apt-config dump >/dev/null 2>&1 || {
rm -f "$APT_HOOK"
}
}
# Main function to remove subscription banner
remove_subscription_banner_v3() {
local pve_version
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1 || echo "unknown")
msg_info "$(translate "Detected Proxmox VE") ${pve_version} - $(translate "applying banner patch")"
# Remove old APT hooks
for f in /etc/apt/apt.conf.d/*nag*; do
[[ -e "$f" ]] && rm -f "$f"
done
# Create backup for desktop UI
local backup_file
backup_file=$(create_backup "$JS_FILE")
if [ -n "$backup_file" ]; then
# msg_ok "$(translate "Desktop UI backup created"): $backup_file"
:
fi
if [ -f "$MOBILE_UI_FILE" ]; then
local mobile_backup
mobile_backup=$(create_backup "$MOBILE_UI_FILE")
if [ -n "$mobile_backup" ]; then
# msg_ok "$(translate "Mobile UI backup created"): $mobile_backup"
:
fi
fi
# Create patch script and APT hook
create_patch_script
create_apt_hook
# Apply the patch
if ! "$PATCH_BIN"; then
msg_error "$(translate "Error applying patch. Backups preserved at"): $BACKUP_DIR"
return 1
fi
# Register tool as applied
register_tool "subscription_banner" true
msg_ok "$(translate "Subscription banner removed successfully")"
msg_ok "$(translate "Desktop and Mobile UI patched")"
msg_ok "$(translate "Refresh your browser (Ctrl+Shift+R) to see changes")"
}
# Run if executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
remove_subscription_banner_v3
fi

View File

@@ -1,124 +0,0 @@
#!/bin/bash
# ==========================================================
# Remove Subscription Banner - Proxmox VE 9.x
# ==========================================================
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
VENV_PATH="/opt/googletrans-env"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
register_tool() {
local tool="$1"
local state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
remove_subscription_banner_pve9() {
local JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
local MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
local GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
local APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
local pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1)
local pve_major=$(echo "$pve_version" | cut -d. -f1)
if [ "$pve_major" -lt 9 ] 2>/dev/null; then
msg_error "This script is for PVE 9.x only. Detected PVE $pve_version"
return 1
fi
msg_info "Detected Proxmox VE $pve_version - Applying PVE 9.x patches"
if [ ! -f "$JS_FILE" ]; then
msg_error "JavaScript file not found: $JS_FILE"
return 1
fi
local backup_file="${JS_FILE}.backup.pve9.$(date +%Y%m%d_%H%M%S)"
cp "$JS_FILE" "$backup_file"
for f in /etc/apt/apt.conf.d/*nag*; do
[[ -e "$f" ]] && rm -f "$f"
done
[[ -f "$GZ_FILE" ]] && rm -f "$GZ_FILE"
[[ -f "$MIN_JS_FILE" ]] && rm -f "$MIN_JS_FILE"
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/cache/nginx/ -type f -delete 2>/dev/null || true
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
sed -i "s/subscriptionActive: ''/subscriptionActive: true/g" "$JS_FILE"
sed -i "s/title: gettext('No valid subscription')/title: gettext('Community Edition')/g" "$JS_FILE"
sed -i "s/You do not have a valid subscription for this server/Community Edition - No subscription required/g" "$JS_FILE"
sed -i "s/Enterprise repository needs valid subscription/Enterprise repository configured/g" "$JS_FILE"
sed -i "s/icon: Ext\.Msg\.WARNING/icon: Ext.Msg.INFO/g" "$JS_FILE"
sed -i "s/subscription = !(/subscription = false \&\& (/g" "$JS_FILE"
if grep -q "res\.data\.status\.toLowerCase() !== 'active'" "$JS_FILE"; then
msg_warn "Some patches may not have applied correctly, retrying..."
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
fi
[[ -f "$APT_HOOK" ]] && rm -f "$APT_HOOK"
cat > "$APT_HOOK" << 'EOF'
DPkg::Post-Invoke {
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/res\\.data\\.status\\.toLowerCase() !== '\''active'\''/false/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscriptionActive: '\'\'\''/subscriptionActive: true/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/title: gettext('\''No valid subscription'\'')/title: gettext('\''Community Edition'\'')/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscription = !(/subscription = false \\&\\& (/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"rm -f /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz || true";
};
EOF
chmod 644 "$APT_HOOK"
if ! apt-config dump >/dev/null 2>&1; then
msg_warn "APT hook has syntax issues, removing..."
rm -f "$APT_HOOK"
else
msg_ok "APT hook created successfully"
fi
systemctl reload nginx 2>/dev/null || true
msg_ok "Subscription banner removed successfully for Proxmox VE $pve_version"
msg_ok "Banner removal process completed - refresh your browser to see changes"
register_tool "subscription_banner" true
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
remove_subscription_banner_pve9
fi

View File

@@ -1,119 +0,0 @@
#!/bin/bash
# ==========================================================
# Remove Subscription Banner - Proxmox VE 9.x ONLY
# ==========================================================
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
VENV_PATH="/opt/googletrans-env"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
# Tool registration system
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
register_tool() {
local tool="$1"
local state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
remove_subscription_banner_pve9() {
local JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
local MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
local GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
local APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
# Verify PVE 9.x
local pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1)
local pve_major=$(echo "$pve_version" | cut -d. -f1)
if [ "$pve_major" -lt 9 ] 2>/dev/null; then
msg_error "This script is for PVE 9.x only. Detected PVE $pve_version"
return 1
fi
msg_info "Detected Proxmox VE $pve_version - Applying PVE 9.x patches"
# Verify that the file exists
if [ ! -f "$JS_FILE" ]; then
msg_error "JavaScript file not found: $JS_FILE"
return 1
fi
# Create backup of original file
local backup_file="${JS_FILE}.backup.pve9.$(date +%Y%m%d_%H%M%S)"
cp "$JS_FILE" "$backup_file"
# Clean any existing problematic APT hooks
for f in /etc/apt/apt.conf.d/*nag*; do
[[ -e "$f" ]] && rm -f "$f"
done
# Main subscription check patches for PVE 9
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
sed -i "s/subscriptionActive: ''/subscriptionActive: true/g" "$JS_FILE"
sed -i "s/title: gettext('No valid subscription')/title: gettext('Community Edition')/g" "$JS_FILE"
# Additional UX improvements for PVE 9
sed -i "s/You do not have a valid subscription for this server/Community Edition - No subscription required/g" "$JS_FILE"
sed -i "s/Enterprise repository needs valid subscription/Enterprise repository configured/g" "$JS_FILE"
sed -i "s/icon: Ext\.Msg\.WARNING/icon: Ext.Msg.INFO/g" "$JS_FILE"
# Additional subscription patterns that may exist in PVE 9
sed -i "s/subscription = !(/subscription = false \&\& (/g" "$JS_FILE"
# Remove compressed/minified files to force regeneration
[[ -f "$GZ_FILE" ]] && rm -f "$GZ_FILE"
[[ -f "$MIN_JS_FILE" ]] && rm -f "$MIN_JS_FILE"
# Clear various caches
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
# Create PVE 9.x specific APT hook
[[ -f "$APT_HOOK" ]] && rm -f "$APT_HOOK"
cat > "$APT_HOOK" << 'EOF'
DPkg::Post-Invoke {
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/res\\.data\\.status\\.toLowerCase() !== '\''active'\''/false/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscriptionActive: '\'\'\''/subscriptionActive: true/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/title: gettext('\''No valid subscription'\'')/title: gettext('\''Community Edition'\'')/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"test -e /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && sed -i 's/subscription = !(/subscription = false \\&\\& (/g' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js || true";
"rm -f /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz || true";
};
EOF
chmod 644 "$APT_HOOK"
# Verify APT hook syntax
if ! apt-config dump >/dev/null 2>&1; then
msg_warn "APT hook has syntax issues, removing..."
rm -f "$APT_HOOK"
else
msg_ok "APT hook created successfully"
fi
msg_ok "Subscription banner removed successfully for Proxmox VE $pve_version"
msg_ok "Banner removal process completed"
register_tool "subscription_banner" true
}
# Execute function if called directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
remove_subscription_banner_pve9
fi

View File

@@ -1,257 +0,0 @@
#!/bin/bash
# ==========================================================
# Remove Subscription Banner - Proxmox VE 9.x (Clean Version)
# ==========================================================
set -euo pipefail
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
register_tool() {
command -v jq >/dev/null 2>&1 || return 0
local tool="$1" state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" \
> "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
MOBILE_TPL="/usr/share/pve-yew-mobile-gui/index.html.tpl"
APT_HOOK="/etc/apt/apt.conf.d/no-nag-script"
PATCH_BIN="/usr/local/bin/pve-remove-nag.sh"
MARK_JS="PROXMENUX_NAG_REMOVED_v2"
MARK_MOBILE="<!-- PROXMENUX: MOBILE NAG PATCH v2 -->"
verify_js_integrity() {
local file="$1"
[ -f "$file" ] || return 1
[ -s "$file" ] || return 1
grep -Eq 'Ext|function|var|const|let' "$file" || return 1
if LC_ALL=C grep -qP '\x00' "$file" 2>/dev/null; then
return 1
fi
return 0
}
create_backup() {
local file="$1"
local backup_dir="$BASE_DIR/backups"
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="$backup_dir/$(basename "$file").backup.$timestamp"
mkdir -p "$backup_dir"
if [ -f "$file" ]; then
cp -a "$file" "$backup_file"
ls -t "$backup_dir"/"$(basename "$file")".backup.* 2>/dev/null | tail -n +6 | xargs -r rm -f 2>/dev/null || true
echo "$backup_file"
fi
}
# ----------------------------------------------------
create_patch_script() {
cat > "$PATCH_BIN" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
MIN_JS_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js"
GZ_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.gz"
MOBILE_TPL="/usr/share/pve-yew-mobile-gui/index.html.tpl"
MARK_JS="PROXMENUX_NAG_REMOVED_v2"
MARK_MOBILE="<!-- PROXMENUX: MOBILE NAG PATCH v2 -->"
BASE_DIR="/usr/local/share/proxmenux"
verify_js_integrity() {
local file="$1"
[ -f "$file" ] && [ -s "$file" ] && grep -Eq 'Ext|function' "$file" && ! LC_ALL=C grep -qP '\x00' "$file" 2>/dev/null
}
patch_web() {
[ -f "$JS_FILE" ] || return 0
grep -q "$MARK_JS" "$JS_FILE" && return 0
local backup_dir="$BASE_DIR/backups"
mkdir -p "$backup_dir"
local backup="$backup_dir/$(basename "$JS_FILE").backup.$(date +%Y%m%d_%H%M%S)"
cp -a "$JS_FILE" "$backup"
trap "cp -a '$backup' '$JS_FILE' 2>/dev/null || true" ERR
sed -i '1s|^|/* '"$MARK_JS"' */\n|' "$JS_FILE"
local patterns_found=0
if grep -q "res\.data\.status\.toLowerCase() !== 'active'" "$JS_FILE"; then
sed -i "s/res\.data\.status\.toLowerCase() !== 'active'/false/g" "$JS_FILE"
patterns_found=$((patterns_found + 1))
fi
if grep -q "subscriptionActive: ''" "$JS_FILE"; then
sed -i "s/subscriptionActive: ''/subscriptionActive: true/g" "$JS_FILE"
patterns_found=$((patterns_found + 1))
fi
if grep -q "title: gettext('No valid subscription')" "$JS_FILE"; then
sed -i "s/title: gettext('No valid subscription')/title: gettext('Community Edition')/g" "$JS_FILE"
patterns_found=$((patterns_found + 1))
fi
if grep -q "icon: Ext\.Msg\.WARNING" "$JS_FILE"; then
sed -i "s/icon: Ext\.Msg\.WARNING/icon: Ext.Msg.INFO/g" "$JS_FILE"
patterns_found=$((patterns_found + 1))
fi
if grep -q "subscription = !(" "$JS_FILE"; then
sed -i "s/subscription = !(/subscription = false \&\& (/g" "$JS_FILE"
patterns_found=$((patterns_found + 1))
fi
# Si nada coincidió (cambio upstream), restaura y sal limpio
if [ "${patterns_found:-0}" -eq 0 ]; then
cp -a "$backup" "$JS_FILE"
return 0
fi
# Verificación final
if ! verify_js_integrity "$JS_FILE"; then
cp -a "$backup" "$JS_FILE"
return 1
fi
# Limpiar artefactos/cachés
rm -f "$MIN_JS_FILE" "$GZ_FILE" 2>/dev/null || true
find /var/cache/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/lib/pve-manager/ -name "*.js*" -delete 2>/dev/null || true
find /var/cache/nginx/ -type f -delete 2>/dev/null || true
trap - ERR
}
patch_mobile() {
[ -f "$MOBILE_TPL" ] || return 0
grep -q "$MARK_MOBILE" "$MOBILE_TPL" && return 0
local backup_dir="$BASE_DIR/backups"
mkdir -p "$backup_dir"
cp -a "$MOBILE_TPL" "$backup_dir/$(basename "$MOBILE_TPL").backup.$(date +%Y%m%d_%H%M%S)"
cat >> "$MOBILE_TPL" <<EOM
$MARK_MOBILE
<script>
(function() {
'use strict';
function removeSubscriptionElements() {
try {
const dialogs = document.querySelectorAll('dialog.pwt-outer-dialog');
dialogs.forEach(d => {
const text = (d.textContent || '').toLowerCase();
if (text.includes('subscription') || text.includes('no valid')) { d.remove(); }
});
const cards = document.querySelectorAll('.pwt-card.pwt-p-2.pwt-d-flex.pwt-interactive.pwt-justify-content-center');
cards.forEach(c => {
const text = (c.textContent || '').toLowerCase();
const hasButton = c.querySelector('button');
if (!hasButton && (text.includes('subscription') || text.includes('no valid'))) { c.remove(); }
});
const alerts = document.querySelectorAll('[class*="alert"], [class*="warning"], [class*="notice"]');
alerts.forEach(a => {
const text = (a.textContent || '').toLowerCase();
if (text.includes('subscription') || text.includes('no valid')) { a.remove(); }
});
} catch (e) { console.warn('Error removing subscription elements:', e); }
}
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', removeSubscriptionElements); }
else { removeSubscriptionElements(); }
const observer = new MutationObserver(removeSubscriptionElements);
if (document.body) {
observer.observe(document.body, { childList: true, subtree: true });
const interval = setInterval(removeSubscriptionElements, 500);
setTimeout(() => { try { observer.disconnect(); clearInterval(interval); } catch(e){} }, 30000);
}
})();
</script>
EOM
}
reload_services() {
systemctl is-active --quiet pveproxy 2>/dev/null && {
systemctl reload pveproxy 2>/dev/null || systemctl restart pveproxy 2>/dev/null || true
}
systemctl is-active --quiet nginx 2>/dev/null && {
systemctl reload nginx 2>/dev/null || true
}
systemctl is-active --quiet pvedaemon 2>/dev/null && {
systemctl reload pvedaemon 2>/dev/null || true
}
find /var/cache/pve-manager/ -type f -delete 2>/dev/null || true
find /var/lib/pve-manager/ -type f -delete 2>/dev/null || true
}
main() {
patch_web || return 1
patch_mobile
reload_services
}
main
EOF
chmod 755 "$PATCH_BIN"
}
# ----------------------------------------------------
create_apt_hook() {
cat > "$APT_HOOK" <<'EOF'
/* ProxMenux: reapply nag patch after upgrades */
DPkg::Post-Invoke { "/usr/local/bin/pve-remove-nag.sh || true"; };
EOF
chmod 644 "$APT_HOOK"
apt-config dump >/dev/null 2>&1 || { msg_warn "APT hook syntax issue"; rm -f "$APT_HOOK"; }
}
remove_subscription_banner_pve9() {
local pve_version
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+' | head -1 || true)
local pve_major="${pve_version%%.*}"
msg_info "$(translate "Detected Proxmox VE ${pve_version:-9.x} removing subscription banner")"
create_patch_script
create_apt_hook
if ! "$PATCH_BIN"; then
msg_error "$(translate "Error applying patches")"
return 1
fi
register_tool "subscription_banner" true
msg_ok "$(translate "Subscription banner removed successfully.")"
msg_ok "$(translate "Refresh your browser to see changes.")"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
remove_subscription_banner_pve9
fi

View File

@@ -1,339 +0,0 @@
#!/bin/bash
# ==========================================================
# Proxmox VE Update Script
# ==========================================================
# Configuration
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
VENV_PATH="/opt/googletrans-env"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
register_tool() {
local tool="$1"
local state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
download_common_functions() {
if ! source "$LOCAL_SCRIPTS/global/common-functions.sh"; then
return 1
fi
}
update_pve9() {
local pve_version=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1)
local start_time=$(date +%s)
local log_file="/var/log/proxmox-update-$(date +%Y%m%d-%H%M%S).log"
local changes_made=false
local OS_CODENAME="$(grep "VERSION_CODENAME=" /etc/os-release | cut -d"=" -f 2 | xargs)"
local TARGET_CODENAME="trixie"
if [ -z "$OS_CODENAME" ]; then
OS_CODENAME=$(lsb_release -cs 2>/dev/null || echo "trixie")
fi
download_common_functions
msg_info2 "$(translate "Detected: Proxmox VE $pve_version (Current: $OS_CODENAME, Target: $TARGET_CODENAME)")"
echo -e
local available_space=$(df /var/cache/apt/archives | awk 'NR==2 {print int($4/1024)}')
if [ "$available_space" -lt 1024 ]; then
msg_error "$(translate "Insufficient disk space. Available: ${available_space}MB")"
echo -e
msg_success "$(translate "Press Enter to return to menu...")"
read -r
return 1
fi
if ! ping -c 1 download.proxmox.com >/dev/null 2>&1; then
msg_error "$(translate "Cannot reach Proxmox repositories")"
echo -e
msg_success "$(translate "Press Enter to return to menu...")"
read -r
return 1
fi
disable_sources_repo() {
local file="$1"
if [[ -f "$file" ]]; then
sed -i ':a;/^\n*$/{$d;N;ba}' "$file"
if grep -q "^Enabled:" "$file"; then
sed -i 's/^Enabled:.*$/Enabled: false/' "$file"
else
echo "Enabled: false" >> "$file"
fi
if ! grep -q "^Types: " "$file"; then
msg_warn "$(translate "Malformed .sources file detected, removing: $(basename "$file")")"
rm -f "$file"
fi
return 0
fi
return 1
}
if disable_sources_repo "/etc/apt/sources.list.d/pve-enterprise.sources"; then
msg_ok "$(translate "Enterprise Proxmox repository disabled")"
changes_made=true
fi
if disable_sources_repo "/etc/apt/sources.list.d/ceph.sources"; then
msg_ok "$(translate "Enterprise Proxmox Ceph repository disabled")"
changes_made=true
fi
for legacy_file in /etc/apt/sources.list.d/pve-public-repo.list \
/etc/apt/sources.list.d/pve-install-repo.list \
/etc/apt/sources.list.d/debian.list; do
if [[ -f "$legacy_file" ]]; then
rm -f "$legacy_file"
msg_ok "$(translate "Removed legacy repository: $(basename "$legacy_file")")"
fi
done
if [[ -f /etc/apt/sources.list.d/debian.sources ]]; then
rm -f /etc/apt/sources.list.d/debian.sources
msg_ok "$(translate "Old debian.sources file removed to prevent duplication")"
fi
msg_info "$(translate "Creating Proxmox VE 9.x no-subscription repository...")"
cat > /etc/apt/sources.list.d/proxmox.sources << EOF
Enabled: true
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: ${TARGET_CODENAME}
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
msg_ok "$(translate "Proxmox VE 9.x no-subscription repository created")"
changes_made=true
msg_info "$(translate "Creating Debian ${TARGET_CODENAME} sources file...")"
cat > /etc/apt/sources.list.d/debian.sources << EOF
Types: deb
URIs: http://deb.debian.org/debian/
Suites: ${TARGET_CODENAME} ${TARGET_CODENAME}-updates
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
URIs: http://security.debian.org/debian-security/
Suites: ${TARGET_CODENAME}-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
msg_ok "$(translate "Debian repositories configured for $TARGET_CODENAME")"
local firmware_conf="/etc/apt/apt.conf.d/no-firmware-warnings.conf"
if [ ! -f "$firmware_conf" ]; then
msg_info "$(translate "Disabling non-free firmware warnings...")"
echo 'APT::Get::Update::SourceListWarnings::NonFreeFirmware "false";' > "$firmware_conf"
msg_ok "$(translate "Non-free firmware warnings disabled")"
fi
update_output=$(apt-get update 2>&1)
update_exit_code=$?
if [ $update_exit_code -eq 0 ]; then
msg_ok "$(translate "Package lists updated successfully")"
else
if echo "$update_output" | grep -q "NO_PUBKEY\|GPG error"; then
msg_info "$(translate "Fixing GPG key issues...")"
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $(echo "$update_output" | grep "NO_PUBKEY" | sed 's/.*NO_PUBKEY //' | head -1) 2>/dev/null
if apt-get update > "$log_file" 2>&1; then
msg_ok "$(translate "Package lists updated after GPG fix")"
else
msg_error "$(translate "Failed to update package lists. Check log: $log_file")"
return 1
fi
elif echo "$update_output" | grep -q "404\|Failed to fetch"; then
msg_warn "$(translate "Some repositories are not available, continuing with available ones...")"
else
msg_error "$(translate "Failed to update package lists. Check log: $log_file")"
echo "Error details: $update_output"
return 1
fi
fi
if apt policy 2>/dev/null | grep -q "${TARGET_CODENAME}.*pve-no-subscription"; then
msg_ok "$(translate "Proxmox VE 9.x repositories verified")"
else
msg_warn "$(translate "Proxmox VE 9.x repositories verification inconclusive, continuing...")"
fi
local current_pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
local available_pve_version=$(apt-cache policy pve-manager 2>/dev/null | grep -oP 'Candidate: \K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
local upgradable=$(apt list --upgradable 2>/dev/null | grep -c "upgradable")
local security_updates=$(apt list --upgradable 2>/dev/null | grep -c "security")
show_update_menu() {
local current_version="$1"
local target_version="$2"
local upgradable_count="$3"
local security_count="$4"
local menu_text="$(translate "System Update Information")\n\n"
menu_text+="$(translate "Current PVE Version"): $current_version\n"
if [ -n "$target_version" ] && [ "$target_version" != "$current_version" ]; then
menu_text+="$(translate "Available PVE Version"): $target_version\n"
fi
menu_text+="\n$(translate "Package Updates Available"): $upgradable_count\n"
menu_text+="$(translate "Security Updates"): $security_count\n\n"
if [ "$upgradable_count" -eq 0 ]; then
menu_text+="$(translate "System is already up to date")"
whiptail --title "$(translate "Update Status")" --msgbox "$menu_text" 15 70
return 2
else
menu_text+="$(translate "Do you want to proceed with the system update?")"
if whiptail --title "$(translate "Proxmox Update")" --yesno "$menu_text" 18 70; then
return 0
else
return 1
fi
fi
}
show_update_menu "$current_pve_version" "$available_pve_version" "$upgradable" "$security_updates"
MENU_RESULT=$?
if [[ $MENU_RESULT -eq 1 ]]; then
msg_info2 "$(translate "Update cancelled by user")"
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
return 0
elif [[ $MENU_RESULT -eq 2 ]]; then
msg_ok "$(translate "System is already up to date. No update needed.")"
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
return 0
fi
msg_info "$(translate "Cleaning up unused time synchronization services...")"
if /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' purge ntp openntpd systemd-timesyncd > /dev/null 2>&1; then
msg_ok "$(translate "Old time services removed successfully")"
else
msg_warn "$(translate "Some old time services could not be removed (not installed)")"
fi
msg_info "$(translate "Updating packages...")"
apt-get install pv -y > /dev/null 2>&1
msg_ok "$(translate "Packages updated successfully")"
tput sc
DEBIAN_FRONTEND=noninteractive apt-get -y \
-o Dpkg::Options::='--force-confdef' \
-o Dpkg::Options::='--force-confold' \
dist-upgrade 2>&1 | while IFS= read -r line; do
echo "$line" >> "$log_file"
if [[ "$line" =~ \[[#=\-]+\]\ *[0-9]{1,3}% ]]; then
continue
fi
if [[ "$line" =~ ^(Setting\ up|Unpacking|Preparing\ to\ unpack|Processing\ triggers\ for) ]]; then
package_name=$(echo "$line" | sed -E 's/.*(Setting up|Unpacking|Preparing to unpack|Processing triggers for) ([^ :]+).*/\2/')
[ -z "$package_name" ] && package_name="$(translate "Unknown")"
row=$(( $(tput lines) - 6 ))
tput cup $row 0; printf "%s\n" "$(translate "Installing packages...")"
tput cup $((row + 1)) 0; printf "%s\n" "──────────────────────────────────────────────"
tput cup $((row + 2)) 0; printf "%s %s\n" "$(translate "Package:")" "$package_name"
tput cup $((row + 3)) 0; printf "%s\n" "Progress: [ ] 0%"
tput cup $((row + 4)) 0; printf "%s\n" "──────────────────────────────────────────────"
for i in $(seq 1 10); do
sleep 0.1
progress=$((i * 10))
tput cup $((row + 3)) 9
printf "[%-50s] %3d%%" "$(printf "#%.0s" $(seq 1 $((progress/2))))" "$progress"
done
fi
done
tput rc
tput ed
upgrade_exit_code=${PIPESTATUS[0]}
if [ $upgrade_exit_code -eq 0 ]; then
msg_ok "$(translate "System upgrade completed successfully")"
else
msg_error "$(translate "System upgrade failed. Check log: $log_file")"
return 1
fi
msg_info "$(translate "Installing essential Proxmox packages...")"
local additional_packages="zfsutils-linux proxmox-backup-restore-image chrony"
if /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install $additional_packages >> "$log_file" 2>&1; then
msg_ok "$(translate "Essential Proxmox packages installed")"
else
msg_warn "$(translate "Some essential Proxmox packages may not have been installed")"
fi
lvm_repair_check
cleanup_duplicate_repos
#msg_info "$(translate "Performing system cleanup...")"
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
msg_ok "$(translate "Cleanup finished")"
local end_time=$(date +%s)
local duration=$((end_time - start_time))
local minutes=$((duration / 60))
local seconds=$((duration % 60))
echo -e "${TAB}${BGN}$(translate "====== PVE UPDATE COMPLETED ======")${CL}"
echo -e "${TAB}${GN}⏱️ $(translate "Duration")${CL}: ${BL}${minutes}m ${seconds}s${CL}"
echo -e "${TAB}${GN}📄 $(translate "Log file")${CL}: ${BL}$log_file${CL}"
echo -e "${TAB}${GN}📦 $(translate "Packages upgraded")${CL}: ${BL}$upgradable${CL}"
echo -e "${TAB}${GN}🖥️ $(translate "Proxmox VE")${CL}: ${BL}$target_version (Debian $OS_CODENAME)${CL}"
msg_ok "$(translate "Proxmox VE 9.x configuration completed.")"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
update_pve9
fi

View File

@@ -1,304 +0,0 @@
#!/bin/bash
# ==========================================================
# Proxmox VE Update Script - Improved Version
# ==========================================================
# Configuration
REPO_URL="https://raw.githubusercontent.com/MacRimi/ProxMenux/main"
BASE_DIR="/usr/local/share/proxmenux"
UTILS_FILE="$BASE_DIR/utils.sh"
VENV_PATH="/opt/googletrans-env"
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
load_language
initialize_cache
ensure_tools_json() {
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
}
register_tool() {
local tool="$1"
local state="$2"
ensure_tools_json
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
}
download_common_functions() {
if ! source <(curl -s "$REPO_URL/scripts/global/common-functions.sh"); then
return 1
fi
}
update_pve9() {
local pve_version=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1)
local start_time=$(date +%s)
local log_file="/var/log/proxmox-update-$(date +%Y%m%d-%H%M%S).log"
local changes_made=false
local OS_CODENAME="$(grep "VERSION_CODENAME=" /etc/os-release | cut -d"=" -f 2 | xargs)"
local TARGET_CODENAME="trixie"
local screen_capture="/tmp/proxmenux_screen_capture_$$.txt"
if [ -z "$OS_CODENAME" ]; then
OS_CODENAME=$(lsb_release -cs 2>/dev/null || echo "trixie")
fi
download_common_functions
{
msg_info2 "$(translate "Detected: Proxmox VE $pve_version (Current: $OS_CODENAME, Target: $TARGET_CODENAME)")"
} | tee -a "$screen_capture"
local available_space=$(df /var/cache/apt/archives | awk 'NR==2 {print int($4/1024)}')
if [ "$available_space" -lt 1024 ]; then
msg_error "$(translate "Insufficient disk space. Available: ${available_space}MB")"
echo -e
msg_success "$(translate "Press Enter to return to menu...")"
read -r
return 1
fi
if ! ping -c 1 download.proxmox.com >/dev/null 2>&1; then
msg_error "$(translate "Cannot reach Proxmox repositories")"
echo -e
msg_success "$(translate "Press Enter to return to menu...")"
read -r
return 1
fi
disable_sources_repo() {
local file="$1"
if [[ -f "$file" ]]; then
sed -i ':a;/^\n*$/{$d;N;ba}' "$file"
if grep -q "^Enabled:" "$file"; then
sed -i 's/^Enabled:.*$/Enabled: false/' "$file"
else
echo "Enabled: false" >> "$file"
fi
if ! grep -q "^Types: " "$file"; then
msg_warn "$(translate "Malformed .sources file detected, removing: $(basename "$file")")"
rm -f "$file"
fi
return 0
fi
return 1
}
if disable_sources_repo "/etc/apt/sources.list.d/pve-enterprise.sources"; then
msg_ok "$(translate "Enterprise Proxmox repository disabled")" | tee -a "$screen_capture"
changes_made=true
fi
if disable_sources_repo "/etc/apt/sources.list.d/ceph.sources"; then
msg_ok "$(translate "Enterprise Proxmox Ceph repository disabled")" | tee -a "$screen_capture"
changes_made=true
fi
for legacy_file in /etc/apt/sources.list.d/pve-public-repo.list \
/etc/apt/sources.list.d/pve-install-repo.list \
/etc/apt/sources.list.d/debian.list; do
if [[ -f "$legacy_file" ]]; then
rm -f "$legacy_file"
msg_ok "$(translate "Removed legacy repository: $(basename "$legacy_file")")" | tee -a "$screen_capture"
fi
done
if [[ -f /etc/apt/sources.list.d/debian.sources ]]; then
rm -f /etc/apt/sources.list.d/debian.sources
msg_ok "$(translate "Old debian.sources file removed to prevent duplication")" | tee -a "$screen_capture"
fi
msg_info "$(translate "Creating Proxmox VE 9.x no-subscription repository...")"
cat > /etc/apt/sources.list.d/proxmox.sources << EOF
Enabled: true
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: ${TARGET_CODENAME}
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
msg_ok "$(translate "Proxmox VE 9.x no-subscription repository created")" | tee -a "$screen_capture"
changes_made=true
msg_info "$(translate "Creating Debian ${TARGET_CODENAME} sources file...")"
cat > /etc/apt/sources.list.d/debian.sources << EOF
Types: deb
URIs: http://deb.debian.org/debian/
Suites: ${TARGET_CODENAME} ${TARGET_CODENAME}-updates
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
URIs: http://security.debian.org/debian-security/
Suites: ${TARGET_CODENAME}-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
msg_ok "$(translate "Debian repositories configured for $TARGET_CODENAME")"
local firmware_conf="/etc/apt/apt.conf.d/no-firmware-warnings.conf"
if [ ! -f "$firmware_conf" ]; then
msg_info "$(translate "Disabling non-free firmware warnings...")"
echo 'APT::Get::Update::SourceListWarnings::NonFreeFirmware "false";' > "$firmware_conf"
msg_ok "$(translate "Non-free firmware warnings disabled")"
fi
#update_output=$(apt-get update 2>&1)
update_output=$(apt-get -o Dpkg::Progress-Fancy=1 update 2>&1)
update_exit_code=$?
if [ $update_exit_code -eq 0 ]; then
msg_ok "$(translate "Package lists updated successfully")" | tee -a "$screen_capture"
else
if echo "$update_output" | grep -q "NO_PUBKEY\|GPG error"; then
msg_info "$(translate "Fixing GPG key issues...")"
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $(echo "$update_output" | grep "NO_PUBKEY" | sed 's/.*NO_PUBKEY //' | head -1) 2>/dev/null
if apt-get update > "$log_file" 2>&1; then
msg_ok "$(translate "Package lists updated after GPG fix")" | tee -a "$screen_capture"
else
msg_error "$(translate "Failed to update package lists. Check log: $log_file")"
return 1
fi
elif echo "$update_output" | grep -q "404\|Failed to fetch"; then
msg_warn "$(translate "Some repositories are not available, continuing with available ones...")"
else
msg_error "$(translate "Failed to update package lists. Check log: $log_file")"
echo "Error details: $update_output"
return 1
fi
fi
if apt policy 2>/dev/null | grep -q "${TARGET_CODENAME}.*pve-no-subscription"; then
msg_ok "$(translate "Proxmox VE 9.x repositories verified")" | tee -a "$screen_capture"
else
msg_warn "$(translate "Proxmox VE 9.x repositories verification inconclusive, continuing...")"
fi
local current_pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
local available_pve_version=$(apt-cache policy pve-manager 2>/dev/null | grep -oP 'Candidate: \K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
local upgradable=$(apt list --upgradable 2>/dev/null | grep -c "upgradable")
local security_updates=$(apt list --upgradable 2>/dev/null | grep -c "security")
show_update_menu() {
local current_version="$1"
local target_version="$2"
local upgradable_count="$3"
local security_count="$4"
local menu_text="$(translate "System Update Information")\n\n"
menu_text+="$(translate "Current PVE Version"): $current_version\n"
if [ -n "$target_version" ] && [ "$target_version" != "$current_version" ]; then
menu_text+="$(translate "Available PVE Version"): $target_version\n"
fi
menu_text+="\n$(translate "Package Updates Available"): $upgradable_count\n"
menu_text+="$(translate "Security Updates"): $security_count\n\n"
if [ "$upgradable_count" -eq 0 ]; then
menu_text+="$(translate "System is already up to date")"
whiptail --title "$(translate "Update Status")" --msgbox "$menu_text" 15 70
return 2
else
menu_text+="$(translate "Do you want to proceed with the system update?")"
if whiptail --title "$(translate "Proxmox Update")" --yesno "$menu_text" 18 70; then
return 0
else
return 1
fi
fi
}
show_update_menu "$current_pve_version" "$available_pve_version" "$upgradable" "$security_updates"
MENU_RESULT=$?
clear
show_proxmenux_logo
msg_title "$(translate "$SCRIPT_TITLE")"
cat "$screen_capture"
if [[ $MENU_RESULT -eq 1 ]]; then
msg_info2 "$(translate "Update cancelled by user")"
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
rm -f "$screen_capture"
return 0
elif [[ $MENU_RESULT -eq 2 ]]; then
msg_ok "$(translate "System is already up to date. No update needed.")"
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
rm -f "$screen_capture"
return 0
fi
msg_info "$(translate "Cleaning up unused time synchronization services...")"
if /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' purge ntp openntpd systemd-timesyncd > /dev/null 2>&1; then
msg_ok "$(translate "Old time services removed successfully")"
else
msg_warn "$(translate "Some old time services could not be removed (not installed)")"
fi
echo -e
DEBIAN_FRONTEND=noninteractive apt-get -y \
-o Dpkg::Options::='--force-confdef' \
-o Dpkg::Options::='--force-confold' \
dist-upgrade 2>&1 | tee -a "$log_file"
upgrade_exit_code=${PIPESTATUS[0]}
echo -e
clear
show_proxmenux_logo
msg_title "$(translate "$SCRIPT_TITLE")"
cat "$screen_capture"
if [ $upgrade_exit_code -ne 0 ]; then
msg_error "$(translate "System upgrade failed. Check log: $log_file")"
rm -f "$screen_capture"
return 1
fi
msg_info "$(translate "Installing essential Proxmox packages...")"
local additional_packages="zfsutils-linux proxmox-backup-restore-image chrony"
if /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install $additional_packages >> "$log_file" 2>&1; then
msg_ok "$(translate "Essential Proxmox packages installed")"
else
msg_warn "$(translate "Some essential Proxmox packages may not have been installed")"
fi
lvm_repair_check
cleanup_duplicate_repos
apt-get -y autoremove > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
msg_ok "$(translate "Cleanup finished")"
local end_time=$(date +%s)
local duration=$((end_time - start_time))
local minutes=$((duration / 60))
local seconds=$((duration % 60))
echo -e "${TAB}${BGN}$(translate "====== PVE UPDATE COMPLETED ======")${CL}"
echo -e "${TAB}${GN}⏱️ $(translate "Duration")${CL}: ${BL}${minutes}m ${seconds}s${CL}"
echo -e "${TAB}${GN}📄 $(translate "Log file")${CL}: ${BL}$log_file${CL}"
echo -e "${TAB}${GN}📦 $(translate "Packages upgraded")${CL}: ${BL}$upgradable${CL}"
echo -e "${TAB}${GN}🖥️ $(translate "Proxmox VE")${CL}: ${BL}$available_pve_version (Debian $OS_CODENAME)${CL}"
msg_ok "$(translate "Proxmox VE 9.x configuration completed.")"
rm -f "$screen_capture"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
update_pve9
fi