Bugzilla 常用命令与运维实战

Bugzilla 5.2 运维实战:checksetup 幂等重跑、sanitycheck 巡检、邮件链路与 contrib 工具箱、collectstats 统计、REST API 全流程实测(token/api_key/状态流转)与 pg_dump 备份恢复演练,附 API key 请求头不认证等真实排障。

BugzillaBugzilla2026/10/28

Bugzilla 常用命令与运维实战

目标:面向已经完成部署的管理员,覆盖 Bugzilla 5.2 日常运维的全部命令面:checksetup 重跑与模板预编译、sanitycheck 数据巡检、邮件链路运维、统计采集、contrib 工具箱、REST API 自动化(含认证方式实测结论)与备份恢复演练。全部命令与回显来自实测环境(Ubuntu 24.04 + PostgreSQL 16 + Bugzilla 5.2,部署与参数细节见本专栏前两篇),实测日期 2026-10-27。

一、环境信息

项目取值
Bugzilla5.2(/var/www/html/bugzilla,Perl v5.38.2,污点模式运行)
数据库PostgreSQL 16.15,库名/角色 bugs
管理员admin@example.com / q1w2e3r4
API Key实测生成的管理员的 key(下文展示生成过程,生产请自行生成并妥善保管)
已有数据产品 TestProduct;bug #1、#2(REST 实测创建)

二、命令速查总览

Bugzilla 的运维命令分两层:安装根目录的主脚本与 contrib/ 工具箱。实测清点:

根目录主脚本:

checksetup.pl        install-module.pl    testserver.pl        sanitycheck.pl
collectstats.pl      whine.pl             whineatnews.pl       jobqueue.pl
email_in.pl          importxml.pl         migrate.pl           mod_perl.pl
runtests.pl          clean-bug-user-last-visit.pl

contrib/ 工具箱:

Bugzilla.pm  README  bugzilla-queue.rhel  bugzilla-queue.suse  bugzilla-submit
bz_webservice_demo.pl  bzdbcopy.pl  cmdline/  console.pl  convert-workflow.pl
extension-convert.pl  fixperms.pl  jb2bz.py  merge-users.pl  mysqld-watcher.pl
new-yui.sh  perl-fmt  recode.pl  sendbugmail.pl  sendunsentbugmail.pl

其中 contrib/cmdline/ 还有六个命令行查询器:bugcount、bugids、buglist、bugs、bugslink、makequery。

三、安装器与库维护

3.1 checksetup.pl 重跑(幂等)

checksetup.pl 可随时重复执行,是最重要的「维护模式」入口:升级版本、改 localconfig、装新扩展、修复权限后都要重跑。实测对已部署环境直接重跑:

cd /var/www/html/bugzilla
./checksetup.pl

实测回显(尾部——与首轮部署相比只做增量动作):

Checking for               DBD-Pg (v2.7.0)    ok: found v3.18.0 
Checking for           PostgreSQL (v8.03.0000) ok: found v16.00.1500 
Checking for               DBD-Pg (v2.17.2)   ok: found v3.18.0 

Removing existing compiled templates...
Precompiling templates...done.
Fixing file permissions...
checksetup.pl complete.

判读:schema 无变化时不再建表,只做「模板重编译 + 权限修复」。如果重跑卡在某一步,通常是 localconfig 与数据库现状不一致(如密码改错连不上库),按报错回滚即可,checksetup 不会破坏已有数据。

3.2 模块管理 install-module.pl

补装/升级 Perl 模块的统一入口(装进 Bugzilla 目录内,不动系统包):

/usr/bin/perl install-module.pl <Module::Name>   # 单模块
/usr/bin/perl install-module.pl --all            # 全部必装+可选

3.3 部署自检 testserver.pl

./testserver.pl http://localhost/bugzilla/

输出逐项 TEST-OK/TEST-FAILED(判读方法见部署篇 5.1 节),升级或迁移 Apache 配置后建议复跑。

四、数据一致性巡检 sanitycheck

4.1 CLI 形态

./sanitycheck.pl --login=admin@example.com

实测回显:无任何输出,退出码 0——sanitycheck 的设计是「无事发生即沉默」,发现异常时输出问题清单并(配置了邮件时)把报告寄给该用户。注意它只接受 --login,没有 --password 选项:CLI 以本地 root 身份运行,直接以指定用户身份执行(信任模型是「能登上服务器就能代用户巡检」),这也是为什么文档都建议用管理员账号跑。

4.2 Web 形态与检查范围

管理员登录后 Administration → Sanity Check(sanitycheck.cgi)可交互执行同一套检查并当场查看结果。其检查范围(源自 sanitycheck.cgi 实测梳理)包括:标志(flag)与产品/组件错位、无组件的产品、状态流转配置一致性、历史遗留枚举类型、组权限校验与布尔字段缺漏、hook 一致性等。

⚠️ 注意:sanitycheck 发现问题后会在页面提供「修复」按钮(如重建全文索引、补缺失值)。修复动作直接写库,大库上先备份再点。

五、邮件链路运维

