Build your own ISO¶
Yes, you can produce an Obarun image on your own machine and end up with an
.iso file you can write to a stick. It is the same script the project runs
every month, iso-builder, and it
is meant to be run from inside the cloned repository.
Local builds work, but CI is the primary use case
The repository's own README says it plainly: local builds are possible but not what the pipeline is tuned for. If something breaks, check the pipeline before assuming your machine is at fault.
What you need¶
- Root. The script uses
losetup,mkfs.ext4,mountandchroot. There is no rootless mode. - Disk, on a real filesystem. Around 6 GiB for a
minimalbuild: an 8 GiB ext4 image of which the theme fills part, a 1.1 GiB squashfs, and a 1.3 GiB ISO. Ajwmbuild pulls several times more packages and needs noticeably more. obinstall, because the whole rootfs is built byobinstall-cli, and because the themes live in its package under/var/lib/obarun/obinstall/themes/.- The build tools, the ones the pipeline installs:
# pacman -S --needed obinstall mkinitcpio mtools dosfstools squashfs-tools \
libisoburn grub syslinux arch-install-scripts qemu-base oblog fakeroot
qemu-base is there for the last step, which boots the finished image headless
for three seconds as a smoke check.
Build it¶
Where you build matters: not /tmp, not /root
/var/tmp is the safe choice. Two different traps sit on either side of
it.
/tmp is a tmpfs, mounted by the boot module and sized from your RAM.
On a 4 GiB machine that is under 2 GiB, and the build needs several times
that. The ext4 image cannot grow, so the loop filesystem flips read-only
somewhere in the middle of the package install:
error: could not create directory .../var/lib/pacman/local/graphene-1.10.8-2/: Read-only file system
error: failed to commit transaction (transaction aborted)
ERROR [pacstrap] Step pacstrap failed
Check before you start: findmnt /tmp tells you the type and
df -h /tmp the size.
/root is mode 0700. iso-live/pacman.conf sets
DownloadUser = alpm, so pacman drops to the unprivileged alpm user to
download, and that user cannot cross root's home. The build dies on the
very first sync:
error: could not open file .../sync/download-XXXXXX/obcore.db.part: Permission denied
error: failed to synchronize all databases (failed to retrieve some files)
The pipeline meets neither, because it builds in $CI_PROJECT_DIR, on
disk and world-traversable.
# mkdir -p /var/tmp/isobuild && cd /var/tmp/isobuild
# git clone https://git.obarun.org/obdev/iso-builder.git
# cd iso-builder
# OBINSTALL_NO_UPDATE=1 ./scripts/build-iso.sh
Run it from inside the cloned iso-builder/ directory, the one holding
scripts/ and iso-live/. The script takes $PWD as its base and looks for
iso-live/ under it, so it fails anywhere else.
OBINSTALL_NO_UPDATE=1 is not optional in practice
Without it, obinstall tries to update itself before installing anything.
That path runs makepkg as the nobody user, makepkg calls sudo to
install its missing build dependencies, and sudo asks for a password
nobody does not have:
The build sits there until you interrupt it. With the variable set, the step is skipped outright and the log says so:
obinstall-cli also takes --no-update, and [update].enabled = false in
/etc/obarun/obinstall/obinstall.conf disables it permanently, but the
environment variable is what reaches obinstall-cli through
build-iso.sh, which calls it for you.
If you use sudo rather than a root shell
sudo drops the variable. Pass it as part of the command, or export it
and use sudo -E:
sudo ./scripts/build-iso.sh with the variable merely exported in your
shell runs the self-update anyway, and you are back to the password
prompt.
What comes out¶
The version is the build date, and the ISO 9660 label matches the file name. That is your image: verify the checksum, write it to a stick as described in Download and write the ISO, and boot it.
The last step boots the finished image in QEMU for three seconds and reports
QEMU smoke test passed. If that line is there and the exit status is 0, the
image at least gets through its bootloader.
One warning you can ignore
Early in the run, obinstall tries to update itself and gives up:
It is not fatal, the build carries on and the image is fine.
Choosing the theme¶
THEME defaults to minimal. Any theme the installed obinstall package
provides works, and the name ends up in the image name so two themes do not
collide:
THEME |
Image |
|---|---|
minimal |
obarun-<date>-x86_64.iso |
jwm |
obarun-JWM-<date>-x86_64.iso |
List what your machine offers:
How the build works¶
iso-builder ships no package list and no theme of its own. It creates an empty
ext4 image, mounts it, and calls
obinstall-cli on it, exactly the way an
operator would call it on a disk.
The live medium and a disk install come out of the same code path. Package
installation, the theme overlay, the 66 services, the users and the initramfs
are all the installer's work in both cases. What iso-builder adds is only what
a bootable medium needs:
- Create and mount the ext4 image.
- Run
obinstall-cliagainst it with the chosen theme. - Release the chroot bind mounts.
- Install the live-only packages from
iso-live/extra_packages. - Overlay
iso-live/rootfs/<theme>/and fix ownership. - Build the archiso initramfs with
mkinitcpio. - Wipe caches, logs and
/etc/machine-id. - Write version markers, then the squashfs.
- Assemble the BIOS and UEFI boot paths, then
xorriso. - Boot the result headless for three seconds.
Customising what the image ships¶
Where a change goes depends on whether it belongs to the installed system or to the medium:
| What you want to change | Where it goes |
|---|---|
| A package, a service, a dotfile, a user | The obinstall theme, in the obinstall repository, not in iso-builder |
| A package only the live medium needs | iso-live/extra_packages |
A file only the live medium needs, such as the /etc/issue announcing the live credentials |
iso-live/rootfs/<theme>/ |
| A repository or a pacman option the rootfs is built with | iso-live/pacman.conf |
| A boot menu entry or a kernel command line | iso-live/syslinux/, iso-live/grub/, iso-live/isolinux/ |
So for an image with your own package set, the thing to write is an obinstall
theme, not a fork of iso-builder. A theme is a package list, a set of 66
services to enable, files to overlay, and a customizeChroot hook. See
docs/theme-authoring.md.
That way your customisation works identically for a disk install and for an image.
Two pacman configs, not interchangeable
pacman.conf at the top of the clone is the build environment's config.
iso-live/pacman.conf is the ISO rootfs's config, passed explicitly to
obinstall-cli --pacconf. Leave the second one out and obinstall falls back
to the host's /etc/pacman.conf, which is not what the image should be
built with.
The older tool¶
obarun-mkiso, in obextra, is the standalone script that predates this
pipeline. It is still packaged, but the official images are no longer built with
it, and its shipped default configuration still points at a git host that no
longer exists. Prefer iso-builder and an obinstall theme.