5210R - Custom AlmaLinux 8 ISO building

Posted by: mstauber Category: Development

Developer diary entry about re-spinning an AlmaLinux 8 ISO to provide us with a custom BlueOnyx 5210R installation ISO.

Editors Note: When CentOS 8 came out I wrote a developer blog entry on how I went about respinning the CentOS 8 ISO to provide us with a BlueOnyx 5210R installation image. Since then that page has gotten many search engine hits from people who were looking for a solution to their own ISO image building ordeals. With the EOL of CentOS 8 and the emergence of AlmaLinux 8 we have since long switched BlueOnyx 5210R to use AlmaLinux 8 as a base and our installation ISO uses a modified AlmaLinux 8 ISO. Here is how we do that.

Premise:

You want a custom OS installation ISO that not only installs AlmaLinux 8, but also RPMs from other YUM/DNF repositories. So you have your own YUM repository with all the extra RPMs that you want to include in your custom ISO. That custom repository has a Group file that has at least one group that lists all the RPMs you want to install. In our case that group is called "BlueOnyx".

You need an AlmaLinux 8 build box where you run the build process for the ISO.

You have downloaded a suitable AlmaLinux 8 ISO image from the official mirrors. I recommend to use the "Minimal" ISO and our latest BlueOnyx 5210R ISO is a respin of the official AlmaLinux-8.6-x86_64-minimal.iso 

How to do it:

We're taking the AlmaLinux 8 ISO and doing a re-spin by adjusting the isolinux.cfg, grub.conf, cleaning out all RPMs and stuffing the CD with just the RPMs we need. Which also required a new comps.xml.

The obvious first step was to mount and rip off the AlmaLinux-8.6-x86_64-minimal.iso and copy all files to our work directory - which in my case is /home/build_cd.5210R/5210R. That means: Everything in the /home/build_cd.5210R/5210R directory will end up in the ISO. The structure and directories there hold no surprises and it looks like this:

[root@alma build_cd.5210R]# tree -d -L 5 /home/build_cd.5210R
.
├── 5210R
│ ├── .discinfo
│ ├── .treeinfo
│ ├── EFI
│ │ └── BOOT
│ ├── GPL
│ ├── images
│ │ ├── efiboot.img
│ │ ├── install.img
│ │ └── pxeboot
│ ├── isolinux
│ │ ├── boot.cat
│ │ ├── boot.msg
│ │ ├── grub.conf
│ │ ├── initrd.img
│ │ ├── isolinux.bin
│ │ ├── isolinux.cfg
│ │ ├── ldlinux.c32
│ │ ├── libcom32.c32
│ │ ├── libutil.c32
│ │ ├── memtest
│ │ ├── splash.png
│ │ ├── vesamenu.c32
│ │ └── vmlinuz
│ ├── ks
│ │ ├── kick_nolvm.cfg
│ │ ├── kick_small.cfg
│ │ └── kickstart.cfg
│ ├── media.repo
│ └── Minimal
│ ├── Packages
│ └── repodata
└── yum-env
├── compsbuilder
└── root
├── etc
└── var
├── cache
│ └── dnf
├── lib
│ ├── dnf
│ └── rpm
└── log

There is the "Minimal" directory that hold the local DNF/YUM repository which the ISO uses. The sub-directories "Packages" and "repodata" of it can be cleaned out for now.

Our BlueOnyx 5210R YUM repository already has a comps.xml that defines the group "BlueOnyx" and it's RPMs. So we can do a "yum groupinstall blueonyx" that gets us everything we need aboard.

Anaconda needs the "base" and "core" Groups in order to perform an install and we also want at least a minimal install or the what AlmaLinux calls the "Custom Operating System" group in their comps.xml.

So how do we get all the RPMs from these various groups into the "Minimal" repository of our ISO? YUM to the rescue!

First of all, replicate the below directory and file structure - if you haven't already done so:

/home/build_cd.5210R/yum-env/
├── compsbuilder
└── root
├── etc
│ └── os-release
└── var

These are all directories. Except /home/build_cd.5210R/yum-env/etc/os-release, which is a copy of /etc/os-release from your AlmaLinux 8 build box. You can copy it straight over. The directory /home/build_cd.5210R/yum-env will be used to download our RPMs into and it will also have the logfiles of the transactions and its own separate RPM database which we can query. Make sure your AlmaLinux 8 build box own YUM/DNF is tied into all the YUM repositories that you need for the ISO images and that these repositories are enabled.