邮件是 Bugzilla 协作闭环的生命线,运维要点全部围绕 mail_delivery_method(参数详解见《Bugzilla 配置参数详解》):

  1. 调试落盘:mail_delivery_method=Test 时所有信件追加到 data/mailer.testfile,实测一次评论触发的邮件包含 multipart/alternative 双部件与完整 Message-ID/X-Bugzilla-* 头,可直接回放排查格式问题。
  2. 补发积压:contrib/sendunsentbugmail.pl——扫描因故未发出的邮件并补发(如发送中断后),实测直接执行即可,无参数。
  3. 补发单封:contrib/sendbugmail.pl <bug_id> 重发指定 bug 的通知。
  4. 入站邮件:email_in.pl 从标准输入读邮件正文建单/评论(配合邮件网关)。实测运行方式有个坑:必须以 ./email_in.pl 执行,若写成 perl email_in.pl 会报错(见排障实录 3)。完整用法(实测 ./email_in.pl --help 回显节选):
Usage:
    ./email_in.pl [-vvv] [--default name=value] [--override name=value] <
    email.txt

    Reads an email on STDIN (the standard input).

    Options:

       --verbose (-v)        - Make the script print more to STDERR.
                               Specify multiple times to print even more.

       --default name=value  - Specify defaults for field values, like
                               product=TestProduct. Can be specified multiple
                               times to specify defaults for multiple fields.
  1. 定时催办:whine.pl(按 whine 配置定时发提醒)与 whineatnews.pl(把 assignee 有变化的 bug 汇总寄出),两者均为 cron 驱动,生产环境按分钟/天粒度注册。
  2. 异步队列:jobqueue.pl——use_mailer_queue=1 时作为 TheSchwartz 队列守护进程收发邮件(需 TheSchwartz + Daemon-Generic 模块,实测环境该模块已装但未启用队列,保持同步发送)。contrib 下的 bugzilla-queue.rhel / bugzilla-queue.suse 是它的系统服务模板。

六、统计采集与杂项工具

  • collectstats.pl:按产品采集 bug 数量趋势到 data/mining/,供报表图表页使用。建议 cron 每日执行(实测静默运行正常)。
  • clean-bug-user-last-visit.pl:清理用户最后访问记录表,控制库膨胀。
  • importxml.pl:按 Bugzilla XML 格式批量导入 bug(迁移/初始化常用)。
  • migrate.pl:数据库抽象层迁移助手。
  • contrib/bzdbcopy.pl:跨数据库复制 Bugzilla 库(如 MySQL → PostgreSQL 迁移的官方工具)。
  • contrib/convert-workflow.pl / fixperms.pl / merge-users.pl / recode.pl:工作流转换、权限修复、账号合并、编码转换等一次性维护件。
  • contrib/cmdline/:六个 shell 友好的查询器(bugcount、buglist、makequery 等),适合接入监控脚本做指标采集。

七、REST API 实战

7.1 认证方式实测结论(重要)

实测三种方式的真实支持情况:

方式实测结果
POST /rest/login?login=...&password=... 获取 token,后续 ?token=...✅ 可用
?api_key=<key> 查询参数✅ 可用
X-Bugzilla-API-Key 请求头❌ 实测不认证(按登出用户处理,返回 code 505)

API Key 的生成有两条路:Web 界面 Preferences → API Keys 页自助生成;或 CLI 直接调模块(实测):

cd /var/www/html/bugzilla
perl -I. -e 'use Bugzilla; use Bugzilla::User::APIKey; Bugzilla->usage_mode(1);
  my $k = Bugzilla::User::APIKey->create({user_id=>1, description=>"ops-test"});
  print $k->api_key, "\n";'

实测回显(生成了一把真实可用的 key):

N3xjxG07kX9HDBopIZc74Y8TSUjGdA2ULKaSjeAU

7.2 只读接口实测

KEY=N3xjxG07kX9HDBopIZc74Y8TSUjGdA2ULKaSjeAU
curl -s http://localhost/bugzilla/rest/version
curl -s 'http://localhost/bugzilla/rest/login?login=admin@example.com&password=q1w2e3r4'
curl -s 'http://localhost/bugzilla/rest/user/1?api_key='$KEY
curl -s 'http://localhost/bugzilla/rest/bug/1?api_key='$KEY
curl -s 'http://localhost/bugzilla/rest/product?names=TestProduct&api_key='$KEY

实测回显(节选):

