PVE 9 去除”无有效订阅”弹窗教程

 

Proxmox VE 9 正式发布后,不少小伙伴在升级或全新安装后发现,每次登录 Web 管理界面都会弹出”No valid subscription”的提示框。虽然不影响功能使用,但频繁点击确认确实很烦人。今天这篇教程就手把手教你如何彻底去除这个弹窗,并提供一个一键脚本方便日后维护。

 

一、原理说明

PVE 的订阅弹窗是通过前端 JavaScript 控制的,核心逻辑位于以下文件:

/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js

文件中有一个

checked_command

函数,负责在每次执行需要订阅验证的操作前检查订阅状态。如果检测到未激活订阅,就会调用

Ext.Msg.show()

弹出警告框。我们的目标就是让这个函数”短路”,直接执行原始命令而跳过订阅检查。

 

二、方法一:一键命令(快速搞定)

如果你只想快速解决问题,在 PVE 节点的 Shell 中执行以下命令即可:

cp /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.bak && sed -i "s/res.data.status.toLowerCase() !== 'active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service

执行完毕后,按

Ctrl + F5

强制刷新浏览器页面,弹窗即消失。

 

三、方法二:手动修改(推荐了解原理)

如果你想了解具体改了什么,可以按以下步骤手动操作。

1. 备份原文件

cp /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js.bak

2. 编辑文件

nano /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js

在 nano 中按

Ctrl + W

搜索

checked_command

找到函数定义。原函数大约长这样:

checked_command: function (orig_cmd) {
    Proxmox.Utils.API2Request({
        url: '/nodes/localhost/subscription',
        method: 'GET',
        success: function (response, opts) {
            let res = response.result;
            if (res === null || res === undefined || !res || res.data.status.toLowerCase() !== 'active') {
                Ext.Msg.show({
                    title: gettext('No valid subscription'),
                    // ... 弹窗配置
                });
            } else {
                orig_cmd();
            }
        },
    });
}

3. 替换为简化版

将整个函数体替换为以下内容:

checked_command: function (orig_cmd) {
    orig_cmd();
}

4. 重启服务

systemctl restart pveproxy.service

然后按

Ctrl + F5

刷新浏览器即可。

 

四、方法三:一键脚本(更新后自动复用)

考虑到每次

apt upgrade

更新

proxmox-widget-toolkit

包后,修改都会被覆盖,我整理了一个 Shell 脚本,方便每次更新后一键重新应用。

 

脚本功能

– 自动备份原文件到

/root/.pve-nag-backups/

– 智能检测是否已修改过,避免重复操作
– 双重策略:先尝试完整替换函数,失败则回退到条件替换
– 支持一键恢复原始文件

 

使用方法

将以下脚本保存为

remove-pve-nag.sh

Bash 脚本:

#!/bin/bash
set -euo pipefail

WTK_FILE="/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js"
BACKUP_DIR="/root/.pve-nag-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo -e "${RED}错误: 请使用 root 权限运行${NC}"
        exit 1
    fi
}

backup_original() {
    mkdir -p "$BACKUP_DIR"
    cp "$WTK_FILE" "$BACKUP_DIR/proxmoxlib.js.bak.$TIMESTAMP"
    echo -e "${GREEN}✓ 已备份原文件${NC}"
}

apply_patch() {
    python3 - "$WTK_FILE" << 'PYEOF'
import sys
file_path = sys.argv[1]
with open(file_path, 'r') as f:
    content = f.read()

old_func = """checked_command: function (orig_cmd) {
            Proxmox.Utils.API2Request({
                url: '/nodes/localhost/subscription',
                method: 'GET',
                failure: function (response, opts) {
                    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
                },
                success: function (response, opts) {
                    let res = response.result;
                    if (
                        res === null ||
                        res === undefined ||
                        !res ||
                        res.data.status.toLowerCase() !== 'active'
                    ) {
                        Ext.Msg.show({
                            title: gettext('No valid subscription'),
                            icon: Ext.Msg.WARNING,
                            message: Proxmox.Utils.getNoSubKeyHtml(res.data.url),
                            buttons: Ext.Msg.OK,
                            callback: function (btn) {
                                if (btn !== 'ok') {
                                    return;
                                }
                                orig_cmd();
                            },
                        });
                    } else {
                        orig_cmd();
                    }
                },
            });
        }"""

new_func = """checked_command: function (orig_cmd) {
            orig_cmd();
        }"""

if old_func in content:
    content = content.replace(old_func, new_func)
    with open(file_path, 'w') as f:
        f.write(content)
    print("PATCH_OK")
else:
    print("PATCH_FAIL")
PYEOF
}

apply_fallback() {
    sed -i "s/res.data.status.toLowerCase() !== 'active'/false/g" "$WTK_FILE"
    echo "PATCH_OK"
}

main() {
    echo "========================================"
    echo "PVE 9 去除订阅弹窗脚本"
    echo "========================================"
    check_root
    backup_original
    result=$(apply_patch)
    if [[ "$result" != "PATCH_OK" ]]; then
        echo -e "${YELLOW}尝试备用方案...${NC}"
        apply_fallback
    fi
    systemctl restart pveproxy.service
    echo -e "${GREEN}✓ 完成!请按 Ctrl+F5 刷新浏览器${NC}"
}

main

赋予执行权限并运行:

chmod +x remove-pve-nag.sh
sudo bash remove-pve-nag.sh

每次系统更新后如果弹窗又回来了,直接再执行一次即可:

sudo bash remove-pve-nag.sh

 

五、如何恢复原始文件

如果你需要恢复,脚本每次运行都会自动备份。找到对应的备份文件后执行:

cp /root/.pve-nag-backups/proxmoxlib.js.bak.20260717_152500 /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
systemctl restart pveproxy.service

 

六、注意事项

1. 权限要求:所有操作都需要 root 权限,建议在 PVE 节点的 Shell 中直接执行。

2. 更新覆盖

proxmox-widget-toolkit

包更新后修改会被还原,建议保留脚本文件,更新后重新运行。

3. 浏览器缓存:修改完成后务必按

Ctrl + F5

强制刷新,否则可能仍看到缓存的旧页面。

 

七、总结

PVE 9 去除订阅弹窗的核心就是修改

proxmoxlib.js

中的

checked_command

函数。无论是直接执行 sed 命令、手动编辑,还是使用我提供的脚本,效果都是一样的。推荐把脚本放在服务器上,每次

apt upgrade

后顺手执行一下,一劳永逸。

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

− 6 = 1