Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions archlinux/Containerfile.base → Containerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ RUN curl https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/

# Perform a clean system installation with latest Arch Linux packages in chroot to correctly execute hooks, this uses host's Pacman
RUN pacman --noconfirm --sync --needed arch-install-scripts \
&& pacstrap -K -P /mnt base \
&& pacstrap -K -P /mnt base base-devel linux-firmware fwupd \
&& cp -av /etc/pacman.d/ /mnt/etc/

# |
Expand All @@ -23,14 +23,15 @@ FROM scratch AS base
COPY --from=rootfs /mnt /

# Clock
ARG SYSTEM_OPT_TIMEZONE
RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime
# Define o fuso horário para o Brasil (Mato Grosso)
RUN ln --symbolic --force /usr/share/zoneinfo/America/Cuiaba /etc/localtime

# Keymap hook
ARG SYSTEM_OPT_KEYMAP
RUN echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf
# Define o layout do teclado para o padrão brasileiro ABNT2
RUN echo "KEYMAP=br-abnt2" > /etc/vconsole.conf

# Language
RUN echo 'LANG=en_US.UTF-8' > /etc/locale.conf \
&& echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \
# Define o idioma e local para Português do Brasil
RUN echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \
&& echo 'pt_BR.UTF-8 UTF-8' > /etc/locale.gen \
&& locale-gen
234 changes: 115 additions & 119 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,160 +1,156 @@
## OSTree in Arch Linux using Podman

