status 与 doctor
ironflock status 显示机器上有哪些 IronFlock 组件以及它们是否在运行。ironflock doctor 检查机器能否运行设备代理程序,以及能否访问代理程序要通信的主机。请在连接机器之前,以及设备没有上线时使用它们。
这两个命令都不做任何更改,也不询问任何内容。它们可在 Linux 和 macOS 上运行,无需 root,以 root 身份运行时能读取更多内容。借助 --host,它们可以在另一台机器上运行,也可以同时在多台机器上运行(通过 SSH 管理远程机器)。在那里,当登录账户就是 root,或者可以无需密码、无需终端地使用 sudo 时,它们以 root 身份运行;否则,它们以登录账户的身份运行,不会询问,它们的提示会给出带 --host root@machine 的命令。
ironflock status
显示这台机器上的设备代理程序、Appliance 和操作系统:安装了什么、版本、服务是否在运行、设备及其项目,以及代理程序上一次自我更新。Appliance 是在现场一台机器上运行的完整 IronFlock 系统(IronFlock Appliance);对于 Appliance,该命令还会显示其 UI 的地址、许可证、各服务的健康状况,以及等待中的更新(Appliance 命令)。在 IronFlockOS 上,该命令还会显示根槽位以及需要注意的事项。
ironflock status [flags]运行平台: Linux;在 macOS 上,它显示系统,并显示未安装任何组件。Root: 不需要;少数信息需要 root。询问: 无。
该命令没有自己的标志。它接受全局标志(全局标志)。
没有 root 时,有些信息无法读取:设备及其项目,因为代理程序的 .flock 只有 root 可读;在 Appliance 上,由于其文件夹 /opt/ironflock 属于 root,还包括各个版本、Appliance 的 URL、其许可证和更新,以及代理程序的更新。Appliance 各服务的健康状况需要 root 或 docker 组。它们显示为 unknown (needs root),JSON 字段 needs_root 会列出它们,sudo ironflock status 可以读取它们。
# 以您的登录账户读取这台机器上的内容
ironflock status
# 以 JSON 形式输出全部内容
sudo ironflock status --json
# 通过 SSH 查看另一台机器的状态
ironflock --host pi@device-17 status文本输出
$ ironflock status
Agent: installed in /opt/ironflock/device-agent
Version: 1.6.9
Service: running (ironflock-device-agent.service)
Connection: unknown (this agent does not report it)
Device: unknown (needs root)
Swarm: unknown (needs root)
Update: none pending
Appliance: not installed
System: Debian GNU/Linux 12 (bookworm)
Run 'sudo ironflock status' to read what needs root.Swarm 是设备所属的项目。对于正在运行的代理程序,Connection 为 unknown:迄今发布的代理程序不会在机器上报告其连接状态。
在 IronFlockOS 上
系统这一行显示镜像及其两个根槽位(根槽位与数据分区):
System: IronFlockOS 0.13.0 (amd64-efi, base)
Image: ironflockos-amd64-efi-base (build 20261105T120000Z-g1a2b3c4)
Slot A: inactive, good
Slot B: booted, good, 0.13.0 installed 2026-11-05T14:00:00Z
Next boot: slot BIronFlockOS 设备的代理程序是镜像在设备注册时设置的那个,位于 /data 上的 /opt/ironflock/device-agent 中,显示方式与其他系统上相同。尚未注册的设备没有代理程序;镜像自带一个,这一行会说明设备如何注册(下面第一行)。如果本次启动时无法挂载 /data,那么无论设备是否已注册,都看不到代理程序的文件夹,这一行会改为说明这一点(下面第二行):
Agent: not enrolled yet: the device enrolls with a .flock on its IRONFLOCKOS partition at its next start, or now with 'sudo ironflock agent configure -c <file>'
Agent: not to be seen: /data, which holds the agent and its .flock, could not be mounted (below); a .flock on the IRONFLOCKOS partition enrolls the device at its next start for as long as /data is missing在系统之下,只有当 IronFlockOS 有需要说明的情况时,才会分别显示以下各行:
| 行 | 显示条件 |
|---|---|
Last reset: | 上一次恢复出厂设置失败或已放弃。os reset 说明了记录的含义 |
Reset hold: | 有一次重置尚未结束(wait:在旧所有者的数据可能还在 /data 上时,不会采用 IRONFLOCKOS 分区上的 .flock 或 proxy.conf;copy:重置已开始擦除),或者重置已放弃,且无法删除随之而来的 .flock 和 proxy.conf,这些文件保持未使用(gave-up) |
/data: | 无法挂载 /data:设备在根槽位自己的文件夹上运行,没有 Docker 和应用 |
/apps: | /apps 不是数据分区的文件夹:应用可以运行,但会在下一次操作系统更新时丢失数据 |
Last reset: gave up after 3 attempts at 2026-11-11T09:00:00Z: the data partition is not the partition named data on the disk of the root slot; /data holds the old data; left of the old owner: the data partition, the booted root slot, the other root slot
Reset hold: wait: a reset is open; a .flock or proxy.conf on the IRONFLOCKOS partition is not taken while the old owner's data may be on /data
/data: NOT MOUNTED: the device runs on the root slot's own folders; Docker and the apps do not run, and what is written now is lost with the next update
/apps: not the data partition's folder: the apps run, but lose their data at the next OS update重置的某次尝试失败时,若重置保留状态为 wait 或 copy,记录显示为 attempt 1 of 3 failed at <time>: <reason>; /data holds the old data; the next start tries again;没有重置保留时,则显示 no request is open now。没有 root 时,显示的重置记录是运行中槽位里的副本,因为 IRONFLOCKOS 分区属于 root。
上一次 os install
在任何带有 EFI 变量的 Linux 上,如果存在 IronFlock 的 EFI 变量 IronFlockInstall,OS install: 这一行会显示上一次 ironflock os install 在其中记录的内容。每个用户都可以读取该变量。如果无法读取该变量,或者机器没有 EFI 变量,则既没有这一行,也没有警告;值无法解析时会给出警告。
System: Debian GNU/Linux 13 (trixie)
OS install: 'ironflock os install' stopped at 2026-11-11T10:00:00Z before it wrote the disk: the disk /dev/sda is not the plan's: its size changed from 64.0 GB to 32.0 GB; nothing was changed, and this system runs as before| 阶段 | 这一行显示 |
|---|---|
stopped | 它在写入磁盘之前停止、停止的原因,以及未做任何更改 |
handed-over | 在旧系统上:安装程序在重启时没有运行,未做任何更改。在 IronFlockOS 上:它写入了这个系统,但无法记录安装是如何结束的 |
writing | 它已开始写入磁盘,但没有记录写入完成 |
done | 在 IronFlockOS 上:这个系统是由 os install 安装的。在其他系统上:它将 IronFlockOS 写入了机器的某个磁盘,而正在运行的是另一个系统 |
failed | 它写入了磁盘,但写入的内容回读校验失败,并附原因 |
该记录永远不会被清除。这一行会一直保留,直到下一次 os install 替换它;在转换而来的设备上,它作为系统以这种方式安装的说明一直保留。
JSON 结果
--json 将相同的内容写成一个 JSON 对象,这里分多行显示;命令实际写在一行上。
{
"agent": {
"installed": true,
"layout": "current",
"dir": "/opt/ironflock/device-agent",
"version": "1.6.9",
"service": {"unit": "ironflock-device-agent.service", "state": "running"},
"connection": "unknown",
"device": "demo-device",
"swarm": "demo_swarm",
"update": {"state": "none"}
},
"appliance": {"installed": false},
"os": {"name": "Debian GNU/Linux 12 (bookworm)", "id": "debian", "version": "12", "ironflockos": false},
"needs_root": []
}无法读取的信息为 unknown;如果原因不是缺少 root,stderr 上会有一条警告说明原因。
| 字段 | 取值 |
|---|---|
agent.installed | 安装了代理程序时为 true。此时,且仅在此时,才有从 layout 到 update 的各字段。在 IronFlockOS 上,false 表示设备尚未注册 |
agent.unfinished_install | true:没有代理程序,但之前的一次安装在装上代理程序之前就停止了;agent install 会先撤销它。其他情况下不存在该字段 |
agent.layout | current(/opt/ironflock/device-agent)、legacy(/opt/reagent,来自早期的安装程序)、migrating(代理程序正在将旧布局迁移到当前布局) |
agent.dir | 代理程序的文件夹 |
agent.version | 代理程序的二进制文件在 -version 下给出的版本 |
agent.service | unit 和 state:running、starting、stopping、stopped、failed、not_found(systemd 不认识该单元)、unknown |
agent.connection | 代理程序未运行时为 disconnected。正在运行的代理程序的连接状态为 unknown;connected 来自会报告连接状态的代理程序 |
agent.device、agent.swarm | 设备的名称及其项目,取自 .flock。.flock 中的其他内容都不会读取 |
agent.update | 上一次自我更新。state:none(没有进行中的更新,也没有失败)、activating、probation(新版本正在运行,必须连接成功以证明自己)、rolled_back(更新失败,之前的版本重新运行,稍后会再次尝试新版本)、blocked(更新彻底失败;代理程序等待更新的发布版本)、unknown。另有 version、previous_version、reason 和 updated_at |
appliance.installed | 安装了 IronFlock Appliance(存在其单元 ironflock.service)时为 true;此时有 dir、version、channel、url、license、service、health 和 update |
appliance.data_left | 仅当未安装 Appliance、而 /opt/ironflock 中仍有其数据时出现(这些数据由不带 --purge 的 appliance remove 或中途停止的安装留下):该文件夹 |
appliance.version、appliance.channel | 其文件夹中的文件 VERSION 和 CHANNEL |
appliance.url | 其 UI 的地址:其 .env 中的 HOME_URL。.env 中存放着它的机密信息,其他内容都不会读取 |
appliance.license | 其 license.env 中有许可证密钥时为 present,没有时为 missing;其 LICENSE_KEY 不是许可证密钥(UUID)时为 invalid:Appliance 的每个命令都会忽略这样的密钥,文本输出会说明这一点。密钥永远不会显示 |
appliance.service | ironflock.service,状态取值与代理程序的相同。running 表示该单元已启动各容器,并不表示每个容器都健康 |
appliance.health | 其各服务的状况,来自 docker ps:state 为 healthy(每个服务都在运行并通过其健康检查,或者没有健康检查,或者运行过一次并以 0 结束)、starting(有健康检查尚未完成)、unhealthy、down(没有容器)、unknown;services,容器的数量;problems,每个不健康的服务及其 state(unhealthy、starting、restarting、带 exit_code 的 exited……) |
appliance.update | 等待中的更新,来自其 UI 和重试定时器所写的状态文件:state 为 none(没有请求更新,或上一次更新已完成)、running、failed(重试定时器会再次尝试)、unknown;另有 version、since 和 message。cut_short(仅限 root)指出一次中途被打断的更新所保留文件的发布版本:下一次更新会先把它们放回去。不会查询任何发布版本 |
appliance.ironflock | 仅当 Appliance 的单元每次启动时运行的 ironflock(path,即 /usr/local/bin/ironflock)缺失(state 为 missing),或者比上一次安装或更新 Appliance 的 ironflock(installed)旧(state 为 older;version 为它给出的版本)时出现。仅限 root,且仅适用于由 ironflock 安装的 Appliance。此时文本输出中有一行 ironflock:,说明应安装什么 |
os.name、os.id、os.version | /etc/os-release 中的 PRETTY_NAME、ID 和 VERSION_ID;在 Mac 上为 macOS 15.5、macos、15.5 |
os.ironflockos | 在 IronFlockOS 上为 true。此时 os.version 为其 IMAGE_VERSION,并且有下面的各字段 |
os.image、os.build | 镜像的 IMAGE_ID 和 BUILD_ID |
os.booted_slot、os.primary_slot | 系统当前运行所在的槽位,以及下次启动时使用的槽位:A 或 B |
os.slots | 根槽位:name(A)、rauc_slot(rootfs.0)、state(booted、active、inactive)、boot_status(good、bad),以及更新在该槽位安装的发布版本的 version 和 installed_at(用镜像写入的槽位没有这两项)。无法读取槽位时不存在该字段 |
os.last_reset | 上一次恢复出厂设置的记录,仅当其为 failed 或 gave-up 时存在:result、time、version、attempt、attempts_max、reason、data(old、new、none:/data 当前保存的内容),对于 gave-up 还有 left(取值为 data、booted-slot、other-slot:旧所有者的哪些内容可能还在) |
os.reset_hold | wait、copy 或 gave-up,仅在存在重置保留时出现(参见上表) |
os.data_missing | true,仅当无法挂载 /data 时出现 |
os.install | 上一次 os install 记录的内容,在任何带有 EFI 变量的 Linux 上,仅当该记录存在且可读取时出现:stage、time(RFC 3339,UTC)和 reason(用于 stopped 和 failed) |
os.apps_not_persistent | true,仅当 /apps 不是数据分区的文件夹时出现 |
needs_root | 因命令未以 root 身份运行而显示 unknown 的字段,例如 agent.device 和 agent.swarm。没有遗漏任何内容时为空 |
退出码
只要写出了概览,退出码就是 0,即使概览显示代理程序已停止、更新已回滚或槽位损坏也是如此:status 只报告,不做判断,由脚本读取各字段。无法写出概览时为 1。其他退出码参见退出码。
ironflock doctor
检查这台机器能否运行设备代理程序,以及能否访问代理程序要通信的主机:系统、systemd、Docker、可用磁盘空间、时钟、DNS、代理、下载服务器,以及设备 .flock 中列出的主机。
ironflock doctor [flags]运行平台: Linux 和 macOS。Root: 不需要;没有 root 就无法检查的检查项为 skipped,并会说明这一点。询问: 无。
| 标志 | 含义 |
|---|---|
-c、--config <file> | 设备的 .flock 文件,检查其中的主机(默认:已安装代理程序的 .flock 文件) |
agent install 在更改任何内容之前会运行这些检查(privileges 和 docker 除外),并在 system、systemd、disk_space 或 download_tree 失败时停止。
# 以您的登录账户检查这台机器
ironflock doctor
# 以 root 身份检查全部内容,输出 JSON
sudo ironflock doctor --json
# 在安装 .flock 之前检查其中的主机
ironflock doctor -c device.flock结果
每个检查项都有一个 id、一个结果和一行结论。结果不是 ok 时,会附带一条说明该怎么做的提示。
| 结果 | 含义 |
|---|---|
ok | 无需任何操作 |
warning | 可能可以工作,但效果不好 |
failed | 以机器当前的状态,代理程序无法安装或无法工作 |
skipped | 检查项无法进行检查;结论会说明原因 |
检查项
各检查项按显示顺序列出。检查项的 id 保持不变;新的检查项会获得新的 id。
| ID | 检查内容 | 不为 ok 时 |
|---|---|---|
privileges | 命令是否以 root 身份运行 | 没有 root 且有检查项无法检查时为 warning;结论会列出这些检查项。请运行 sudo ironflock doctor |
system | Linux,基于 Debian 或 Ubuntu(安装从 apt 获取软件包)或 IronFlockOS,以及下载代理程序所针对的架构 | 其他系统上为 failed,带 apt 的其他 Linux 上为 warning。agent install 在 failed 时停止 |
systemd | 系统由 systemd 运行(存在 /run/systemd/system) | 系统不由 systemd 运行时为 failed;此时 agent install 停止。系统处于 degraded 状态(有单元失败)时为 warning |
docker | Docker 在运行(docker info) | 没有 Docker 时为 ok,因为 agent install 会安装它;但在已安装代理程序的情况下为 failed。没有 root 且用户不在 docker 组中时为 skipped |
disk_space | /opt/ironflock 和 /var(Docker、apt、日志)的可用空间 | /opt 中少于 128 MiB 时为 failed:代理程序的安装或更新会在那里保存两份二进制文件。任一位置少于 2 GiB 时为 warning |
clock | 将这台机器的时钟与下载服务器响应中的 Date 比较;如果响应由缓存保存过,还会计入其 Age | 相差 10 秒以内为 ok,5 分钟以内为 warning,超过则为 failed:已签名的请求和短期令牌会被拒绝,应用的数据会带有错误的时间。时钟偏差很大时 TLS 本身就会失败:failed,并给出机器上的时间。参见时间同步 (NTP) |
dns | 这台机器自己解析的名称:它直接访问的主机,以及代理 | 某个名称无法解析。通过代理访问的主机由代理负责解析 |
proxy | 网络检查所经过的代理,以及该设置的来源:安装时的记录(/etc/ironflock/proxy.env),否则为环境变量 | 不是代理的 URL 时为 failed。没有 root 且记录在只有 root 可读的该文件中时为 skipped |
download_tree | agent install 所用下载服务器上的代理程序:其通道映射(按 agent install 的读取方式:device-agent/manifest-v2.json,否则为 manifest.json),以及该架构下生产通道的代理程序。使用 Appliance 的镜像站时,镜像站没有提供的内容会像 agent install 那样到 IronFlock 云中查找:镜像站不提供通道映射时查找整个代理程序,镜像站提供映射但没有文件时查找代理程序的文件 | 没有可下载的代理程序时为 failed,使用 Appliance 的镜像站时即镜像站和云都没有它;此时 agent install 停止。服务器错误(5xx)为 warning,镜像站没有、由云提供的代理程序同样为 warning |
device_endpoint | .flock 中的 device_endpoint_url 有响应 | 没有响应:代理程序在那里连接到 IronFlock |
docker_registry | .flock 中的 docker_registry_url 有响应(https://<host>/v2/;带端口时使用普通 HTTP,例如局域网中 Appliance 的镜像仓库) | 没有响应:设备从那里拉取其应用的镜像 |
update_server | 代理程序的更新服务器有其通道映射:.flock 中的 update_url(Appliance 的镜像站),否则为 IronFlock 云 | 没有响应或没有通道映射:代理程序从那里获取更新 |
下载服务器就是 agent install 所用的服务器:--download-base,否则是环境变量 IRONFLOCK_DL_BASE,否则是 .flock 所指定的 Appliance 的下载镜像站(其 update_url,前提是它不是 IronFlock 云的主机),镜像站没有提供的内容由云提供,再否则是 IronFlock 云(代理程序从哪里来)。设备必须能访问的主机列在网络要求中。
有无 -c 与 root
最后三项检查需要一个 .flock:-c 指定的那个,否则为已安装代理程序的 .flock。
| 以 root 身份 | 没有 root | |
|---|---|---|
不带 -c | 已安装代理程序的 .flock 中的主机 | 最后三项检查为 skipped:已安装代理程序的 .flock 只有 root 可读 |
带 -c | 所给 .flock 中的主机 | 所给 .flock 中的主机 |
没有 root 时,用户不在 docker 组中时 docker 也为 skipped,安装时记录了代理时 proxy 也为 skipped。此时,主机没有响应的网络检查同样为 skipped(对于 dns,是无法解析的名称),因为它可能通过已记录的代理得到响应。privileges 会列出每个无法检查的检查项,sudo ironflock doctor 会运行它们。
网络检查如何判定
- 只要收到 HTTP 响应,无论状态码如何,主机都算有响应。通过代理发出的普通 HTTP 请求收到 502、503 或 504 时不算响应:代理在无法访问主机时会返回这些状态码。
- TLS 拒绝的证书不算响应。唯一的例外是 Appliance 自有 CA 的证书,前提是
.flock中指定了appliance_domain:代理程序信任该证书。 - 检查经过检查项
proxy的代理,遵循下载所遵循的HTTPS_PROXY、HTTP_PROXY和NO_PROXY规则(重定向中的每个请求也是如此),并等待响应 20 秒。 - 因
NO_PROXY中的某个条目而不经过代理的主机会直接连接。如果这样连接没有响应,结论会指出该条目,例如(directly: instance-registry.ironflock.com is in NO_PROXY),提示会建议删除该条目;当该设置来自安装时的记录时,提示会给出完成删除的agent configure --no-proxy。
输出
$ sudo ironflock doctor
Download base: https://instance-registry.ironflock.com/dl
Device file: /opt/ironflock/device-agent/device-config.flock
CHECK RESULT FINDING
privileges ok runs as root
system ok Debian GNU/Linux 12 (bookworm), amd64
systemd ok systemd runs this system
docker ok Docker 27.3.1 runs
disk_space ok 50.0 GB free for /opt and /var
clock ok within 10 s of the download server's clock
dns ok resolves instance-registry.ironflock.com, cbw.ironflock.com, europe-docker.pkg.dev
proxy ok none: the connections go direct
download_tree ok https://instance-registry.ironflock.com/dl has the agent 1.6.9 for amd64
device_endpoint ok cbw.ironflock.com answers
docker_registry failed europe-docker.pkg.dev cannot be reached: no answer within 20 s
update_server ok https://instance-registry.ironflock.com/dl has the agent's updates
What to do:
docker_registry: the device pulls its apps' images from there: let this machine reach europe-docker.pkg.dev on port 443, directly or through the proxy
Failed: docker_registry.使用 .flock 中 Appliance 的镜像站时,第一行会说明这一点:
Download base: http://10.0.0.5:15002/dl (the appliance's mirror of the .flock; the IronFlock cloud for what it does not give)使用 --json 时的输出如下,这里有所缩减并分多行显示;命令实际写成一行。
{
"result": "failed",
"checks": [
{"id": "privileges", "result": "ok", "finding": "runs as root"},
{"id": "docker_registry", "result": "failed", "finding": "europe-docker.pkg.dev cannot be reached: no answer within 20 s", "hint": "the device pulls its apps' images from there: let this machine reach europe-docker.pkg.dev on port 443, directly or through the proxy"}
],
"download_base": "https://instance-registry.ironflock.com/dl",
"flock": "/opt/ironflock/device-agent/device-config.flock"
}| 字段 | 取值 |
|---|---|
result | 有检查项失败时为 failed,有检查项给出警告时为 warning,否则为 ok。跳过的检查项不会导致失败 |
checks | 各检查项,按上面的顺序:id、result、finding,以及除 ok 之外的每个结果都带有的 hint |
download_base | 所检查的下载服务器。使用 Appliance 的镜像站时,只有镜像站;检查到云中查找时,结论会指出云 |
flock | 检查了其中主机的 .flock;没有时为 null |
任何输出都不会显示机密信息:对于 .flock,检查只读取其中的主机;代理的密码显示为 xxxxx。
退出码
没有检查项失败时,退出码为 0;警告不算失败。有检查项失败时为 1:结果会说明是哪一项,之后没有错误行;使用 --json 时,stdout 中是结果,而不是错误对象。无法读取 -c 的 .flock 时,退出码为 1 并附带错误。其他退出码参见退出码。