A fix for a nasty SLES 15 SP3 Beta / openSUSE 15.3 Beta Autoyast bug in rules.xml handling

Currently beta versions of both SLES 15 SP3 and openSUSE 15.3 are available for broader testing. In doing so I stumbled over a nasty bug in Autoyast, SUSE’s solution for automatic OS installations, when using the rules.xml mechanism:

Screenshot of SLES 15 SP3 Beta error popup on rules.xml's supposed invalidity
SLES 15 SP3 Beta error popup on rules.xml’s supposed invalidity

Autoyast complains that “the rules file is not a valid XML document”, with the detail error message ERROR: Internal found no define for haspcmica. Which is funny not only because of the broken English in the error message but also because neither did my rules.xml contain any reference to haspcmica nor would it be required to. But the included hint about manual validation is actually useful because it leads to the actual culprit: /usr/share/YaST2/schema/autoyast/rng/rules.rng, which is a RelaxNG schema used to validate rules.xml files. This file is part of the installation system and the yast2-schema RPM and old farts will immediately have spotted that there is a typo: the old expansion card standard for laptops was called PCMCIA, not PCMICA, so it should have been haspcmcia, not haspcmica.

But it turns out, the string should have not been added at all: it has been removed from the schema upstream just two days ago. So if we applied that fix as well, we could continue testing the SLES 15 SP3 / openSUSE Linux 15.3 Betas. And how do we do that? Through linuxrc’s Driver Update Disk (DUD) mechanism!

Yes, DUDs used to be disks but nowadays we usually refer to (compressed) tar or cpio archives. DUDs get specified in the kernel command line but do get picked up by linuxrc, which is the friendly helper in initrd/initramfs images responsible for starting your Linux distribution’s installer. SUSE’s old Update Media HOWTO still serves as a good documentation together with the mkdud HOWTO and mkdud is also what we will use in this case alongside with mksusecd.

Step 1: Create a temporary directory:

mkdir -p dud/extracted

Step 2: Extract the yast2-schema RPM from the SLES 15 SP3 ISO (adapt for the openSUSE Linux 15.3 Beta) to obtain the rules.rng file:

mount -o loop /your/path/SLE-15-SP3-Full-x86_64-PublicBeta-Media1.iso /mnt
cd dud/extracted
rpm2cpio /mnt/Module-Basesystem/x86_64/yast2-schema-4.3.18-1.2.x86_64.rpm | cpio -ivd
umount /mnt

Step 3: Create the necessary directory structure and copy the file to be replaced in the installation system:

cd ..
mkdir -p usr/share/YaST2/schema/autoyast/rng
cp extracted/usr/share/YaST2/schema/autoyast/rng/rules.rng usr/share/YaST2/schema/autoyast/rng/

Step 4: Delete the temporary directory since we don’t need it anymore:

rm -r extracted

Step 5: Open the usr/share/YaST2/schema/autoyast/rng/ file in your favorite text editor and remove the | haspcmica line to reflect the upstream change.

Step 6: Install the mkdud utility and create the DUD:

zypper in mkdud
cd ..
mkdud --create yast2-schema-dud.tar.gz --name yast2-schema --dist sles15 --format tar.gz dud

Step 7: Install the mksusecd utility and create a patched version of the SLES 15 SP3 Beta ISO that includes our DUD in its initrd with a command such as the following:

mksusecd --create SLE-15-SP3-Full-x86_64-PublicBeta-Media1-patched.iso \
         --initrd yast2-schema-dud.tar.gz \
         --boot dud=file:/yast2-schema-dud.tar.gz \

Note that you could also supply the DUD via an extra USB stick or ISO image but I prefer having to deal with just one.

If you now boot that ISO and press Escape when the “Loading basic drivers” splash screen appears you can see the DUD being applied…

Screenshot of the DUD being applied
The DUD being applied

…and also observe that your rules.xml file now gets correctly applied:

Screenshot of the rules.xml file now being correctly applied
The rules.xml file now being correctly applied

If you want to see what happened behind the scenes press CTRL-ALT-F2 to switch to a text console. A ls -l / shows the DUD archive yast2-schema-dud.tar.gz that was added to the initrd and a ls -l /usr/share/YaST2/schema/autoyast/rng/r* shows that linuxrc replaced the patched file with a symlink into the unpacked DUD and all other neighboring files in that directory with symlinks into the original initrd image:

Screenshot of the fixed SLES 15 SP3 Beta Installation system
The fixed SLES 15 SP3 Beta Installation system