外观
omv-rpc 与 JSON-RPC 接口
Web 界面上的每一个按钮背后,都是对 OMV 后台的一次 RPC 调用。命令行工具 omv-rpc 走的是同一条通道。读完这一篇,你能看懂界面在调用什么,用 omv-rpc 查询磁盘、文件系统、服务和配置,并且知道调用修改类方法时要遵守的流程。
开始之前
- 命令在 OMV 的 shell(root 身份)里执行。
- 本文只示范只读调用。修改配置、批量操作和脚本化的完整做法见 用 omv-rpc 写自动化脚本。
- 示例里用
jq整理输出,OMV 自带它。 - RPC 是 OMV 的内部接口,不是承诺稳定的公开 API。服务、方法和返回字段会随版本变化,脚本在 OMV 升级后要重新验证。
RPC 在哪一层
text
浏览器(Angular 前端)
│ POST /rpc.php,JSON 请求
▼
nginx → php-fpm(rpc.php)
│ Session 等少数服务在这里处理
│ 其余请求通过 Unix socket 转发
▼
omv-engined(RPC 守护进程) ←── omv-rpc(命令行,直连这个 socket)
│
▼
配置数据库、系统命令、Salt 部署要点有三个:
- 界面和
omv-rpc最终都调用omv-engined里的同一批服务,所以界面能做的事,omv-rpc基本都能做。 - 登录、退出、会话验证(
Session服务)由rpc.php在 php-fpm 里处理,不经过omv-engined,omv-rpc调不到。 omv-engined的 socket 是/var/lib/openmediavault/engined.sock,权限0770,属组openmediavault-engined,所以只有 root 和这个组的成员能用omv-rpc。
请求与响应
浏览器发给 rpc.php 的请求
请求体是一段 JSON,包含四个字段:
| 字段 | 含义 |
|---|---|
service | 服务名,例如 FileSystemMgmt |
method | 方法名,例如 enumerateMountedFilesystems |
params | 方法参数,一个 JSON 对象,没有参数时是空对象 |
options | 可选,目前只有 updatelastaccess,设为 false 时这次调用不会刷新会话的最后访问时间(界面里自动轮询的请求用它) |
响应也是 JSON:
json
{"response": <方法的返回值>, "error": null}出错时 response 为 null,error 里有 code、message 和 trace。
omv-rpc 的用法
text
omv-rpc [选项] <服务> <方法> [参数]
选项:
-u, --user 以哪个用户的身份调用,默认是 admin
-h, --help 帮助- 参数是一段 JSON 字符串,用单引号包起来,避免 shell 吞掉里面的双引号。没有参数的方法可以省略这一项。
- 成功时,
omv-rpc把方法的返回值(不含外层的response包装)以 JSON 打印到标准输出,退出码为 0。 - 失败时,把完整的错误对象以 JSON 打印到标准错误,退出码为 1。
在浏览器里看界面调用了什么 RPC
想知道某个按钮对应哪个 RPC,最快的办法是看浏览器的开发者工具:
- 在 OMV 页面按 F12 打开开发者工具,切到网络(Network)标签。
- 在过滤框里输入
rpc.php,然后在界面上操作一次。 - 点开请求,看载荷(Payload)里的
service、method、params,以及响应(Response)里的返回值。
例如打开 存储器 → 文件系统(Storage → File Systems)页面,会看到 FileSystemMgmt 服务的 getListBg 调用;点击卸载,会看到 umountByDir。
不要把登录请求发给别人
登录时的请求(Session 服务的 login)里包含明文用户名和密码。给别人看抓包或导出 HAR 文件之前,先删除这类请求。也不要用脚本从外部直接调用 rpc.php 来做自动化,会话和 Cookie 的处理都很脆弱,在 OMV 本机用 omv-rpc 更可靠。
服务与方法
下面是核心包里主要的 RPC 服务。插件会在同一个目录里加入自己的服务,例如 Compose 插件的 Compose。
| 服务 | 做什么 | 一些方法 |
|---|---|---|
Config | 配置数据库与「应用」 | isDirty、applyChanges、revertChanges、get、set、delete |
System | 系统信息与电源 | getInformation、getTimeSettings、setTimeSettings、reboot、shutdown |
Services | 各服务的启用与运行状态 | getStatus |
DiskMgmt | 物理磁盘 | enumerateDevices、getHdParm、setHdParm、wipe |
FileSystemMgmt | 文件系统 | enumerateMountedFilesystems、getCandidates、create、grow、umountByDir |
ShareMgmt | 共享文件夹 | enumerateSharedFolders、set、getPrivileges、setPrivileges、快照相关 |
UserMgmt | 用户与用户组 | enumerateUsers、getUser、setUser、deleteUser、importUsers、importGroups |
SMB、NFS、SSH、Rsync、Rsyncd | 文件共享与同步服务 | getSettings、setSettings、getShareList、setShare 等 |
Smart | S.M.A.R.T. | enumerateDevices、getAttributes、getSelfTestLogs、getScheduleList |
Network、Iptables | 网络接口与防火墙 | enumerateDevices、getInterfaceList、setEthernetIface、getRules |
Apt、Plugin | 软件更新与插件 | getUpgradedList、upgrade、enumeratePlugins、install、remove |
Cron、PowerMgmt | 计划任务与电源 | getList、execute、get、set |
Notification、EmailNotification | 通知事件与邮件设置 | getList、setList、get、set、sendTestEmail |
CertificateMgmt、WebGui | 证书与 Web 界面设置 | getList、create、getSettings、setSettings |
EnvVars | 环境变量(envvars 插件用) | enumerate、getList、set、apply |
Exec | 后台任务的状态与输出 | isRunning、getOutput、stop |
服务和方法都定义在 OMV 的 shell 里,下面这些命令是只读的:
sh
# 列出所有 RPC 服务文件
ls /usr/share/openmediavault/engined/rpc/
# 看某个服务注册了哪些方法,例如 SSH
grep -o 'registerMethod("[A-Za-z]*")' /usr/share/openmediavault/engined/rpc/ssh.inc
# 看某个方法的参数定义,例如 SSH.set(参数定义的 ID 是 rpc.ssh.set)
jq '.[] | select(.id == "rpc.ssh.set")' /usr/share/openmediavault/datamodels/rpc.ssh.json参数定义是 JSON Schema,required: true 的字段必须提供。很多 set 类方法要求提供全部字段,而不是只传你想改的那个,所以要先 get、改一个字段再 set,见 用 omv-rpc 写自动化脚本。
几个约定
- 列表方法(
getList、getUserList等)需要start和limit两个参数,limit为-1表示不限制数量,sortfield、sortdir、search可选。例如{"start": 0, "limit": -1}。 enumerate开头的方法一般直接返回数组,不分页,不需要参数。- 以
Bg结尾的方法在后台运行,立即返回一个状态文件名,界面用它显示进度条;脚本里直接用不带Bg的同步版本更简单,需要轮询时用Exec服务的isRunning和getOutput。 - OMV 8 起,
UserMgmt的enumerateUsers等方法默认只返回用户的基本信息,加上参数{"detail": "full"}才返回完整信息。这是官方更新记录里提到的一次 API 变化,说明接口会变。
身份与权限
omv-rpc 以谁的身份调用,由 -u 决定:
- 用户名是
admin(默认)时,以管理员身份调用,所有方法都可用。 - 其他任何用户名都按普通用户调用,只能用开放给普通用户的方法(比如修改自己的密码)。注意这和 Web 登录不同,Web 界面里
openmediavault-admin组的所有成员都是管理员,但omv-rpc只认admin这个名字。
只读调用示例
sh
# 版本、内核、运行时间,以及有没有待应用的更改、待升级的软件包
omv-rpc System getInformation \
| jq '{version, kernel, uptime, configDirty, dirtyModules, rebootRequired, availablePkgUpdates}'
# 各服务是否启用、是否在运行
omv-rpc Services getStatus | jq -r '.data[] | [.name, .enabled, .running] | @tsv'
# 物理磁盘:设备、型号、序列号、容量、电源状态、温度
omv-rpc DiskMgmt enumerateDevices \
| jq -r '.[] | [.canonicaldevicefile, .model, .serialnumber, .size, .powermode, .temperature] | @tsv'
# 已挂载的文件系统(不含系统盘)
omv-rpc FileSystemMgmt enumerateMountedFilesystems '{"includeroot": false}' \
| jq -r '.[] | [.devicefile, .type, .mountpoint, .used, .available] | @tsv'
# 有没有待应用的配置更改?返回 true 或 false
omv-rpc Config isDirty '{"modules": []}'
# 按数据模型 ID 读取配置对象,效果和 omv-confdbadm read 一样
omv-rpc Config get '{"id": "conf.service.ssh"}'DiskMgmt.enumerateDevices 的输出在操作磁盘之前很有用:用型号和序列号核对目标盘,比只看 /dev/sdX 可靠得多。
修改配置:只说流程
修改类的 RPC 会改动系统
set、delete、create、wipe、reboot 这类方法没有「撤销」。动手前确认有备份,并先在测试机上验证。完整示例见 用 omv-rpc 写自动化脚本。
通过 RPC 修改配置,和在界面里点保存是同一回事,所以流程也一样:
- 调用对应的服务方法(如
SSH.set)。后台会校验参数、写进数据库,并把相关模块标记为「待应用」。 - 调用
Config.applyChanges(参数{"modules": [], "force": false}),部署所有待应用模块,作用等同于点击应用。
尽量用服务自己的方法,而不是通用的 Config.set。Config.set 只改数据库,不会做创建系统用户、创建目录这类附带动作。
检查结果
下面几条是只读的,能得到合理结果说明 RPC 通道正常:
sh
omv-rpc System noop # 随机返回一句《沙丘》台词,用来测试连通性
omv-rpc System getInformation | jq .version常见问题
Failed to connect to socket。 omv-engined 没有运行,见 502 Bad Gateway 与 Failed to connect to socket。
报参数校验错误。 对照上面的 jq 命令看这个方法的参数定义,required 字段是否都给了,类型是否对(数字不要加引号,布尔值是 true 或 false)。
用 -u 指定了另一个管理员账户,却提示没有权限。 omv-rpc 只把 admin 当作管理员,改用默认的 admin。
参考资料
- 官方文档:omv-rpc
- 源码:
engined/rpc、datamodels、rpc.php