Skip to content

Commit

Permalink
docs: work on the next version
Browse files Browse the repository at this point in the history
  • Loading branch information
koehlma committed Jan 10, 2025
1 parent d67d72e commit 75b59c4
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 58 deletions.
2 changes: 1 addition & 1 deletion www/docs/bakery/devices/raspberry-pi.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Here is an overview over all the supported Raspberry Pi models:

[^1]: Requires the U-Boot boot flow.

**⚠️ Please also read the remarks for the respective boards bellow.**
**⚠️ Please also read the remarks for the respective boards below.**

Raspberry Pi OS releases based on Debian Bullseye and Bookworm are supported.

Expand Down
23 changes: 13 additions & 10 deletions www/docs/bakery/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

_Rugix Bakery_ is a flexible, user-friendly build system for bespoke Linux distributions. It enables you to build customized variants of binary distributions, such as [Debian](https://debian.org/) and [Alpine Linux](https://alpinelinux.org/), or to build distributions entirely from source, leveraging industry standards like the [Yocto Project](https://www.yoctoproject.org/). While inherently flexible and not tied to any specific distribution, Rugix Bakery ships with ready-to-use integrations for Debian, Alpine Linux, Raspberry Pi OS, and the Yocto Project's Poky reference distribution.

Typically, Rugix Bakery is used to build _full system images_ and Rugix Ctrl _update bundles_ for OTA system updates. System images generally contain a complete Linux root filesystem, a Linux kernel, and other, additional files required for booting a system. For [supported devices](/devices), Rugix Bakery can build bootable images that are ready to be flashed onto a device out of the box. Rugix Bakery allows you to declare multiple system images and other _build artifacts_[^1], while partially sharing build configurations and outputs between them. This feature is particularly useful when building different variants of an image for different devices that share a common base.
Typically, Rugix Bakery is used to build _full system images_ and Rugix Ctrl _update bundles_ for OTA system updates. System images generally contain a complete Linux root filesystem, a Linux kernel, and other, additional files required for booting a system. For [supported devices](/devices), Rugix Bakery can build bootable images that are ready to be flashed onto a device out of the box. Rugix Bakery allows you to declare multiple system images and other _build artifacts_[^build-artifacts], while partially sharing build configurations and outputs between them. This feature is particularly useful when building different variants of an image for different devices that share a common base.

[^build-artifacts]: For example, individual filesystems, documentation, or a _software bill of materials_ (SBOM).


## Setup and Installation
Expand Down Expand Up @@ -30,14 +32,19 @@ If you run `./run-bakery help` you should get usage instructions for Rugix Baker

The shell script will also pin your project to a specific major version of Rugix Bakery thereby preventing breaking changes from breaking your build. By setting the `RUGIX_BAKERY_IMAGE` environment variable you can also pin Rugix Bakery to a specific Docker image. This adds an additional layer of protection against breaking changes and of security should the Rugix Bakery repository be compromised. For production setups, it is therefore recommended to always pin Rugix Bakery to a specific Docker image.

Rugix Bakery currently requires the container to run in privileged mode such that `chroot` and bind mounts are available within the container. These are required to run tools inside an environment that looks like the final system. In the future, we plan to leverage Linux user namespaces to isolate the build and the system from the host without requiring elevated privileges.
Rugix Bakery currently requires the container to run in privileged mode such that `chroot` and bind mounts are available within the container. These are required to run tools inside an environment that looks like the final system. In the future, we plan to leverage Linux user namespaces to isolate the build and the system from the host without requiring elevated privileges.[^privileges]

[^privileges]: Existing tools use different approaches to set up an environment that looks like the final system without requiring privileges. For instance, Yocto uses a tool called [Pseudo](https://git.yoctoproject.org/pseudo/about/) (an alternative to the better-known tool [Fakeroot](https://manpages.debian.org/bookworm/pseudo/fakeroot.1.en.html)), to intercepts calls to system APIs via `LD_PRELOAD` and thereby fake a root environment. This approach has limitations, for instance, it does not work with statically-linked binaries and also does not allow starting services binding sockets to ports below 1024. Rugix Bakery strives to provide a container-like environment by using Linux namespaces and process isolation which does not suffer from the same limitations as existing approaches and thereby mimics a real system more closely.


## Build Process: High-Level Introduction

Before we get into further details, let’s first look at Rugix Bakery’s build process from a high-level perspective.

The build process revolves around two key concepts: _layers_ and _recipes_. A _layer_ consists of the _build outputs_ of a specific stage of the build process. Typically, a layer provides a root filesystem and a kernel for a system. Layers can be built on top of each other, thereby reusing and extending an existing root filesystem as well as any other build outputs that are part of the previous layer. In that regard, layers are akin to image layers in Docker.[^2] A _recipe_ describes additions and modifications to be made to a layer. A layer is then built by applying the recipes specified in the layer's build configuration, optionally using a _parent layer_ as a base.
The build process revolves around two key concepts: _layers_ and _recipes_. A _layer_ consists of the _build outputs_ of a specific stage of the build process. Typically, a layer provides a root filesystem and a kernel for a system. Layers can be built on top of each other, thereby reusing and extending an existing root filesystem as well as any other build outputs that are part of the previous layer. In that regard, layers are akin to image layers in Docker.[^yocto-layers] A _recipe_ describes additions and modifications to be made to a layer. A layer is then built by applying the recipes specified in the layer's build configuration, optionally using a _parent layer_ as a base.

[^yocto-layers]: If you are coming from Yocto, Rugix Bakery layers are distinct from Yocto layers in that they contain actual _build outputs_ while Yocto layers add or modify _build metadata and configurations_ used by the build system.


Here is a summary of the core concepts of the build process:

Expand All @@ -50,7 +57,7 @@ Here is a summary of the core concepts of the build process:
Rugix Bakery implements a build process that generates build artifacts from layers created by executing recipes.

**Example: Two Device Variants.**
Assume you have an application that you want to integrate into a Debian-based system and then deploy to two different device variants. In Rugix Bakery, you would define a layer for your application building upon a Debian parent layer. The device-specific modifications will then be realized by a layer per device variant using the application layer as a parent. Finally Rugix Bakery will generate a full system image for initial provisioning and a Rugix Ctrl update bundle for each variant, respectively. The figure bellow shows the corresponding build tree with the final build artifacts at the bottom.
Assume you have an application that you want to integrate into a Debian-based system and then deploy to two different device variants. In Rugix Bakery, you would define a layer for your application building upon a Debian parent layer. The device-specific modifications will then be realized by a layer per device variant using the application layer as a parent. Finally Rugix Bakery will generate a full system image for initial provisioning and a Rugix Ctrl update bundle for each variant, respectively. The figure below shows the corresponding build tree with the final build artifacts at the bottom.

<p>
```mermaid
Expand All @@ -75,10 +82,6 @@ If you are using Rugix Bakery with Yocto, then the entire Yocto build for a give
:::

**Building from Source.**
While Rugix Bakery can be used to build applications from source as part of the build process, its primary use case is to assemble pre-built components into a full system. It is completely fine to use Rugix Bakery as a final phase of a larger build pipeline, building binaries and other parts of your application with external tools and then injecting them into a Rugix Bakery build. While building everything from source in a coherent system like Yocto has some advantages, it also introduces a lot of complexity and overhead that may not be worthwhile for every project.[^3] Rugix Bakery's central strength lies in its ability to exploit the stability, familiarity, and the maintenance effort that goes into proven binary distributions like Debian, thereby lowering the entry barrier and required resources to build rock-solid software distributions for embedded and IoT devices, or anywhere a custom Linux OS is needed.


[^1]: For example, individual filesystems, documentation, or a _software bill of materials_ (SBOM).
[^2]: If you are coming from Yocto, Rugix Bakery layers are distinct from Yocto layers in that they contain actual _build outputs_ while Yocto layers add or modify _build metadata and configurations_ used by the build system.
[^3]: Often, reproducibility, license compliance, and fine-grained control of compile-time options are cited as reasons for using Yocto over Debian, however, (1) not only can [most Debian packages be built 100% reproducibly](https://tests.reproducible-builds.org/debian/reproducible.html) but [Debian snapshots](https://snapshot.debian.org/) dating back to 2005 also provide a way to build Debian-based systems fully reproducibly, (2) all Debian packages come with license information that can be used to generate an SBOM and ensure compliance, and (3) the exact sources for all Debian packages are available and can be used to build custom variants of these packages, e.g., with fine-tuned compile-time options. That being said there are many other good reasons for using Yocto, e.g., when you are using a device for which the manufacturer provides a board support package but no support for a binary distribution like Debian. Whether or not the advantages of Yocto are worth the added complexity and required engineering resources should be evaluated based on the requirements of a project.
While Rugix Bakery can be used to build applications from source as part of the build process, its primary use case is to assemble pre-built components into a full system. It is completely fine to use Rugix Bakery as a final phase of a larger build pipeline, building binaries and other parts of your application with external tools and then injecting them into a Rugix Bakery build. While building everything from source in a coherent system like Yocto has some advantages, it also introduces a lot of complexity and overhead that may not be worthwhile for every project.[^yocto-reasons] Rugix Bakery's central strength lies in its ability to exploit the stability, familiarity, and the maintenance effort that goes into proven binary distributions like Debian, thereby lowering the entry barrier and required resources to build rock-solid software distributions for embedded and IoT devices, or anywhere a custom Linux OS is needed.

[^yocto-reasons]: Often, reproducibility, license compliance, and fine-grained control of compile-time options are cited as reasons for using Yocto over Debian, however, (1) not only can [most Debian packages be built 100% reproducibly](https://tests.reproducible-builds.org/debian/reproducible.html) but [Debian snapshots](https://snapshot.debian.org/) dating back to 2005 also provide a way to build Debian-based systems fully reproducibly, (2) all Debian packages come with license information that can be used to generate an SBOM and ensure compliance, and (3) the exact sources for all Debian packages are available and can be used to build custom variants of these packages, e.g., with fine-tuned compile-time options. That being said there are many other good reasons for using Yocto, e.g., when you are using a device for which the manufacturer provides a board support package but no support for a binary distribution like Debian. Whether or not the advantages of Yocto are worth the added complexity and required engineering resources should be evaluated based on the requirements of a project.
8 changes: 5 additions & 3 deletions www/docs/bakery/layers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ url = "https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_
Rugix Bakery can download images and TAR archives from HTTP URLs and create layers from them. This is useful if one wants to take an existing system image as a basis, e.g., when building a customized variant of Raspberry Pi OS. In addition to HTTP URLs, file URLs starting with `file://` are also supported. These URLs are resolved relative to the project directory.

:::tip
You can use this to import a root filesystem built with an external tool, e.g., [Buildroot](https://buildroot.org/).
You can use this to import a root filesystem built with an external tool, e.g., [Buildroot](https://buildroot.org/) or [Yocto](https://www.yoctoproject.org/).
:::

Note that imported layers must not specify any recipes. Customizations are applied by using them as a parent.
Expand All @@ -92,13 +92,15 @@ Note that imported layers must not specify any recipes. Customizations are appli
Recipes may depend on other recipes and as such will pull in their dependencies automatically when specified in the `recipes` list of a layer. To avoid that, e.g., when you want to replace some recipe with a local variant, you can exclude certain recipes from a layer. To this end, you can provide a list of recipes to exclude via the `exclude` property.


## Layer Configuration
## Configuration Reference

For reference, here is the complete schema for project configuration files:
For reference, here is the complete schema for layer configuration files:

<JSONSchemaViewer schema={LayerSchema} viewerOptions={{
DescriptionComponent: ({description}) => <ReactMarkdown children={description} />
}}/>

You will find the most recent version of this schema [on GitHub](https://github.com/silitics/rugix/blob/main/schemas/rugix-bakery-layer.schema.json).


[^1]: The layer should be fully reproducible, however, Rugix Bakery does currently not support building images reproducibly. We will add this functionality in the future such that images can be reproduced bit-by-bit.
2 changes: 0 additions & 2 deletions www/docs/bakery/projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ architecture = "arm64"

The `#:schema` directive is used to specify a [JSON Schema](https://json-schema.org/) for the TOML file. Rugix Bakery comes with JSON Schemas for all its configuration files, enabling easy validation and autocompletion in modern IDEs.

#### Configuration Reference

For reference, here is the complete schema for project configuration files:

<JSONSchemaViewer schema={ProjectSchema} viewerOptions={{
Expand Down
Loading

0 comments on commit 75b59c4

Please sign in to comment.