← 返回 Skills 市场
1447443432

HAP升级指南

作者 1447443432 · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ⚠ suspicious
49
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install hap-upgrade-guide
功能描述
明道云 HAP 私有部署版本升级专属 skill。只要用户提到 HAP 私有部署升级、跨版本升级、升级注意事项、升级前后附加操作、单机或集群升级步骤、升级文档生成、版本兼容性或架构镜像支持,就必须触发本 skill。即使用户没有明确说"用 hap-upgrade",只要任务与 HAP 私有部署升级决策或升级执行有...
使用说明 (SKILL.md)

HAP 私有部署升级帮助

用于两类任务:

  • 回答 HAP 私有部署升级相关咨询
  • 生成可执行的升级指南 Markdown 文档,并自动转换为 HTML 文档

核心原则:

  • 只依据官方文档和实时页面内容回答,不能凭记忆补全版本细节
  • 允许跨版本直接升级,但必须合并跨越路径中的附加操作
  • 架构兼容性以 https://docs-pd.mingdao.com/version 总表实时标记为唯一准则
  • 所有命令必须保持官方原意,不擅自改写命令逻辑

何时使用

出现以下任一情形时,必须使用本 skill:

  • 用户询问某个 HAP 私有部署版本是否能升级到另一个版本
  • 用户询问升级前要做什么、会跨过哪些附加操作、是否支持跨版本升级
  • 用户要求输出升级步骤、升级 SOP、升级文档、升级手册
  • 用户给出当前版本、目标版本、部署模式、架构、联网情况,请求生成文档
  • 用户询问某一目标版本是否支持 AMD64ARM64

如果任务不是 HAP 私有部署升级,而是一般部署、故障排查、功能使用说明,不使用本 skill。

输出类型

根据用户意图,在以下两种输出之间选择:

  • 咨询答复:给出结论、依据、风险点、缺失信息
  • 升级指南:输出完整 Markdown 文档,然后调用 scripts/md_to_html.py 自动生成 HTML 文档(带侧边目录、代码复制按钮),包含可执行步骤和末尾声明

如果用户明确要求"生成文档""给我一份操作手册""整理成升级指南",按升级指南处理。否则默认先给咨询答复;当信息齐全时,也可以直接生成文档。

执行顺序

严格按以下顺序执行,不要跳步。

Step 1. 先收集 5 项关键信息

重要:在未收集完以下 5 项关键信息之前,不得开始获取网页或生成文档。

如果用户未提供完整信息,先补齐,再继续:

  1. 当前版本,例如 v7.0.4
  2. 目标版本,例如 v7.2.0
  3. 部署模式:单机模式集群模式
  4. 架构:AMD64ARM64
  5. 服务器是否可访问互联网

信息补齐方式

  • 当 1~2 项缺失时:直接询问用户提供具体版本号
  • 当 3~5 项缺失时:必须使用 ask_followup_question 工具提供选项供用户选择
    • 单独缺失部署模式:提供"单机模式"和"集群模式"两个选项(单选)
    • 单独缺失架构:提供"AMD64"和"ARM64"两个选项(单选)
    • 单独缺失网络:提供"可访问互联网"和"离线环境"两个选项(单选)
    • 同时缺失多项:在同一个 ask_followup_question 中提供多个问题,分别列出对应选项

这 5 项不完整时,不得生成最终升级文档,也不得开始获取网页。

Step 2. 规范化版本号

在后续所有步骤中,同时维护两种版本号形态:

  • 应用版本:不带 v,用于命令、镜像标签、脚本参数、配置文件
  • 显示版本:带 v,用于标题、正文说明

规范化规则:

  • 用户输入 v7.1 时,规范化为应用版本 7.1.0,显示版本 v7.1.0
  • 用户输入 7.2.0 时,应用版本保持 7.2.0,显示版本补成 v7.2.0
  • 任何命令、URL、镜像 tag 中都不要带 v

Step 3. 先读取本地参考文件

开始抓取官网前,按需读取这些资源:

  • references/site-structure.md
    • 只用于了解 URL 规律、页面入口和部署文档位置
    • 不能使用其中的兼容性快照替代实时校验
  • references/merge-rules.md
    • 用于合并跨版本附加操作
  • references/command-library.md
    • 用于生成联网 / 离线、单机 / 集群、AMD64 / ARM64 的示例命令
  • assets/upgrade-guide-template-standalone.mdassets/upgrade-guide-template-cluster.md
    • 仅在需要生成升级指南时读取
    • 必须先读取模板,再填充文档
    • HTML 由脚本从 Markdown 自动生成,无需读取 HTML 模板

Step 4. 抓取官方实时页面

必须抓取:

  • 版本总表:https://docs-pd.mingdao.com/version

从总表中识别:

  • 当前版本到目标版本之间所有被跨过的版本
    • 不含当前版本
    • 包含目标版本
    • 按从旧到新排序
  • 每个版本是否"含附加操作"
  • 目标版本在所选架构列中的实时标记

仅对"含附加操作"的版本,再抓取其详情页:

  • URL 规律:https://docs-pd.mingdao.com/upgrade/{应用版本}/

如果升级详情页中的附加操作只是一个超链接、跳转入口或"详见某文档"的简写,不能停在该页面文本。必须继续打开对应链接,提取实际执行步骤、命令、依赖资源和注意事项,再整理进最终文档。

Step 5. 做架构校验,必要时立即中止

架构校验是最高优先级。只以总表中的实时标记为准:

  • 才表示支持
  • 空白、、缺失、无法确认,都视为不支持
  • 不能因为详情页出现通用命令、arm64 标签页或相似内容,就推断该版本支持该架构

如果目标版本不支持用户指定架构,立即停止生成文档,并直接回复:

抱歉,目标版本 {显示版本} 官方尚未发布 {架构} 镜像(以发布历史总表为准),升级文档生成任务已中止。

Step 6. 提取附加操作并分类

仅从"含附加操作"的版本详情页提取实际需要的操作,分成两类:

  • HAP 微服务升级前操作
  • HAP 微服务升级后操作

可能遇到的升级前操作示例:

  • 镜像命名变更
  • 创建 MongoDB 数据库
  • 存储组件升级(仅单机)
  • 文档预览服务升级
  • 重新初始化预置文件
  • MongoDB 预置数据更新
  • 集群 service.yaml 新增服务配置

可能遇到的升级后操作示例:

  • 单机进入容器执行 MySQL DDL
  • 集群进入 config Pod 执行 MySQL DDL
  • 集群进入 config Pod 执行 MongoDB DDL
  • 集群进入 config Pod 执行文件初始化命令

这些只是示例,不是完整列表。不要根据"示例类型"虚构步骤,也不要把未列出的线上实际操作忽略掉。详情页没有的,不生成;详情页实际出现但此处未列出的,也必须纳入处理。

