# Building Arcline OS ## Prerequisites A Debian-family host (or container) with root/sudo: ``` debootstrap # rootfs bootstrap squashfs-tools # ISO rootfs compression grub2-common # grub-mkrescue (hybrid ISO) xorriso cpio # ISO assembly bash make curl git # build orchestration go (≥ 1.21) # only needed for `make toolchain` ``` Check or install them: ``` scripts/check-host-deps.sh # report what's missing scripts/check-host-deps.sh --install # apt-get install the missing bits ``` ## Quickstart ``` make check # validate the tree (fast, offline, safe) make rootfs-server # build just the server rootfs make iso-server # build a bootable server ISO make iso # build all three editions make image-cloud # build the cloud edition as a qcow2 disk image make toolchain # build the 11 Go tools into .deb make vendor # build Grafana/Loki/Promtail .debs make test # run smoke tests against built rootfs(es) ``` ## Outputs Everything lands under `build/`: | Path | Contents | |------|----------| | `build/rootfs//` | extracted rootfs (from `make rootfs-*`) | | `build/artifacts/arcline---.tar.xz` | archived rootfs | | `build/artifacts/arcline---.iso` | bootable live ISO | | `build/artifacts/arcline---.qcow2` | bootable disk image | | `build/debs/*.deb` | Arcline toolchain + vendor packages | Each artifact ships with a `.sha256` checksum file. ## Disk images & installing - `make image-` builds a bootable **qcow2** disk image (the cloud edition's primary output; also handy for VM-testing server/workstation). Options: `--format raw`, `--size 4G`, `--boot efi`. - `scripts/install.sh /dev/sdX --edition server` installs a built rootfs onto a real disk (asks for explicit confirmation, then partitions, lays out btrfs subvolumes, installs GRUB, and writes a real fstab). Both reuse the shared `scripts/deploy-disk.sh`. ## Secure boot Optional, MOK-based. See [secureboot](secureboot.md): ```bash scripts/secureboot/gen-keys.sh ARCLINE_SIGN=1 make iso-server ``` ## Reproducibility knobs Set these as environment variables or edit `versions.mk`: | Variable | Meaning | Default | |----------|---------|---------| | `VERSION` | release version string | `0.1.0` | | `DEBIAN_SUITE` | Debian base | `trixie` | | `ARCH` | target architecture | `amd64` | | `DEBIAN_MIRROR` | mirror for the base | `http://deb.debian.org/debian` | | `ARCLINE_LIVE` | install live-boot into rootfs | unset (set by ISO build) | | `ARCLINE_LOCK_ROOT` | lock root account (`passwd -l root`) | `0` | | `ARCLINE_EXTRA_REPOS` | fetch grafana/loki upstream repos | `0` | | `ARCLINE_TOOLCHAIN` | toolchain in image builds | `auto` | | `ARCLINE_SIGN` | sign boot chain with the MOK (secure boot) | `0` | | `BOOT` | bootloader in the image: `bios` → grub-pc, `efi` → grub-efi-amd64 + shim-signed | `bios` | > **Why one bootloader?** `grub-pc` and `grub-efi-amd64` conflict, so apt fails > with *"held broken packages"* if both are in a package list. Arcline ships > exactly the one matching `BOOT` (injected by `build-rootfs.sh`). For a UEFI + > secure-boot build: `BOOT=efi make iso-server` (or `make image-cloud` with > `BOOT=efi`). The deployed image/install uses the same variable by default. ## Building without the Arcline toolchain The 11 Go tools (see `docs/toolchain.md`) are **optional** in an image — a normal `make iso-server` with no `.deb`s in `build/debs/` already produces a minimal, toolchain-free image. This is controlled by `ARCLINE_TOOLCHAIN`: | Mode | Behaviour | |------|-----------| | `auto` (default) | install the tools if `build/debs/*.deb` exist, otherwise build without them (with a warning) | | `skip` | never install the tools, even if debs are present | | `require` | **fail** the build if no toolchain debs are available | Examples: ```bash make iso-server # auto: tools in if you ran `make toolchain` make iso-server-minimal # skip: guaranteed toolchain-free image ARCLINE_TOOLCHAIN=skip make iso-server ARCLINE_TOOLCHAIN=require make iso-server # release builds must ship the tools ``` Everything else — hardened base, firewall, btrfs, observability (Prometheus/node_exporter are Debian-main packages), zero-telemetry — is independent of the toolchain and always included. ## Notes on the ISO The ISO is a **graphical installer** medium: it boots to a minimal live session (Xorg) that auto-starts the Arcline installer window. Pick a target disk, confirm the device path, and it installs to disk with the btrfs layout, GRUB, and a real fstab — driven by the same `deploy-disk.sh` core as the scripted installer. The live session is built by `build-live.sh` on top of the **clean** rootfs; the ISO carries that clean rootfs as the install source (`install/`), so what lands on disk is the hardened installed system — never the live session with the installer in it. Install a user + desktop afterwards if you want a graphical login (workstation edition already ships KDE Plasma + SDDM and boots to it). ### Burning the ISO The ISO is **hybrid** (BIOS + UEFI). Write it to a USB stick with `dd` (or Ventoy), not as a file copy: ```bash sudo dd if=build/artifacts/arcline-server-0.1.0-amd64.iso of=/dev/sdX bs=4M status=progress ``` The build verifies the finished ISO actually contains **both** boot entries and prints `✓ EFI boot entry present` / `✓ BIOS boot entry present`; `BOOT=efi` builds **fail** if the EFI entry is missing. ### UEFI says "make sure there is a bootable uefi x64 image" That firmware error means the ISO had no UEFI boot entry. `grub-mkrescue` builds the ISO bootloader from the **build host's** GRUB, so the host needs the UEFI modules even though the image is `BOOT=efi`: ```bash sudo apt-get install -y grub-efi-amd64-bin grub-pc-bin mtools scripts/check-host-deps.sh # should now pass; rebuild the ISO ``` If the entry was present but it still won't boot, enable/disable Secure Boot (our `BOOT=bios` ISOs are unsigned and will be refused by Secure Boot — use `BOOT=efi make iso-server` plus the MOK flow in `docs/secureboot.md` for signed, Secure-Boot-friendly media).