Create custom rocky ISO with custom repository

Good day.

I need to create an installation ISO with Rocky Linux, but with an additional repository of my own and favorite packages. At first glance, it is enough to use the mkksiso tool.

mkksiso --ks <my kickstart file> --add <my repository> <original Rocky Linux ISO> <my new installation ISO>

But in this case, outdated repositories from the original ISO will be used. Or I will be forced to use online repositories to have latest updates.

I need to perform an automatic installation on the equipment in an isolated environment. Of course, I could create my own repository with the latest packages on the local network, but I would like to have everything I need on one ISO. In addition, I would like to perform another customization of the installation ISO.

I have studied the Lorax documentation and got the desired boot.iso. However, as @nazunalika correctly noted here boot.iso it does not contain repositories. boot.iso it does not look like a complete image from which it is possible to install, because it does not contain the .treeinfo file. As I understood from the anaconda source code, the installer searches for it on ISO and uses the data from it.

Question: How to make right the installation ISO from boot.iso?
Obviously, we need to append the .treeinfo file, add it to the ISO and add the required repositories.
What tool should I use to do this? Maybe mkksiso or something else?

If you are using the DVD iso we already provide, then the repositories on that ISO are from the release of that version, so yes, they will be out of date. You will be required to run a dnf update to get fully up to date post install.

This requires you to have the repositories locally and to use xorriso to combine everything together.

xorriso can be provided a “dialog” or otherwise a script that tells it what to do.

/usr/bin/xorriso -dialog on < /mnt/compose/9/latest-Rocky-9/work/entries/xorriso-x86_64-dvd.txt

Example xorriso dialog from above (trimmed to shorten the post), this lists every single file that will be added to the ISO:

-indev /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/lorax/images/boot.iso
-outdev Rocky-9.4-x86_64-dvd.iso
-boot_image any replay
-joliet on
-system_id LINUX
-compliance joliet_long_names

-volid Rocky-9-4-x86_64-dvd
-update /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/EFI/BOOT/grub.cfg EFI/BOOT/grub.cfg
-update /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/images/efiboot.img images/efiboot.img
-update /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/isolinux/isolinux.cfg isolinux/isolinux.cfg
-update /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/.discinfo .discinfo
-map /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/.treeinfo .treeinfo
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/0136654a4ede48381dc4bf8306af9c273579aae936ceec7e683c82e7cdde7863-other.sqlite.gz AppStream/repodata/0136654a4ede48381dc4bf8306af9c273579aae936ceec7e683c82e7cdde7863-other.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/04bbb4a0-6f6c-49d2-bf99-8fc7bbcdc587-UPDATEINFO.xml.gz AppStream/repodata/04bbb4a0-6f6c-49d2-bf99-8fc7bbcdc587-UPDATEINFO.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/070d8a5d8aceffddf867605b233bd1bd3ab9e3befcaa80a9242230a176f6bf9a-primary.sqlite.gz AppStream/repodata/070d8a5d8aceffddf867605b233bd1bd3ab9e3befcaa80a9242230a176f6bf9a-primary.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-FILELISTS.xml.gz AppStream/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-FILELISTS.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-GROUPS.xml AppStream/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-GROUPS.xml
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-GROUPS.xml.gz AppStream/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-GROUPS.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-MODULES.yaml.gz AppStream/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-MODULES.yaml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-OTHER.xml.gz AppStream/repodata/17038fe5-4604-4b47-8985-91da1f9126e3-OTHER.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/b0f4add3-84c9-4705-a2b5-f4f0b9ecd91b-PRIMARY.xml.gz AppStream/repodata/b0f4add3-84c9-4705-a2b5-f4f0b9ecd91b-PRIMARY.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/da0f35900dcd9e861ede6ad3fc62984bcd5a1521d866f567f08d186e5f7b5ce4-filelists.sqlite.gz AppStream/repodata/da0f35900dcd9e861ede6ad3fc62984bcd5a1521d866f567f08d186e5f7b5ce4-filelists.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/repomd.xml AppStream/repodata/repomd.xml
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/repodata/repomd.xml.asc AppStream/repodata/repomd.xml.asc
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/09bf773e6ca9f0a28fbf7a51026ee76173cb785fad9b383fa7b023ccde0693cf-filelists.sqlite.gz BaseOS/repodata/09bf773e6ca9f0a28fbf7a51026ee76173cb785fad9b383fa7b023ccde0693cf-filelists.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/4c3c542e-0dd5-49fa-9335-9cc6cd0446c7-PRIMARY.xml.gz BaseOS/repodata/4c3c542e-0dd5-49fa-9335-9cc6cd0446c7-PRIMARY.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/78ccc921d9ff0c45f9a22026bedf63e6f99ab68f788a73d467eeeb874d3e3276-other.sqlite.gz BaseOS/repodata/78ccc921d9ff0c45f9a22026bedf63e6f99ab68f788a73d467eeeb874d3e3276-other.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-FILELISTS.xml.gz BaseOS/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-FILELISTS.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-GROUPS.xml BaseOS/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-GROUPS.xml
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-GROUPS.xml.gz BaseOS/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-GROUPS.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-OTHER.xml.gz BaseOS/repodata/ae3999d9-4410-416e-8f49-dd215a1cbff1-OTHER.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/d9675e6d-d2b8-46d4-977f-de7f2e7fe6f1-UPDATEINFO.xml.gz BaseOS/repodata/d9675e6d-d2b8-46d4-977f-de7f2e7fe6f1-UPDATEINFO.xml.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/e6af173e0af860135bb23adb322845d3d9be23788f70235cab98af4cbc315c36-primary.sqlite.gz BaseOS/repodata/e6af173e0af860135bb23adb322845d3d9be23788f70235cab98af4cbc315c36-primary.sqlite.gz
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/repomd.xml BaseOS/repodata/repomd.xml
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/repodata/repomd.xml.asc BaseOS/repodata/repomd.xml.asc
-map /mnt/compose/9/latest-Rocky-9/work/lorax/x86_64/dvd/media.repo media.repo
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/Packages/3/389-ds-base-2.4.5-6.el9_4.x86_64.rpm AppStream/Packages/3/389-ds-base-2.4.5-6.el9_4.x86_64.rpm
-map /mnt/compose/9/latest-Rocky-9/compose/AppStream/x86_64/os/Packages/3/389-ds-base-libs-2.4.5-6.el9_4.x86_64.rpm AppStream/Packages/3/389-ds-base-libs-2.4.5-6.el9_4.x86_64.rpm
. . .
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/Packages/b/bash-5.1.8-9.el9.x86_64.rpm BaseOS/Packages/b/bash-5.1.8-9.el9.x86_64.rpm
-map /mnt/compose/9/latest-Rocky-9/compose/BaseOS/x86_64/os/Packages/b/bash-completion-2.11-5.el9.noarch.rpm BaseOS/Packages/b/bash-completion-2.11-5.el9.noarch.rpm
. . .

-end

If you are using one that already exists (such as the one from the DVD), you can simply copy it and modify as you see fit by hand. As a word of caution, one slight misconfiguration will break the installer, so it may take experimentation.

If you are making a brand new one to be placed on a new boot.iso, the best way is using the productmd python module. You can find examples of it being used in empanadas shared and empanadas iso utils. You would take the generated file and add it into the iso using xorriso, just like in the example above.

It seems to look like exactly what I need.
I will investigate this code.
Thank you!!!