Step 7. 合并跨版本附加操作

如果跨越多个含附加操作的版本,必须读取并遵循 references/merge-rules.md。要把它理解为"合并原则文档",不是"允许操作类型清单"。

特别注意:

  • 同类 MongoDB 建库应合并成一次登录和一次整理后的建库列表
  • 存储组件只升级到跨越路径要求的最高版本
  • MongoDB 预置数据只执行涉及该操作的最新版本命令
  • 升级后脚本按版本从低到高顺序排列
  • 集群新增服务配置需要把多版本新增项合并到同一节里

MongoDB 预置数据更新的文档结构要求

此操作必须独立成步骤,且在"第一阶段:HAP 微服务升级前操作"中单独列出:

  1. "提前准备"阶段

    • 仅说明:MongoDB 预置数据更新脚本将在升级前操作阶段通过联网方式直接拉取执行,无需提前下载
    • 禁止在此阶段执行预置数据更新命令
  2. "第一阶段:HAP 微服务升级前操作"阶段

    • 必须单独列为一个编号步骤,标题为"MongoDB 预置数据更新"
    • 必须包含以下说明:
      • 此操作在原版本服务运行状态下执行,无需停机
      • 本次升级路径跨越的含此操作版本列表(如:v6.5.0、v7.0.0、v7.2.0)
      • 按合并规则仅执行最新版本(如:7.2.0)的命令
    • 执行命令示例:
      bash -c "$(curl -fsSL https://pdpublic.mingdao.com/private-deployment/data/preset_mongodb_docker.sh)" -s 7.2.0
      
  3. 禁止事项

    • 禁止将预置数据更新与其他升级前操作合并为一个步骤
    • 禁止在"提前准备"阶段直接执行预置数据更新命令
    • 禁止遗漏"在原版本服务运行状态下执行,无需停机"的说明

特殊操作识别规则

在提取和合并附加操作时,必须识别以下特殊操作,并按对应章节规范编写:

  1. v5.1.0 镜像拆分操作:识别到后,按照"特殊升级操作的文档结构要求"章节中"v5.1.0 镜像拆分操作(关键结构变更)"的规范编写
  2. v5.5.0 MongoDB 升级操作:识别到后,按照"特殊升级操作的文档结构要求"章节中"v5.5.0 MongoDB 升级操作(重大升级)"的规范编写
  3. MongoDB 预置数据更新:识别到后,按照本章节"MongoDB 预置数据更新的文档结构要求"的规范编写

特殊升级操作的文档结构要求(v5.1.0 镜像拆分和 v5.5.0 MongoDB 升级)

