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 existInclude = /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$VARdirectly 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-libskpmcoreqt6-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 calamaresshows a segfault or immediate exitldd /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-configpackage 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