User:M1cha/Install Arch Linux inside OSTree
Introduction
ostree is a toolset, that allows booting from readonly root filesystem images similar to how smartphones work. ostree is a little bit more than that so it's recommended to read their introduction first. A good summary would probably be that ostree is like "git for operating system binaries". To clear up the confusion right away: What you may call "image" or "root filesystem" is simply called a "tree". You deploy a "tree" to a system and boot from it.
Most distributions like Fedora Kinoite or CoreOS regularly build up-to-date versions of their OS and publish them to public ostree repositories. For Arch Linux that's less useful, because almost every system has different packages installed and everyone makes different modifications to the system. So instead, this guide shows a simple way to build your own trees using archlinux-ostree and your own shell script, so you can build them on the machine you want to deploy them to.
Advantages of using ostree
While these are best documented by the official ostree documentation, here's a few that are specific to Arch Linux:
- If you install a new tree, it'll be applied after the next reboot, so no more issues with loading kernel modules after updating the kernel.
- ostree manages
/etc
and does a three-way merge on it during updates. You'll never have pacnew files again and you can easily see your changes by comparing/usr/etc
against/etc
.
Why we need the arch-ostree tool
This guide utilizes archlinux-ostree. It has a very specific, and limited purpose:
- Simplify building and committing pacman based trees.
- Simplify setting up a fresh ostree installation from within the official arch live ISO.
So after you are done with the initial setup, you'll only need that tool to build a new, updated tree.
Pre-installation
- While OSTree supports multiple bootloaders, this guide was only tested with GRUB2.
- This guide assumes that you already have a working rootfs build script
Follow Installation_guide#Pre-installation with the goal of having both your root file system and essential partitions like the EFI system partition and the boot partition mounted at /mnt
.
Prepare the live environment
Increase live root partition size
We need to install some bigger packages like Podman, so you'll have to make some space as described in Archiso#Adjusting the size of the root file system. Make sure you have enough RAM for that.
Refresh / Update pacman
Since we will install new packages we have to make sure wen can install them. Usually you just need to sync:
# pacman -Sy
Depending on the age of the ISO you might run into issues with that and you'll have to update the whole system. Before you do that you should add linux to the ignore list so you don't loose the ability to load kernel modules:
... [options] ... IgnorePkg=linux
And then:
# pacman -Syu
Create a setup directory
We'll have to create lots of files so you should create a temporary directory for them on your mounted rootfs:
# mkdir /mnt/setup
Since that directory is also used by arch-ostree
, you can't put it anywhere else.
Install arch-ostree
# pacman -S git # git clone https://github.com/M1cha/archlinux-ostree.git /mnt/setup/archlinux-ostree # export PATH="/mnt/setup/archlinux-ostree:$PATH"
Download your rootfs build script
If you have them on a public GitHub repository:
# git clone https://github.com/USER/REPO.git /mnt/setup/ostree-build-script
Run preparation script
The rest of the steps are automated. It just installs some dependencies and configures podman to store it's data at /mnt/setup
.
# arch-ostree prepare_live_env
Installation
Initialize ostree
This creates a stateroot called archlinux
:
# ostree admin init-fs --sysroot /mnt --modern /mnt # ostree admin stateroot-init --sysroot /mnt archlinux # ostree config --repo /mnt/ostree/repo set sysroot.bootprefix 1
Build builder container
Many arch-ostree
commands run code inside a container. This container first needs to be built using:
# arch-ostree build_builder_container
Build your tree
First build your new tree into a directory:
# arch-ostree \ --aur-dir /mnt/setup/aur \ --pacman-cache /mnt/setup/pacman_cache \ --rootfs-dir /mnt/setup/rootfs \ build_rootfs_directory \ /mnt/setup/ostree-build-script/build_rootfs.sh
Then commit it into your freshly created OSTree repository on the branch archlinux
:
# arch-ostree \ --rootfs-dir /mnt/setup/rootfs \ --ostree-repo /mnt/ostree/repo \ commit_rootfs_directory \ -- -v -b archlinux
Create deployment environment
We need to deploy the tree from an environment that looks similar to the booted system. This is especially true for installing the bootloader. For that reason we checkout the freshly committed tree into a directory so arch-ostree
can use it as a chroot environment:
# ostree checkout \ --repo /mnt/ostree/repo \ --require-hardlinks \ archlinux /mnt/setup/deployment
The deployment directory needs to be on the rootfs partition, so the deployment-environment from which you'll install your bootloader, will see that as it's root partition.
Deploy
First open a shell inside the deployment environment. All other commands in this section have to be run inside it:
# arch-ostree \ --deploy-env-dir /mnt/setup/deployment \ --sysroot-dir /mnt \ deploy_env -- \ /bin/bash
Install bootloader
Don't use GRUB config files to add kernel command line arguments. You can manage them using OSTree.
See [GRUB2]] for more information. You can use ostree with all kinds of setups including UEFI, BIOS and LVM. If your preferred setup doesn't work with this, open a discussion.
Here's a common example where your EFI system partition was mounted at /efi
and your boot partition was mounted at /boot
. First, run the normal grub installer:
# grub-install --target x86_64-efi --efi-directory /efi --bootloader-id=GRUB
Then we have to symlink the grub config to where OSTree will generate it:
# ln -sf ../loader/grub.cfg /boot/grub/grub.cfg
Create the deployment
Deploy the branch archlinux
into the stateroot archlinux
. Modify the --karg=
arguments according to your setup.
# ostree admin deploy \ --os=archlinux \ --no-merge \ --karg-none \ --karg=root=UUID="MY_UUID" \ --karg=rw \ archlinux
Configure
Since you just created a new deployment with a clear copy of /etc
, you have to do some basic setup before you can boot into it.
Generate fstab
# genfstab -U /mnt >> /mnt/ostree/deploy/archlinux/deploy/*/etc/fstab
Set root password
# vim /mnt/ostree/deploy/archlinux/deploy/*/etc/shadow
Set-up home directory
/home
within the tree is a symlink to /var/home
. If this directory doesn't exist, systemd will create another symlink in it's place that points to /home
on your root partition(/sysroot/home
on a booted ostree system). This allows sharing /home
between multiple stateroots. If that's what you want, you have to create that directory:
# mkdir /mnt/home
If you want a separate home directory for every stateroot, you can create one on {{ic|/var|| and systemd will leave it alone:
# mkdir /mnt/ostree/deploy/archlinux/var/home
The path to you /var
partition might be different depending on you partition scheme.
Reboot
Everything is ready to use and you can reboot into your new system now.
Update
Updating the currently running system is much easier, because ostree detects the stateroot it's running in and uses that as the default.
First, build new tree:
# arch-ostree \ --aur-dir /mnt/setup/aur \ --pacman-cache /mnt/setup/pacman_cache \ --rootfs-dir /mnt/setup/rootfs \ build_rootfs_directory \ /mnt/setup/ostree-build-script/build_rootfs.sh
Then, commit it:
# arch-ostree \ --rootfs-dir /mnt/setup/rootfs \ commit_rootfs_directory \ -- -v -b archlinux
And deploy it:
# ostree admin deploy archlinux