以下两个特殊升级操作必须按照官网文档详细编写,禁止简化或概括:

  1. v5.1.0 镜像拆分操作(关键结构变更)

    • 触发条件:当升级路径跨越 v5.1.0 版本时,必须在"第一阶段:HAP 微服务升级前操作"中单独列为一个编号步骤
    • 标题:必须为"v5.1.0 镜像拆分操作(关键结构变更 ⚠️)"
    • 必须包含的详细内容: a. 重要警告:明确说明这是"重大的结构性变更",必须严格按照官网文档步骤调整 docker-compose.yaml 配置 b. 镜像拆分说明
      • 原来的 mingdaoyun-community 镜像被拆分为两个独立镜像
      • mingdaoyun-sc:1.0.0:负责存储组件相关服务
      • mingdaoyun-command:node1018-python36:负责扩展代码块执行环境
      • 需要在 docker-compose.yaml 中新增 sccommand 两个服务配置
      • Python 版本升级至 3.6,可能导致旧代码块依赖不兼容 c. 单机模式调整步骤(严格按官网文档执行):
      • 步骤 1:备份当前配置文件(提供完整命令)
      • 步骤 2:修改 /data/mingdao/script/docker-compose.yaml
        • 2.1 在 app 服务中追加环境变量引用(提供完整的 YAML 配置示例)
        • 2.2 新增 sccommand 服务(提供完整的 YAML 配置示例)
      • 步骤 3:调整存储组件配置(根据实际情况选择):
        • 3.1 若自定义存储组件连接地址为 127.0.0.1,将其改为 sc(提供修改前后对比)
        • 3.2 若启用自定义文件对象存储,将文件存储挂载从 app 移动到 sc(提供完整 YAML 示例)
        • 3.3 若 app 服务中映射了存储组件端口,将端口映射从 app 移动到 sc(提供完整 YAML 示例)
        • 3.4 若原有代码块依赖库持久化挂载,将挂载从 app 移动到 command(提供完整 YAML 示例)
      • 步骤 4:完整修改示例(提供完整的 docker-compose.yaml 修改后的关键部分)
      • 步骤 5:验证配置文件格式(提供验证命令)
      • 步骤 6:重启服务并验证(提供完整的重启命令和验证命令)
      • 步骤 7:验证功能(列出需要验证的功能点) d. 重要注意事项(必须列出所有关键点):
      • 镜像拆分:原 mingdaoyun-community 镜像拆分为 sc(存储计算)和 command(代码执行)两个独立服务
      • Python 版本升级:Python 升级至 3.6,可能导致旧代码块依赖不兼容,需重新安装依赖
      • 存储组件连接:若原配置使用 127.0.0.1,必须改为 sc
      • 文件挂载调整:所有存储相关挂载需移至 sc 服务,代码依赖挂载需移至 command 服务
      • 端口映射:存储组件端口映射需从 app 移至 sc
      • Flink 升级(如已启用):需升级到版本 1.17.1.510,参考官网 Flink 升级指南
    • 要求
      • 所有 YAML 配置示例必须完整、可直接复制
      • 所有命令必须提供完整代码块
      • 不能只说"参考官网文档",必须将官网文档的关键步骤和命令完整展开
  2. v5.5.0 MongoDB 升级操作(重大升级)

    • 触发条件:当升级路径跨越 v5.5.0 版本时,必须在"第一阶段:HAP 微服务升级前操作"中单独列为一个编号步骤
    • 标题:必须为"v5.5.0 MongoDB 升级操作(重大升级 ⚠️)"
    • 必须包含的详细内容: a. 重要警告:明确说明这是"重大版本升级",涉及数据格式变更,必须严格按照以下步骤操作 b. MongoDB 升级说明
      • 升级范围:从 v3.4 升级到 v4.4
      • 升级方式:参考官方文档 MongoDB 3.4 升级到 4.4
      • 升级完成后必须重建 mdwsrows 库下所有自建索引 c. 升级前重要提示(必须在升级步骤前单独列出):
      • 升级时长:与MongoDB集合数量直接相关
        • 查看集合数量命令:find /data/mingdao/script/volume/data/mongodb/ -name '*collection*' | wc -l
        • 参考时长:1万集合约1分钟,10万集合约10分钟,30万集合约30分钟
      • 版本路径:必须逐版本升级:3.4 → 3.6 → 4.0 → 4.2 → 4.4(共4次升级)
      • 数据路径:默认路径为 /data/mingdao/script/volume/data/mongodb,如自定义请相应调整 d. 升级步骤(严格按照官网文档执行):
      • 步骤 1:停止所有服务(提供完整命令)
        # 在管理器根目录执行(通常在 /usr/local/MDPrivateDeployment/)
        bash ./service.sh stopall
        
      • 步骤 2:备份数据(提供检查数据大小和创建备份的完整命令)
        # 检查磁盘空间
        du -sh /data/mingdao/script/volume/data/mongodb
        
        # 创建备份(备份目录可自定义)
        mkdir -p /backup && tar -zcvf /backup/mongodb3.4_$(date +%Y%m%d%H%M%S).tar.gz /data/mingdao/script/volume/data/mongodb
        
      • 步骤 3:拉取升级辅助镜像(提供完整命令)
        docker pull registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-sc-upgrade:1.0.0
        
      • 步骤 4:逐版本升级执行(提供完整的 4 个升级命令,每个命令都必须包含完整的参数)
        # 3.4 到 3.6
        docker run -i --rm -v /data/mingdao/script/volume/data/mongodb:/data/mongodb registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-sc-upgrade:1.0.0 \x3C\x3C\x3C 'upgradeMongodb.sh 3.4 3.6'
        
        # 3.6 到 4.0
        docker run -i --rm -v /data/mingdao/script/volume/data/mongodb:/data/mongodb registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-sc-upgrade:1.0.0 \x3C\x3C\x3C 'upgradeMongodb.sh 3.6 4.0'
        
        # 4.0 到 4.2
        docker run -i --rm -v /data/mingdao/script/volume/data/mongodb:/data/mongodb registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-sc-upgrade:1.0.0 \x3C\x3C\x3C 'upgradeMongodb.sh 4.0 4.2'
        
        # 4.2 到 4.4
        docker run -i --rm -v /data/mingdao/script/volume/data/mongodb:/data/mongodb registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-sc-upgrade:1.0.0 \x3C\x3C\x3C 'upgradeMongodb.sh 4.2 4.4'
        
      • 步骤 5:升级成功标志(说明如何判断升级完成)
        • 当看到输出中包含 newRunVersion: 4.4 时表示升级成功
        • 其他常见输出:
          • 成功升级:显示 newRunVersion: 目标版本
          • 已执行过升级:显示 exit upgrade
          • 版本不匹配:显示错误信息,需要重复执行上一个成功的升级命令
      • 步骤 6:故障处理提示(提供查看详细日志的方法)
        # 如果升级过程中出现版本不匹配错误,需要重复执行上一个成功的升级命令
        # 多次尝试仍失败可查看日志
        cat /data/mingdao/script/volume/data/mongodb/upgrade-xxxx.log
        
      e. 重建 mdwsrows 库的自建索引(必须详细展开,不能一笔带过):
      • 参考 MongoDB 索引重建文档 执行
      • 第一部分:重建 mdwsrows 数据库索引
        • 步骤 1:进入存储组件容器(提供完整命令)
          docker exec -it $(docker ps | grep mingdaoyun-sc | awk '{print $1}') bash
          
        • 步骤 2:创建脚本文件 reIndex.js(提供完整的 JavaScript 脚本内容,不能省略)
          var targetDbName = "mdwsrows";
          // 集合白名单,白名单中的集合不重建索引
          var collectionWhitelist = ["discussion", "rowrelations", "workSheetRowTopic", "workSheetTopic", "wslogs"];
          // 索引白名单,白名单中的索引不重建
          var indexWhitelist = ["_id_", "idx_ctime", "idx_utime", "uk_rowid", "idx_tp_status", "idx_thirdprimary"];
          
          // 格式化时间函数
          function formatDateTime() {
              var now = new Date();
              var utc8Time = new Date(now.getTime() + (8 * 60 * 60 * 1000));
              return utc8Time.toISOString().replace('Z', '+08:00');
          }
          
          // 格式化输出函数
          function printHeader(text) {
              print("\
          

" + "=".repeat(100)); print(text); print("=".repeat(100)); }

        function printSection(text) {
            print("\

" + "-".repeat(80)); print(text); print("-".repeat(80)); }

        function printTimedAction(time, action) {
            print(`\

[${time}] ${action}`); }

        // 格式化 JSON,保持一致的缩进
        function formatJSON(obj, indent = 5) {
            return JSON.stringify(obj, null, 2).split('\

').map((line, i) => i === 0 ? line : ' '.repeat(indent) + line).join('
'); }

        // 格式化 createIndex 命令
        function formatCreateIndexCommand(collName, key, options) {
            return `db.${collName}.createIndex(${formatJSON(key)},\
 ${formatJSON(options)})`;
        }

        function printCommand(command) {
            print("  └─ Execute:");
            print("     " + command);
        }

        function printCompletion(seconds) {
            print(`  └─ ✓ Completed in ${seconds.toFixed(3)} seconds\

`); }

        // 连接到指定数据库
        var targetDb = db.getSiblingDB(targetDbName);
        var startTime = formatDateTime();
        printHeader("MongoDB Index Rebuild Process");
        print(`\

• Start Time: ${startTime}); print(• Target Database: ${targetDb.getName()}`);

        // 获取所有要重建所有的集合(过滤集合白名单)
        var collections = targetDb.getCollectionNames().filter(function(collName) {
            return !collectionWhitelist.includes(collName) && !collName.startsWith('system.');
        });

        print(`• Total Collections: ${collections.length}`);
        collections.forEach(function(collName, index) {
            var coll = targetDb.getCollection(collName);
            var stats = coll.stats();
            
            // 输出集合信息和进度
            printSection(`Processing Collection [${index + 1}/${collections.length}]: ${collName}`);
            print(`\

• Document Count: ${stats.count}); print(• Storage Size: ${stats.storageSize} bytes`);

            // 获取需要重建的索引(过滤索引白名单)
            var indexes = coll.getIndexes();
            var rebuildIndexes = indexes.filter(function(idx) {
                return !indexWhitelist.includes(idx.name);
            });
            
            if (rebuildIndexes.length === 0) {
                print("\

✓ No indexes need to be rebuilt."); return; }

            // 输出索引重建计划
            print(`\

• Indexes to Rebuild (${rebuildIndexes.length}):); rebuildIndexes.forEach(function(idx) { print( ├─ Name: ${idx.name.padEnd(20)}); print( │ Key: ${JSON.stringify(idx.key)}`); });

            // 重建每个索引
            rebuildIndexes.forEach(function(idx) {
                var key = idx.key;
                var options = {};
                
                // 复制索引配置(排除系统属性)
                for (var prop in idx) {
                    if (!["v", "ns", "background"].includes(prop)) {
                        options[prop] = idx[prop];
                    }
                }
                options.background = true; // 后台构建索引
                
                try {
                    // 删除旧索引
                    var dropTime = formatDateTime();
                    printTimedAction(dropTime, `Dropping Index: ${idx.name}`);
                    printCommand(`db.${collName}.dropIndex("${idx.name}")`);
                    var dropStart = new Date();
                    coll.dropIndex(idx.name);
                    var dropEnd = new Date();
                    printCompletion((dropEnd - dropStart) / 1000);
                    
                    // 创建新索引
                    var createTime = formatDateTime();
                    printTimedAction(createTime, `Creating Index: ${idx.name}`);
                    printCommand(formatCreateIndexCommand(collName, key, options));
                    var createStart = new Date();
                    coll.createIndex(key, options);
                    var createEnd = new Date();
                    printCompletion((createEnd - createStart) / 1000);
                } catch (e) {
                    print(`  └─ ✗ Error: ${e.message}`);
                    print("     Skipping this index...\

"); } }); });

        var endTime = formatDateTime();
        printHeader("Process Completed");
        print(`\

• End Time: ${endTime}`); * 步骤 3:执行脚本(根据 MongoDB 认证配置,提供无认证和有认证两种情况的完整命令)bash # MongoDB 无认证 nohup mongo mongodb://127.0.0.1:27017/admin --quiet reIndex.js >> reIndex_output.log 2>&1 &

        # MongoDB 有认证(替换 root:password 为实际用户名和密码)
        nohup mongo mongodb://root:[email protected]:27017/admin --quiet reIndex.js >> reIndex_output.log 2>&1 &
        ```
      * 步骤 4:观察日志(提供观察进度的命令)
        ```bash
        # 实时查看日志输出
        tail -f reIndex_output.log

        # 等待脚本执行完成(日志结尾会输出 "Process Complete" 与 "End Time")
        ```
    - **第二部分:重建 HAP 系统依赖索引**:
      * 步骤 5:创建脚本文件 `reIndexWithCmd.js`(提供完整的 JavaScript 脚本内容,不能省略)
        ```javascript
        // ====================================================================
        //                          CONFIGURATION
        // ====================================================================
        // 在这里配置您需要重建索引的数据库及其白名单集合
        // 格式: "数据库名": ["要跳过的集合1", "要跳过的集合2..."]
        // 如果某个库下所有集合都需要重建索引,请使用空数组 []
        var targetDatabases = {
            "mdpost": [],
            "MDHistory": []
        };

        // ====================================================================
        // 格式化输出函数 (无需修改)
        function printHeader(text) {
            print("\

" + "=".repeat(100)); print(text); print("=".repeat(100)); }

        function printSection(text) {
            print("\

" + "-".repeat(80)); print(text); print("-".repeat(80)); }

        function formatDateTime() {
            var now = new Date();
            var utc8Time = new Date(now.getTime() + (8 * 60 * 60 * 1000));
            return utc8Time.toISOString().replace('Z', '+08:00');
        }

        function formatJSON(obj, indent = 5) {
            if (obj === undefined || obj === null) {
                return "Not available";
            }
            return JSON.stringify(obj, null, 2).split('\

').map((line, i) => i === 0 ? line : ' '.repeat(indent) + line).join('
'); }

        function formatFileSize(bytes) {
            if (bytes === undefined || bytes === null) return "N/A";
            return (bytes / 1024 / 1024).toFixed(2) + " MB";
        }

        function printTimedAction(time, action) {
            print(`\

[${time}] ${action}`); }

        function printCompletion(seconds) {
            print(`  └─ ✓ Completed in ${seconds.toFixed(3)} seconds\

`); }

        // ====================================================================
        //                          SCRIPT EXECUTION
        // ====================================================================
        var overallStartTime = formatDateTime();
        printHeader("MongoDB Multi-Database Index Rebuild Process Started");
        print(`\

• Overall Start Time: ${overallStartTime}); print(• Databases to Process: ${Object.keys(targetDatabases).join(', ')}`);

        // 遍历配置中的所有数据库
        for (var dbName in targetDatabases) {
            if (targetDatabases.hasOwnProperty(dbName)) {
                printHeader(`Processing Database: [ ${dbName} ]`);
                
                // 获取目标数据库连接
                var currentDb = db.getSiblingDB(dbName);
                
                // 获取当前数据库的集合黑名单(即需要跳过的集合列表)
                var excludedCollections = targetDatabases[dbName];
                print(`\

• Target Database: ${currentDb.getName()}); print(• Excluded Collections: ${formatJSON(excludedCollections)}`);

                // 获取所有集合
                var collections = currentDb.getCollectionNames();
                
                // 过滤掉黑名单中的集合和系统集合
                var validCollections = collections.filter(collection => 
                    !excludedCollections.includes(collection) && !collection.startsWith('system.')
                );
                
                print(`• Total Collections to Process in this DB: ${validCollections.length}`);
                
                if (validCollections.length === 0) {
                    print("\

No collections to process in this database. Moving to the next one."); continue; }

                validCollections.forEach(function(collection, index) {
                    try {
                        // 获取集合统计信息
                        var stats = currentDb[collection].stats();
                        
                        // 输出集合信息和进度
                        printSection(`Processing Collection [${index + 1}/${validCollections.length}]: ${collection}`);
                        print(`\

• Collection Statistics:); print( ├─ Storage Size: ${formatFileSize(stats.storageSize)}); print( └─ Document Count: ${(stats.count || 0).toLocaleString()}`);

                        // 获取当前索引信息
                        var indexes = currentDb[collection].getIndexes();
                        print(`\

• Current Indexes (${indexes.length}):); indexes.forEach(function(idx, i) { const isLast = i === indexes.length - 1; print(${isLast ? '└' : '├'}─ Name: ${idx.name.padEnd(20)}); print(${isLast ? ' ' : '│'} Key: ${formatJSON(idx.key)}`); });

                        // 执行 reIndex
                        var execTime = formatDateTime();
                        printTimedAction(execTime, "Executing reIndex()");
                        print("  └─ Execute:");
                        print(`     db.getSiblingDB('${dbName}').getCollection('${collection}').reIndex()`);
                        
                        var startExec = new Date();
                        var result = currentDb[collection].reIndex();
                        var endExec = new Date();
                        
                        if (result.ok === 1) {
                            printCompletion((endExec - startExec) / 1000);
                            print("• Operation Results:");
                            print(`  ├─ Previous Index Count: ${result.nIndexesWas}`);
                            print(`  ├─ Current Index Count: ${result.nIndexes}`);
                            if (result.operationTime !== undefined) {
                                print(`  ├─ Operation Time: ${formatJSON(result.operationTime)}`);
                            } else {
                                print(`  ├─ Operation Time: Not available (non-replica set deployment)`);
                            }
                            if (result.$clusterTime !== undefined) {
                                print(`  └─ Cluster Time: ${formatJSON(result.$clusterTime)}`);
                            } else {
                                print(`  └─ Cluster Time: Not available (non-replica set deployment)`);
                            }
                        } else {
                            print(`  └─ ✗ ReIndex failed: ${formatJSON(result)}`);
                        }
                    } catch (e) {
                        print(`  └─ ✗ Error: ${e.message}`);
                        print("     Skipping this collection...\

"); } }); } }

        var overallEndTime = formatDateTime();
        printHeader("Process Completed");
        print(`\

• Overall End Time: ${overallEndTime}`); * 步骤 6:执行脚本(根据 MongoDB 认证配置,提供无认证和有认证两种情况的完整命令)bash # MongoDB 无认证 nohup mongo mongodb://127.0.0.1:27017/admin --quiet reIndexWithCmd.js >> reIndexWithCmd_output.log 2>&1 &

        # MongoDB 有认证(替换 root:password 为实际用户名和密码)
        nohup mongo mongodb://root:[email protected]:27017/admin --quiet reIndexWithCmd.js >> reIndexWithCmd_output.log 2>&1 &
        ```
      * 步骤 7:观察日志(提供观察进度的命令)
        ```bash
        # 实时查看日志输出
        tail -f reIndexWithCmd_output.log

        # 等待脚本执行完成(日志结尾会输出 "Process Complete" 与 "End Time")
        ```
    - **操作前最终确认**(必须列出所有确认项):
      * 已在测试环境验证过此流程
      * 已对生产数据库进行完整备份
      * 已选择业务低峰期窗口
      * 已通知相关用户可能出现的服务影响
 f. **建议和注意事项**:
    * 在重建索引前,先导出当前所有索引的定义
    * 索引重建可能需要较长时间,取决于数据量和索引数量
    * 重建期间可能影响系统性能,建议在低峰期执行
    * 如果 `mongo` 命令没加入 PATH 变量,需指定绝对路径
  • 要求
    • 所有命令必须提供完整代码块,不能省略参数
    • JavaScript 脚本内容必须完整,不能只说"参考官网文档"
    • 必须区分无认证和有认证两种情况
    • 必须提供观察日志的命令
    • 必须详细列出所有升级步骤,不能一笔带过
  1. 禁止事项
    • 禁止简化或概括这两个特殊升级操作的步骤
    • 禁止只提供参考链接而不展开详细步骤
    • 禁止省略 JavaScript 脚本内容
    • 禁止省略命令中的任何参数
    • 禁止将这两个操作与其他升级前操作合并为一个步骤
    • 禁止遗漏任何警告、注意事项或验证步骤

镜像名称规范化规则

在生成升级文档时,必须严格遵守以下镜像名称映射规则,禁止根据官网显示名称推断实际镜像名称:

1. 文档预览服务镜像名称

官网显示名称 实际镜像名称 说明
mingdaoyun-doc-preview mingdaoyun-doc 文档预览服务主镜像
mingdaoyun-doc-preview-extension mingdaoyun-ldoc 文档预览扩展服务镜像

重要

  • 文档预览相关的镜像名称必须使用实际镜像名称(mingdaoyun-doc 和 mingdaoyun-ldoc)
  • 禁止直接使用官网文档中显示的 mingdaoyun-doc-preview 或 mingdaoyun-doc-preview-extension
  • 在拉取镜像、修改 docker-compose.yaml 或编写命令时,务必使用正确的实际镜像名称

2. 其他镜像名称

其他镜像名称(如 mingdaoyun-hap、mingdaoyun-sc、mingdaoyun-command 等)以官方文档为准,按官网显示使用。

镜像准备阶段规则

在生成升级文档的"提前准备"章节时,必须遵循以下规则:

1. 镜像版本选择原则

当升级路径跨越多个版本,涉及需要提前拉取的镜像时:

  • 只拉取目标版本的镜像,无需拉取中间版本的镜像
  • 例如:从 v4.8.1 升级到 v6.2.0,只需要拉取 v6.2.0 版本的镜像,不需要拉取 v5.1.0、v5.5.0 等中间版本的镜像

2. 存储组件和文档预览服务镜像

  • 存储组件:直接升级到跨越路径要求的最高版本
  • 文档预览服务:直接升级到跨越路径要求的最高版本
  • 例如:从 v4.8.1 升级到 v6.2.0,存储组件需要升级到 v3.1.0(跨越路径中要求的最高的版本),文档预览需要升级到 v2.0.0

3. "提前准备"章节内容规范

"提前准备"章节必须列出:

  • HAP 微服务镜像(目标版本)
  • 如果升级路径要求存储组件升级,列出对应的存储组件镜像(最高版本)
  • 如果升级路径要求文档预览服务升级,列出对应的文档预览镜像(最高版本,使用正确的镜像名称)
  • 如果升级路径涉及 MongoDB 预置数据更新,列出对应的预置数据下载链接
  • 其他官方文档中明确要求提前准备的资源

禁止

  • 禁止列出不会用到的镜像或资源
  • 禁止列出中间版本的镜像
  • 禁止遗漏官方文档中明确要求提前准备的资源

4. 文档预览服务离线包下载地址规范

在离线环境升级指南的"提前准备"章节中,必须给出文档预览服务的实际 tar.gz 文件下载链接,不得只写文字说明或跳转到离线资源页面。

AMD64 架构实际下载地址

服务 镜像名称 版本 实际下载链接
文档预览服务 mingdaoyun-doc 2.0.0 https://pdpublic.mingdao.com/private-deployment/offline/mingdaoyun-doc-linux-amd64-2.0.0.tar.gz
文档预览扩展服务(ldoc,可选) mingdaoyun-ldoc 2.0.2 https://pdpublic.mingdao.com/private-deployment/offline/mingdaoyun-ldoc-linux-amd64-2.0.2.tar.gz

ARM64 架构下载地址格式(将 amd64 替换为 arm64):

  • https://pdpublic.mingdao.com/private-deployment/offline/mingdaoyun-doc-linux-arm64-2.0.0.tar.gz
  • https://pdpublic.mingdao.com/private-deployment/offline/mingdaoyun-ldoc-linux-arm64-2.0.2.tar.gz

禁止

  • 禁止在离线场景下只写"请前往离线资源页下载"或"下载地址见官网"等文字说明
  • 必须直接在下载表格中填写完整的 https:// 开头的 tar.gz 文件链接
  • 如果官网离线页面有更新的版本,以抓取到的实际页面内容为准,不得使用本规范中过时的版本号

生成升级指南时的要求

1. 先选模板

根据部署模式读取 Markdown 模板:

  • 单机模式:assets/upgrade-guide-template-standalone.md
  • 集群模式:assets/upgrade-guide-template-cluster.md

禁止脱离模板凭记忆重写整个结构。HTML 无需读取模板,由脚本从 MD 自动生成(见 2.3 节)。

2. 再填内容

2.1 Markdown 文档结构要求

Markdown 是唯一事实来源,HTML 从它自动生成,因此 Markdown 内容必须完整、正确。

文档必须包含以下章节(按顺序)

  1. 标题(# HAP 升级指南(单机/集群模式)
  2. 版本信息表格(两列表格:升级路径、部署模式、架构、网络、生成日期)
  3. 提前准备
  4. 升级前准备(必须包含"前端二开注意事项"小节,即便无其他步骤也要保留此节)
  5. 升级步骤
    • 第一阶段:HAP 微服务升级前操作
    • 第二阶段:升级微服务
    • 第三阶段:HAP 微服务升级后操作
  6. 升级后验证
  7. 参考文档
  8. 底部声明(AI 生成声明)

单机模式还包含"异常情况排查"章节;集群模式不包含此章节。

2.2 Markdown 文档填充规则

填充 Markdown 文档时,遵守以下规则:

  • 文档顶部信息必须补全升级路径、部署模式、架构、网络情况、生成日期,必须使用两列 Markdown 表格格式(禁止使用行内加粗键值对格式,因为会挤在一起)。格式示例:

    | 项目 | 内容 |
    |------|------|
    | **升级路径** | v4.8.1 → v7.2.1 |
    | **部署模式** | 单机模式(Docker Compose) |
    | **服务器架构** | AMD64 |
    | **服务器网络** | 可访问互联网 |
    | **文档生成日期** | 2026-03-30 |
    
  • 备份步骤必须保留在最前面

  • "提前准备"必须汇总本次升级实际会用到的全部资源,不限于 HAP 微服务镜像。只要升级步骤或附加操作中会用到镜像、离线包、脚本、预置数据、额外组件资源,都应提前列出

  • 如果某一阶段完全没有步骤,删除整节,不保留占位提示

  • 所有命令必须给出完整代码块,不能写"同上""省略""按前文类似处理"

  • 生成的是面向执行者的文档,不要把模型的推理过程写进正文

  • 如果线上文档把附加操作写成超链接或跳转说明,最终输出时必须把超链接背后的实际步骤展开写入对应章节,不能只给一个链接让用户自己点进去

  • 微服务升级必须包含 ENV_APP_VERSION 变量值设置

    • 单机模式:在"第二阶段:升级微服务"的"修改镜像版本号"步骤中,必须同时说明:
      • 修改 docker-compose.yaml 中的 HAP 镜像版本号
      • 确保 ENV_APP_VERSION 环境变量的值与微服务镜像版本号保持一致(例如:微服务版本是 7.1.1,ENV_APP_VERSION 的值也应设为 7.1.1)
      • 提供完整的修改示例:
        # 修改前
        image: registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-hap:4.8.1
        environment:
          - ENV_APP_VERSION=4.8.1
        
        # 修改后
        image: registry.cn-hangzhou.aliyuncs.com/mdpublic/mingdaoyun-hap:6.2.0
        environment:
          - ENV_APP_VERSION=6.2.0
        
    • 集群模式:在"第二阶段:升级微服务"的升级步骤中,必须同时说明:
      • update.sh update hap {目标版本号} 命令会自动更新镜像版本号
      • ENV_APP_VERSION 环境变量也会通过 update.sh 自动更新为相同的版本号
      • 如果需要手动确认,可以查看部署的 yaml 文件或 Pod 环境变量进行验证
  • 升级前准备中必须包含"前端二开注意事项"小节

    • 位置:放置在"升级前准备"章节中,作为独立编号步骤(编号排在备份、确认版本等步骤之后)
    • 标题前端二次开发注意事项
    • 必须包含以下说明
      • 若系统中存在前端二次开发(即有基于 HAP 前端源码进行过定制开发),升级后前端代码可能与新版本存在冲突
      • 需要前端二开负责同事在升级前或升级后(根据实际情况确定时机),执行以下操作:
        1. 拉取最新的前端二开基础代码(通常为官方前端仓库对应目标版本的分支或 tag)
        2. 将自定义的二开代码合并(merge)进最新基础代码,处理可能存在的冲突
        3. 构建并发布更新后的前端服务,使新版本前端生效
      • 若系统中没有前端二次开发,忽略本注意事项
    • 固定提示语(必须包含):
      > ⚠️ **注意**:如有前端二次开发,请联系前端二开负责同事确认此操作已完成,否则可能导致升级后前端功能异常。
      

2.3 HTML 文档生成

MD 是唯一事实来源,HTML 完全由 AI 直接生成。不依赖任何本地 Python 脚本,也不需要安装任何依赖。

生成 Markdown 文档后,AI 直接读取 MD 文件内容,按以下规范转换为 HTML,并用 write_to_file 写出 .html 文件。


HTML 模板结构(严格遵守)

\x3C!DOCTYPE html>
\x3Chtml lang="zh-CN">
\x3Chead>
  \x3Cmeta charset="UTF-8">
  \x3Cmeta name="viewport" content="width=device-width, initial-scale=1.0">
  \x3Ctitle>{文档标题}\x3C/title>
  \x3Cstyle>
    /* 见下方 CSS 规范 */
  \x3C/style>
\x3C/head>
\x3Cbody>
\x3Cdiv class="layout">
  \x3Cnav class="sidebar">
    \x3Cdiv class="sidebar-title">文档目录\x3C/div>
    \x3Cul class="toc" id="toc">\x3C/ul>
  \x3C/nav>
  \x3Cdiv class="main">
    \x3Cdiv class="content">
      {正文 HTML 内容}
    \x3C/div>
  \x3C/div>
\x3C/div>
\x3Cscript>
  /* 见下方 JS 规范 */
\x3C/script>
\x3C/body>
\x3C/html>

CSS 规范(完整内嵌,不省略)

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: 15px; line-height: 1.75; color: #24292f; background: #f6f8fa;
}

.layout { display: flex; min-height: 100vh; }

.sidebar {
  width: 260px; flex-shrink: 0; background: #fff;
  border-right: 1px solid #d0d7de; position: fixed; top: 0; left: 0;
  height: 100vh; overflow-y: auto; padding: 24px 0;
}
.sidebar-title {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; color: #57606a; padding: 0 20px 10px;
  border-bottom: 1px solid #d0d7de; margin-bottom: 12px;
}
.toc { list-style: none; padding: 0; }
.toc li a {
  display: block; padding: 4px 20px; font-size: 13px; color: #24292f;
  text-decoration: none; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; border-left: 3px solid transparent;
}
.toc li a:hover { background: #f6f8fa; color: #0969da; }
.toc li a.active { border-left-color: #0969da; color: #0969da; font-weight: 600; background: #f0f6ff; }
.toc li.h3 a { padding-left: 34px; font-size: 12.5px; color: #57606a; }
.toc li.h4 a { padding-left: 48px; font-size: 12px; color: #57606a; }

.main { flex: 1; margin-left: 260px; background: #f6f8fa; min-width: 0; }
.content {
  max-width: 980px; margin: 0 auto; padding: 36px 48px 60px;
  background: #fff; border-left: 1px solid #d0d7de;
  border-right: 1px solid #d0d7de; min-height: 100vh;
}

h1 { font-size: 28px; font-weight: 700; margin: 0 0 16px; color: #1f2328; }
h2 { font-size: 22px; font-weight: 600; margin: 36px 0 14px; padding-bottom: 8px; border-bottom: 1px solid #d0d7de; color: #1f2328; }
h3 { font-size: 18px; font-weight: 600; margin: 28px 0 10px; color: #1f2328; }
h4 { font-size: 16px; font-weight: 600; margin: 22px 0 8px; color: #1f2328; }
h5 { font-size: 14px; font-weight: 600; margin: 18px 0 6px; color: #1f2328; }

p { margin-bottom: 14px; color: #24292f; }
ul, ol { margin: 8px 0 14px 24px; color: #24292f; }
li { margin-bottom: 5px; line-height: 1.7; }
li > ul, li > ol { margin: 4px 0 4px 20px; }

blockquote { border-left: 4px solid #d0d7de; margin: 16px 0; padding: 4px 16px; color: #57606a; }
blockquote p { margin-bottom: 4px; }

table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 14px; }
th, td { border: 1px solid #d0d7de; padding: 8px 12px; text-align: left; }
th { background: #f6f8fa; font-weight: 600; }
tr:nth-child(even) td { background: #f6f8fa; }

/* 版本信息表格(文档第一个表格)特殊样式 */
table.meta-block { border-radius: 8px; overflow: hidden; margin-bottom: 28px; }
table.meta-block th { color: #57606a; font-size: 12.5px; text-transform: uppercase; letter-spacing: .4px; width: 140px; }

code {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 85%; background: #eef0f3; border: 1px solid #d0d7de;
  border-radius: 4px; padding: 2px 5px; color: #cf222e;
}

.code-block {
  position: relative; margin: 16px 0; border-radius: 6px;
  overflow: hidden; border: 1px solid #d0d7de;
}
.code-block pre {
  background: #f6f8fa; color: #24292f; margin: 0;
  padding: 16px; overflow-x: auto;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 13.5px; line-height: 1.5;
}
.code-block pre code { background: none; border: none; padding: 0; color: inherit; font-size: inherit; border-radius: 0; }
.code-block::before {
  content: attr(data-lang); position: absolute; top: 8px; left: 12px;
  font-size: 11px; font-family: "SFMono-Regular", Consolas, monospace;
  color: #57606a; text-transform: uppercase; letter-spacing: .5px; pointer-events: none;
}
.code-block[data-lang]:not([data-lang=""]) pre { padding-top: 32px; }

.copy-btn {
  position: absolute; top: 6px; right: 8px; padding: 3px 10px;
  background: rgba(175,184,193,.8); color: #24292f;
  border: 1px solid rgba(27,31,35,.15); border-radius: 4px; cursor: pointer;
  font-size: 12px; font-weight: 500; transition: background .15s, color .15s; z-index: 2;
}
.copy-btn:hover { background: rgba(175,184,193,1); }
.copy-btn.copied { background: #2ea44f; color: #fff; border-color: transparent; }

hr { border: none; border-top: 1px solid #d0d7de; margin: 28px 0; }
a { color: #0969da; text-decoration: none; }
a:hover { text-decoration: underline; }

JS 规范(完整内嵌,不省略)

// 复制按钮
document.querySelectorAll('.copy-btn').forEach(function(btn) {
  btn.addEventListener('click', function() {
    var pre = btn.closest('.code-block').querySelector('pre');
    navigator.clipboard.writeText(pre.innerText).then(function() {
      btn.textContent = '已复制';
      btn.classList.add('copied');
      setTimeout(function() { btn.textContent = '复制'; btn.classList.remove('copied'); }, 1500);
    });
  });
});

// 目录生成 & 滚动高亮
(function() {
  var headings = document.querySelectorAll('.content h2, .content h3, .content h4');
  var toc = document.getElementById('toc');
  if (!toc || headings.length === 0) return;
  headings.forEach(function(h, idx) {
    if (!h.id) h.id = 'heading-' + idx;
    var li = document.createElement('li');
    li.className = h.tagName.toLowerCase();
    var a = document.createElement('a');
    a.href = '#' + h.id;
    a.textContent = h.textContent;
    li.appendChild(a);
    toc.appendChild(li);
  });
  var links = toc.querySelectorAll('a');
  function onScroll() {
    var scrollY = window.scrollY + 80;
    var active = null;
    headings.forEach(function(h) { if (h.offsetTop \x3C= scrollY) active = h.id; });
    links.forEach(function(a) { a.classList.toggle('active', a.getAttribute('href') === '#' + active); });
  }
  window.addEventListener('scroll', onScroll, { passive: true });
  onScroll();
})();

Markdown → HTML 转换规则(AI 执行)

Markdown 语法 HTML 输出
# 标题 \x3Ch1 id="...">标题\x3C/h1>
## 标题 \x3Ch2 id="...">标题\x3C/h2>(id 由标题文字生成,用于目录锚点)
### / #### \x3Ch3> / \x3Ch4>(同上)
` 行内代码 ` \x3Ccode>内容\x3C/code>
` ```lang\
代码\
``` ` \x3Cdiv class="code-block" data-lang="lang">\x3Cpre>\x3Ccode>代码内容\x3C/code>\x3C/pre>\x3Cbutton class="copy-btn">复制\x3C/button>\x3C/div>
**粗体** \x3Cstrong>粗体\x3C/strong>
- 列表项 \x3Cul>\x3Cli>列表项\x3C/li>\x3C/ul>
1. 列表项 \x3Col>\x3Cli>列表项\x3C/li>\x3C/ol>
> 引用 \x3Cblockquote>\x3Cp>引用\x3C/p>\x3C/blockquote>
表格 \x3Ctable> 标准结构,首个表格额外加 class="meta-block"
[文字](url) \x3Ca href="url">文字\x3C/a>
--- \x3Chr>
空行分段 \x3Cp>段落内容\x3C/p>

代码块特别要求(最关键,不得出错):

  • 所有代码内容必须原样保留,不得截断、省略或改写,不论代码有多长(包括 4000+ 字符的 JS 脚本)
  • \x3C > & " 需 HTML 转义为 < > & "
  • data-lang 属性值为代码块语言标识(如 bashyamljavascript),无语言标识时写 data-lang=""
  • 禁止...省略 代替代码内容
  • 禁止在代码块中插入换行符或修改缩进

标题 id 生成规则:取标题文字,保留中文和字母数字,空格转 -,其余字符删除,全部小写。例:第一阶段:HAP 微服务升级前操作id="第一阶段hap-微服务升级前操作"

禁止事项

  • 禁止手动填充任何旧 HTML 模板
  • 禁止省略或截断任何代码块内容
  • 禁止在输出 HTML 前将文件交给用户(必须先写入文件)

3. 严格裁剪模板块

模板中的可选段落必须清理干净:

  • 联网场景:只保留联网版本的段落,删除离线版本的段落
  • 离线场景:只保留离线版本的段落,删除联网版本的段落
  • 最终输出中不得保留"以下二选一""按场景保留其一""删除不适用内容"之类模板提示,也不得保留 {...} 占位说明或模板注释语

4. 命令与内容来源

生成命令时,优先顺序如下:

  1. 当前抓取到的官方升级详情页原文
  2. references/command-library.md
  3. 模板中的固定结构

如果三者出现冲突,以官方实时页面为准;但不要擅自拼接出官网没有表达过的新命令逻辑。

5. 针对不同部署模式的硬规则

  • 集群模式不能生成"存储组件升级"步骤,除非官方实时页面明确要求
  • 单机模式不能生成 kubectlcrictlctr 命令
  • 集群模式不能生成 docker execservice.sh restartall 这类单机命令
  • ARM64 时,涉及镜像名或更新命令时,必须检查是否需要 -arm64

仅做咨询答复时的要求

如果用户只是咨询,不一定要输出完整升级指南,但仍要遵循:

  • 先补齐缺失信息,或明确指出因为哪些信息缺失暂时无法下结论
  • 涉及具体版本结论时,必须先抓取官方页面再回答
  • 回答里要明确区分"已确认事实"和"基于缺失信息的待确认项"
  • 如果判断结果依赖架构支持或是否联网,要把这一点直接说清楚

禁止事项

禁止出现以下行为:

  • 凭训练记忆回答具体版本是否支持某架构
  • 直接使用 references/site-structure.md 中的兼容性快照当作结论
  • 杜撰官网未出现的升级步骤、版本路径、下载地址或脚本命令
  • 在最终文档中保留模板占位符、AI 推理说明、合并逻辑说明
  • 在信息不完整时伪造缺失参数

最终检查清单

在输出前,自检以下项目:

  • 已确认 5 项前置信息
  • 版本号已同时规范化为应用版本和显示版本
  • 已抓取 /version 实时页面
  • 已按目标架构完成兼容性校验
  • 已收集跨越路径中的含附加操作版本
  • 已按 merge-rules.md 合并
  • 需要生成文档时,已读取正确模板
  • 已按网络场景裁剪模板中的可选段落
  • 已把升级详情页或其跳转链接中的实际附加操作完整展开到正文
  • 最终内容中无占位符、无逻辑注释、无残留条件标记
  • 文末已追加声明

固定声明

无论输出咨询答复还是升级指南,只要给出与升级执行相关的正式结论,末尾都附加以下声明:

---
💡 声明:内容由 AI 生成。尽管已努力确保信息的合理性,但 AI 模型仍可能产生不准确、过时或存在偏差的内容。请在执行关键操作前,务必对照[官方文档](https://docs-pd.mingdao.com)进行核实校验。
安全使用建议
Install only if you are comfortable with a skill that generates local Markdown/HTML upgrade guides and includes copy-pasteable production commands. Before using any generated guide, verify commands against the official HAP documentation, avoid curl-pipe-bash unless you have independently downloaded and verified the script, replace default credentials with secure handling, and require human approval before executing any service restart, database migration, or Kubernetes/Docker change.
能力评估
Purpose & Capability
The artifacts coherently target HAP private-deployment upgrade consultation and Markdown/HTML guide generation, using official documentation and local templates. The generated guides include production upgrade, database, Kubernetes, Docker, and service restart commands, which is expected for the purpose but high-impact if followed blindly.
Instruction Scope
The trigger language is broad for HAP upgrade-related tasks, and the skill says that when information is complete it may directly generate documents. It also requires final HTML to be written before handing it to the user, which under-discloses the filesystem side effect for advisory conversations.
Install Mechanism
The package contains Markdown instructions, templates, and reference files only; no install-time scripts, declared dependencies, or hidden executable payloads were found. Static scan was clean and VirusTotal telemetry was null.
Credentials
The operational guidance includes curl-pipe-bash commands for preset MongoDB updates and production mutation commands for Docker, Kubernetes, MySQL, and MongoDB. These are purpose-aligned, but the remote script execution lacks checksum/signature verification guidance.
Persistence & Privilege
The skill does not request persistent background execution, privilege escalation, credential stores, or broad local indexing. It does instruct writing generated HTML files, and examples include inline/default database credentials that could encourage insecure copying or shell-history exposure.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install hap-upgrade-guide
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /hap-upgrade-guide 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
HAP升级指南 v1.0.0 — 首次发布 - 新增专用于明道云 HAP 私有部署环境的升级咨询与文档自动化生成功能。 - 明确升级5项关键信息(当前/目标版本、部署模式、架构、网络环境)的收集、校验与补全流程。 - 全流程严格按官网实时页面与高效查档执行,合并跨版本附加操作并规范升级结构。 - 针对特殊升级场景(如 v5.1.0 镜像拆分、v5.5.0 MongoDB 升级、MongoDB 预置数据更新)制定详细操作与文档结构规范。 - 输出包含详尽可执行操作步骤的升级 Markdown 指南,支持自动转为 HTML 文档。
元数据
Slug hap-upgrade-guide
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

HAP升级指南 是什么?

明道云 HAP 私有部署版本升级专属 skill。只要用户提到 HAP 私有部署升级、跨版本升级、升级注意事项、升级前后附加操作、单机或集群升级步骤、升级文档生成、版本兼容性或架构镜像支持,就必须触发本 skill。即使用户没有明确说"用 hap-upgrade",只要任务与 HAP 私有部署升级决策或升级执行有... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 49 次。

如何安装 HAP升级指南?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install hap-upgrade-guide」即可一键安装,无需额外配置。

HAP升级指南 是免费的吗?

是的,HAP升级指南 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

HAP升级指南 支持哪些平台?

HAP升级指南 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 HAP升级指南?

由 1447443432(@1447443432)开发并维护,当前版本 v1.0.0。

💬 留言讨论