Inside RLXOS 2.0 Source Code - Part 2

Manjeet SinghManjeet Singh
4 min read

Welcome back to our deep dive into the rlxos 2.0 source code! In Part 1, we set the stage by covering the essentials of setting up the environment, installing prerequisites, building the system, and taking it for a test drive. Now, in Part 2, we’re going to peel back the layers and reveal the magic behind the build process, focusing on the enigmatic build tool build specifically for the development of rlxos known as Ignite.

Recall the command we used to create the installer ISO:

make ELEMENT=installer/image.yml

At a glance, it seems straightforward, but under the hood, there’s a symphony of operations conducted by Ignite. Here’s a snippet from our Makefile.

all: $(IGNITE) version.yml ostree-branch.yml channel.yml
ifdef ELEMENT
    $(IGNITE) cache-path=$(CACHE_PATH) build $(ELEMENT)
endif

Let’s break down what’s this command doing under the hood but before that let me introduce to the star of the house Ignite

Ignite: The Heart of our Build Process

Ignite is the powerhouse that drives the rlxos build system. When we kick off the build process, Ignite embarks on a meticulous journey to create a binary component.

  1. Ignite starts by reading and parsing the element file specified at elements/$(ELEMENT). In our case, this is elements/installer/image.yml. This YAML file is like a recipe, detailing the ingredients (components and dependencies) and the steps required to create and specific component.

  2. Next, Ignite constructs a detailed dependency tree. Think of this as mapping out every ingredient needed, along with any sub-ingredients, to ensure nothing is missing. The YAML file outlines these dependencies, ensuring that the build includes every necessary component.

  3. Ignite then sets up a temporary root filesystem at $(CACHE_PATH)/temp/<element-id>-<hash>/. The <hash> is a unique identifier generated from a cryptographic hash of all dependencies, environment variables, and the element file data. This hash ensures build purity by guaranteeing that any change in the dependencies or environment triggers a complete rebuild of all affected components.

  4. With the root filesystem ready, Ignite uses Bubblewrap to run a containerized environment within this filesystem. Bubblewrap is a sand-boxing tool that creates an isolated environment, ensuring that the build process is consistent and free from external influences.

  5. Each YAML file includes a script: configuration. This can be written explicitly or generated at runtime using build classes, source code, or other configurations. These scripts guide Ignite on how to compile the source code or execute the necessary steps to build each component. This flexibility allows for precise control over the build process, accommodating various build requirements and conditions.

  6. Once all compilation steps are completed successfully, Ignite caches the build artifacts. These artifacts are the outputs of the build process and can be used directly or by other build processes. The cached artifacts are stored at $(CACHE_PATH)/cache/<element-id>-<version>-<hash>.pkg. The <hash> used here is the same as in the environment setup, ensuring that the cache precisely matches the required environment. This guarantees that cached artifacts are reliable and reusable.

Ensuring Purity and Bit to Bit reproducibility.

One of the standout features of Ignite is its commitment to build purity and reproducibility. The cryptographic hash system ensures that any modification in the build environment or dependencies results in a full rebuild of all dependent components. This mechanism prevents inconsistencies and guarantees a clean, reliable build every time independent on the environment.

Additional commands

In addition to its primary role in the build process, Ignite offers several other commands that enhance its functionality and streamline the workflow:

  • Status: You can use the command make status ELEMENT=<ELEMENT> to check whether an element is already cached or if it needs a rebuild. This command is incredibly useful for quickly assessing the state of your build environment without initiating a full build.

  • Filepath: The command make filepath ELEMENT=<ELEMENT> prints the filepath of the cached artifact for the specified element. This allows you to easily locate and use the cached files, facilitating integration with other tools or processes.

  • Checkout: The make checkout ELEMENT=<ELEMENT> command, which you might have already used in previous blog, is used to checkout the cached artifact to $(DESTDIR).

Conclusion

In this part of our series, we ventured deep into the intricate workings of the rlxos 2.0 build process, with Ignite at the helm. We explored how Ignite work. Understanding these steps is crucial for anyone looking to contribute to rlxos or enhance its functionality. Stay tuned for Part 3, where we’ll dive into advanced topics like customizing elements, optimizing the build process, and troubleshooting common issues. The journey through rlxos 2.0 continues to unfold, revealing more of its inner workings and the elegance of its design.

1
Subscribe to my newsletter

Read articles from Manjeet Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Manjeet Singh
Manjeet Singh