2 LainOS Layer 01 Developer Guide
Grayson Giles edited this page 2026-06-25 03:20:41 +02:00

LainOS Layer 01 — Architecture & Developer Guide

Last Updated: 2026-06-25
Status: Active Development


Overview

LainOS Layer 01 is a privacy-hardened, systemd-based Arch Linux distribution. Unlike Layer 02 which runs OpenRC, Layer 01 uses standard systemd as PID 1. It is intended as a stable, familiar desktop environment with LainOS privacy hardening applied on top of a conventional Arch base.

Layer 01 is simpler in structure than Layer 02 — it does not require the Protocol 7 compatibility layer, custom C daemons, or the protocol_7_repo. It uses two components: the ISO framework and the Calamares config, pulling packages from standard Arch/Artix repos plus the lainos_repo for packages not available upstream.

┌─────────────────────────────────────────────────────────────┐
│                      ISO Framework                          │
│         (mkarchiso profile, packages, airootfs)             │
│                                                             │
│  ┌─────────────────┐      ┌──────────────────────────────┐  │
│  │ Calamares Config│      │        lainos_repo           │  │
│  │ (installer UI,  │      │  (packages not in Arch repos)│  │
│  │  shellprocess,  │      └──────────────────────────────┘  │
│  │  mkinitcpio)    │                                        │
│  └─────────────────┘                                        │
└─────────────────────────────────────────────────────────────┘
                              │
                    mkarchiso builds
                              │
                              ▼
                    LainOS-*.iso

Part 1 — ISO Framework

Repository: https://forgejo.lain.rocks/lainOS/lainos-iso
Local path: ~/Forgejo/lainos-iso/lainos-iso/

What It Is

The ISO framework is the mkarchiso profile for Layer 01. It defines the package list, the airootfs overlay, boot modes, and the ISO metadata. Because Layer 01 is systemd-based, the profile is significantly simpler than Layer 02 — no custom dracut modules, no eudev, no Protocol 7 daemons.

Structure

lainos-iso/
├── airootfs/                    # Files overlaid into the live squashfs
│   ├── etc/
│   │   ├── calamares/           # Calamares config (from calamares-config package)
│   │   ├── pacman.conf          # Pacman config for the live system
│   │   └── skel/               # Default user home directory contents
│   └── usr/
│       └── local/bin/          # Live system scripts
├── packages.x86_64              # Full package list
├── pacman.conf                  # Pacman config used DURING the ISO build
└── profiledef.sh                # ISO metadata, boot modes, file_permissions

Key Files

packages.x86_64 — Every package installed in the live ISO. Standard packages from Arch [core], [extra], [multilib] and Artix [system], [world], [galaxy]. Special packages from lainos_repo.

profiledef.sh — Defines ISO label, version, boot modes, and the file_permissions array. Every executable script in airootfs/usr/local/bin/ must be declared here:

["/usr/local/bin/scriptname"]="0:0:755"

pacman.conf (profile root) — Used by mkarchiso during the build. Must not reference local repos that don't exist on the build machine. Comment out or remove any [local_repo] entries and custom_repos.conf includes before building on a new machine.

Build Command

doas rm -rf ~/work ~/LainOS-Layer-01/
doas mkarchiso -v -w ~/work -o ~/LainOS-Layer-01 ~/Forgejo/lainos-iso/lainos-iso

Always clear ~/work before rebuilding — stale cached files from a previous build can cause package conflicts or include outdated content in the squashfs.

Verifying ISO Contents

doas mount -o loop ~/LainOS-Layer-01/LainOS-*.iso /mnt
doas unsquashfs -l /mnt/arch/x86_64/airootfs.sfs | grep <filename>
doas unsquashfs -cat /mnt/arch/x86_64/airootfs.sfs etc/calamares/modules/<module>.conf
doas umount /mnt

pacman.conf Gotchas

Layer 01's pacman.conf may reference paths that only exist on the original build machine:

  • [local_repo] pointing to a local filesystem path — comment this out if the path doesn't exist
  • Include = /etc/pacman.d/custom_repos.conf — comment out if the file doesn't exist

If either of these is active and the path doesn't exist, mkarchiso will fail with error: no usable package repositories configured.


Part 2 — Calamares Config

Repository: https://forgejo.lain.rocks/lainOS/lainos-calamares-config
Local path: ~/Forgejo/lainos-calamares-config/
Package name: lainos-calamares-config
Repo: lainos_repo

What It Is

The Calamares config package for Layer 01 controls the graphical installer — partitioning defaults, bootloader config, initramfs generation (mkinitcpio, not dracut), and post-install setup via shellprocess.

Structure

etc/calamares/
├── settings.conf              # Module execution order
└── modules/
    ├── bootloader.conf        # GRUB / systemd-boot config
    ├── partition.conf         # Filesystem defaults
    ├── shellprocess.conf      # Post-install shell commands
    └── unpackfs.conf          # Squashfs source paths

Key Differences from Layer 02

Feature Layer 01 Layer 02
Init system systemd OpenRC
initramfs tool mkinitcpio dracut
Privilege tool sudo doas
udev systemd-udev eudev
Display manager varies greetd + tuigreet
Bootloader GRUB or systemd-boot GRUB only

Because Layer 01 uses mkinitcpio instead of dracut, there is no dracut.conf module and no need for --no-uefi, initramfsName, or force_drivers configuration.

How to Rebuild

cd ~/Forgejo/lainos-calamares-config
git add etc/calamares/modules/<changed-file>
git commit -m "description"
git push   # Must push — PKGBUILD clones from Forgejo