{"version":"5.2"}
{"id":1,"token":"1-BGlJ0zgAhb"}
{"users":[{"name":"admin@example.com","email_enabled":true,"can_login":true,"id":1,"real_name":"admin","email":"admin@example.com","groups":[{"description":"Administrators","id":1,"name":"admin"},...

产品查询的实测细节:GET /rest/product 不带过滤参数会报 The function Product.get requires that you set one of the following parameters: ids, names, type(code 50),必须带 ids 或 names。

7.3 建单与状态流转实测

创建(实测回显 {"id":2}):

curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"product":"TestProduct","component":"TestComponent",
       "summary":"运维验证:第二张工单","version":"unspecified",
       "op_sys":"Linux","platform":"PC",
       "description":"D1 运维篇实测提单。"}' \
  "http://localhost/bugzilla/rest/bug?api_key=$KEY"

状态流转三连(CONFIRMED → IN_PROGRESS → RESOLVED/FIXED,再重开),实测回显依次为:

{"bugs":[{"id":2,"changes":{"status":{"removed":"CONFIRMED","added":"IN_PROGRESS"}},"last_change_time":"2026-10-27T16:34...
{"bugs":[{"changes":{"status":{"added":"RESOLVED","removed":"IN_PROGRESS"},"resolution":{"added":"FIXED","removed":""}},"id":2,...
{"bugs":[{"last_change_time":"2026-10-27T16:35:00Z","changes":{"resolution":{"added":"","removed":"FIXED"},"status":{"added":"CONFIRMED"...

评论(实测回显 {"id":5}):

curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"comment":"运维巡检备注:已复测。"}' \
  "http://localhost/bugzilla/rest/bug/2/comment?api_key=$KEY"

💡 经验:REST 提单传 priority 时必须使用当前字段值体系内的合法值——全新安装默认是 ---/Lowest/Low/Normal/High/Highest 而非 P1-P5,实测传 P3 直接报 invalid priority。字段值可在管理界面按产品定制。

7.4 5.2 REST 的边界(实测不存在的资源)

以下资源在 5.2 的 REST 中不存在,实测统一返回 code 32614:

{"message":"A REST API resource was not found for 'POST /product/create'.","error":true,"code":32614}
{"message":"A REST API resource was not found for 'GET /params'.","error":true,"code":32614}
{"message":"A REST API resource was not found for 'GET /whoami'.","error":true,"code":32614}

即:产品/组件的创建与参数的读写不走 REST,改走 Web 管理界面或 CLI(参数的 CLI 方案见《Bugzilla 配置参数详解》4.3 节);whoami 用 GET /rest/user/<id> 替代。做集成前先核对 Bugzilla/WebService/ 下的资源清单,别按 6.x 文档想当然。

八、备份与恢复

8.1 数据库备份(PostgreSQL 实测)

sudo -u postgres pg_dump bugs > /var/backups/bugs-$(date +%F).sql

实测回显:生成 580,866 字节的 SQL dump(含全部 70+ 张表与数据)。MySQL/MariaDB 部署对应 mysqldump --single-transaction bugs。

8.2 恢复演练(实测)

sudo -u postgres createdb bugs_restore
sudo -u postgres psql -q bugs_restore < /var/backups/bugs-2026-10-27.sql
sudo -u postgres psql -t bugs_restore -c 'SELECT count(*) FROM bugs;'
sudo -u postgres dropdb bugs_restore

实测:恢复后 bugs 表计数为 2(与备份时的两张工单一致),演练库随即清理。恢复到正式库时替换库名并把 localconfig 指向恢复库重跑 checksetup 即可。

8.3 备份范围清单

完整备份 = 数据库 dump + 附件目录 data/attachments/(可配置为本地大附件时另含对应目录)+ 配置文件 localconfig + 运行参数 data/params.json。前三者任意缺一都会导致恢复后不可用。

九、排障实录

实录 1:REST 想当然,32614 频发。按新版文档调用 POST /rest/product/create、GET /rest/params、GET /rest/whoami 全部失败(32614)。原因:5.2 稳定线的 REST 资源面比 6.x/文档站 latest 版本窄。解决:核对 5.2 自带代码 Bugzilla/WebService/ 实际暴露的资源,产品建改走 editproducts.cgi 表单,参数走 CLI。

实录 2:API key 放请求头不认证。实测 -H "X-Bugzilla-API-Key: <key>" 一律按登出用户处理(受保护接口报 code 505)。解决:5.2 实测可用的认证是 ?api_key=<key> 参数或 login 换 token;受影响最大的是走反向代理注入头的自动化脚本。

实录 3:perl email_in.pl --help 报污点错误。实测报错原文:"-T" is on the #! line, it must also be used on the command line at email_in.pl line 1.——用 perl 显式执行会丢掉脚本第一行的 -T 开关,与污点模式冲突。解决:保持可执行位后直接 ./email_in.pl 运行,让 shebang 生效。

实录 4:sanitycheck.pl 找不到 password 选项。实测 ./sanitycheck.pl --login=... --password=... 报 Unknown option: password。原因:CLI 版以运行者身份代指定用户巡检,不校验密码;想验证身份请用 Web 版 sanitycheck.cgi。

十、例行维护清单(建议 cron)

频率动作
每日collectstats.pl 采集趋势;pg_dump 备份并异地存放
每日/按需whineatnews.pl(汇总变更)、whine.pl(到期催办)
每周sanitycheck.pl --login=<admin> 巡检;检查 data/mailer.testfile(Test 模式残留)是否误开
每季恢复演练(8.2 节流程);核对 upgrade_notification 的版本提示

十一、参考链接