2025-01-20 09:03:56 +01:00
#!/usr/bin/env bash
2026-01-06 13:28:12 +01:00
# Copyright (c) 2021-2026 community-scripts ORG
2025-01-20 09:03:56 +01:00
# Author: thost96 (thost96)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
header_info() {
clear
cat <<"EOF"
____ __ _________ ____ __ ____ __ ____
/ __ \/ | / / ____/ / __ \_ ___ _____/ /_ / _/___ _____/ /_____ _/ / /
2025-07-22 20:09:14 +03:00
/ /_/ / /| _/ / / __ / /_/ / __ \/ ___/ __/ / // __ \/ ___/ __/ __ ` / / /
/ ____/ / / / /_/ / / ____/ /_/ ( __ ) /_ _/ // / / ( __ ) /_/ /_/ / / /
/_/ /_/ /_/\_ ___/ /_/ \_ ___/____/\_ _/ /___/_/ /_/____/\_ _/\_ _,_/_/_/
2025-01-20 09:03:56 +01:00
EOF
}
RD = $( echo "\033[01;31m" )
YW = $( echo "\033[33m" )
GN = $( echo "\033[1;92m" )
CL = $( echo "\033[m" )
BFR = "\\r\\033[K"
HOLD = "-"
CM = " ${ GN } ✓ ${ CL } "
CROSS = " ${ RD } ✗ ${ CL } "
set -euo pipefail
shopt -s inherit_errexit nullglob
msg_info() {
local msg = " $1 "
echo -ne " ${ HOLD } ${ YW }${ msg } ..."
}
msg_ok() {
local msg = " $1 "
echo -e " ${ BFR } ${ CM } ${ GN }${ msg }${ CL } "
}
msg_error() {
local msg = " $1 "
echo -e " ${ BFR } ${ CROSS } ${ RD }${ msg }${ CL } "
}
2026-02-17 16:36:20 +01:00
# Telemetry
2026-10-01 08:15:12 +02:00
source <( curl -fsSL " ${ COMMUNITY_SCRIPTS_CORE_URL :- https ://raw.githubusercontent.com/community-scripts/core/main } /api/api.func" ) 2>/dev/null || true
2026-02-18 10:24:06 +01:00
declare -f init_tool_telemetry & >/dev/null && init_tool_telemetry "post-pmg-install" "pve"
2026-02-17 16:36:20 +01:00
2026-04-20 10:18:55 +02:00
if ! dpkg -s proxmox-mailgateway-container >/dev/null 2>& 1 &&
! dpkg -s proxmox-mailgateway >/dev/null 2>& 1; then
2025-08-26 14:05:30 +02:00
msg_error "This script is only intended for Proxmox Mail Gateway"
2026-03-02 10:55:20 +01:00
exit 232
2025-08-26 14:05:30 +02:00
fi
2026-06-23 21:49:52 +10:00
if [ " $( dpkg --print-architecture 2>/dev/null) " = "arm64" ] ; then
msg_error "Proxmox Mail Gateway does not support ARM64."
exit 1
fi
2025-08-26 14:05:30 +02:00
repo_state() {
# $1 = repo name (e.g. pmg-enterprise, pmg-no-subscription, pmgtest)
local repo = " $1 "
local file = ""
local state = "missing"
2026-04-20 10:18:55 +02:00
for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; do
2025-08-26 14:05:30 +02:00
[[ -f " $f " ]] || continue
if grep -q " $repo " " $f " ; then
file = " $f "
2026-04-20 10:18:55 +02:00
if [[ " $f " == *.sources ]] ; then
# deb822 format: check Enabled field
if grep -qiE '^Enabled:\s*no' " $f " ; then
state = "disabled"
else
state = "active"
fi
else
# legacy format
if grep -qE "^[^#].* ${ repo } " " $f " ; then
state = "active"
elif grep -qE "^#.* ${ repo } " " $f " ; then
state = "disabled"
fi
2025-08-26 14:05:30 +02:00
fi
break
fi
done
echo " $state $file "
}
2026-04-20 10:18:55 +02:00
toggle_repo() {
# $1 = file, $2 = action (enable|disable)
local file = " $1 " action = " $2 "
if [[ " $file " == *.sources ]] ; then
if [[ " $action " == "disable" ]] ; then
if grep -qiE '^Enabled:' " $file " ; then
sed -i 's/^Enabled:.*/Enabled: no/' " $file "
else
echo "Enabled: no" >>" $file "
fi
else
sed -i 's/^Enabled:.*/Enabled: yes/' " $file "
fi
else
if [[ " $action " == "disable" ]] ; then
sed -i '/^[^#]/s/^/# /' " $file "
else
sed -i 's/^# *//' " $file "
fi
fi
}
2025-01-20 09:03:56 +01:00
start_routines() {
header_info
VERSION = " $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release) "
2025-08-26 14:05:30 +02:00
# ---- SOURCES ----
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG SOURCES" --menu \
"This will set the correct Debian sources for Proxmox Mail Gateway.\n\nCorrect sources?" 14 58 2 \
2025-01-20 09:03:56 +01:00
"yes" " " \
"no" " " 3>& 2 2>& 1 1>& 3)
case $CHOICE in
yes)
2025-08-26 14:05:30 +02:00
msg_info "Correcting Debian Sources"
2026-04-20 10:18:55 +02:00
cat <<EOF >/etc/apt/sources.list.d/debian.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: ${VERSION} ${VERSION}-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: ${VERSION}-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-01-20 09:03:56 +01:00
EOF
2026-04-20 10:18:55 +02:00
rm -f /etc/apt/sources.list
2025-08-26 14:05:30 +02:00
msg_ok "Corrected Debian Sources"
2025-01-20 09:03:56 +01:00
;;
2025-08-26 14:05:30 +02:00
no) msg_error "Selected no to Correcting Debian Sources" ;;
2025-01-20 09:03:56 +01:00
esac
2025-08-26 14:05:30 +02:00
# ---- PMG-ENTERPRISE ----
read -r state file <<< " $( repo_state pmg-enterprise) "
case $state in
active)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-ENTERPRISE" \
--menu "'pmg-enterprise' repository is currently ENABLED.\n\nWhat do you want to do?" 14 58 3 \
"keep" "Keep as is" \
"disable" "Comment out (disable)" \
"delete" "Delete repo file" \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
keep) msg_ok "Kept 'pmg-enterprise' repository" ;;
disable)
msg_info "Disabling 'pmg-enterprise' repository"
2026-04-20 10:18:55 +02:00
toggle_repo " $file " disable
2025-08-26 14:05:30 +02:00
msg_ok "Disabled 'pmg-enterprise' repository"
;;
delete)
msg_info "Deleting 'pmg-enterprise' repository file"
rm -f " $file "
msg_ok "Deleted 'pmg-enterprise' repository file"
;;
esac
2025-01-20 09:03:56 +01:00
;;
2025-08-26 14:05:30 +02:00
disabled)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-ENTERPRISE" \
--menu "'pmg-enterprise' repository is currently DISABLED.\n\nWhat do you want to do?" 14 58 3 \
"enable" "Uncomment (enable)" \
"keep" "Keep disabled" \
"delete" "Delete repo file" \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
enable )
msg_info "Enabling 'pmg-enterprise' repository"
2026-04-20 10:18:55 +02:00
toggle_repo " $file " enable
2025-08-26 14:05:30 +02:00
msg_ok "Enabled 'pmg-enterprise' repository"
;;
keep) msg_ok "Kept 'pmg-enterprise' repository disabled" ;;
delete)
msg_info "Deleting 'pmg-enterprise' repository file"
rm -f " $file "
msg_ok "Deleted 'pmg-enterprise' repository file"
;;
esac
;;
missing)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-ENTERPRISE" \
--menu "Add 'pmg-enterprise' repository?\n\nOnly for subscription customers." 14 58 2 \
"no" " " \
"yes" " " \
--default-item "no" \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
yes)
msg_info "Adding 'pmg-enterprise' repository"
2026-04-20 10:18:55 +02:00
cat >/etc/apt/sources.list.d/pmg-enterprise.sources <<EOF
Types: deb
URIs: https://enterprise.proxmox.com/debian/pmg
Suites: ${VERSION}
Components: pmg-enterprise
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
2025-08-26 14:05:30 +02:00
EOF
msg_ok "Added 'pmg-enterprise' repository"
;;
no) msg_error "Selected no to Adding 'pmg-enterprise' repository" ;;
esac
2025-01-20 09:03:56 +01:00
;;
esac
2025-08-26 14:05:30 +02:00
# ---- PMG-NO-SUBSCRIPTION ----
read -r state file <<< " $( repo_state pmg-no-subscription) "
case $state in
active)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-NO-SUBSCRIPTION" \
--menu "'pmg-no-subscription' repository is currently ENABLED.\n\nWhat do you want to do?" 14 58 3 \
"keep" "Keep as is" \
"disable" "Comment out (disable)" \
"delete" "Delete repo file" \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
keep) msg_ok "Kept 'pmg-no-subscription' repository" ;;
disable)
msg_info "Disabling 'pmg-no-subscription' repository"
2026-04-20 10:18:55 +02:00
toggle_repo " $file " disable
2025-08-26 14:05:30 +02:00
msg_ok "Disabled 'pmg-no-subscription' repository"
;;
delete)
msg_info "Deleting 'pmg-no-subscription' repository file"
rm -f " $file "
msg_ok "Deleted 'pmg-no-subscription' repository file"
;;
esac
;;
disabled)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-NO-SUBSCRIPTION" \
--menu "'pmg-no-subscription' repository is currently DISABLED.\n\nWhat do you want to do?" 14 58 3 \
"enable" "Uncomment (enable)" \
"keep" "Keep disabled" \
"delete" "Delete repo file" \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
enable )
msg_info "Enabling 'pmg-no-subscription' repository"
2026-04-20 10:18:55 +02:00
toggle_repo " $file " enable
2025-08-26 14:05:30 +02:00
msg_ok "Enabled 'pmg-no-subscription' repository"
;;
keep) msg_ok "Kept 'pmg-no-subscription' repository disabled" ;;
delete)
msg_info "Deleting 'pmg-no-subscription' repository file"
rm -f " $file "
msg_ok "Deleted 'pmg-no-subscription' repository file"
;;
esac
;;
missing)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG-NO-SUBSCRIPTION" \
--menu "Add 'pmg-no-subscription' repository?" 14 58 2 \
"yes" " " \
"no" " " \
3>& 2 2>& 1 1>& 3)
case $CHOICE in
yes)
msg_info "Adding 'pmg-no-subscription' repository"
2026-04-20 10:18:55 +02:00
cat >/etc/apt/sources.list.d/pmg-no-subscription.sources <<EOF
Types: deb
URIs: http://download.proxmox.com/debian/pmg
Suites: ${VERSION}
Components: pmg-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
2025-01-20 09:03:56 +01:00
EOF
2025-08-26 14:05:30 +02:00
msg_ok "Added 'pmg-no-subscription' repository"
;;
no) msg_error "Selected no to Adding 'pmg-no-subscription' repository" ;;
esac
2025-01-20 09:03:56 +01:00
;;
esac
2025-08-26 14:05:30 +02:00
# ---- PMG-TEST ----
read -r state file <<< " $( repo_state pmgtest) "
case $state in
active) msg_ok "'pmgtest' repository already active (skipped)" ;;
disabled) msg_ok "'pmgtest' repository already disabled (skipped)" ;;
missing)
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "PMG TEST" \
--menu "The 'pmgtest' repository can give advanced users access to new features early.\n\nAdd (disabled) 'pmgtest' repository?" 14 58 2 \
"yes" " " \
"no" " " 3>& 2 2>& 1 1>& 3)
case $CHOICE in
yes)
msg_info "Adding 'pmgtest' repository (disabled)"
2026-04-20 10:18:55 +02:00
cat >/etc/apt/sources.list.d/pmgtest.sources <<EOF
Types: deb
URIs: http://download.proxmox.com/debian/pmg
Suites: ${VERSION}
Components: pmgtest
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
Enabled: no
2025-01-20 09:03:56 +01:00
EOF
2025-08-26 14:05:30 +02:00
msg_ok "Added 'pmgtest' repository"
;;
no) msg_error "Selected no to Adding 'pmgtest' repository" ;;
esac
2025-01-20 09:03:56 +01:00
;;
esac
2025-08-26 14:05:30 +02:00
# ---- SUBSCRIPTION NAG ----
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUBSCRIPTION NAG" --menu \
"Disable subscription nag in PMG UI?" 14 58 2 "yes" " " "no" " " 3>& 2 2>& 1 1>& 3)
2025-07-22 20:09:14 +03:00
case $CHOICE in
yes)
2025-08-26 14:05:30 +02:00
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" \
"Supporting the software's development team is essential.\nPlease consider buying a subscription." 10 58
2025-07-22 20:09:14 +03:00
msg_info "Disabling subscription nag"
2025-09-10 13:00:19 +02:00
cat >/etc/apt/apt.conf.d/no-nag-script <<'EOF'
DPkg::Post-Invoke { "if [ -s /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js ] && ! grep -q -F 'NoMoreNagging' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; then sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; fi"; };
EOF
cat >/etc/apt/apt.conf.d/no-nag-script-pmgmanagerlib-mobile <<'EOF'
DPkg::Post-Invoke { "if [ -s /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js ] && ! grep -q -F 'NoMoreNagging' /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js; then sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js; fi"; };
2025-08-26 14:05:30 +02:00
EOF
msg_ok "Disabled subscription nag (clear browser cache!)"
2025-07-22 20:09:14 +03:00
;;
no)
2025-08-26 14:05:30 +02:00
msg_error "Selected no to Disabling subscription nag"
rm -f /etc/apt/apt.conf.d/no-nag-script 2>/dev/null
2025-07-22 20:09:14 +03:00
;;
esac
2025-08-26 14:05:30 +02:00
apt --reinstall install proxmox-widget-toolkit pmg-gui & >/dev/null || msg_error "Widget toolkit reinstall failed"
2025-01-20 09:03:56 +01:00
2025-08-26 14:05:30 +02:00
# ---- UPDATE ----
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu \
"Update Proxmox Mail Gateway now?" 11 58 2 "yes" " " "no" " " 3>& 2 2>& 1 1>& 3)
2025-01-20 09:03:56 +01:00
case $CHOICE in
yes)
msg_info "Updating Proxmox Mail Gateway (Patience)"
2025-08-26 14:05:30 +02:00
apt update & >/dev/null || msg_error "apt update failed"
apt -y dist-upgrade & >/dev/null || msg_error "apt dist-upgrade failed"
2025-01-20 09:03:56 +01:00
msg_ok "Updated Proxmox Mail Gateway"
;;
2025-08-26 14:05:30 +02:00
no) msg_error "Selected no to updating Proxmox Mail Gateway" ;;
2025-01-20 09:03:56 +01:00
esac
2025-08-26 14:05:30 +02:00
# ---- REMINDER ----
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Post-Install Reminder" --msgbox \
"IMPORTANT:
Please run this script on every PMG node individually if you have multiple nodes.
After completing these steps, it is strongly recommended to REBOOT your node.
After the upgrade or post-install routines, always clear your browser cache or perform a hard reload (Ctrl+Shift+R) before using the PMG Web UI to avoid UI display issues." 20 80
# ---- REBOOT ----
CHOICE = $( whiptail --backtitle "Proxmox VE Helper Scripts" --title "REBOOT" --menu \
"Reboot Proxmox Mail Gateway now? (recommended)" 11 58 2 "yes" " " "no" " " 3>& 2 2>& 1 1>& 3)
2025-01-20 09:03:56 +01:00
case $CHOICE in
yes)
msg_info "Rebooting Proxmox Mail Gateway"
sleep 2
msg_ok "Completed Post Install Routines"
reboot
;;
no)
2025-08-26 14:05:30 +02:00
msg_error "Selected no to reboot (Reboot recommended)"
2025-01-20 09:03:56 +01:00
msg_ok "Completed Post Install Routines"
;;
esac
}
header_info
echo -e "\nThis script will Perform Post Install Routines.\n"
while true; do
2025-08-26 14:05:30 +02:00
read -rp "Start the Proxmox Mail Gateway Post Install Script (y/n)? " yn
2025-01-20 09:03:56 +01:00
case $yn in
[ Yy] *) break ;;
2025-04-01 10:25:46 +02:00
[ Nn] *)
clear
exit
;;
2025-01-20 09:03:56 +01:00
*) echo "Please answer yes or no." ;;
esac
done
start_routines