Pagure 5.14.1 常用 CLI 与运维命令详解
Pagure 5.14.1 常用 CLI 与运维命令详解:pagure-admin 全部子命令实测、gitolite3 与 SSH 授权运维、备份恢复与服务日志取证,所有命令均含真实回显,适用于 Ubuntu 22.04 LTS 环境的日常管理与排障。
Pagure 5.14.1 常用 CLI 与运维命令详解
目标:系统梳理 Pagure 5.14.1 的运维命令面——管理 CLI
pagure-admin全部 17 个子命令(语法、参数与真实回显)、Web/worker 两个 systemd 单元的服务管理与日志、数据库与 git 仓库的备份恢复、REST API 的令牌调用,以及命令执行身份相关的三类实测故障处置。全部命令与回显已在 Ubuntu 22.04.5 LTS 的 Pagure 5.14.1 实例实测(2026-10-28)。部署与配置见 《Pagure 5.14.1 Ubuntu 22.04 安装指南》 与 《Pagure 5.14.1 配置参数详解》。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Pagure:5.14.1(源码
/opt/pagure,虚拟环境/opt/pagure/venv,配置/etc/pagure/pagure.cfg) - PostgreSQL 14.24、Redis 6.0.16、gitolite3 3.6.12-1、Gunicorn 26.2.0、Celery 5.6.3
- 服务单元:
pagure-web、pagure-worker(均 git 用户运行) - 日志目录:
/var/log/pagure/(access_web.log、error_web.log) - 示例管理账号:
admin/q1w2e3r4;示例项目public-demo
二、工具概览
Pagure 的运维命令集中在四个入口:
| 工具 | 位置 | 用途 |
|---|---|---|
pagure-admin | /opt/pagure/venv/bin/pagure-admin | 管理员 CLI:令牌、组、只读、分支、ACL、封禁等 |
| systemd 单元 | pagure-web / pagure-worker | Web 与异步任务服务的启停和日志 |
pg_dump + tar | 系统自带 | 数据库与 git 仓库备份 |
| REST API | http://localhost/api/0/ | 脚本化操作(建 issue、查分支等) |
pagure-admin --help 全量输出(实测):
usage: pagure-admin [-h] [-c CONFIG] [--debug]
{refresh-gitolite,refresh-ssh,clear-hook-token,admin-token,get-watch,update-watch,read-only,new-group,list-groups,block-user,upload-repospanner-hook,ensure-project-hooks,delete-project,sanitize-spam-user,create-branch,set-default-branch,update-acls}
...
The admin CLI for this pagure instance
options:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Specify a configuration to use
--debug Increase the verbosity of the information displayed
actions:
{refresh-gitolite,refresh-ssh,clear-hook-token,admin-token,get-watch,update-watch,read-only,new-group,list-groups,block-user,upload-repospanner-hook,ensure-project-hooks,delete-project,sanitize-spam-user,create-branch,set-default-branch,update-acls}
refresh-gitolite Re-generate the gitolite config file
refresh-ssh Re-write to disk every user's ssh key stored in the
database
clear-hook-token Generate a new hook token for every project in this
instance
admin-token Manages the admin tokens for this instance
get-watch Get someone's watch status on a project
update-watch Update someone's watch status on a project
read-only Get or set the read-only flag on a project
new-group Create a new group on this pagure instance
list-groups Lists existing groups on this pagure instance
block-user Prevents an user to interact with this pagure instance
until the specified date
upload-repospanner-hook
Upload repoSpanner hook script
ensure-project-hooks
Ensure all projects have their hooks setup
delete-project Delete the project specified
sanitize-spam-user Delete repos and tickets by the user specified
create-branch Create the specified branch in the specified project
set-default-branch Set the specified branch as default
update-acls Update the ACLs stored in the database with the ones
defined in the configuration file (addition only, no
ACLs are removed from the database).
三、前置条件
PAGURE_ADMIN_USERS包含执行者用户名(本环境为['admin']),否则多数子命令拒绝执行;- 命令需带配置环境:
export PAGURE_CONFIG=/etc/pagure/pagure.cfg(或每次前缀该变量); - 涉及 git 仓库直接读写的子命令(
create-branch、set-default-branch)应以 git 用户运行,root 会触发 pygit2 属主校验失败(实测报错见 6.4); - 需要操作目标项目存在(本文以
public-demo为例)。
四、各工具详解
4.1 pagure-admin:API 管理令牌
admin-token 系列管理管理员 API 令牌。先看已有令牌:
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin admin-token list
实测输出:
TC9UXJSDNL9Q5Z99K499N23OTD1XQSVNY2GW5WB1RBRC1XAKOXCXXFL54MQ33WBY -- admin -- 2027-12-31 00:00:00
创建令牌是交互式流程:admin-token create <用户> <到期日> 后先打印 ACL 清单,输入逗号分隔的 ACL 编号,再确认:
printf "0,2,7,10\nn\n" | PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin admin-token create admin 2027-06-30
实测输出(回答 n 中止创建,仅演示流程):
0. internal_access
1. issue_comment
2. issue_create
3. issue_change_status
4. pull_request_flag
5. pull_request_comment
6. pull_request_merge
7. generate_acls_project
8. group_modify
9. commit_flag
10. create_branch
11. tag_project
Which ACLs do you want to associated with this token?
(Comma separated list): ACLs selected:
0. internal_access
2. issue_create
7. generate_acls_project
10. create_branch
Do you want to create this API token?
Do you want to continue? [y/N]
💡 说明:把最后一问回答为
y即真正创建,令牌明文只显示一次(本环境已创建一枚 2027-12-31 到期的令牌,ACL 为上表 0/2/7/10 四项)。生产环境令牌等同于账号部分权限,按最小授权选择 ACL。
4.2 pagure-admin:用户组管理
创建组(new-group <组名> <创建者用户名>,--display、--description 可选,需确认):
echo y | PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin new-group packagers admin --display Packagers --description "Core packager team"
实测输出:
Group `packagers` created.
User `admin` added to the group `packagers`.
列出组:
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin list-groups
实测输出:
List of groups on this Pagure instance:
Group: 1 - name packagers
空实例时该命令返回 No groups found in this pagure instance.(实测)。
4.3 pagure-admin:关注状态(watch)
查询某用户对项目的关注状态(参数顺序为 <项目> <用户>):
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin get-watch public-demo admin
实测输出:
On public-demo user: admin is watching the following items: issues, pull-requests
修改关注状态,合法值为 -1, 0, 1, 2, 3,传错值会实测报错:
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin update-watch public-demo admin --status 1
实测输出:
Updating watch status of admin to 1 (watch issues and PRs) on public-demo
# 反例:--status all
Invalid status provided: all not in -1, 0, 1, 2, 3
4.4 pagure-admin:项目只读开关
不跟值即查询:
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin read-only public-demo
实测输出:
The current read-only flag of the project public-demo is set to False
设置只读/恢复可写(--ro 只接受小写 true/false):
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin read-only public-demo --ro true
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin read-only public-demo --ro false
实测输出(依次两行):
The read-only flag of the project public-demo has been set to True
The read-only flag of the project public-demo has been set to False
💡 说明:只读态下该项目的 git 推送会被拒绝,常用于迁移或事故冻结;恢复可写后无需其他操作。
4.5 pagure-admin:gitolite 与 SSH 维护
重新生成 gitolite ACL 配置并编译(需确认两次):
printf "y\ny\n" | PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin refresh-gitolite
实测输出:
Please note that you have not selected a project or --all. Do you want to recompile the existing config file?
Do you want to continue? [y/N]y
Do you want to re-generate the gitolite.conf file for group: None and project: None?
Do you want to continue? [y/N]y
Gitolite ACLs updated
重新落盘全部用户 SSH 公钥(refresh-ssh)在 5.14.1 存在缺陷:直接运行实测报错:
Do you want to re-generate all the ssh keys for every user in the database? (Depending on your instance this may take a while and result in an outage while it lasts)
Do you want to continue? [y/N]y
Error: Working outside of application context.
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
原因:该子命令调用的 pagure.flask_app.generate_user_key_files() 依赖 Flask 应用上下文与 flask.g.session。等价变通(实测通过,公钥正常生成到 keydir):
PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/python -c "
from pagure.flask_app import create_app, generate_user_key_files
import pagure.config
from pagure.lib import model_base
app = create_app()
with app.app_context():
from flask import g
g.session = model_base.create_session(pagure.config.config['DB_URL'])
print(generate_user_key_files())
g.session.commit()
"
实测输出:
None
💡 说明:函数执行成功无返回值(打印 None),效果等同
refresh-ssh——用户公钥重写进GITOLITE_KEYDIR。可用ls /srv/git/gitolite-admin/keydir/核对(实测见admin.pub)。
4.6 pagure-admin:令牌与 ACL 维护
重置全站 hook token(WebHook 密钥,安全事件时用,需确认):
echo y | PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin clear-hook-token
实测输出:
Do you want to re-generate all the hook token for every user in the database? This will break every web-hook set-up on this instance. You should only ever run this for a security issue
Do you want to continue? [y/N]y
Hook token all re-generated
同步配置文件中的 ACL 定义到数据库(只增不减,需确认):
echo y | PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin update-acls
实测输出:
ACLS in the database synced with the list in the configuration file
4.7 pagure-admin:分支管理
创建分支(以 git 用户运行;--from-branch 与 --from-commit 二选一,末尾两个位置参数是新分支名与操作者):
printf "y\n" | su - git -c "PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin create-branch public-demo --from-branch main feature-x admin"
实测输出:
Branch created
用 API 确认:
curl -s http://localhost/api/0/public-demo/git/branches
实测输出:
{"branches":["feature-x","main"],"default":"main","total_branches":2}
设置默认分支(同样以 git 用户运行):
su - git -c "PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin set-default-branch public-demo main"
实测输出:
Branch main set as default
⚠️ 注意:
create-branch内部是对仓库的直接 git 推送,会经过 gitolite 的 update 钩子。若报Can't locate Gitolite/Hooks/Update.pm in @INC,按「七、常见问题」7.2 给钩子补库路径后重试(本环境已修复)。
4.8 pagure-admin:仅 repoSpanner 与高危子命令
ensure-project-hooks <hookID>:仅适用于 repoSpanner 存储后端,位置参数是 repoSpanner hook ID;本环境为 gitolite 部署,实测该命令因缺参数报error: the following arguments are required: hook,未做 repoSpanner 实测。block-user <用户> <日期>、delete-project、sanitize-spam-user:破坏性命令,本环境未实测(避免破坏演示数据)。其行为按命令行定义为:block-user将用户封禁至指定日期(如pagure-admin block-user spammer 2027-01-01,预期输出确认提示并写入封禁记录);delete-project删除指定项目及其仓库;sanitize-spam-user批量删除指定用户的仓库与工单。三者均需在PAGURE_ADMIN_USERS名单内执行并二次确认。
4.9 服务管理与日志
systemctl is-active pagure-web
systemctl is-active pagure-worker
systemctl restart pagure-web
systemctl restart pagure-worker
journalctl -u pagure-worker -n 20 --no-pager
实测输出(is-active 两次各一行):
active
active
Web 访问日志样例(tail /var/log/pagure/access_web.log,实测节选):
- - [28/Oct/2026:00:41:16 +0000] "GET /api/0/public-demo/git/branches HTTP/1.0" 200 58 "-" "curl/7.81.0"
- - [28/Oct/2026:00:44:39 +0000] "GET /api/0/public-demo/git/branches HTTP/1.0" 200 70 "-" "curl/7.81.0"
应用错误日志在 /var/log/pagure/error_web.log(Gunicorn error-logfile 落点)。worker 的任务日志(gitolite 编译、邮件发送等)只进 journald,journalctl -u pagure-worker 是排障第一入口(实测案例见 6.1)。
4.10 备份与恢复
数据库备份(含 54 张元数据表)与 git 仓库备份(实测命令):
mkdir -p /srv/backup
su postgres -c "pg_dump pagure" | gzip > /srv/backup/pagure-db-$(date +%F).sql.gz
tar -czf /srv/backup/pagure-git-$(date +%F).tar.gz -C /srv/git repositories gitolite-admin .gitolite.rc
ls -lh /srv/backup/
实测输出:
total 52K
-rw-r--r-- 1 root root 11K Oct 28 00:46 pagure-db.sql.gz
-rw-r--r-- 1 root root 37K Oct 28 00:46 pagure-git.tar.gz
备份完整性校验(实测):
gzip -t /srv/backup/pagure-db.sql.gz && echo DB_DUMP_OK
tar -tzf /srv/backup/pagure-git.tar.gz | head -3
实测输出:
DB_DUMP_OK
repositories/
repositories/gitolite-admin.git/
恢复流程(预期结果,未在实库演练删除后恢复):先 su postgres -c "psql -c 'CREATE DATABASE pagure OWNER pagure;'",再 gunzip -c /srv/backup/pagure-db-<日期>.sql.gz | su postgres -c "psql -d pagure" 导入元数据,最后解包 git 备份回 /srv/git 并 chown -R git:git /srv/git,重启两个服务单元后用 curl -s http://localhost/api/0/version 验证。
4.11 REST API 令牌调用
用 4.1 创建的管理令牌调用 API(Authorization: token <令牌> 头)。实测创建一条工单:
curl -s -X POST "http://localhost/api/0/public-demo/new_issue" \
-H "Authorization: token TC9UXJSDNL9Q5Z99K499N23OTD1XQSVNY2GW5WB1RBRC1XAKOXCXXFL54MQ33WBY" \
-H "Content-Type: application/json" \
-d '{"title":"CLI 实测 issue","issue_content":"Created via REST API with admin token"}'
实测输出(输出节选(实测首尾),完整 JSON 较长):
{"issue":{"assignee":null,"blocks":[],"close_status":null,"closed_at":null,"closed_by":null,"comments":[],"content":"Created via REST API with admin token","custom_fields":[],"date_created":"<bound method Arrow.timestamp of <Arrow [2026-10-28T00:47:17.460093+00:00]>>","depends":[],"full_url":"http:/
匿名可读的分支查询无需令牌(实测):
curl -s http://localhost/api/0/public-demo/git/branches
{"branches":["feature-x","main"],"default":"main","total_branches":2}
4.12 gitolite 常用命令
手工触发 gitolite 编译(等效 refresh-gitolite 的编译段,以 git 用户执行):
su - git -c "HOME=/srv/git gitolite compile && echo COMPILE_OK"
实测输出:
COMPILE_OK
SSH 通道与授权自检(列出当前账号被授权的全部仓库):
ssh -i ~/.ssh/pagure_admin git@localhost info
实测输出:
hello admin, this is git@pagure running gitolite3 3.6.12-1 (Debian) on git 2.34.1
R W admin/demo-project
R W docs/admin/demo-project
R W docs/public-demo
R W public-demo
R W requests/admin/demo-project
R W requests/public-demo
R W tickets/admin/demo-project
R W tickets/public-demo
五、注意事项
- 执行身份:会触发 gitolite 编译的命令(
refresh-gitolite)与直写 git 仓库的命令(create-branch、set-default-branch)以 git 用户运行最安全;root 运行会把authorized_keys、仓库文件写成 root 属主,引发后续 worker 报错(见 6.1)。 - 交互确认:
refresh-gitolite要确认两次、refresh-ssh/clear-hook-token/update-acls/create-branch各一次;脚本化时用printf "y\ny\n" |管道应答。 - 令牌安全:
admin-token create的令牌明文仅显示一次;clear-hook-token会打断全部 WebHook。 --ro与 watch 状态值大小写敏感:--ro只认小写true/false,watch 只认-1,0,1,2,3。get-watch/update-watch参数顺序是<项目> <用户>,与直觉相反,写反会报No user "<项目名>" found(实测)。
六、常用命令速查
日常运维按「高频 → 低频」排序的命令速查表(执行身份栏 P=root 可执行、G=建议 git 用户):
| 目的 | 命令(PA=/opt/pagure/venv/bin/pagure-admin) | 身份 |
|---|---|---|
| 查服务状态 | systemctl is-active pagure-web / is-active pagure-worker | P |
| 看 worker 日志 | journalctl -u pagure-worker -n 20 --no-pager | P |
| 列管理员令牌 | PA admin-token list | P |
| 创建组 | PA new-group <组> <用户> --display <显示名> | P |
| 列组 | PA list-groups | P |
| 查关注状态 | PA get-watch <项目> <用户> | P |
| 项目只读 | PA read-only <项目> [--ro true|false] | P |
| 重建 gitolite ACL | PA refresh-gitolite(两次确认) | G |
| 重写用户公钥 | 4.5 节 app_context 变通命令 | P |
| 重置 hook token | PA clear-hook-token(打断全部 WebHook) | P |
| 同步 ACL 定义 | PA update-acls | P |
| 建分支 | PA create-branch <项目> --from-branch <源> <新分支> <操作者> | G |
| 设默认分支 | PA set-default-branch <项目> <分支> | G |
| 数据库备份 | su postgres -c "pg_dump pagure" | gzip > <文件> | P |
| 仓库备份 | tar -czf <文件> -C /srv/git repositories gitolite-admin .gitolite.rc | P |
| SSH 授权自检 | ssh -i ~/.ssh/pagure_admin git@localhost info | P |
| 手工编译 gitolite | su - git -c "HOME=/srv/git gitolite compile" | G |
速查表解读:日常巡检用前两行加 API 探活(curl -s http://localhost/api/0/version);变更类操作集中在 gitolite/分支三行,务必按身份栏执行;备份两行建议纳入 cron,文件名带日期(4.10 节实测形态)。
七、常见问题
7.1 worker 报 authorized_keys Permission denied
现象:journalctl -u pagure-worker 实测出现:
Oct 28 00:46:12 pagure celery[8032]: raise pagure.exceptions.PagureException(error_msg)
Oct 28 00:46:12 pagure celery[8032]: pagure.exceptions.PagureException: The command "HOME=/srv/git gitolite compile && HOME=/srv/git gitolite trigger POST_COMPILE" failed with
Oct 28 00:46:12 pagure celery[8032]: out: "b''
Oct 28 00:46:12 pagure celery[8032]: err:"b'FATAL: open /srv/git/.ssh/authorized_keys failed: Permission denied\n\n'"
定位与解决:stat -c '%U:%G %a' /srv/git/.ssh/authorized_keys 发现属主是 root(此前以 root 跑过 refresh-gitolite)。修复:
chown git:git /srv/git/.ssh/authorized_keys
chmod 600 /srv/git/.ssh/authorized_keys
su - git -c "HOME=/srv/git gitolite compile && echo COMPILE_OK"
实测输出:
COMPILE_OK
7.2 create-branch 报 Can't locate Gitolite/Hooks/Update.pm
现象:pagure-admin create-branch 以 root 执行时实测报:
Empty compile time value given to use lib at hooks/update line 6.
Can't locate Gitolite/Hooks/Update.pm in @INC (you may need to install the Gitolite::Hooks::Update module) ...
error: hook declined to update refs/heads/feature-x
原因:gitolite 的 update 钩子依赖环境变量 GL_LIBDIR(仅经 gitolite-shell 网关的 SSH 推送才会注入);create-branch 内部直推仓库绕过了网关,use lib $ENV{GL_LIBDIR} 拿到空值。
解决:给钩子加 Debian 库路径兜底(实测后 create-branch 返回 Branch created):
sed -i "s|use lib \$ENV{GL_LIBDIR};|use lib \$ENV{GL_LIBDIR} \|\| '/usr/share/gitolite3/lib';|" \
/srv/git/gitolite-admin/hooks/common/update
7.3 refresh-ssh 报 Working outside of application context
现象与等价变通见 4.5 节:5.14.1 的 pagure-admin refresh-ssh 缺应用上下文支撑,用 create_app().app_context() 包装 generate_user_key_files() 实测可完成同等操作。
7.4 以 root 运行仓库类子命令报属主错误
现象(实测):
_pygit2.GitError: /srv/git/repositories/public-demo.git: repository path '/srv/git/repositories/public-demo.git/' is not owned by current user
解决:切 git 用户执行(su - git -c "PAGURE_CONFIG=/etc/pagure/pagure.cfg /opt/pagure/venv/bin/pagure-admin ..."),仅数据库类子命令(admin-token、list-groups 等)不受此限制。
7.5 SSH 推送报 pre-receive hook declined
现象:git push 报 remote: /usr/bin/env: 'python': No such file or directory 与 ! [remote rejected] main -> main (pre-receive hook declined)。
原因与解决:Pagure 仓库钩子 hookrunner 的 shebang 是 #!/usr/bin/env python,虚拟环境无该名字的解释器;把 shebang 改为虚拟环境绝对路径即可(完整排障过程与修复后实测输出见《Pagure 5.14.1 Ubuntu 22.04 安装指南》8.3 节)。
七、参考链接
- 管理命令源码(子命令定义与交互逻辑):
/opt/pagure/pagure/cli/admin.py - 官方文档:工具与部署说明(源码内 doc/install.rst):https://pagure.io/pagure/blob/master/f/doc/install.rst
- REST API 说明(实例内置于
/api/0/各端点返回):https://pagure.io/pagure/blob/master/f/doc/api - 本文取证基线:Pagure 5.14.1,2026-10-28 实测(Ubuntu 22.04.5 LTS 单机实例)
- 延伸阅读:《Pagure 5.14.1 Ubuntu 22.04 安装指南》、《Pagure 5.14.1 配置参数详解》、《Pagure 介绍与选型指南》