Xandikos 0.4.10 常用 CLI 命令与工具详解
Xandikos 0.4.10 CLI 全面实测:serve/create-collection/import-imip/multi-user 四子命令与 xandikos-milter 独立入口(任务书 mkcol/import/export 子命令不存在之纠偏)、create-collection 热生效与嵌套路径、import-imip 邮件格式红线与 auto-apply 双落盘、基于 Git 仓库的数据管理/备份(git clone、bundle)/恢复(历史点取回、克隆重建服务器)逐条实测。
Xandikos 0.4.10 常用 CLI 命令与工具详解
0.4.x 完成 CLI 子命令化重构。纠偏:早期资料/任务口径中的
xandikos mkcol、xandikos import、xandikos export、xandikos dav子命令在 0.4.10 中均不存在,实际子命令面为{serve, create-collection, import-imip, multi-user, help},另有独立入口xandikos-milter。本文全部命令为 2026-11-02 实测(取证:/opt/data/quzuo/tmp/xandikos/evidence.md§2/5/6/9)。
一、子命令总览
$ xandikos --help
usage: xandikos [-h] [--version] {serve,create-collection,import-imip,multi-user,help} ...
serve Run a Xandikos server
create-collection Create a calendar or address book collection
import-imip Import an iMIP email message from stdin into a schedule inbox
multi-user Run a multi-user Xandikos server (experimental)
pipx 安装同时提供 xandikos-milter(Postfix/Sendmail SMFI milter 独立进程)。
二、serve:服务器主命令
参数全量分组详解见《配置参数详解》篇;日常三条:
xandikos serve -d /srv/xandikos/data --defaults -l 0.0.0.0 -p 8080 # 首次
xandikos serve -d /srv/xandikos/data -l /run/xandikos.sock --socket-mode 660 --socket-group www-data # 反代+unix socket
xandikos serve -d /srv/xandikos/data --dump-dav-xml --debug # 排障
三、create-collection:离线建集合(实测)
$ xandikos create-collection -d data --type calendar --name cli-cal \
--displayname "CLI Calendar" --color "#FF0000"
Successfully created calendar collection: cli-cal
要点(全部实测):
- 路径语义:
--name是相对-d根的路径组件。只写cli-cal落在根级(URL/cli-cal/,不在任何 principal 下);要建进日历家目录需写嵌套名:--name user/calendars/cli-cal2; - 热生效:对运行中的服务器,新建集合立即可见(PROPFIND
/user/calendars/cli-cal2/→ 207,无需重启); - 元数据入 Git:创建即产生 commit
Set collection type./Set display name.;.xandikosINI 文件记录 type/displayname/color; --type仅calendar|addressbook两种(schedule inbox/outbox 由--defaults或 principal 逻辑创建);- 后续 PUT 事件正常(实测 201 并生成
Added Xandikos 取证事件commit)。
等价于 MKCALENDAR 的离线版:客户端场景用 curl MKCALENDAR,运维脚本场景用本命令。
四、import-imip:邮件入日程(实测,格式红线)
用法:stdin 喂完整邮件(非裸 iCalendar)。
$ xandikos import-imip -d data --principal /user/ --autocreate < invite.eml
Inbox auto-apply: created imip-20261102-001@xandikos-test in /user/calendars/calendar for REQUEST
Imported iMIP REQUEST message <imip-20261102-001@example.com> ('Invitation: ...') into /user/inbox/376e61a9-....ics.
实测红线与行为:
- 邮件必须含
text/calendar部件:裸 VCALENDAR 或Content-Type: text/itip均被拒:Invalid iMIP payload ...: Message does not contain a text/calendar part;正确写法Content-Type: text/calendar; method=REQUEST+From/To/Message-ID头; - auto-apply 双落盘:REQUEST 邀请自动写入 principal 默认日历(新事件文件 + commit
Added iMIP schedule invitation),原始消息同时归档进 schedule inbox 集合(UUID 文件名 + 独立 commit); - 三种投递目标模式:本地
-d DIRECTORY(本文实测);远程--server-url(POST 到 schedule-inbox URL,配--username/--password-fileBasic 认证)或--principal-url(自动发现 schedule-inbox-URL);--unix-socket走本机 socket; - Postfix 管道集成:
.forward/Sieve 把日程邮件 pipe 给本命令,或长期监听用serve --imip-listen unix:/sockets/imip.sock(LMTP)。
五、xandikos-milter:milter 独立进程
usage: xandikos-milter [--listen unix:/sockets/milter.sock|host:port]
[--listen-mode 660] [--listen-group postfix]
(--lmtp-socket PATH | --server-url URL [--username U --password-file F] [--unix-socket S])
Postfix 侧 smtpd_milters=unix:/sockets/milter.sock 即把入站 iMIP 邮件实时导入 schedule inbox(transport 二选一:LMTP socket 对接 serve --imip-listen,或直接 POST 到 HTTP 服务)。等价能力也可用 serve --milter-listen 进程内开启,免第二进程。
六、multi-user:实验性多用户服务器
$ xandikos multi-user -d mu-data --defaults -l 0.0.0.0 -p 8170
WARNING:root:Multi-user mode is experimental, may not be stable and not yet provide sufficient isolation between users. Use with caution.
实测:根页 200;未认证 PROPFIND 返回 <unauthenticated/> principal;配 --htpasswd 后按用户隔离 principal(路径模板 --principal-path-prefix/suffix)。结论同配置篇:生产多用户勿押注。
七、Git 仓库数据管理(核心运维面)
每个集合目录就是标准 Git 仓库,git CLI 直接可用(实测 dulwich 写的仓库与官方 git 完全互操作):
# 审计:谁在何时改了什么(含 User-Agent)
$ git -C data/user/calendars/work log --oneline
c2e20c1 Delete Second event
e73b51c Added Second event
b84ec57 Added Xandikos 取证事件
9c62b48 Set description.
3927847 Set display name.
c54b657 Set collection type.
# 看单次变更 diff
$ git -C data/user/calendars/work show b84ec57 --stat
# 找回被 DELETE 的事件(时光机)
$ git -C data/user/calendars/work show HEAD~1:evt-20261101-002.ics
BEGIN:VCALENDAR
...
SUMMARY:Second event
- 误删恢复后重新 PUT 回服务器即成为新 HEAD 条目(历史不冲突);
- etag=blob SHA、ctag=tree id:
git cat-file与 DAV 响应可互相印证; - commit 作者=运行账号 Git 身份,部署前显式配
user.name/user.email; - 原生 git hooks(post-commit 推镜像仓等)可用,见配置篇第九节。
八、备份与恢复实测
8.1 备份三档
# 档一:整站目录快照(含全部 .git 历史)
tar czf xandikos-backup.tgz -C /srv/xandikos data
# 档二:单集合 git clone(实测)
$ git clone --quiet data/user/calendars/work backup/work-repo
$ git -C backup/work-repo log --oneline | head -3
c2e20c1 Delete Second event
e73b51c Added Second event
b84ec57 Added Xandikos 取证事件
# 档三:git bundle(单文件增量,适合异地)
git -C data/user/calendars/work bundle create work.bundle --all
8.2 恢复闭环(实测逐字)
$ mkdir -p restore/user/calendars
$ cp -r backup/work-repo restore/user/calendars/work
$ xandikos serve -d restore -p 8171 &
$ curl -s http://127.0.0.1:8171/user/calendars/work/evt-20261101-001.ics | grep SUMMARY
SUMMARY:Xandikos 取证事件
$ curl -s -X REPORT -H "Depth: 1" ... http://127.0.0.1:8171/user/calendars/work/
<ns0:getetag>"85f5cc45404b76bbc358a383fdfa46c93adb9d1f"</ns0:getetag>
克隆仓库直接作为新数据根起服,事件可读、ETag 与原实例逐字节一致(85f5cc45...),无需任何导入步骤。整站恢复=解 tar 后原样起服。
8.3 迁移注意
- 集合仓库间不能跨集合 git merge(业务语义由 DAV 层管理),跨实例迁移用
git clone整仓; - Docker 与 pipx 形态数据目录可互换(实测布局一致),注意容器 uid=1000 对宿主目录属主的要求(见部署篇)。
九、常用命令速查表
| 场景 | 命令 |
|---|---|
| 首次起服 | xandikos serve -d DATA --defaults -p 8080 |
| 建日历(离线) | xandikos create-collection -d DATA --type calendar --name user/calendars/NAME --displayname "..." |
| 建地址簿 | 同上 --type addressbook |
| 导入日程邮件 | xandikos import-imip -d DATA --principal /user/ --autocreate < mail.eml |
| 审计历史 | git -C DATA/user/calendars/CAL log --oneline |
| 恢复误删 | git -C ... show <sha>:file.ics → curl PUT 回 |
| 备份 | tar czf 整站 / git clone / git bundle |
| 排障 | serve --dump-dav-xml --debug |
| 版本核对 | xandikos --version + 启动横幅依赖栈行 |