Another cycle, another planning post. This is a continuation of Planning OTA work for Jasmine Sprint 4
Last cycle was great and terrible at the same time. We made real progress on getting to know RAUC and to connect our systems at the bottom of the stack, where boot loaders live. Arguably this is the harder part as the part above RAUC where we talk to the cloud to get updates, is less constrained as we can design nearly arbitrary system. The last cycle was also the moment we explored enough to see the complete picture of the bottom layer. There’s somewhat more work to be done than we originally expected but it’s all along the same lines and along the same trajectory as before.
The most important single piece of code we got from last cycle is the boot protocol adapter. rauc: add BootProtocolAdapter - adapting SystemOTA boot to RAUC (!107) · Merge requests · OSTC / OHOS / components / SystemOTA · GitLab. This shows how to connect our logic to RAUC’s expectations for a custom boot loader backend. We now see that two elements are required: a boot loader handler and an install handler. We need the install handler to invoke
boot.Protocol.Reboot with the special flag for one-off EFI “next boot”-style support.
The boot loader hook also evolved, from a plain client poking the boot loader methods directly, to a client using a dedicated API, so that we can have the right atomicity guarantees and so that nothing in this critical part can ever race, as D-Bus activation ensures that only one instance of SystemOTA is running.
The advent of read-only images has made one more part evident. We need to either handle ASOS partitioning model explicitly inside SystemOTA, with the right partitions mounted, with the right data copied at the right time or we need to offer a hook system of our own so that the read only support programs can run at the right time. Right now I lean towards the hook system, as it provides loose coupling and makes it possible to use SystemOTA in other scenarios.
Lastly, I was thinking about RAUC bundles. I’m a bit grumpy at myself that I didn’t explore this in more detail before. I’m no longer sure we can implement direct-transfer installs, without intermediate space and I’m not sure how to handle deltas, without seriously hacking the RAUC bundle model. A bundle is a squashfs with a signature attached. Inside the squashfs there are separate images for each slot class. This is a dramatic problem, as we cannot download the bundle to a slot directly. Now we must always download the bundle to scratch space, mount it, and then copy the slot image. Deltas are even worse, as what we must compute is a delta of a bundle, not the image. Think double-squashdelta. I have some idas on what to do but for the moment I’m going to push this problem away and only look at it at the next cycle.
I would like to end this cycle with SystemOTA able to handle
rauc install bundle.img from command line, doing the right thing on a real Raspberry Pi. I’ve captured it in a re-cycled task from last cycle - Integrate sysotad with RAUC bootloader for RPi4 (#13) · Issues · OSTC / OHOS / components / SystemOTA · GitLab
On the larger front I think we need to face the challenge of read only images, their integration with LAVA and to see the work on the state operator design. I’m not sure how much that design will change or if the code will be exactly what I had in mind (go tooling at image build time, C program inside initrd) but I’m not worried about the details just yet.
Happy coding and let’s get this done!