Customized AlmaLinux9.3 iso with kickstart file errors with Failed to setup installation souce:

I wish to install AlmaLinux 9.3 on a VMware virtual machine. I generated a template kickstart config by performing an install:

# Generated by Anaconda 34.25.3.8
# Generated by pykickstart v3.32
#version=RHEL9
# Use graphical install
graphical

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Use CDROM installation media
cdrom

%packages
@^minimal-environment

%end

# Run the Setup Agent on first boot
firstboot --enable

# Generated using Blivet version 3.6.0
ignoredisk --only-use=sda
autopart
# Partition clearing information
clearpart --none --initlabel

# System timezone
timezone America/New_York --utc

#Root password
rootpw --lock
user --groups=wheel --name=build --password=$6$6dwCGo0bNSEIY.FQ$1TlMKzNRlTtncT85ORF7hjF6eHLChTOwKb5GCz6bYWvYUcInDG75qB.K9bFj83uXeSvNt0JLOm6FhWGr4DKeJ/ --iscrypted --gecos="build"

Next, I generate a custom AlmaLinux 9.3 iso image and stuffed this kickstart configuration into it. My script:

$ cat ~/question.sh 
sudo rm -rf /data/alma-modified.iso /data/custom_iso
sudo mkdir -p /mnt/almaiso
mkdir -p /data/custom_iso

