diff --git a/www/docs/ctrl/bootstrapping.mdx b/www/docs/ctrl/bootstrapping.mdx index 94384e8a..31d7a951 100644 --- a/www/docs/ctrl/bootstrapping.mdx +++ b/www/docs/ctrl/bootstrapping.mdx @@ -20,13 +20,13 @@ The bootstrapping process can include a variety of steps such as: - Generating unique device identifiers and security certificates. - Customizing configurations to suit device-specific requirements. -When [configured to run before the init process](./state-management.md), Rugix Ctrl can also carry out bootstrapping steps. For instance, unless configured otherwise, it will grow the partition table and initialize the data partition where the persistent state lives. Rugix Ctrl's bootstrapping process is flexible and you can adapt it to your specific needs by adding bootstrapping hooks. +When [configured to run before the init system](./state-management.md), Rugix Ctrl can also carry out bootstrapping steps. For instance, unless configured otherwise, it will grow the partition table and initialize the data partition where the persistent state lives. Rugix Ctrl's bootstrapping process is flexible and you can adapt it to your specific needs by adding bootstrapping hooks. :::info The bootstrapping process is configured in the `/etc/rugix/bootstrapping.toml` configuration file. It requires a config partition to be configured and present. The config partition must contain a file `/.rugpi/bootstrap` to trigger the bootstrapping process. This file is deleted after the bootstrapping process to ensure that it does not run again.[^bootstrap-in-production] ::: -[^bootstrap-in-production]: Note that a malicious actor may be able to create this file on a production device and then trigger the bootstrapping process, even if secure boot and other security measurements are in place. This may pose a security risk. In those cases, it is recommended to use a user-defined early bootstrapping step that will check whether the device should be bootstrapped using some other source, such as one-time-programmable memory, and abort the process based on the outcome of that check. +[^bootstrap-in-production]: Note that a malicious actor may be able to create this file on a production device and then trigger the bootstrapping process, even if secure boot and other security measures are in place. This may pose a security risk. In those cases, it is recommended to use a user-defined `prepare` bootstrapping hook that will check whether the device should be bootstrapped using some other source, such as one-time-programmable memory, and abort the process based on the outcome of that check. ## System Layout @@ -39,7 +39,7 @@ The layout always affects the disk of the booted root filesystem. Unless configu Rugix Ctrl supports MBR (DOS) partition tables and GPT partition tables. Here are two example layouts: -```toml title="bootstrapping.toml" +```toml title="/etc/rugix/bootstrapping.toml" [layout] type = "mbr" partitions = [ @@ -53,7 +53,7 @@ partitions = [ ] ``` -```toml title="bootstrapping.toml" +```toml title="/etc/rugix/bootstrapping.toml" [layout] type = "gpt" partitions = [ @@ -84,7 +84,7 @@ type = "none" ``` :::note -Rugix Ctrl will only create new partitions that do not already exist and grow partitions that already exist. Furthermore, it will only create filesystems on partitions that it created itself to prevent accidental data loss. +Rugix Ctrl will only create new partitions that do not already exist and grow partitions that do already exist. Furthermore, it will only create filesystems on partitions that it created itself to prevent accidental data loss. ::: @@ -110,6 +110,10 @@ In addition, the config partition is mounted read-only (usually at `/run/rugix/m ## Configuration Reference +For reference, here is the complete schema for the bootstrapping configuration file: + -}}/> \ No newline at end of file +}}/> + +You will find the most recent version of this schema [on GitHub](https://github.com/silitics/rugix/blob/main/schemas/rugix-ctrl-bootstrapping.schema.json). \ No newline at end of file diff --git a/www/docs/ctrl/hooks.md b/www/docs/ctrl/hooks.md index 5d2cfdcd..612f11c6 100644 --- a/www/docs/ctrl/hooks.md +++ b/www/docs/ctrl/hooks.md @@ -6,9 +6,9 @@ sidebar_position: 4 _Hooks_ provide a powerful mechanism to inject custom behavior at various stages of Rugix Ctrl's operation. -Hooks are scripts that are executed at specific points in the execution flow of an operation. For instance, you can run custom scripts after an update is installed (but before the system is rebooted) or before it is committed. Hooks are organized based on the type of the operation and the point in time, referred to as _stage_, when they should run. In addition, each hook has a _rank_. You can use hooks to customize and extend various parts of Rugix Ctrl based on your needs and requirements. +Hooks are scripts that are executed at specific points in the execution of an operation. For instance, you can run custom scripts after an update is installed (but before the system is rebooted) or before it is committed. Hooks are organized based on the type of the operation and the point in time, referred to as _stage_, when they should run. In addition, each hook has a _rank_, specifying the order in which hooks run. You can use hooks to customize and extend various parts of Rugix Ctrl based on your needs and requirements. -Hooks are placed in `/etc/rugix/hooks`. Each operation gets its own directory, for instance, `/etc/rugix/hooks/bootstrap` contains [bootstrapping hooks](./bootstrapping.md) and `/etc/rugix/hooks/system-commit` contains [system commit hooks](./over-the-air-updates.md). Each directory has a subdirectory for each stage of the respective operation. For instance, `system-commit` has a `prepare` stage. The hooks of this stage will run before performing the commit. To add a hook to the respective stage, a file with the name `-` is placed in the stage directory. Importantly, hooks with a lower `` run earlier than those with a higher ``. +Hooks are placed in `/etc/rugix/hooks`. Each operation gets its own directory, for instance, `/etc/rugix/hooks/bootstrap` contains [bootstrapping hooks](./bootstrapping.md) and `/etc/rugix/hooks/system-commit` contains [system commit hooks](./over-the-air-updates.md). Each directory gets a subdirectory for each stage of the respective operation. For instance, `system-commit` has a `prepare` stage. The hooks of this stage will run before performing the commit. To add a hook to the respective stage, a file with the name `-` is placed in the stage directory. Here, `` is an integer and hooks with a lower rank run earlier than those with a higher rank. For instance, you may add the following file to add a check before committing to an update: diff --git a/www/docs/ctrl/index.md b/www/docs/ctrl/index.md index 7c558ebe..311f988c 100644 --- a/www/docs/ctrl/index.md +++ b/www/docs/ctrl/index.md @@ -4,7 +4,7 @@ _Rugix Ctrl_ is a powerful tool for robust over-the-air system updates and syste To set the stage, let's first focus on the things that could go wrong and the ideal features and properties of an update solution. -1. **Interrupted Updates:** If something interrupts the update process, such as an unplanned power outage, a partially installed update may leave the system in an inoperable state. Therefore, a robust update solution must be _transactional_, ensuring that updates are either installed completely or not at all, always leaving the system in an operational state, no matter what happens. +1. **Interrupted Updates:** If something interrupts the update process, such as an unplanned power outage, a partially installed update may leave the system in an inoperable state. Therefore, a robust update solution must be _atomic_, ensuring that updates are either installed completely or not at all, always leaving the system in an operational state, no matter what happens. 2. **Uncertain Production Environment:** While extensive testing should be done prior to deploying any updates, replicating the exact production environment and conditions can be difficult. An update that turns out to be incompatible with the particularities of the production environment under difficult to replicate conditions may leave the system in an inoperable state. Therefore, a robust update solution must have the possibility for _on-device validation and rollback_ of updates. If any problems are detected with an update on a particular device, a rollback to the previous, known-good version should be automatically triggered. @@ -12,7 +12,7 @@ To set the stage, let's first focus on the things that could go wrong and the id 4. **Cyber Attacks:** A malicious actor may try to compromise a device by installing a manipulated update. Therefore, an update solution should provide mechanisms to prevent manipulated updates from being installed. -Rugix Ctrl addresses these challenges by ensuring transactional updates, on-device validation with rollback capabilities, reliable state management, and protection against malicious updates. By utilizing Rugix Ctrl, you can rest assured that your devices remain reliable, secure, and up-to-date, **allowing you to focus on delivering value to your users**. +Rugix Ctrl addresses these challenges by ensuring atomic updates, on-device validation with rollback capabilities, reliable state management, and protection against malicious updates. By utilizing Rugix Ctrl, you can rest assured that your devices remain reliable, secure, and up-to-date, **allowing you to focus on delivering value to your users**. ## High-Level Overview diff --git a/www/docs/ctrl/over-the-air-updates.mdx b/www/docs/ctrl/over-the-air-updates.mdx index 42a44f50..223a1f62 100644 --- a/www/docs/ctrl/over-the-air-updates.mdx +++ b/www/docs/ctrl/over-the-air-updates.mdx @@ -10,18 +10,24 @@ import ConfigSchema from "@site/schemas/rugix-ctrl-system.schema.json"; # Over-the-Air Updates -Rugpi supports robust *over-the-air* (OTA) updates with rollback support to the previous version. -OTA updates comprise the full system including firmware files and the boot configuration. -Rugpi uses an A/B approach ensuring that a working copy of the previous version is always kept. -This approach drastically reduces the likelihood of bricking devices in the field due to corrupted software caused by a failed or incomplete update, thereby reducing any related support effort. -In addition, it has the following advantages: +Rugix Ctrl's core functionality is the safe installation of _over-the-air_ (OTA) system updates. + +**A/B Update Scheme.** A typical Rugix Ctrl setup uses an _A/B update scheme_ with redundant system partitions (A and B). When an update is available, it is installed on the inactive partition (e.g., if the device is currently using partition A, the update is installed on partition B). This allows the device to temporarily switch to the updated partition upon reboot, ensuring a seamless and fail-safe update process as the previous partition remains untouched and can be reverted to in case of any issues. After on-device validation of the update, the update is then committed by permanently switching to the now active partition as the default boot partition. This approach drastically reduces the likelihood of bricking devices in the field due to corrupted or incompatible software and failed or incomplete updates, thereby minimizing any related support effort. In addition, it has the following advantages: - OTA updates can almost completely run in the background, without adversely affecting any users of a device. The only service interruption is caused, when the device reboots into the new version. Rebooting to finalize an update can happen at the discretion of users and, if all goes well, does not take longer than any normal reboot, minimizing any inconveniences. -- As the previous version is kept, a rollback to the old version is possible if users experience any problems with the new version.[^1] +- As the previous version is kept, a rollback to the old version is possible if users experience any problems with the new version.[^rollback] + +[^rollback]: This requires application support. + +**Other Update Schemes.** We generally recommend using an A/B update scheme due to the advantages stated above. For cases where an A/B update scheme is not the right choice, Rugix Ctrl can flexibly be configured for other update schemes, for instance, an asymmetric setup with a recovery partition or a setup with more than two redundant system partitions. + +To commit and switch between systems, Rugix Ctrl needs to integrate with the bootloader of the system. -[^1]: This requires application support. +:::tip +When building a system with Rugix Bakery for one of the generic and specific targets, you will get a system with a working OTA update integration out-of-the-box using an A/B update scheme. In that case, no configuration is necessary. +::: ### A/B Update Scheme diff --git a/www/docs/getting-started.md b/www/docs/getting-started.md index a6c01bce..46a2c78c 100644 --- a/www/docs/getting-started.md +++ b/www/docs/getting-started.md @@ -4,121 +4,198 @@ sidebar_position: 1 # Getting Started 🚀 -Rugpi consists of two components, _Rugpi Bakery_ for building customized system images, and _Rugpi Ctrl_ for maintaining and managing a system. -This quick-start guide takes you through the steps necessary to build a customized system image with Rugpi Bakery. -This image will contain Rugpi Ctrl for managing a system's state and for installing over-the-air system updates. +Rugix is a collection of tools designed to build reliable embedded Linux devices with over-the-air update capabilities. +In this guide, we use two of these tools: _Rugix Bakery_, a flexible and user-friendly build system for bespoke Linux distributions, and _Rugix Ctrl_, a powerful tool for robust over-the-air system updates and system state management. +Although these tools are designed to work seamlessly together, you can also use them independently for your own projects. +But for now, let's keep things simple! -You can build images locally or with a CI/CD system like GitHub Actions. -Here, we go through the process of building images locally. -For details about running Rugpi Bakery with a CI/CD system, checkout the [user guide's section on CI/CD Integration](./guide/ci-cd-integration). +With Rugix, our mission is clear: **Simplify the development of embedded Linux devices.** +This quickstart guide will walk you through the steps required to build a production-ready, customized variant of [Debian](https://www.debian.org) with over-the-air update support, which you can readily run on any EFI-compatible system or deploy on a Raspberry Pi. +We aim for this guide to take at most one hour to complete, even if you have no prior experience with embedded Linux. +So, let's get started and unlock the potential of Rugix for your embedded projects! ## Setup and Installation -Rugpi Bakery is distributed as a Docker image (for `arm64` and `amd64`) because it relies on various Linux tools and facilities to build images. -Building images outside of Docker is fundamentally only possible on Linux and not officially supported. -So, to build an image locally, a working [Docker](https://www.docker.com/) or [Podman](https://podman.io/) installation is required. +First, you need to set up Rugix Bakery. +Rugix Bakery is distributed as a Docker image (for `arm64` and `amd64`). +To build an image, a working [Docker](https://www.docker.com/) or [Podman](https://podman.io/) installation is required. On MacOS, please make sure to use the [MacOS virtualization framework and VirtioFS](https://docs.docker.com/desktop/settings/mac/#general), which is the default with recent versions of Docker Desktop. -For Windows, please use [WSL](https://learn.microsoft.com/en-us/windows/wsl/about). +On Windows, please use [WSL](https://learn.microsoft.com/en-us/windows/wsl/about). -For convenience, Rugpi Bakery ships as a small shell script named `run-bakery`. -The script runs an ephemeral Docker container and sets everything up as required. -To start a fresh Rugpi project, create an empty directory and then run +As a convenience, we provide a small shell script named `run-bakery`. +The script runs an ephemeral Docker container with Rugix Bakery and sets everything up as required. +To start a fresh project, create an empty directory and then run: ```shell -curl -O https://raw.githubusercontent.com/silitics/rugpi/v0.7.0/bakery/run-bakery && chmod +x ./run-bakery +curl -O https://raw.githubusercontent.com/silitics/rugix/v0.8.0/bakery/run-bakery && chmod +x ./run-bakery ``` -within this directory. -This will download the `run-bakery` shell script from Rugpi's GitHub repository and make it executable. -You can then run Rugpi Bakery with `./run-bakery`. -If you use a version control system to manage the project, it is good practice to commit the `run-bakery` shell script into the repository so that everyone can run it without any additional setup. +This will download the `run-bakery` shell script from Rugix's GitHub repository and make it executable. +You can then run Rugix Bakery with `./run-bakery`. +If you run `./run-bakery help` you will get usage instructions for Rugix Bakery. -If you run `./run-bakery help` you should now get usage instructions for Rugpi Bakery. +#### Emulation of Foreign Architectures -### Emulation of Foreign Architectures - -If you want to build images for foreign architectures, you also need to configure [`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc) for emulation. +If you want to build distributions for foreign architectures, you also need to configure [`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc) for emulation.[^foreign-architecture] The easiest way to do so, and as we are already using Docker anyway, is by running the following command: +[^foreign-architecture]: A foreign architecture is a CPU architecture that is different from the one of your host machine. For instance, building images for Raspberry Pi (which has a 64-bit ARM CPU) on an x86 Intel or AMD machine requires emulation. + ```shell docker run --privileged --rm tonistiigi/binfmt --install all ``` -This will allow you to build images for a huge variety of different architectures. +This will allow you to build distributions for a huge variety of different architectures. ## Initializing the Project -To build an image, you first need to create a few configurations files in the project directory. -Rugpi Bakery ships with a set of templates to help you get started quickly. -You can list the available templates by running: +Rugix Bakery ships with a set of project templates to help you get started quickly. +You can list the available templates with: ```shell ./run-bakery init ``` -To initialize the project with a template, run: +For the purposes of this guide, we are using the `quickstart-guide` template. +To initialize the project with this template run: ```shell -./run-bakery init