Then create the following script and run it:

#!/bin/bash 
#  
# Copyright (c) 2019-2022 Michael Stauber, SOLARSPEED.NET
# Copyright (c) 2019-2022 Team BlueOnyx, BLUEONYX.IT
#
# Clean Packages directory:
rm -f /home/build_cd.5210R/5210R/Minimal/Packages/*
# Zap YUM/DNF-Info from last run:
rm -Rf /home/build_cd.5210R/yum-env/root/var
# Get all needed RPMs:
LC_ALL=C /usr/bin/dnf-3 -y groupinstall base --downloadonly --downloaddir=/home/build_cd.5210R/5210R/Minimal/Packages/ --installroot=/home/build_cd.5210R/yum-env/root/ --releasever=8
LC_ALL=C /usr/bin/dnf-3 -y groupinstall core --downloadonly --downloaddir=/home/build_cd.5210R/5210R/Minimal/Packages/ --installroot=/home/build_cd.5210R/yum-env/root/ --releasever=8
LC_ALL=C /usr/bin/dnf-3 -y groupinstall "Custom Operating System" blueonyx --downloadonly --downloaddir=/home/build_cd.5210R/5210R/Minimal/Packages/ --installroot=/home/build_cd.5210R/yum-env/root/ --releasever=8
LC_ALL=C /usr/bin/dnf-3 -y install dnf yum NetworkManager dracut-config-generic dracut-norescue firewalld kernel nfs-utils rsync tar dnf-utils anaconda grub2 grub2-efi-x64 efibootmgr efivar-libs shim-x64 authconfig chrony firewalld memtest86+ syslinux pv --downloadonly --downloaddir=/home/build_cd.5210R/5210R/Minimal/Packages/ --installroot=/home/build_cd.5210R/yum-env/root/ --releasever=8

That downloads all required RPMs that we need for the 5210R ISO. In our case the required RPMs are everything from these groups:

  • base  - an AlmaLinux group
  • core  - an AlmaLinux group
  • "Custom Operating System"   - an AlmaLinux group
  • blueonyx - our own group
  • And some select RPMs that we really need to get going, such as "dnf", "yum", "NetworkManager" and so on.

In order to rebuild the repository data for this newly populated "Minimal" ISO repository we need a custom comps.xml. No biggy. We can create one by hand! Oh, wait. There are now a whopping 1831 RPMs in that repository. That would require a lot of typing. \o/

Yum to the rescue again! But before we get to that, some preparational steps: Create the file /home/build_cd.5210R/yum-env/compsbuilder/comps.xml_header and put this into it:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE newcomps PUBLIC "-//CentOS//DTD Comps info//EN" "comps.dtd"> 

<comps>
 <group>
   <id>core</id>
   <name>Core</name>
   <description>Smallest possible installation</description>
   <default>false</default>
   <uservisible>false</uservisible>
   <packagelist>
     <packagereq variant="Minimal" type="mandatory">audit</packagereq>
     <packagereq variant="Minimal" type="mandatory">basesystem</packagereq>
     <packagereq variant="Minimal" type="mandatory">bash</packagereq>
     <packagereq variant="Minimal" type="mandatory">coreutils</packagereq>
     <packagereq variant="Minimal" type="mandatory">cronie</packagereq>
     <packagereq variant="Minimal" type="mandatory">curl</packagereq>
     <packagereq variant="Minimal" type="mandatory">dnf</packagereq>
     <packagereq variant="Minimal" type="mandatory">yum</packagereq>
     <packagereq variant="Minimal" type="mandatory">e2fsprogs</packagereq>
     <packagereq variant="Minimal" type="mandatory">filesystem</packagereq>
     <packagereq variant="Minimal" type="mandatory">firewalld</packagereq>
     <packagereq variant="Minimal" type="mandatory">glibc</packagereq>
     <packagereq variant="Minimal" type="mandatory">grubby</packagereq>
     <packagereq variant="Minimal" type="mandatory">hostname</packagereq>
     <packagereq variant="Minimal" type="mandatory">initscripts</packagereq>
     <packagereq variant="Minimal" type="mandatory">iproute</packagereq>
     <packagereq variant="Minimal" type="mandatory">iprutils</packagereq>
     <packagereq variant="Minimal" type="mandatory">iputils</packagereq>
     <packagereq variant="Minimal" type="mandatory" arch="aarch64,ppc64le,x86_64">irqbalance</packagereq>
     <packagereq variant="Minimal" type="mandatory">kbd</packagereq>
     <packagereq variant="Minimal" type="mandatory">kexec-tools</packagereq>
     <packagereq variant="Minimal" type="mandatory">less</packagereq>
     <packagereq variant="Minimal" type="mandatory">man-db</packagereq>
     <packagereq variant="Minimal" type="mandatory">ncurses</packagereq>
     <packagereq variant="Minimal" type="mandatory">openssh-clients</packagereq>
     <packagereq variant="Minimal" type="mandatory">openssh-server</packagereq>
     <packagereq variant="Minimal" type="mandatory">parted</packagereq>
     <packagereq variant="Minimal" type="mandatory">passwd</packagereq>
     <packagereq variant="Minimal" type="mandatory">plymouth</packagereq>
     <packagereq variant="Minimal" type="mandatory">policycoreutils</packagereq>
     <packagereq variant="Minimal" type="mandatory">procps-ng</packagereq>
     <packagereq variant="Minimal" type="mandatory">rootfiles</packagereq>
     <packagereq variant="Minimal" type="mandatory">rpm</packagereq>
     <packagereq variant="Minimal" type="mandatory">rng-tools</packagereq>
     <packagereq variant="Minimal" type="mandatory">rsyslog</packagereq>
     <packagereq variant="Minimal" type="mandatory">selinux-policy-targeted</packagereq>
     <packagereq variant="Minimal" type="mandatory">setup</packagereq>
     <packagereq variant="Minimal" type="mandatory">shadow-utils</packagereq>
     <packagereq variant="Minimal" type="mandatory">sssd-common</packagereq>
     <packagereq variant="Minimal" type="mandatory">sssd-kcm</packagereq>
     <packagereq variant="Minimal" type="mandatory">sudo</packagereq>
     <packagereq variant="Minimal" type="mandatory">systemd</packagereq>
     <packagereq variant="Minimal" type="mandatory">tuned</packagereq>
     <packagereq variant="Minimal" type="mandatory">util-linux</packagereq>
     <packagereq variant="Minimal" type="mandatory">vim-minimal</packagereq>
     <packagereq variant="Minimal" type="mandatory">xfsprogs</packagereq>
     <packagereq variant="Minimal" type="default">authselect</packagereq>
     <packagereq variant="Minimal" type="default" arch="x86_64">biosdevname</packagereq>
     <packagereq variant="Minimal" type="default">prefixdevname</packagereq>
     <packagereq variant="Minimal" type="default">dnf-plugins-core</packagereq>
     <packagereq variant="Minimal" type="default">dracut-config-rescue</packagereq>
     <packagereq variant="Minimal" type="default">iwl100-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl105-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl135-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl1000-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl2000-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl2030-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl3160-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl3945-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl4965-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl5000-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl5150-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl6000-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl6000g2a-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl6050-firmware</packagereq>
     <packagereq variant="Minimal" type="default">iwl7260-firmware</packagereq>
     <packagereq variant="Minimal" type="default">NetworkManager</packagereq>
     <packagereq variant="Minimal" type="default">NetworkManager-team</packagereq>
     <packagereq variant="Minimal" type="default">NetworkManager-tui</packagereq>
     <packagereq variant="Minimal" type="default">libsysfs</packagereq>
     <packagereq variant="Minimal" type="default">linux-firmware</packagereq>
     <packagereq variant="Minimal" type="default">lshw</packagereq>
     <packagereq variant="Minimal" type="default">lsscsi</packagereq>
     <packagereq variant="Minimal" type="default">kernel-tools</packagereq>
     <packagereq variant="Minimal" type="default" arch="x86_64">microcode_ctl</packagereq>
     <packagereq variant="Minimal" type="default" arch="ppc64le">opal-prd</packagereq>
     <packagereq variant="Minimal" type="default" arch="ppc64le">ppc64-diag</packagereq>
     <packagereq variant="Minimal" type="default" arch="ppc64le">powerpc-utils</packagereq>
     <packagereq variant="Minimal" type="default" arch="ppc64le">lsvpd</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils-base</packagereq>
     <packagereq variant="Minimal" type="default">sg3_utils</packagereq>
     <packagereq variant="Minimal" type="default">sg3_utils-libs</packagereq>
     <packagereq variant="Minimal" type="optional">dracut-config-generic</packagereq>
     <packagereq variant="Minimal" type="optional">dracut-network</packagereq>
     <packagereq variant="Minimal" type="optional" arch="s390x">libzfcphbaapi</packagereq>
     <packagereq variant="Minimal" type="optional">rdma-core</packagereq>
     <packagereq variant="Minimal" type="optional">selinux-policy-mls</packagereq>
     <packagereq variant="Minimal" type="optional" arch="x86_64">tboot</packagereq>
     <packagereq variant="Minimal" type="optional">initial-setup</packagereq>
     <packagereq variant="Minimal" type="mandatory">dnf-plugin-spacewalk</packagereq>
   </packagelist>
 </group>
 <group>
   <id>base</id>
   <name>Base</name>
   <description>The standard installation of AlmaLinux.</description>
   <default>false</default>
   <uservisible>false</uservisible>
   <packagelist>
     <packagereq variant="Minimal" type="mandatory">acl</packagereq>
     <packagereq variant="Minimal" type="mandatory">at</packagereq>
     <packagereq variant="Minimal" type="mandatory">attr</packagereq>
     <packagereq variant="Minimal" type="mandatory">bc</packagereq>
     <packagereq variant="Minimal" type="mandatory">cpio</packagereq>
     <packagereq variant="Minimal" type="mandatory">crontabs</packagereq>
     <packagereq variant="Minimal" type="mandatory">cyrus-sasl-plain</packagereq>
     <packagereq variant="Minimal" type="mandatory">dbus</packagereq>
     <packagereq variant="Minimal" type="mandatory">ed</packagereq>
     <packagereq variant="Minimal" type="mandatory">file</packagereq>
     <packagereq variant="Minimal" type="mandatory">iptstate</packagereq>
     <packagereq variant="Minimal" type="mandatory" arch="aarch64,ppc64le,x86_64">irqbalance</packagereq>
     <packagereq variant="Minimal" type="mandatory">kpatch</packagereq>
     <packagereq variant="Minimal" type="mandatory">logrotate</packagereq>
     <packagereq variant="Minimal" type="mandatory">lsof</packagereq>
     <packagereq variant="Minimal" type="mandatory" arch="x86_64">mcelog</packagereq>
     <packagereq variant="Minimal" type="mandatory" arch="x86_64">microcode_ctl</packagereq>
     <packagereq variant="Minimal" type="mandatory">net-tools</packagereq>
     <packagereq variant="Minimal" type="mandatory">pciutils</packagereq>
     <packagereq variant="Minimal" type="mandatory">psacct</packagereq>
     <packagereq variant="Minimal" type="mandatory">quota</packagereq>
     <packagereq variant="Minimal" type="mandatory">almalinux-release</packagereq>
     <packagereq variant="Minimal" type="mandatory">sudo</packagereq>
     <packagereq variant="Minimal" type="mandatory">symlinks</packagereq>
     <packagereq variant="Minimal" type="mandatory">systemd-udev</packagereq>
     <packagereq variant="Minimal" type="mandatory">tar</packagereq>
     <packagereq variant="Minimal" type="mandatory">tree</packagereq>
     <packagereq variant="Minimal" type="mandatory">util-linux-user</packagereq>
     <packagereq variant="Minimal" type="mandatory">rsyslog-gnutls</packagereq>
     <packagereq variant="Minimal" type="mandatory">rsyslog-gssapi</packagereq>
     <packagereq variant="Minimal" type="mandatory">rsyslog-relp</packagereq>
     <packagereq variant="Minimal" type="default">bash-completion</packagereq>
     <packagereq variant="Minimal" type="default">blktrace</packagereq>
     <packagereq variant="Minimal" type="default">bpftool</packagereq>
     <packagereq variant="Minimal" type="default">bzip2</packagereq>
     <packagereq variant="Minimal" type="default">chrony</packagereq>
     <packagereq variant="Minimal" type="default">cockpit</packagereq>
     <packagereq variant="Minimal" type="default">cryptsetup</packagereq>
     <packagereq variant="Minimal" type="default">dos2unix</packagereq>
     <packagereq variant="Minimal" type="default">dosfstools</packagereq>
     <packagereq variant="Minimal" type="default">ethtool</packagereq>
     <packagereq variant="Minimal" type="default">gnupg2</packagereq>
     <packagereq variant="Minimal" type="default">ledmon</packagereq>
     <packagereq variant="Minimal" type="default">libstoragemgmt</packagereq>
     <packagereq variant="Minimal" type="default">lvm2</packagereq>
     <packagereq variant="Minimal" type="default">mailcap</packagereq>
     <packagereq variant="Minimal" type="default">man-pages</packagereq>
     <packagereq variant="Minimal" type="default">mdadm</packagereq>
     <packagereq variant="Minimal" type="default">mlocate</packagereq>
     <packagereq variant="Minimal" type="default">mtr</packagereq>
     <packagereq variant="Minimal" type="default">nano</packagereq>
     <packagereq variant="Minimal" type="default">pinfo</packagereq>
     <packagereq variant="Minimal" type="default">plymouth</packagereq>
     <packagereq variant="Minimal" type="default">realmd</packagereq>
     <packagereq variant="Minimal" type="default">rng-tools</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils-cmsfs-fuse</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils-cpacfstatsd</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils-hmcdrvfs</packagereq>
     <packagereq variant="Minimal" type="default" arch="s390x">s390utils-zdsfs</packagereq>
     <packagereq variant="Minimal" type="default">rsync</packagereq>
     <packagereq variant="Minimal" type="default">smartmontools</packagereq>
     <packagereq variant="Minimal" type="default">sos</packagereq>
     <packagereq variant="Minimal" type="default">sssd</packagereq>
     <packagereq variant="Minimal" type="default">strace</packagereq>
     <packagereq variant="Minimal" type="default">teamd</packagereq>
     <packagereq variant="Minimal" type="default">time</packagereq>
     <packagereq variant="Minimal" type="default">unzip</packagereq>
     <packagereq variant="Minimal" type="default">usbutils</packagereq>
     <packagereq variant="Minimal" type="default">vdo</packagereq>
     <packagereq variant="Minimal" type="default">kmod-kvdo</packagereq>
     <packagereq variant="Minimal" type="default">virt-what</packagereq>
     <packagereq variant="Minimal" type="default">which</packagereq>
     <packagereq variant="Minimal" type="default">words</packagereq>
     <packagereq variant="Minimal" type="default">xfsdump</packagereq>
     <packagereq variant="Minimal" type="default">zip</packagereq>
     <packagereq variant="Minimal" type="optional">cifs-utils</packagereq>
     <packagereq variant="Minimal" type="optional">fwupd</packagereq>
     <packagereq variant="Minimal" type="optional" arch="aarch64,x86_64">fwupdate</packagereq>
     <packagereq variant="Minimal" type="optional">ima-evm-utils</packagereq>
     <packagereq variant="Minimal" type="optional">nfs-utils</packagereq>
     <packagereq variant="Minimal" type="optional">nvmetcli</packagereq>
     <packagereq variant="Minimal" type="optional" arch="ppc64le">servicelog</packagereq>
     <packagereq variant="Minimal" type="optional">traceroute</packagereq>
     <packagereq variant="Minimal" type="optional">zsh</packagereq>
     <packagereq variant="Minimal" type="optional">cockpit-doc</packagereq>
     <packagereq variant="Minimal" type="default" arch="ppc64le,x86_64">fprintd-pam</packagereq>
     <packagereq variant="Minimal" type="default">nmap-ncat</packagereq>
     <packagereq variant="Minimal" type="default">tcpdump</packagereq>
     <packagereq variant="Minimal" type="default">wget</packagereq>
     <packagereq variant="Minimal" type="default">vim-enhanced</packagereq>
     <packagereq variant="Minimal" type="default">insights-client</packagereq>
   </packagelist>
 </group>
 <group>
   <id>blueonyx</id>
   <name>BlueOnyx</name>
   <description>BlueOnyx 5210R</description>
   <default>true</default>
   <uservisible>true</uservisible>
   <packagelist>

That is the "top" part of your comps.xml and we use it as template. Then create the file /home/build_cd.5210R/yum-env/compsbuilder/comps.xml_footer and put this into it:

    </packagelist> 
 </group>
 <environment arch="ppc64le,x86_64">
   <id>graphical-server-environment</id>
   <name>BlueOnyx 5210R</name>
   <description>BlueOnyx 5210R for AlmaLinux 8.3</description>
   <display_order>1</display_order>
   <grouplist>
     <groupid>blueonyx</groupid>
     <groupid>core</groupid>
   </grouplist>
 </environment>
 <langpacks>
   <match name="aspell" install="aspell-%s"/>
   <match name="autocorr-en" install="autocorr-%s"/>
   <match name="gnome-getting-started-docs" install="gnome-getting-started-docs-%s"/>
   <match name="hunspell" install="hunspell-%s"/>
   <match name="hyphen" install="hyphen-%s"/>
   <match name="libreoffice-core" install="libreoffice-langpack-%s"/>
   <match name="libreoffice-core" install="libreoffice-help-%s"/>
   <match name="man-pages" install="man-pages-%s"/>
   <match name="mythes" install="mythes-%s"/>
 </langpacks>
</comps>

That is the bottom part of the comps.xml template. And we let YUM fill in the blanks with this script:

#!/bin/bash 
#
# Copyright (c) 2019-2022 Michael Stauber, SOLARSPEED.NET
# Copyright (c) 2019-2022 Team BlueOnyx, BLUEONYX.IT

# Generate comps.xml
cat /home/build_cd.5210R/yum-env/compsbuilder/comps.xml_header > /home/build_cd.5210R/yum-env/compsbuilder/comps.xml
LC_ALL=C /usr/bin/dnf-3 list --downloadonly --downloaddir=/home/build_cd.5210R/5210R/Minimal/Packages/ --installroot=/home/build_cd.5210R/yum-env/root/ --releasever=8 | awk {'print $1'} | sed -e 's@.i686@@'| sed -e 's@.x86_64@@'|sed -e 's@.noarch@@'|sort -u | awk {'print " <packagereq variant=\"Minimal\" type=\"mandatory\">"$1"</packagereq>"'} >> /home/build_cd.5210R/yum-env/compsbuilder/comps.xml
cat /home/build_cd.5210R/yum-env/compsbuilder/comps.xml_footer >> /home/build_cd.5210R/yum-env/compsbuilder/comps.xml

As you can see: It uses YUM/DNF to parse the RPM list and it inserts it right into the middle of our freshly generated comps.xml, that consists of the comps.xml_header, our YUM/DNF inserted part and the comps.xml_footer

Now we need to rebuild our YUM repository config files. As AlmaLinux 8 uses modular repositories, we really need an modules.yaml as well. Let me save you a lot of time by saying: The AlmaLinux Minimal ISO doesn't have one, but I grabbed one from their other ISO images. You can download it here and place it under /home/build_cd.5210R/yum-env/compsbuilder/modules.yaml. At the time you are reading this article, that modules.yaml may be outdated. In that case grab the most recent one from one of the official AlmaLinux 8 mirrors. Like this one. The file is called <uuid>-modules.yaml.gz. Gunzip it, rename it to modules.yaml, store it into under /home/build_cd.5210R/yum-env/compsbuilder/modules.yaml and you're good to go.

Well, almost. Say you include RPMs in your install order that are from a typically not active module repository? Like in our case for BlueOnyx 5210R where we have the module streams "python27" and "python38" active? In that case your custom kickstart script(s) on the ISOs must specifically set these module streams to active. That's why our %packages section in our three kickstart scripts looks like this:

%packages 
@minimal-environment
@core
authconfig
python27
python38
-postfix  
-kde-runtime
-kde-l10n-*
%end

With all that out of the way it is now time to roll up the ISO. Run this script to run both "createrepo" and "modifyrepo_c" against the "Minimal" directory:

#!/bin/bash 
#  
# Copyright (c) 2019-2022 Michael Stauber, SOLARSPEED.NET
# Copyright (c) 2019-2022 Team BlueOnyx, BLUEONYX.IT

# Create Repo:

mkdir -p /home/build_cd.5210R/5210R/Minimal/repodata

cp /home/build_cd.5210R/yum-env/compsbuilder/comps.xml /home/build_cd.5210R/5210R/Minimal/repodata/comps.xml
createrepo -s sha1 -g /home/build_cd.5210R/5210R/Minimal/repodata/comps.xml /home/build_cd.5210R/5210R/Minimal
cp /home/build_cd.5210R/yum-env/compsbuilder/comps.xml /home/build_cd.5210R/5210R/Minimal/repodata/comps.xml
cp /home/build_cd.5210R/yum-env/compsbuilder/modules.yaml /home/build_cd.5210R/5210R/Minimal/modules.yaml
modifyrepo_c --mdtype=modules /home/build_cd.5210R/5210R/Minimal/modules.yaml /home/build_cd.5210R/5210R/Minimal/repodata/

That runs "createrepo" with our custom comps.xml and then runs "modifyrepo_c" with our modules.yaml against the repo to add the module configuration to the repository as well. Now we're almost there: We do have a working repository for the ISO. Now we need to tell the installer that it actually should install the bloody extra RPMs as well. This requires some fiddling and a custom kickstart.cfg and I will NOT go into custom kickstart scripting, as it is a pretty complex topic in itself.

You will also need to modify /EFI/BOOT/grub.conf and /isolinux/isolinux.cfg on the ISO so that when the ISO boots, it presents the correct boot options to do the installation with our custom kickstart script. To give you an idea I have provided a directory here that has all the replacement configs and the custom kickstart scripts that we use for our BlueOnyx 5210R ISO image.

Once all these replacements are in place, it is time to roll up the ISO. This script does that:

#!/bin/bash 
#
# Copyright (c) 2015-2022 Michael Stauber, SOLARSPEED.NET
# Copyright (c) 2015-2022 Team BlueOnyx, BLUEONYX.IT

VER="5210R-AlmaLinux-8.6-"$(shell date --rfc-3339=date | sed s/-//g)

cd /home/build_cd.5210R/
rm -f /home/build_cd.5210R/5210R/BlueOnyx-$VER.iso

echo -n "Creating ISO Image BlueOnyx-$VER.iso "

# New 5210R one:
LC_ALL=C /usr/bin/mkisofs -o /home/build_cd.5210R/BlueOnyx-$VER.iso -b isolinux/isolinux.bin -J -R -l -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -graft-points -V "AlmaLinux-8-6-x86_64-dvd" /home/build_cd.5210R/5210R
LC_ALL=C isohybrid --uefi /home/build_cd.5210R/BlueOnyx-$VER.iso

cd ..
echo -n "[ "; echo -en "\\033[1;36mDONE\\033[0;39m"; echo " ]"
echo -n "Implanting MD5sum "
cd /home/build_cd.5210R
LC_ALL=C /usr/bin/implantisomd5 /home/build_cd.5210R/BlueOnyx-$VER.iso
echo -n "[ "; echo -en "\\033[1;36mDONE\\033[0;39m"; echo " ]"
echo

Of note here is that we build the ISO with UEFI support, so it will boot on systems with and without UEFI. Also take note that we did NOT change the name of the ISO and it remains the same as the ISO that we ripped off: "AlmaLinux-8-6-x86_64-dvd"

Do NOT change the name unless you know what you're doing. Because the UEFI grub.cfg, the isolinux/isolinux.cfg *and* the .discinfo and .treeinfo all have references to this name in one way or another and things will break hard if you get this wrong.

If you did it right, you will now have a custom ISO image that boots and installs all custom RPMs that you had specified in the provided kickstart - as long as that matches what was downloaded with YUM/DNF into the ISO's repository.

All in all? It's not that complicated as some might try to make you believe it is. The obstacles are basically just having the right comps.xml, the modules.yaml, a good kickstart script and then making the ends meet in the middle. If you need any assistance or further pointers? Don't hesitate to ask.


Return
General
May 27, 2022 Category: Development Posted by: mstauber
Previous page: CMU Migrations Next page: Site Prefix