sudo mount -o loop /tmp/AlmaLinux-9.3-x86_64-minimal.iso /mnt/almaiso
cp -r /mnt/almaiso/* /data/custom_iso
cp /data/ks.cfg /data/custom_iso/
sudo chmod -R go+r /data/custom_iso

# Replace
# linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=Intersight quiet with
# linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=Intersight quiet inst.ks=cdrom:/ks.cfg
sudo sed -i '0,/linuxefi \(.*\)/s||linuxefi \1 inst.ks=cdrom:/ks.cfg |' /data/custom_iso/EFI/BOOT/grub.cfg
# Generate modified iso
cd /data/custom_iso && mkisofs \
	-V "AlmaLinux-9-3-x86_64-dvd" \
	-A "AlmaLinux-9-3-x86_64-dvd" \
	-o /data/alma-modified.iso \
	-joliet-long \
	-b isolinux/isolinux.bin \
	-c isolinux/boot.cat \
	-no-emul-boot \
	-boot-load-size 4 \
	-boot-info-table \
	-eltorito-alt-boot -e images/efiboot.img \
	-no-emul-boot \
	-R -J -v -T \
	.
sudo umount /mnt/almaiso

Output from running the script:

$ bash -x ~/question.sh
+ sudo rm -rf /data/alma-modified.iso /data/custom_iso
+ sudo mkdir -p /mnt/almaiso
+ mkdir -p /data/custom_iso
+ sudo mount -o loop /tmp/AlmaLinux-9.3-x86_64-minimal.iso /mnt/almaiso
mount: /mnt/almaiso: /tmp/AlmaLinux-9.3-x86_64-minimal.iso is already mounted.
+ cp -r /mnt/almaiso/EFI /mnt/almaiso/EULA /mnt/almaiso/LICENSE /mnt/almaiso/Minimal /mnt/almaiso/RPM-GPG-KEY-AlmaLinux-9 /mnt/almaiso/TRANS.TBL /mnt/almaiso/extra_files.json /mnt/almaiso/images /mnt/almaiso/isolinux /mnt/almaiso/media.repo /data/custom_iso
+ cp /data/ks.cfg /data/custom_iso/
+ sudo chmod -R go+r /data/custom_iso
+ sudo sed -i '0,/linuxefi \(.*\)/s||linuxefi \1 inst.ks=cdrom:/ks.cfg |' /data/custom_iso/EFI/BOOT/grub.cfg
+ cd /data/custom_iso
+ mkisofs -V AlmaLinux-9-3-x86_64-dvd -A AlmaLinux-9-3-x86_64-dvd -o /data/alma-modified.iso -joliet-long -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -R -J -v -T .
xorriso 1.5.4 : RockRidge filesystem manipulator, libburnia project.

Drive current: -outdev 'stdio:/data/alma-modified.iso'
Media current: stdio file, overwriteable
Media status : is blank
Media summary: 0 sessions, 0 data blocks, 0 data, 19.6g free
xorriso : WARNING : -volid text does not comply to ISO 9660 / ECMA 119 rules
xorriso : NOTE : -as genisofs: Ignored option '-T'
Added to ISO image: directory '/'='/data/custom_iso'
xorriso : UPDATE :    1012 files added in 1 seconds
xorriso : UPDATE :    1012 files added in 1 seconds
xorriso : UPDATE :  4.98% done
xorriso : UPDATE :  41.20% done
xorriso : UPDATE :  97.59% done
ISO image produced: 965090 sectors
Written to medium : 965090 sectors at LBA 0
Writing to 'stdio:/data/alma-modified.iso' completed successfully.

+ sudo umount /mnt/almaiso

I uploaded this iso image to my datastore:

$ govc datastore.upload -ds $VCENTER_DATASTORE  /data/alma-modified.iso alma-modified.iso
[08-03-24 06:22:22] Uploading... OK

After powering on the VM, the UI displays an error under Installation source and says
“Error setting up base repository”.

I want to install AlmaLinux only from the CDROM without fetching any packages from alma’s repositories online. I suspect that the additional text inst.ks=cdrom:/ks.cfg added to grub.cfg isn’t correct and couldn’t find any documentation on how to specify the cdrom.

On the VM, /proc/cmdline shows

BOOT_IMAGE=/images/pxeboot/vmlinuz inst.stage2=hd:LABEL=AlmaLinux-9-3-x86_64-dvd quiet inst.ks=cdrom:/ks.cfg

Snippet from anaconda.log:

11:23:22,731 DBG ui.gui.hubs: spoke is not ready: KeyboardSpoke
11:23:22,731 DBG ui.gui.hubs: setting KeyboardSpoke status to: Getting list of layouts...
11:23:22,743 DBG ui.gui.hubs: spoke is not ready: SoftwareSelectionSpoke
11:23:22,753 DBG ui.gui.hubs: spoke is not ready: SourceSpoke
11:23:22,753 DBG ui.gui.hubs: setting SourceSpoke status to: Setting up installation source...
11:23:22,753 DBG ui.gui.hubs: setting SourceSpoke status to: Probing storage...
11:23:22,753 DBG ui.gui.hubs: setting SourceSpoke status to: Failed to set up installation source
11:23:22,763 DBG ui.gui.hubs: spoke is ready: SourceSpoke
11:23:22,765 INF ui.gui.helpers: kickstart installation stopped for info: User interaction required on spoke Installation Source
11:23:22,766 DBG ui.gui.hubs: setting SoftwareSelectionSpoke status to: Failed to set up installation source
11:23:22,766 DBG ui.gui.hubs: setting StorageSpoke status to: Probing storage...
11:23:22,766 DBG ui.gui.hubs: setting StorageSpoke status to: Probing storage...
11:23:22,766 DBG ui.gui.hubs: setting OSCAPSpoke status to: Fetching content data
11:23:22,767 DBG ui.gui.hubs: spoke is not ready: OSCAPSpoke
11:23:22,772 DBG ui.gui.hubs: spoke is ready: PasswordSpoke
11:23:22,774 DBG ui.gui.hubs: kickstart installation, spoke Root Password is ready
11:23:22,853 DBG ui.gui.utils: Finished applying <bound method AddLayoutDialog._addLayout of <pyanaconda.ui.gui.spokes.keyboard.AddLayoutDialog object at 0x7fccc8042400>> on <list object at 0x7fccc2e82800>
11:23:22,854 INF threading: Thread Done: AnaAddLayoutsInitThread (140517518079552)
11:23:22,855 INF lifecycle: Module initialized: KeyboardSpoke
11:23:22,855 INF threading: Thread Done: AnaKeyboardThread (140517937145408)
06:23:22,000 INF isys: System time set to Fri Mar  8 11:23:22 2024 UTC
06:23:22,000 INF isys: System time set to Fri Mar  8 11:23:22 2024 UTC
06:23:22,000 INF isys: System time set to Fri Mar  8 11:23:22 2024 UTC
06:23:22,001 INF lifecycle: Module initialized: DatetimeSpoke
06:23:22,001 INF threading: Thread Done: AnaDateTimeThread (140517417154112)
06:23:22,005 INF lifecycle: Module initialized: StorageSpoke
06:23:22,005 INF threading: Thread Done: AnaStorageWatcher (140517390296640)
06:23:22,010 DBG ui.gui.hubs: spoke is ready: KeyboardSpoke
06:23:22,012 DBG ui.gui.hubs: kickstart installation, spoke Keyboard is ready
06:23:22,017 DBG ui.gui.hubs: spoke is ready: DatetimeSpoke
06:23:22,018 DBG ui.gui.hubs: kickstart installation, spoke Time & Date is ready
06:23:22,023 DBG ui.gui.spokes.storage: Running the execute method for the AUTOMATIC partitioning method.
06:23:22,024 INF threading: Running Thread: AnaExecuteStorageThread (140517390296640)
06:23:22,024 DBG ui.gui.spokes.storage: Saving storage configuration...
06:23:22,108 DBG ui.gui.hubs: spoke is not ready: StorageSpoke
06:23:22,108 DBG ui.gui.hubs: setting StorageSpoke status to: Saving storage configuration...
06:23:22,258 INF threading: Thread Done: AnaPayloadThread (140517429995072)
06:23:22,259 DBG ui.gui.spokes.software_selection: Skip the initialization of the software selection.
06:23:22,259 INF lifecycle: Module initialized: SoftwareSelectionSpoke
06:23:22,259 INF threading: Thread Done: AnaSoftwareWatcher (140517400106560)
06:23:22,264 INF lifecycle: Module initialized: SourceSpoke
06:23:22,264 INF lifecycle: All modules have been initialized.
06:23:22,264 DBG misc: OSCAP addon: Anaconda init_done signal triggered
06:23:22,264 INF threading: Thread Done: AnaSourceWatcher (140517408499264)
06:23:22,264 DBG ui.gui.spokes.installation_source: Clearing checks in source spoke
06:23:22,265 DBG ui.gui.spokes.installation_source: Setting up repos: []
06:23:22,325 DBG ui.gui.hubs: spoke is ready: SoftwareSelectionSpoke
06:23:22,325 INF ui.gui.helpers: kickstart installation stopped for info: User interaction required on spoke Software Selection
06:23:22,343 DBG ui.gui.hubs: spoke is ready: SourceSpoke
06:23:22,347 INF ui.gui.helpers: kickstart installation stopped for info: User interaction required on spoke Installation Source
06:23:22,999 INF misc: OSCAP addon: Identified /usr/share/xml/scap/ssg/content//ssg-almalinux9-ds.xml as Source Data Stream
06:23:23,000 INF misc: OSCAP Addon: finished looking at the content
06:23:23,000 INF misc: OSCAP Addon: Opening SCAP content at /usr/share/xml/scap/ssg/content/ssg-almalinux9-ds.xml without considering tailoring
06:23:23,044 DBG ui.gui.spokes.storage: Checking storage configuration...
06:23:23,112 DBG ui.gui.hubs: setting StorageSpoke status to: Checking storage configuration...
06:23:23,740 INF misc: OSCAP Addon: Done with analysis
06:23:23,743 INF threading: Thread Done: OSCAPguiWaitForDataFetchThread (140517381641792)
06:23:23,817 DBG ui.gui.hubs: spoke is ready: OSCAPSpoke
06:23:23,817 DBG ui.gui.hubs: kickstart installation, spoke Security Profile is ready
06:23:23,818 DBG ui.gui.hubs: spoke is ready: OSCAPSpoke
06:23:23,818 DBG ui.gui.hubs: kickstart installation, spoke Security Profile is ready
06:23:23,819 DBG ui.gui.hubs: spoke is ready: OSCAPSpoke
06:23:23,819 DBG ui.gui.hubs: kickstart installation, spoke Security Profile is ready
06:23:24,089 DBG ui.gui.spokes.storage: Partitioning has been applied: ValidationReport(error_messages=[], warning_messages=[])
06:23:24,090 INF threading: Thread Done: AnaExecuteStorageThread (140517390296640)
06:23:24,150 DBG ui.gui.hubs: incomplete spokes: [SourceSpoke, SoftwareSelectionSpoke]
06:23:24,151 DBG ui.gui.hubs: spoke is ready: StorageSpoke
06:23:24,152 DBG ui.gui.hubs: kickstart installation, spoke Installation Destination is ready
06:23:24,155 DBG ui.gui.hubs: spoke is not ready: KdumpSpoke
06:23:24,158 DBG ui.gui.hubs: spoke is ready: KdumpSpoke
06:23:24,158 DBG ui.gui.hubs: kickstart installation, spoke KDUMP is ready