# Bump pkgrel
sed -i "s/^pkgrel=\([0-9]*\)/pkgrel=$(( $(grep -oP '(?<=pkgrel=)\d+' PKGBUILD) + 1 ))/" PKGBUILD
grep pkgrel PKGBUILD
git add PKGBUILD && git commit -m "bump pkgrel" && git push

# Build and deploy to lainos_repo
rm -rf src pkg && makepkg -f
cp lainos-calamares-config-*.pkg.tar.zst /path/to/lainos_repo/x86_64/
repo-add /path/to/lainos_repo/x86_64/lainos_repo.db.tar.gz \
  /path/to/lainos_repo/x86_64/lainos-calamares-config-*.pkg.tar.zst

Then rebuild the ISO.

shellprocess Rules

Same rules apply as Layer 02:

  • Never use ${VAR} or $VAR directly in command strings — Calamares intercepts both
  • Never use literal newlines in YAML strings — use printf 'line1\nline2\n'
  • Scripts called from shellprocess must be standalone files at absolute paths

Part 3 — Rebuilding Calamares on Boost/KPMCore Updates

Location: https://forgejo.lain.rocks/lainOS/lainos-iso/src/branch/main/calamares-rebuild
Local path: ~/Forgejo/lainos-iso/calamares-rebuild/
Package name: lainos-calamares
Repo: lainos_repo

What It Is

Calamares links against boost and KPMCore (KDE Partition Manager Core). When Arch updates these libraries, the upstream Calamares binary breaks. LainOS maintains a custom Calamares build that must be rebuilt whenever boost or kpmcore receive major updates. The rebuild kit lives inside the ISO framework repo at calamares-rebuild/.

When to Rebuild

Watch for pacman updates to these packages:

  • boost-libs
  • kpmcore
  • qt6-base (less common)

When they update, the installed Calamares will segfault or fail to start in the live session until rebuilt against the new versions.

Signs You Need a Rebuild

  • Calamares crashes immediately on launch in the live session
  • doas calamares shows a segfault or immediate exit
  • ldd /usr/bin/calamares | grep "not found" shows missing shared libraries

How to Rebuild

cd ~/Forgejo/lainos-iso/calamares-rebuild/

Follow the instructions in that directory — it patches Calamares source, builds against current system libraries, and produces a new package.

After rebuilding:

cp lainos-calamares-*.pkg.tar.zst /path/to/lainos_repo/x86_64/
repo-add /path/to/lainos_repo/x86_64/lainos_repo.db.tar.gz \
  /path/to/lainos_repo/x86_64/lainos-calamares-*.pkg.tar.zst

Then rebuild the ISO to pick up the new Calamares package.


Part 4 — lainos_repo

URL: https://gitlab.com/lainos/lainos_repo/-/raw/main/x86_64/

What It Is

The lainos_repo contains packages that are not available in the standard Arch or Artix repositories. This includes:

  • Pre-built AUR packages included in the ISO
  • Patched versions of upstream packages
  • LainOS-specific utilities and tools
  • The lainos-calamares-config package for Layer 01

When to Add a Package

Add a package to lainos_repo when:

  • It's in the AUR but you want it pre-installed without requiring the user to build it
  • An upstream package needs patching for LainOS compatibility
  • It's a LainOS-specific package with no upstream equivalent

Managing the Repo

# Add a new package
repo-add /path/to/lainos_repo/x86_64/lainos_repo.db.tar.gz \
  /path/to/lainos_repo/x86_64/newpackage-*.pkg.tar.zst

# Rebuild entire database (after corruption or bulk additions)
cd /path/to/lainos_repo/x86_64/
repo-add lainos_repo.db.tar.gz *.pkg.tar.zst

Never run repo-add against a single file when other packages exist — it resets the database to contain only that one package.


How the Parts Fit Together

Dependency Chain

lainos-calamares-config changes
        │
        ▼
rebuild package → push to lainos_repo
        │
        ▼
rebuild ISO (mkarchiso pulls new package)
        │
        ▼
test install in VM → test on baremetal
ISO framework changes (airootfs, packages.x86_64, profiledef.sh)
        │
        ▼
git push to Forgejo
        │
        ▼
rebuild ISO directly (no package rebuild needed)
        │
        ▼
verify squashfs contents → test

What Triggers a Full ISO Rebuild

Change Type Package Rebuild? ISO Rebuild?
Calamares config (modules) Yes Yes
lainos_repo package added/updated Depends Yes
airootfs file No Yes
packages.x86_64 No Yes
profiledef.sh No Yes

Common Mistakes

Mistake Symptom Fix
[local_repo] active in pacman.conf error: no usable package repositories configured Comment out local repo entries that don't exist on build machine
custom_repos.conf include missing Same as above Comment out the Include line
Not clearing ~/work Stale packages cause conflicts doas rm -rf ~/work before rebuilding
Not pushing before makepkg Old version built Always git push before building
Literal newline in shellprocess YAML shellprocess could not be loaded Use printf 'line1\nline2\n'
Script not in profiledef.sh file_permissions Script not executable Add ["/usr/local/bin/script"]="0:0:755"
Single-file repo-add Database shows only one package Use *.pkg.tar.zst wildcard

Diagnostic Commands

# Verify squashfs contents
doas mount -o loop ~/LainOS-Layer-01/LainOS-*.iso /mnt
doas unsquashfs -l /mnt/arch/x86_64/airootfs.sfs | grep <filename>
doas umount /mnt

# Calamares session log (from live session)
doas grep -n "" /root/.cache/calamares/session.log | sed -n 'START,ENDp'

# Check repo database
pacman -Sl lainos_repo

# Verify pacman.conf has usable repos
grep -E "^\[|^Server|^Include" ~/Forgejo/lainos-iso/lainos-iso/pacman.conf