#update #boot #embedded-devices #installation #linux #block-device #rauc

app caterpillar

在启动过程中检测并应用RAUC更新包

2个不稳定版本

0.2.0 2023年9月28日
0.1.0 2023年9月6日

#352 in Unix API

MIT/Apache

145KB
3K SLoC

caterpillar

caterpillar是一个用于检测和安装在附加块设备上发现的RAUC更新包的工具。RAUC是一种更新嵌入式设备固件的方法。

Caterpillar利用D-Bus

  • UDisks2 (用于枚举和(卸载)块设备)
  • RAUC (用于验证和安装更新包)
  • logind (用于安装成功后的重启)

应用程序还公开了自己的D-Bus接口。更多关于如何使用它的信息可以在交互式更新部分找到。

配置

可以使用位于/etc/caterpillar/caterpillar.toml配置文件配置caterpillar的一些行为。还可以通过所有大写的环境变量来覆盖行为,前缀为CATERPILLAR_ (例如,autorun = true -> CATERPILLAR_AUTORUN=true)。

用例

Caterpillar支持两种操作模式,非交互式和交互式,这些将在下面的部分中详细说明。

应用程序在后台运行,使用 caterpillar.service systemd 单元。其他以 root 运行的应用程序可以通过 D-Bus 与其通信。

Caterpillar 负责检测所有连接的块设备,并在它们上挂载兼容的文件系统。在每个挂载文件系统的顶层目录中,它搜索版本高于当前系统版本的兼容 RAUC 更新包,并允许安装它们。当将单个兼容包放置在可配置的覆盖目录中时,caterpillar 还能安装较低版本的包。

注意:仅支持 semver 版本比较!

更新成功后,caterpillar 将卸载所有之前挂载的设备,并可选择触发系统重启(以便进入更新后的系统)。

以下图表概述了 caterpillarraucudisks2 之间的交互。

An overview graph of the caterpillar process in a boot scenario

交互式更新

Caterpillar 提供了一个 D-Bus 接口,允许以 root 身份运行的外部应用程序与其通信。

自省

应用程序以 idle 模式启动,等待外部输入。

[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         false        emits-change
.State                  property  s         "idle"       emits-change
.Updated                property  b         false        emits-change
.UpdateFound            signal    a(sssb)   -            -

搜索更新

注意:建议订阅 UpdateFound 信号,该信号将传播找到的更新。

使用 SearchForUpdate 方法,可以请求 caterpillar 搜索兼容更新。

[root@system ~]# busctl call de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar SearchForUpdate

如果找到兼容更新,caterpillarState 属性将变为 updatefound(如果没有找到更新,则短暂地变为 noupdatefound,然后再次卸载挂载的设备并返回到 idle)。

[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE  FLAGS
.InstallUpdate          method    bb        -             -
.SearchForUpdate        method    -         -             -
.MarkedForReboot        property  b         false         emits-change
.State                  property  s         "updatefound" emits-change
.Updated                property  b         false         emits-change
.UpdateFound            signal    a(sssb)   -             -

将发出 UpdateFound 信号,提供一个长度为 1 的数组,包含有关可用更新的信息。

  • 更新文件的绝对路径
  • 当前版本
  • 新版本
  • 更新是否为覆盖(布尔值)
[root@system ~]# dbus-monitor --system "type='signal',path='/de/sleepmap/Caterpillar',interface='de.sleepmap.Caterpillar',member='UpdateFound'"
signal time=1695853835.109057 sender=:1.37 -> destination=(null destination) serial=8 path=/de/sleepmap/Caterpillar; interface=de.sleepmap.Caterpillar; member=UpdateFound
   array [
      struct {
         string "/run/media/root/bundle_disk_btrfs/update.raucb"
         string "0.0.0"
         string "1.0.0"
         boolean false
      }
   ]

安装更新

使用 InstallUpdate 方法,可以触发 caterpillar 安装(可选重启)或跳过找到的更新。

请求跳过更新而不重启(请求重启在未同时更新时没有效果),caterpillar 将卸载所有之前挂载的设备并返回到其 idle 状态(Updated 属性保持不变)。

[root@system ~]# busctl call de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar InstallUpdate bb false false
[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         false        emits-change
.State                  property  s         "idle"       emits-change
.Updated                property  b         false        emits-change
.UpdateFound            signal    a(sssb)   -            -

请求更新但不重启时,caterpillar 将更新系统,卸载所有之前挂载的设备,并返回到其 idle 状态,在成功更新后将其 Updated 属性设置为 true

[root@system ~]# busctl call de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar InstallUpdate bb true false
[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         false        emits-change
.State                  property  s         "updating"   emits-change
.Updated                property  b         false        emits-change
.UpdateFound            signal    a(sssb)   -            -
[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         false        emits-change
.State                  property  s         "idle"       emits-change
.Updated                property  b         true         emits-change
.UpdateFound            signal    a(sssb)   -            -

请求更新并重启时,caterpillar 将更新系统,卸载所有之前挂载的设备,并进入 done 状态。其 UpdatedMarkedForReboot 属性都将设置为 true

[root@system ~]# busctl call de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar InstallUpdate bb true false
[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         true         emits-change
.State                  property  s         "updating"   emits-change
.Updated                property  b         false        emits-change
.UpdateFound            signal    a(sssb)   -            -
[root@system ~]# busctl introspect de.sleepmap.Caterpillar /de/sleepmap/Caterpillar de.sleepmap.Caterpillar
NAME                    TYPE      SIGNATURE RESULT/VALUE FLAGS
.InstallUpdate          method    bb        -            -
.SearchForUpdate        method    -         -            -
.MarkedForReboot        property  b         true         emits-change
.State                  property  s         "done"       emits-change
.Updated                property  b         true         emits-change
.UpdateFound            signal    a(sssb)   -            -

引导过程中的非交互式更新

Caterpillar 可以配置为在首次运行时以非交互方式运行,使用 autorun 配置选项。在此模式下,应用程序将自动(无需用户输入)

  • 检测所有块设备并挂载兼容的文件系统
  • 搜索和选择一个兼容的更新包
    • 如果在挂载点中找到包含单个更新包的顶级覆盖目录
    • 如果挂载点的顶级目录中存在多个更新包,则选择版本最高的一个
  • 安装所选的更新包
  • 重启

构建中

Caterpillar是用Rust编写的,并使用cargo构建

cargo build --frozen --release --all-features

测试

可以使用以下方式执行单元测试

cargo test -- --skip integration

注意:集成测试设置需要相当大的空间(约10-20 GiB),并且只能串行运行(耗时较长)。

cargo test integration

集成测试需要在测试系统上提供以下工具

许可证

所有代码贡献都根据Apache-2.0MIT条款双许可。有关许可的更多信息,请参阅贡献指南。

资助

本项目的实施得到了Nonlinear Labs GmbH的资助。

依赖项

~18–31MB
~487K SLoC