owned this note
owned this note
Published
Linked with GitHub
In the [previous article](https://vanillaos.org/2023/03/07/vanilla-os-2.0-orchid-initial-work.html), we announced the development of Vanilla OS 2.0 to change the base from Ubuntu to Debian.
We've documented the changes we've done since that post, and the challenges.
The first thing we did was to create a copy of Debian Sid's repositories to make our own modifications and freeze them. We used [Aptly](https://www.aptly.info) to generate a mirror that includes the main and non-free components to guarantee that users have access to proprietary drivers in a single repository. We've thoroughly tested the repositories to make sure that they work properly and was able to handle under heavy load.
We also worked on OEM changes in the first setup and the installer. We moved user-related configurations, such as user creation, from the installer to the first setup, to let the user handle user creation. This means that manufacturers won't need to create new credentials for the user anymore. Another important change was to create GNOME sessions dedicated to the installer and the first setup. They are mandated and restricted GNOME environment, preventing the user from exiting the system with unconfigured states.
One of the big challenges with Vanilla OS 2.0 was to rebase the system on an OCI image structure with distinst, a choice we made to improve reproducibility and reliability. The images are built by a remote infrastructure and distributed to the user as OCI images. The first problem we encountered was incompatibility with our previous model: squashfs. We reconsidered this decision and created our own tool called Albius to address this issue.
Albius is the Vanilla OS installation backend, entirely written in Go. It is a utility to download, extract and configure an OCI image for the system root. The project is led by Mateus B. Melchiades, who designs, develops and tests the majority of the utility. Last time, we promised to add disk encryption, and as such, Albius supports LUKS2!
Since Albius and ABRoot v2 share a lot of code, we created a new library named Prometheus, which serves as the engine for containers. Prometheus uses the libraries that are used in Podman, Docker and Buildah to check the status of images, pull images from container registries, build images, and to easily integrate with our container registry.
When we developed ABRoot, we believed that it would be easy to update it to support the new structure, but as time went by, we realized that a rewrite was inevitable, as v1 was handled by the package manager, but v2 handled it completely differently. The differences should be noticeable right from the start, as the update is verified by comparing the digests of the current image with the most recent image in the registry. If these two images do not match, then only the data that differ will be downloaded (also known as delta updates), extracted in a transactional folder, GRUB will be updated and the old root filesystem will be swapped with the new root.
> Many challenges followed in ABRoot v2, such as removing the "abroot shell" and "abroot exec" command created a problem, how to install extra drivers in the system? Exec and Shell were removed because it just wouldn't be possible to open a shell in the root during the transactional phase, so we needed a way for users to embed instructions into that process. For this reason we decided to create a sort of package manager internal to ABRoot, namely the "abroot pkg add|remove|list|apply" command. This is not a real package manager but more of an orchestrator, the packages are not applied autonomously but only upon explicit request. For example, let's say you want to install the nvidia drivers, in ABRoot v1 the command was "abroot exec apt install nvidia-drivers" and this would have immediately created a new transaction and proceeded to change the second root. In ABRoot v2 instead the packages are registered internally and wait to be applied, in fact using the "abroot pkg add nvidia-drivers" command, these will not be applied immediately in the root but will wait for instruction, even after a reboot. The user can decide to remove the packages with "abroot pkg remove nvidia-drivers" or apply them with "abroot pkg apply" which will start a new transaction. But as we said the transactions in ABRoot v2 are not managed by the package manager and there is no way during the life cycle of the transaction to open a shell, so we opted for an image composition system internal to ABRoot, in fact once requested to apply packages, ABRoot will create a local image based on the latest available, adding these packages, always atomically and verified to ensure that no broken transactions are applied. Now if you're wondering what happens when a new update becomes available, well, your local image will simply be rebuilt based on that update.