Massive shout-out to [M1cha](https://github.com/M1cha/) for making this possible ([M1cha/archlinux-ostree](https://github.com/M1cha/archlinux-ostree)).

### Overview

This is a helper script which aids in curating your own setup by demonstrating how to:
1. Build an immutable OSTree image by using rootfs from a Podman Containerfile.
2. Partition and prepare UEFI/GPT disks for a minimal OSTree host system.
3. Generate OSTree repository in a empty filesystem.
4. Integrate OSTree with GRUB2 bootloader.
5. Upgrade an existing OSTree repository with a new rootfs image.

### Disk structure

```console
/
├── boot
│   └── efi
└── ostree
├── deploy
│   └── archlinux
└── repo
├── config
├── extensions
├── objects
├── refs
├── state
└── tmp
```
-----

### Persistence
# RAGostree-utility

Everything is deleted between deployments **except** for:
- `/dev` partitions which OSTree does not reside on are untouched.
- `/etc` only if `--merge` option is specified.
- `/home` is symlinked to `/var/home` (see below).
- `/var` data here is mounted from `/ostree/deploy/archlinux/var` to avoid duplication.

Notes:
- `/var/cache/podman` is populated _only_ after the first deployment (to avoid including old data from the build machine), this speeds up consecutive builds.
- `/var/lib/containers` same as above but for Podman layers and images. Base images are updated automatically during `upgrade` command.
**RAGLinux** é um sistema operacional baseado em **Arch Linux** com uma abordagem moderna e robusta: um sistema de arquivos raiz **imutável**, gerenciado de forma atômica pelo **OSTree** e construído com a flexibilidade do **Podman**.

### Technology stack
O objetivo deste projeto é fornecer a estabilidade de um sistema imutável, onde as atualizações são seguras e reversíveis, combinada com a vasta gama de pacotes e a filosofia "faça você mesmo" do Arch Linux.

- OSTree
- Podman with CRUN and Native-Overlayfs
- GRUB2
- XFS _(not required)_
-----

### Motivation
## 🌟 Principais Características

My vision is to build a secure and minimal base system which is resilient against breakage and provides setup automation to reduce the burden of doing manual tasks. This can be achieved by:
* **Sistema Imutável**: O diretório raiz (`/`) é montado como somente leitura, prevenindo modificações acidentais e garantindo que cada "versão" do sistema seja consistente e testada.
* **Atualizações Atômicas**: As atualizações são aplicadas em uma nova "árvore" do sistema. A mudança para a nova versão ocorre em uma única operação (geralmente na reinicialização), eliminando o risco de um sistema quebrar no meio de uma atualização.
* **Rollbacks Simples**: Se uma atualização causar problemas, reverter para a versão anterior funcional é um comando simples e instantâneo.
* **Construção via Containers**: A imagem base do sistema é construída dentro de um container Podman, garantindo um ambiente de build limpo, reprodutível e isolado.
* **Separação Clara**: O sistema operacional é estritamente separado dos dados e configurações do usuário, que residem em subvolumes Btrfs separados (`/home`, `/var`).

- Git.
- Read-only system files.
- Restore points.
- Automatic deployment, installation & configuration.
- Using only required components like kernel/firmware/driver, microcode and GGC in the base.
- Doing the rest in temporary namespaces such as Podman.
-----

### Goal
## 🛠️ Tecnologias Utilizadas

- Reproducible deployments.
- Versioned rollbacks.
- Immutable filesystem.
- Distribution agnostic toolset.
- Configuration management.
- Rootfs creation via containers.
- Each deployment does a factory reset of system's configuration _(unless overridden)_.
* **Base System**: [Arch Linux](https://archlinux.org/)
* **Gerenciamento Atômico**: [OSTree](https://ostreedev.github.io/ostree/)
* **Sistema de Arquivos**: [Btrfs](https://btrfs.wiki.kernel.org/)
* **Construção (Build)**: [Podman](https://podman.io/)
* **Bootloader**: [GRUB](https://www.gnu.org/software/grub/)

### Similar projects
-----

- **[Elemental Toolkit](https://github.com/rancher/elemental-toolkit)**
- **[KairOS](https://github.com/kairos-io/kairos)**
- **[BootC](https://github.com/containers/bootc)**
- [NixOS](https://nixos.org)
- [ABRoot](https://github.com/Vanilla-OS/ABRoot)
- [Transactional Update + BTRFS snapshots](https://microos.opensuse.org)
- [AshOS](https://github.com/ashos/ashos)
- [LinuxKit](https://github.com/linuxkit/linuxkit)
## 🚀 Estrutura do Projeto

## Usage
```
raglinux/
├── raglinux.sh # Script principal de instalação e gerenciamento
├── Containerfile.base # Define a imagem base do sistema (pacotes e configs)
├── post-install.sh # (Opcional) Script para configurações pós-instalação
├── archlinux/ # Configurações específicas do Arch
├── cachyos/ # (Opcional) Configurações para builds alternativas
└── Containerfile.host.example # Exemplo para customizações do host
```

1. **Boot into any Arch Linux system:**
-----

For instance, using a live CD/USB ISO image from: [Arch Linux Downloads](https://archlinux.org/download).
## ⚙️ Uso e Gerenciamento

2. **Clone this repository:**
O script `raglinux.sh` é a principal ferramenta para interagir com o sistema em nível de build e deploy.

```console
$ sudo pacman -Sy git
$ git clone https://github.com/GrabbenD/ostree-utility.git && cd ostree-utility
```
### Instalação Inicial

3. **Find `ID-LINK` for installation device where OSTree image will be deployed:**
Para criar o primeiro deployment do sistema em um dispositivo de bloco (ex: `/dev/sda`).

```console
$ lsblk -o NAME,TYPE,FSTYPE,MODEL,ID-LINK,SIZE,MOUNTPOINTS,LABEL
NAME TYPE FSTYPE MODEL ID-LINK SIZE MOUNTPOINTS LABEL
sdb disk Virtual Disk scsi-360022480c22be84f8a61b39bbaed612f 300G
├─sdb1 part vfat scsi-360022480c22be84f8a61b39bbaed612f-part1 256M SYS_BOOT
├─sdb2 part xfs scsi-360022480c22be84f8a61b39bbaed612f-part2 24.7G SYS_ROOT
└─sdb3 part xfs scsi-360022480c22be84f8a61b39bbaed612f-part3 275G SYS_HOME
```
```bash
# Exemplo de uso
./raglinux.sh install --dev /dev/sda --keymap br-abnt2 --time America/Sao_Paulo
```

4. **Perform a takeover installation:**
### Atualizando o Sistema (Upgrade)

**⚠️ WARNING ⚠️**
Isso irá construir uma nova imagem, criar um novo commit no OSTree e prepará-lo para ser o próximo boot.

`ostree.sh` is destructive and has no prompts while partitioning the specified disk, **proceed with caution**:
```bash
# Cria um novo commit OSTree com as últimas atualizações
./raglinux.sh upgrade
```

```console
$ chmod +x ostree.sh
$ sudo ./ostree.sh install --dev scsi-360022480c22be84f8a61b39bbaed612f
```
Após o upgrade, reinicie o sistema para aplicar a nova versão.

⚙️ Update your BIOS boot order to access the installation.
### Revertendo uma Atualização (Rollback)

💡 Default login is: `root` / `ostree`
Caso a última atualização apresente algum problema, você pode facilmente reverter.

💡 Use different Containerfile(s) with `--file FILE1:TAG1,FILE2:TAG2` option
```bash
# Reverte para o deployment anterior (marcado como 0)
./raglinux.sh revert
```

5. **Upgrade an existing installation:**
### Opções do Script `raglinux.sh`

While booted into a OSTree system, use:
| Opção | Argumento Longo | Descrição | Padrão |
| :--- | :--- | :--- |:--- |
| `-b` | `--base-os` | Nome do sistema operacional para o repositório OSTree. | `raglinux` |
| `-c` | `--cmdline` | Argumentos extras para a linha de comando do Kernel. | |
| `-d` | `--dev` | Dispositivo de bloco (SCSI/NVMe) para a instalação. | |
| `-f` | `--file` | Caminho para o(s) `Containerfile`(s) a serem usados no build. | |
| `-k` | `--keymap` | Layout de teclado para o console (TTY). | |
| `-t` | `--time` | Fuso horário (Timezone) no formato `Região/Cidade`. | |
| `-m` | `--merge` | Mantém o diretório `/etc` durante um upgrade. | |
| `-n` | `--no-cache` | Ignora o cache do Pacman e do Podman durante o build. | |
| `-q` | `--quiet` | Reduz a quantidade de logs exibidos na saída. | |

```console
$ sudo ./ostree.sh upgrade
```
-----

💡 Use `--merge` option to preserve contents of `/etc`
## 📦 Gerenciamento de Aplicações

6. **Revert to previous commit:**
Em um sistema imutável, o gerenciamento de pacotes tradicional (`pacman -S ...`) não é usado diretamente no sistema host. Em vez disso, a instalação de aplicações de usuário é feita de forma isolada:

To undo the latest deployment _(0)_; boot into the previous configuration _(1)_ and execute:
* **Flatpak**: O método recomendado para aplicações gráficas. Elas rodam em seu próprio sandbox e não alteram o sistema base.
* **Podman / Distrobox**: Ideal para ferramentas de linha de comando e ambientes de desenvolvimento. Crie containers com as distribuições e pacotes que precisar, sem "sujar" o sistema host.
* **Binários em `/home`**: Para aplicações simples que não requerem dependências complexas, você pode executá-las a partir do seu diretório pessoal.

```console
$ sudo ./ostree.sh revert
```
-----

## Tips
## 🗂️ Estrutura do Sistema de Arquivos (Pós-instalação)

### Read-only
O RAGLinux utiliza subvolumes Btrfs para separar os dados do sistema.

This attribute can be temporarily removed with Overlay filesystem which allows you to modify read-only paths without persisting the changes:
* `/` (raiz): **Imutável**. Gerenciado pelo OSTree.
* `/home`: Subvolume `@home`. **Mutável**. Armazena os arquivos e configurações dos usuários.
* `/var`: Subvolume `@var`. **Mutável**. Contém dados variáveis como logs, caches de aplicações, etc.
* `/ostree`: Subvolume `@ostree`. Contém os deployments (versões) do sistema operacional.
* `/boot/efi`: Partição EFI para o bootloader.

```console
$ ostree admin unlock
```
-----

### Outdated repository cache
## 🧠 Desafios Resolvidos Durante o Desenvolvimento

> `error: failed retrieving file '{name}.pkg.tar.zst' from {source} : The requested URL returned error: 404`
1. **Espaço Insuficiente no LiveCD (`airootfs`)**

Your persistent cache is out of sync with upstream, this can be resolved with:
* **Problema**: O ambiente de instalação do Arch tem um `tmpfs` limitado, que estourava durante o build do container.
* **Solução**: Direcionar o diretório temporário e a raiz do Podman para o disco de destino (`/mnt`), que possui espaço de sobra.
```bash
export TMPDIR=/mnt/podman/tmp
# Configurar /mnt/podman como storage root do Podman
```

```console
$ ./ostree.sh upgrade --no-podman-cache
```
2. **Volume do Podman Não Encontrado**

* **Problema**: O Podman não conseguia montar o cache do Pacman pois o diretório de destino não existia no host antes do build.
* **Solução**: Criar manualmente a estrutura de diretórios do cache antes de invocar o comando `podman build`.
```bash
mkdir -p /mnt/podman/var/cache/pacman
```

3. **GRUB Não se Instalava Corretamente no Chroot**

* **Problema**: O comando `grub-mkconfig` falhava por não encontrar os dispositivos e informações do sistema quando executado de um chroot simples.
* **Solução**: Fazer o bind mount dos pseudo-sistemas de arquivos (`/dev`, `/proc`, `/sys`) do host para dentro do ambiente chroot antes de executar o comando.
```bash
for i in /dev /proc /sys; do mount -o bind $i ${DEPLOY_PATH}${i}; done
chroot ${DEPLOY_PATH} grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg
```

-----

## 🌐 Configurações Padrão

* **Espelho Brasileiro do Pacman**: Para garantir downloads mais rápidos, o `pacman.conf` é configurado por padrão para utilizar o espelho `br.mirrors.cicku.me`.
* **Pacotes Base**: A imagem (`Containerfile.base`) inclui um sistema funcional com Plasma Desktop (KDE), ferramentas de containerização (Podman, Distrobox), Pipewire para áudio e outros utilitários essenciais.

-----

### Autor

Gabriel Aguiar Rocha – [GitHub](https://github.com/gabrielrocha)
Loading