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)/恢复(历史点取回、克隆重建服务器)逐条实测。

XandikosXandikosCalDAVCardDAVgit自托管2026/11/02

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

要点(全部实测):

  1. 路径语义:--name 是相对 -d 根的路径组件。只写 cli-cal 落在根级(URL /cli-cal/,不在任何 principal 下);要建进日历家目录需写嵌套名:--name user/calendars/cli-cal2;
  2. 热生效:对运行中的服务器,新建集合立即可见(PROPFIND /user/calendars/cli-cal2/ → 207,无需重启);
  3. 元数据入 Git:创建即产生 commit Set collection type. / Set display name.;.xandikos INI 文件记录 type/displayname/color;
  4. --type 仅 calendar|addressbook 两种(schedule inbox/outbox 由 --defaults 或 principal 逻辑创建);
  5. 后续 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-file Basic 认证)或 --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 + 启动横幅依赖栈行
Xandikos 0.4.10 常用 CLI 命令与工具详解 - Quzuo