Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mkdud for openSUSE:Factory checked 
in at 2025-09-10 20:23:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mkdud (Old)
 and      /work/SRC/openSUSE:Factory/.mkdud.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mkdud"

Wed Sep 10 20:23:04 2025 rev:39 rq:1303674 version:2.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/mkdud/mkdud.changes      2025-08-28 
17:20:36.996114099 +0200
+++ /work/SRC/openSUSE:Factory/.mkdud.new.1977/mkdud.changes    2025-09-10 
20:23:23.004106818 +0200
@@ -1,0 +2,17 @@
+Wed Sep 10 16:25:06 UTC 2025 - [email protected]
+
+- merge gh#openSUSE/mkdud#45
+- fix "How to apply" output
+- 2.2
+
+--------------------------------------------------------------------
+Wed Sep 10 16:02:20 UTC 2025 - [email protected]
+
+- merge gh#openSUSE/mkdud#44
+- support expressing installation ISO changes in DUDs
+  (jsc#PED-13262)
+- add --dracut-hook option
+- update documentation
+- 2.1
+
+--------------------------------------------------------------------

Old:
----
  mkdud-2.0.tar.xz

New:
----
  mkdud-2.2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mkdud.spec ++++++
--- /var/tmp/diff_new_pack.9TvP53/_old  2025-09-10 20:23:23.440125229 +0200
+++ /var/tmp/diff_new_pack.9TvP53/_new  2025-09-10 20:23:23.440125229 +0200
@@ -49,7 +49,7 @@
 Summary:        Create driver update from rpms
 License:        GPL-3.0-or-later
 Group:          Hardware/Other
-Version:        2.0
+Version:        2.2
 Release:        0
 Source:         %{name}-%{version}.tar.xz
 Url:            https://github.com/openSUSE/mkdud

++++++ mkdud-2.0.tar.xz -> mkdud-2.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/HOWTO.md new/mkdud-2.2/HOWTO.md
--- old/mkdud-2.0/HOWTO.md      2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/HOWTO.md      2025-09-10 18:25:06.000000000 +0200
@@ -175,17 +175,32 @@
 to enable the `foo` service.
 
 
-## Execute commands (YaST only)
+## Execute commands
 
 Sometimes the commands in `update.pre` are run too late for your purpose. It 
is possible to run commands immediately (when the driver update has
-been loaded). For this, the `exec` config option can be used. For example
+been loaded). For this, the `exec` option can be used. For example
 
 ```sh
-mkdud --create foo.dud --dist xxx --config "exec=rmmod foo"
+mkdud --create foo.dud --dist xxx --exec="rmmod foo"
 ```
 
 would unload module `foo` immediately.
 
+Note that the moment when this command is run differs between installations 
using YaST and Agama.
+
+For YaST, the command is run just before any kernel module changes would be 
handled.
+
+For Agama, the command is run at the end of the pre-pivot dracut hook - after 
Agama has handled the driver update.
+
+Agama-based installations use dracut in the initrd. mkdud offers a 
`--dracut-hook` option to conveniently run code
+at specifc dracut hooks. For example:
+
+```sh
+mkdud --create foo.dud --dist sle16 --dracut-hook cmdline:"echo Hello!"
+```
+
+Would insert a script in dracut hook `cmdline` that runs "echo Hello!".
+
 
 ## Combine driver updates
 
@@ -302,7 +317,7 @@
     ID:
       45f627da-b7c4-48ed-94c1-31e25ed92442
     Installer:
-      YaST
+      Agama
     Modules:
       e1000.ko.xz (6.12.0-160000.18-default.x86_64)
     Initrd:
@@ -328,9 +343,43 @@
 - sets the root password used in the installation system (note the different 
option compared to the last example)
 - sets boot option `nomodeset`
 
-Since boot options can not be changed during an installation (it is too late), 
the
-DUD can only be applied by modifying the installation medium.
+Since boot options cannot be changed during an installation the
+DUD can only be applied by modifying the installation medium using mkmedia.
+
+### Example 4
+
+```
+# mkdir -p /tmp/foo/EFI/BOOT
+# cp /usr/share/efi/x86_64/shim.efi /tmp/foo/EFI/BOOT/bootx64.efi
+# cp /usr/share/grub2/x86_64-efi/grub.efi /tmp/foo/EFI/BOOT/grub.efi
+# mkdud --create foo.dud --dist leap16.0 --name "Test update" \
+  --iso /tmp/foo
+===  Update #1  ===
+  [openSUSE Leap 16.0]
+    Name:
+      Test update
+    ID:
+      15aad607-f8e6-46d2-9667-7434ef3660ae
+    Installer:
+      Agama
+    ISO:
+      /EFI/BOOT/bootx64.efi
+      /EFI/BOOT/grub.efi
+    How to apply this DUD:
+      [✘] during installation: using boot option dud=URL_TO_DUD_FILE
+      [✘] during installation: unpacked on local file system with label 
'OEMDRV'
+      [✘] during installation: renamed as 'driverupdate' in installation 
repository
+      [✘] rebuilding installation media using 'mkmedia --initrd DUD_FILE ...'
+      [✔] rebuilding installation media using 'mkmedia --apply-dud DUD_FILE 
...'
+```
+
+This DUD
+
+- is intended for Agama (Leap 16.0)
+- updates shim and grub on the installation medium (taking binaries from the 
currently installed packages)
 
+Since the cfhanges are intended for the installation ISO itself the
+DUD can only be applied by modifying the installation medium using mkmedia.
 
 
 ## Troubleshooting (YaST-based installations)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/README.md new/mkdud-2.2/README.md
--- old/mkdud-2.0/README.md     2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/README.md     2025-09-10 18:25:06.000000000 +0200
@@ -35,16 +35,43 @@
 - update kernel modules
 - change files in the initrd of the installation medium
 - change files in the installation system / live root of the installation 
medium
+- change files on the installation medium
 - change boot options
 - change installer config options
 - provide updated packages to be installed
 - add scripts to be run before and after the installer runs
 
-The format of DUDs is described in the [Update Media 
Howto](http://ftp.suse.com/pub/people/hvogel/Update-Media-HOWTO/Update-Media-HOWTO.html).
+mkdud provides an easy way to create these DUDs. See [Driver updates and 
you](HOWTO.md) for detailed instructions and usage examples.
 
-`mkdud` provides an easy way to create these DUDs.
+The file format of DUDs is described in the [Update Media 
Howto](http://ftp.suse.com/pub/people/hvogel/Update-Media-HOWTO/Update-Media-HOWTO.html).
 
-See [HOWTO](HOWTO.md) for detailed instructions.
+mkdud and 
[mkmedia](https://github.com/openSUSE/mksusecd?tab=readme-ov-file#mkmedia) 
support an extension of this format that allows expressing changes intended for 
the initrd used
+during installation and the installation medium itself. For this, two new sub 
directories `initrd` and `iso` are added to the
+driver update [directory 
structure](https://ftp.suse.com/pub/people/hvogel/Update-Media-HOWTO/Update-Media-HOWTO.html#id_dud1).
+
+With this extension, the internal driver update layout looks like this:
+
+```
+linux/
+└── suse/
+    └── x86_64-sle16/
+        ├── dud.config
+        ├── initrd/
+        │   └── foo1
+        ├── inst-sys/
+        │   └── foo2
+        ├── install/
+        │   ├── update.pre     # only for YaST
+        │   ├── update.post    # only for YaST
+        │   ├── update.post2   # only for YaST
+        │   └── foo3.rpm
+        ├── iso/
+        │   └── foo4
+        └── modules/
+            ├── module.order
+            ├── module1.ko.zst
+            └── module2.ko.zst
+```
 
 ### DUD formats
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/VERSION new/mkdud-2.2/VERSION
--- old/mkdud-2.0/VERSION       2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/VERSION       2025-09-10 18:25:06.000000000 +0200
@@ -1 +1 @@
-2.0
+2.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/changelog new/mkdud-2.2/changelog
--- old/mkdud-2.0/changelog     2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/changelog     2025-09-10 18:25:06.000000000 +0200
@@ -1,3 +1,14 @@
+2025-09-10:    2.2
+       - merge gh#openSUSE/mkdud#45
+       - fix "How to apply" output
+
+2025-09-10:    2.1
+       - merge gh#openSUSE/mkdud#44
+       - support expressing installation ISO changes in DUDs
+         (jsc#PED-13262)
+       - add --dracut-hook option
+       - update documentation
+
 2025-08-28:    2.0
        - merge gh#openSUSE/mkdud#42
        - make mkdud SLE-16 aware (jsc#PED-13262)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/mkdud new/mkdud-2.2/mkdud
--- old/mkdud-2.0/mkdud 2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/mkdud 2025-09-10 18:25:06.000000000 +0200
@@ -139,6 +139,7 @@
 my $opt_prio = 50;
 my @opt_name;
 my @opt_exec;
+my @opt_hook;
 my $opt_no_docs = 1;
 my $opt_save_temp;
 my %opt_install;
@@ -159,8 +160,10 @@
 my $opt_fix_usr_src = 1;
 my $opt_fix_dist = 1;
 my $opt_fix_adddir = 1;
+my $opt_check_hooks = 1;
 my @opt_initrd;
 my $opt_installer;
+my @opt_iso;
 
 # global variables
 my $dud;
@@ -179,6 +182,7 @@
 my $pubkey_info;
 my $yast_version = 0;
 my $mkisofs = -x '/usr/bin/mkisofs' ? '/usr/bin/mkisofs' : 
'/usr/bin/genisoimage';
+my $hooks;
 
 # linuxrc versions in service packs
 my $servicepack;
@@ -193,6 +197,12 @@
 $servicepack->{11}{3} = "3.3.91";
 $servicepack->{11}{4} = "3.3.108";
 
+my %dracut_hooks;
+@dracut_hooks{qw (
+  cleanup cmdline emergency mount netroot pre-mount pre-pivot pre-shutdown 
pre-trigger pre-udev shutdown shutdown-emergency
+  initqueue/finished initqueue/online initqueue/settled initqueue/timeout
+)} = ( 1 .. 100 );
+
 GetOptions(
   'create|c=s'       => sub { $opt_create = 1; $dud = $_[1] },
   'show|s=s'         => sub { $opt_show = 1; $dud = $_[1] },
@@ -202,6 +212,7 @@
   'prio|p=i'         => \$opt_prio,
   'name|n=s'         => \@opt_name,
   'exec|x=s'         => \@opt_exec,
+  'dracut-hook|hook=s' => \@opt_hook,
   'config=s'         => \@opt_config,
   'condition=s'      => \@opt_condition,
   'may-replace-yast' => sub { $opt_fix_yast = 0 },
@@ -212,11 +223,12 @@
   'sign-key=s'       => \$opt_sign_key,
   'sign-key-id=s'    => \$opt_sign_key_id,
   'obs-keys'         => \$opt_obs_keys,
-  'force'            => sub { $opt_fix_yast = $opt_fix_usr_src = $opt_fix_dist 
= $opt_fix_adddir = 0 },
+  'force'            => sub { $opt_fix_yast = $opt_fix_usr_src = $opt_fix_dist 
= $opt_fix_adddir = $opt_check_hooks = 0 },
   'fix-yast!'        => \$opt_fix_yast,
   'fix-usr-src!'     => \$opt_fix_usr_src,
   'fix-dist!'        => \$opt_fix_dist,
   'fix-adddir!'      => \$opt_fix_adddir,
+  'check-hooks!'     => \$opt_check_hooks,
   'format=s'         => \$opt_format,
   'prefix=i'         => \$opt_dud_prefix,
   'volume=s'         => \$opt_volume,
@@ -225,6 +237,7 @@
   'application=s'    => \$opt_application,
   'installer=s'      => \$opt_installer,
   'initrd=s'         => \@opt_initrd,
+  'iso=s'            => \@opt_iso,
   'save-temp'        => \$opt_save_temp,
   'version'          => sub { print "$VERSION\n"; exit 0 },
   'help'             => sub { usage 0 },
@@ -300,13 +313,14 @@
 if($opt_create) {
   file_type $_ for (@ARGV);
   file_type $_, 1 for (@opt_initrd);
+  file_type $_, 2 for (@opt_iso);
 
   my $need_dist;
   for (@files) {
     $need_dist = 1, last if $_->{type} ne "dud";
   }
 
-  $need_dist ||= @opt_config || @opt_exec || @opt_name;
+  $need_dist ||= @opt_config || @opt_exec || @opt_hook || @opt_name || 
@opt_initrd || @opt_iso;
 
   if($need_dist) {
     die "Error: distribution arg is required; use --dist.\n" if !@opt_dist;
@@ -342,7 +356,7 @@
     }
 
     for (@dists) {
-      
if(!/^((leap|kubic|casp|caasp|suse-microos)?\d+\.\d+|tw|sle[sd]\d+|sle1[6-9])$/)
 {
+      
if(!/^((leap|kubic|casp|caasp|suse-microos)?\d+\.\d+|tw|sle[sd]\d+|sle1[6-9]|((fedora|rhel|sll)\d+))$/)
 {
         if(!$opt_fix_dist) {
           print STDERR "***  Note: using unsupported dist \"$_\"\n";
         }
@@ -434,9 +448,11 @@
   -p, --prio NUM                Set repository priority to NUM (default: 50).
   -n, --name NAME               Set driver update name.
   -x, --exec COMMAND            Run command just after the driver update has 
been loaded.
+      --dracut-hook HOOK:CMD    Insert CMD into dracut hook HOOK. See man page 
for details.
   -i, --install METHODS         Package install method. METHODS is a 
comma-separated list
                                 of: instsys, repo, rpm (default: 
'instsys,repo,rpm').
-      --initrd RPM|DIR          Add RPM or DIR to initrd instead of instsys 
(option can be repeated).
+      --initrd RPM|DIR          Add RPM or DIR to initrd (option can be 
repeated).
+      --iso DIR                 Add DIR to installation ISO image (option can 
be repeated).
       --installer INSTALLER     Set installation program. Either agama or yast
                                 (default: auto-detected based on dist).
       --config KEY=VALUE        Set initrd config option KEY to VALUE (option 
can be repeated).
@@ -447,6 +463,7 @@
       --no-fix-dist             Allow to specify an arbitrary distribution 
name with --dist.
       --no-fix-usr-src          Allow driver update to include 
/usr/src/packages.
       --no-fix-adddir           Do not include an updated adddir script.
+      --no-check-hooks          Do not restrict dracut hook names.
       --format FORMAT           Specify archive format for DUD (default: 
cpio.gz).
                                 FORMAT=((cpio|tar|iso)[.(gz|xz)])|rpm.
       --prefix NUM              First directory prefix of driver update.
@@ -531,7 +548,9 @@
   my $gpg = "gpg --homedir=$sign_key_dir --yes --output - 2>/dev/null";
   my $gpg_sign;
 
-  my $for_initrd = $_[1];
+  my $for_instsys = $_[1] == 0;
+  my $for_initrd = $_[1] == 1;
+  my $for_iso = $_[1] == 2;
 
   if(!-e $_[0]) {
     print STDERR "$_[0]: error: no such file or directory\n";
@@ -541,7 +560,7 @@
   $_ = `file -b -k -L $_[0] 2>/dev/null`;
 
   if(/^RPM/) {
-    my $ft = { type => ($for_initrd ? 'rpm_initrd' : 'rpm'), file => $_[0] };
+    my $ft = { type => ($for_initrd ? 'rpm_initrd' : $for_iso ? 'rpm_iso' : 
'rpm'), file => $_[0] };
 
     my $f = `rpm --nosignature -qp --qf 
'%{NAME}\t%{VERSION}\t%{RELEASE}.%{ARCH}' $_[0] 2>$tmp_err`;
     if($f eq "") {
@@ -558,7 +577,7 @@
 
     $ft->{alternatives} = $links if $links;
 
-    if(!$for_initrd) {
+    if($for_instsys) {
       # check if rpm contains a driver update
       # (a directory /linux/suse/foo-bar or /<NUMBER>/linux/suse/foo-bar 
exists)
       for my $line (`rpm --nosignature -qp -lv $_[0] 2>$tmp_err`) {
@@ -604,7 +623,7 @@
       return;
     }
   }
-  elsif(!$for_initrd && $_[0] =~ m#${kext_regexp}$#) {
+  elsif($for_instsys && $_[0] =~ m#${kext_regexp}$#) {
     my $ft = { file => $_[0] };
 
     my $ar = get_file_arch $_[0];
@@ -621,7 +640,7 @@
 
     return;
   }
-  elsif(!$for_initrd && /^ELF/) {
+  elsif($for_instsys && /^ELF/) {
     @i = split /\s*,\s*/;
 
     my $ft = { file => $_[0] };
@@ -640,17 +659,17 @@
 
     return;
   }
-  elsif(!$for_initrd && / (cpio|tar) archive/) {
+  elsif($for_instsys && / (cpio|tar) archive/) {
     $dud = $1;
   }
-  elsif(!$for_initrd && /^(gzip|XZ) compressed data/) {
+  elsif($for_instsys && /^(gzip|XZ) compressed data/) {
     my $cmd = "\L$1";
     my $f = $cmd ne 'gzip' ? $cmd : 'gz';
     my $z = `$cmd -dc $_[0] | file -b -`;
     $dud = "$1.$f" if $z =~ / (cpio|tar) archive/;
     $dud = "iso.$f" if $z =~ / ISO 9660 CD-ROM /;
   }
-  elsif(!$for_initrd && / ISO 9660 CD-ROM /) {
+  elsif($for_instsys && / ISO 9660 CD-ROM /) {
     if(!$>) {
       system "mount -oro,loop $_[0] $tmp_mnt";
       file_type "$tmp_mnt", 1;
@@ -662,7 +681,7 @@
     $dud = 'dummy';
   }
   elsif(-d $_[0]) {
-    if(!$for_initrd) {
+    if($for_instsys) {
       if($_[0] =~ /(^|\/)y2update\/*$/) {
         push @files, { type => 'y2update', file => $_[0] };
 
@@ -683,7 +702,7 @@
     }
 
     if(!$dud) {
-      my $ft = { type => ($for_initrd ? 'initrd' : 'instsys'), file => $_[0] };
+      my $ft = { type => ($for_initrd ? 'initrd' : $for_iso ? 'iso' : 
'instsys'), file => $_[0] };
 
       File::Find::find(sub {
         if(-f $_) {
@@ -701,17 +720,17 @@
       return;
     }
   }
-  elsif(!$for_initrd && -f $_[0] && $_[0] =~ 
m#(^|/)(update\.(pre|post|post2)|module\.(order|config))$#) {
+  elsif($for_instsys && -f $_[0] && $_[0] =~ 
m#(^|/)(update\.(pre|post|post2)|module\.(order|config))$#) {
     push @files, { type => $2, file => $_[0] };
 
     return;
   }
-  elsif(!$for_initrd && -f $_[0] && $_[0] =~ m#(^|/)(.*\.(ycp|ybc|rb))$#) {
+  elsif($for_instsys && -f $_[0] && $_[0] =~ m#(^|/)(.*\.(ycp|ybc|rb))$#) {
     push @files, { type => $3, file => $_[0] };
 
     return;
   }
-  elsif(!$for_initrd && -f $_[0] && -s _ && -T _) {
+  elsif($for_instsys && -f $_[0] && -s _ && -T _) {
     open my $f, $_[0];
     local $/;  # complete file
     my $l = <$f>;
@@ -729,7 +748,7 @@
       return;
     }
   }
-  elsif(!$for_initrd) {
+  elsif($for_instsys) {
     for (`gpg --homedir=$sign_key_dir --verify $_[0] 2>&1`) {
       chomp;
       $gpg_sign = $1, last if /^gpg: Signature made\s*(.*)$/;
@@ -956,6 +975,87 @@
     my @rpms;
     my $scripts;
 
+    if($installer ne 'yast' && @opt_exec) {
+      for my $x (@opt_exec) {
+        push @$hooks, { dir => "pre-pivot", cmd => $x, script_name => 
"99-zz-mkdud.sh" };
+      }
+    }
+
+    if($installer ne 'yast' && (@opt_hook || $hooks)) {
+      for my $x (@opt_hook) {
+        # pre-pivot:99-xxx.sh
+        # pre-pivot:foobar
+
+        die "invalid dracut hook spec: $x\n" if $x !~ /^([^:]+):(.+)$/;
+
+        my $hook_dir = $1;
+        my $cmd = $2;
+
+        die "invalid dracut hook: $hook_dir\n" if !$dracut_hooks{$hook_dir} && 
$opt_check_hooks;
+
+        my $script_name;
+        my $f;
+
+        for($f = 0; $f < @files; $f++) {
+          my $n = $files[$f]{file};
+          $n =~ s#.*/##;
+          last if $n eq $cmd;
+        }
+
+        undef $f if $f >= @files;
+
+        if($cmd =~ /^\d\d-\S+\.sh$/) {
+          die "$cmd: dracut hook script missing\n" unless defined $f;
+          $script_name = $cmd;
+          undef $cmd;
+        }
+        else {
+          undef $f;
+          $script_name = "99-zz-mkdud.sh";
+        }
+
+        my $h = { dir => $hook_dir, script_name => $script_name };
+
+        $h->{cmd} = $cmd if $cmd;
+
+        if(defined $f) {
+          $h->{file} = $files[$f];
+          splice @files, $f, 1;
+        }
+
+        push @$hooks, $h;
+      }
+
+      # print Dumper $hooks;
+
+      if($hooks) {
+        $dud_ok = 1;
+        mkdir "$base/initrd", 0755;
+        open my $f, ">>", "$base/initrd/.update.initrd.$id";
+        close $f;
+        File::Path::mkpath("$base/initrd/var/lib/dracut/hooks", { mode => 0755 
});
+
+        for my $h (@$hooks) {
+          my $dir = "$base/initrd/var/lib/dracut/hooks/$h->{dir}";
+          File::Path::mkpath($dir, { mode => 0755 });
+          my $s = "$dir/$h->{script_name}";
+          if($h->{cmd}) {
+            my $sh = "#! /usr/bin/sh\n";
+            $sh = "" if -f $s;
+            open my $fd, ">>", "$dir/$h->{script_name}";
+            print $fd $sh;
+            print $fd "$h->{cmd}\n";
+            chmod 0755, $fd;
+            close $fd;
+          }
+          elsif($h->{file}) {
+            system "cp '$h->{file}{file}' '$s'";
+            chmod 0755, $s;
+          }
+        }
+      }
+    }
+
     for (@files) {
       next if $_->{arch} && $_->{arch} ne $arch;
 
@@ -967,15 +1067,27 @@
       if($_->{type} eq 'instsys') {
         $dud_ok = 1;
         mkdir "$base/inst-sys", 0755;
+        open my $f, ">>", "$base/inst-sys/.update.$id";
+        close $f;
         system "cp -a '$_->{file}'/* $base/inst-sys";
       }
 
       if($_->{type} eq 'initrd') {
         $dud_ok = 1;
         mkdir "$base/initrd", 0755;
+        open my $f, ">>", "$base/initrd/.update.initrd.$id";
+        close $f;
         system "cp -a '$_->{file}'/* $base/initrd";
       }
 
+      if($_->{type} eq 'iso') {
+        $dud_ok = 1;
+        mkdir "$base/iso", 0755;
+        open my $f, ">>", "$base/iso/.update.iso.$id";
+        close $f;
+        system "cp -a '$_->{file}'/* $base/iso";
+      }
+
       if($_->{type} eq 'rpm') {
         print $cfg "UpdateName:\t$_->{canonical_name}\t$_->{date}\n" if 
!@opt_name;
         $has_update_name = 1;
@@ -1015,6 +1127,16 @@
         apply_alternatives "$base/initrd", $_->{alternatives}, 1;
       }
 
+      # FIXME: this is unlikely to be useful...
+      if($_->{type} eq 'rpm_iso') {
+        $dud_ok = 1;
+        mkdir "$base/iso", 0755;
+        open my $f, ">>", "$base/iso/.update.iso.$id";
+        print $f "package: $_->{canonical_name}\n";
+        close $f;
+        system "rpm2cpio $_->{file} | ( cd $base/iso ; cpio --quiet --sparse 
-dimu --no-absolute-filenames )";
+      }
+
       if($_->{type} eq 'bin' || $_->{type} eq 'lib') {
         $dud_ok = 1;
         mkdir "$base/install", 0755;
@@ -1101,7 +1223,7 @@
       }
     }
 
-    if($opt_fix_yast) {
+    if($installer eq "yast" && $opt_fix_yast) {
       if(lstat "$base/inst-sys/sbin/yast") {
         if(vercmp($yast_version, $REPLACEABLE_YAST) < 0 ) {
           print STDERR
@@ -1113,7 +1235,7 @@
       }
     }
 
-    if($opt_fix_usr_src) {
+    if($installer eq "yast" && $opt_fix_usr_src) {
       if(-e "$base/inst-sys/usr/src/packages") {
         print STDERR
           "***  Note: prevented driver update from including 
/usr/src/packages.\n" .
@@ -1122,7 +1244,7 @@
       }
     }
 
-    if($opt_fix_adddir) {
+    if($installer eq "yast" && $opt_fix_adddir) {
       # only for sle11, sle12, leap42.X, caasp1.X, caasp2.X, caasp3.X
       if(grep { /^(sle[sd]?1[12]|leap42\.|caasp[1-3]\.)/ } (@dists, $dist)) {
         my $danger = 0;
@@ -1141,7 +1263,7 @@
 
     print $cfg "UpdateName:\tUpdate $id\n" if !$has_update_name;
 
-    if(@opt_exec) {
+    if($installer eq 'yast' && @opt_exec) {
       $dud_ok = 1;
       mkdir "$base/install", 0755;
 
@@ -1182,7 +1304,7 @@
       chmod 0755, "$base/install/mkdud.$id.sh";
     }
 
-    if(@opt_condition) {
+    if($installer eq 'yast' && @opt_condition) {
       $dud_ok = 1;
       mkdir "$base/install", 0755;
 
@@ -1251,7 +1373,7 @@
       }
     }
 
-    if(@rpms && $opt_install{repo} && $installer =~ /^(yast)$/i) {
+    if(@rpms && $opt_install{repo} && $installer eq "yast") {
       $dud_ok = 1;
       mkdir "$base/install", 0755;
 
@@ -1578,7 +1700,7 @@
     }
   }
 
-  system "cp $tmp_archive $file_name";
+  system "cp -T $tmp_archive $file_name" and die "failed to create driver 
update\n";
 
   return $tmp_src;
 }
@@ -1752,34 +1874,44 @@
 
   my %p1;
   for (@$l) {
-    
if(/^(\S+)-(sle([sd]?)(\d+)|(leap|kubic|casp|caasp|suse-microos)?(\d+\.\d+)|tw)$/)
 {
-      if($3 eq 's') {
-        push @{$p1{"SUSE Linux Enterprise Server $4"}}, $1;
+    
if(/^(\S+)-((sle([sd]?)|fedora|rhel|sll)(\d+)|(leap|kubic|casp|caasp|suse-microos)?(\d+\.\d+)|tw)$/)
 {
+      # print STDERR "+++ 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 +++\n";
+      if($3 eq 'sles') {
+        push @{$p1{"SUSE Linux Enterprise Server $5"}}, $1;
       }
-      elsif($3 eq 'd') {
-        push @{$p1{"SUSE Linux Enterprise Desktop $4"}}, $1;
+      elsif($3 eq 'sled') {
+        push @{$p1{"SUSE Linux Enterprise Desktop $5"}}, $1;
       }
-      elsif($4 ne '') {
-        push @{$p1{"SUSE Linux Enterprise $4"}}, $1;
+      elsif($3 eq 'sle') {
+        push @{$p1{"SUSE Linux Enterprise $5"}}, $1;
       }
-      elsif($5 eq 'leap') {
-        push @{$p1{"openSUSE Leap $6"}}, $1;
+      elsif($6 eq 'leap') {
+        push @{$p1{"openSUSE Leap $7"}}, $1;
       }
-      elsif($5 eq 'kubic') {
-        push @{$p1{"openSUSE Kubic $6"}}, $1;
+      elsif($6 eq 'kubic') {
+        push @{$p1{"openSUSE Kubic $7"}}, $1;
       }
-      elsif($5 eq 'casp') {
-        push @{$p1{"SUSE Containers as a Service Platform $6"}}, $1;
+      elsif($6 eq 'casp') {
+        push @{$p1{"SUSE Containers as a Service Platform $7"}}, $1;
       }
-      elsif($5 eq 'caasp') {
-        push @{$p1{"SUSE Containers as a Service Platform $6"}}, $1;
+      elsif($6 eq 'caasp') {
+        push @{$p1{"SUSE Containers as a Service Platform $7"}}, $1;
       }
-      elsif($5 eq 'suse-microos') {
-        push @{$p1{"SUSE Linux Enterprise Micro $6"}}, $1;
+      elsif($6 eq 'suse-microos') {
+        push @{$p1{"SUSE Linux Enterprise Micro $7"}}, $1;
       }
       elsif($2 eq "tw") {
         push @{$p1{"openSUSE Tumbleweed"}}, $1;
       }
+      elsif($3 eq 'fedora') {
+        push @{$p1{"Fedora $5"}}, $1;
+      }
+      elsif($3 eq 'rhel') {
+        push @{$p1{"Red Hat Enterprise Linux $5"}}, $1;
+      }
+      elsif($3 eq 'sll') {
+        push @{$p1{"SUSE Liberty Linux $5"}}, $1;
+      }
       else {
         push @{$p1{"openSUSE $2"}}, $1;
       }
@@ -1891,6 +2023,16 @@
   }
   close $f;
 
+  if(open my $fd, "$dir/initrd/var/lib/dracut/hooks/pre-pivot/99-zz-mkdud.sh") 
{
+    while(<$fd>) {
+      chomp;
+      next if /^#/;
+      next if /^\s*$/;
+      $sect{exec} .= "      $_\n";
+    }
+    close $fd;
+  }
+
   $sect{installer} = "      $installer_names->{$installer}\n";
 
   # ----------------------------
@@ -2087,6 +2229,33 @@
   }
 
   # ----------------------------
+  # iso
+
+  if(-d "$dir/iso") {
+    my $max_files = 10;
+
+    chomp(my @f = `cd $dir/iso; find . -type f`);
+    @f = map { s#^\.##; $_ } sort @f;
+    @f = grep { $_ ne "/.update.iso.$id" } @f;
+
+    if(open my $fd, "$dir/iso/.update.iso.$id") {
+      my @l = <$fd>;
+      close $fd;
+      chomp @l;
+      $sect{iso} .= "      - $_.rpm\n" for @l;
+    }
+
+    if(@f > $max_files + 1) {
+      $sect{iso} .= "      $_\n" for (@f[0 .. $max_files - 1]);
+      my $x = @f - $max_files;
+      $sect{iso} .= "      ... ($x more files)\n";
+    }
+    else {
+      $sect{iso} .= "      $_\n" for (@f);
+    }
+  }
+
+  # ----------------------------
   # public rpm keys
 
   for (glob("$dir/inst-sys/usr/lib/rpm/gnupg/keys/* 
$dir/initrd/usr/lib/rpm/gnupg/keys/*")) {
@@ -2112,8 +2281,10 @@
 
   my @is_ok = ( "✔", "✔", "✔", "✔", "✔" );
 
-  $is_ok[0] = $is_ok[3] = "✘" if $sect{initrd} || $sect{boot} || 
($sect{config} && $installer ne "yast");
-  $is_ok[1] = $is_ok[2] = "✘" if $sect{initrd} || $sect{boot} || $installer ne 
"yast";
+  $is_ok[0] = $is_ok[3] = "✘" if $sect{iso} || $sect{initrd} || $sect{boot} || 
($sect{config} && $installer ne "yast");
+  $is_ok[1] = $is_ok[2] = "✘" if $sect{iso} || $sect{initrd} || $sect{boot} || 
$installer ne "yast";
+
+  $is_ok[0] = $is_ok[1] = $is_ok[2] = $is_ok[3] = "✘" if $installer eq 
"anaconda";
 
   my $opt = "dud";
   $opt = "inst.dud" if $installer eq "agama";
@@ -2173,6 +2344,10 @@
     $log .= "    Initrd:\n$sect{initrd}";
   }
 
+  if($sect{iso}) {
+    $log .= "    ISO:\n$sect{iso}";
+  }
+
   if($sect{other}) {
     $log .= "    Other Files:\n$sect{other}";
   }
@@ -2603,7 +2778,9 @@
 
   my $installer = "yast";
 
-  $installer = "agama" if $dist =~ /^(sle[sd]?|leap)(\d+)$/ && $2 >= 16;
+  $installer = "agama" if $dist =~ /^(sle[sd]?|leap)(\d+)/ && $2 >= 16;
+
+  $installer = "anaconda" if $dist =~ /^(fedora|rhel|sll)\d+(\.\d+)?$/;
 
   return $installer;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mkdud-2.0/mkdud_man.adoc new/mkdud-2.2/mkdud_man.adoc
--- old/mkdud-2.0/mkdud_man.adoc        2025-08-28 13:40:49.000000000 +0200
+++ new/mkdud-2.2/mkdud_man.adoc        2025-09-10 18:25:06.000000000 +0200
@@ -83,11 +83,16 @@
 Option can be repeated to specify a multi-line name.
 
 *-x, --exec*=_COMMAND_::
-Run _COMMAND_ right after the driver update has been loaded.
+Run _COMMAND_ right after the driver update has been loaded. +
 Option can be repeated to specify several commands. +
-*Note 1*: This option only works for YaST-based installations. +
-*Note 2*: The commands are run just before kernel modules
-are updated.
+*Note*: The commands are run just before (YaST) or after (Agama) kernel modules
+are updated. +
+
+*--dracut-hook*=_HOOK:CMD_::
+Insert CMD into dracut hook HOOK. +
+HOOK must be a valid dracut hook name. CMD is either a custom script to run or 
a command to run. +
+Option can be repeated. +
+See *Adding dracut hooks* below for details.
 
 *-i, --install*=_METHODS_::
 Package install method. _METHODS_ is a comma-separated list
@@ -101,11 +106,18 @@
   only available for YaST +
 
 *--initrd*=_RPM|DIR_::
-Add RPM or content of DIR to initrd instead of instsys. +
+Add RPM or content of DIR to initrd. +
 Option can be repeated to add several packages or directories. +
 This requires applying the driver update with *mkmedia* to work. +
 See *How to apply driver updates* below for details.
 
+*--iso*=_DIR_::
+Add content of DIR to installation ISO image. +
+Option can be repeated to add several directories. +
+Use this option to update for example shim or grub on the installation medium. 
+
+This requires applying the driver update with *mkmedia* to work. +
+See *How to apply driver updates* below for details.
+
 *--installer*=_INSTALLER_::
 Set installation program. Either agama or yast (default: auto-detected based 
on dist). +
 It is usually not necessary to use this option. There are minor differences in 
handling driver updates
@@ -147,6 +159,10 @@
 Do not include an updated `adddir` script. +
 See *Consistency checks*.
 
+*--no-check-hooks*::
+Do not restict dracut hook names. +
+See *Adding dracut hooks*.
+
 *--format*=_FORMAT_::
 Specify archive format for DUD. _FORMAT_=`((cpio|tar|iso)[.(gz|xz)])|rpm`. +
 Default _FORMAT_ is `cpio.gz` (gzip compressed cpio archive). +
@@ -339,9 +355,41 @@
 - the *--install=rpm* package install method is not available; all package 
updates intended
 for the target system are done by creating a software repository with all 
packages
 - there are no update.pre or update.post scripts
-- the *--exec* option is not available
 
 
+== Adding dracut hooks
+
+You can add dracut hooks using the *--dracut-hook HOOK:CMD* option. This can 
either be a
+provided custom script or a command to run - which is implicitly inserted into 
a suitable script.
+
+Let's see some excamples:
+
+- If *CMD* follows the naming scheme NN-NAME.sh with NN a 2-digit number and 
NAME some arbitrary name then
+it is assumed that this is a script to run in *HOOK*; e.g. *--dracut-hook 
pre-pivot:90-foobar.sh*. Note that
+you still have to provide a script with this name to the mkdud command:
++
+[source]
+----
+mkdud --create foobar.dud --dist sle16 \
+--dracut-hook pre-pivot:90-foobar.sh 90-foobar.sh
+----
+
+- Otherwise, *CMD* is assumed to be a command to run. A *script 
99-zz--mkdud.sh* will be automatically created which
+runs this command and the script is added to *HOOK*; for example:
++
+[source]
+----
+mkdud --create foobar.dud --dist sle16 \
+--dracut-hook "pre-pivot:echo hello"
+----
+
+Hook names can be (or use *--no-check-hooks* to allow arbitrary names):
+
+- cleanup, cmdline, emergency, mount, netroot, pre-mount, pre-pivot, 
pre-shutdown, pre-trigger, pre-udev, shutdown, shutdown-emergency,
+initqueue/finished, initqueue/online, initqueue/settled, initqueue/timeout
+
+See dracut.modules(7) for documentation.
+
 == Consistency Checks
 
 It is possible to create driver updates that will predictably not work
@@ -374,6 +422,9 @@
 update some programs from the `coreutils` package. mkdud implicitly
 includes an update for this script if it detects a need for it.
 
+-  *--[no-]check-hooks* +
+mkdud will only allow dracut hook names it knows about. But dracut may evolve.
+Use this option to disable the check if necessary.
 
 == How to apply driver updates
 
@@ -395,7 +446,7 @@
 installation medium while *--initrd* only adds the driver update to the initrd 
where it will be found and applied at
 installation time (equivalent to using the *inst.dud* or *dud* boot options).
 
-Only with *--apply-dud* you can apply changes to the initrd or boot options.
+Only with *--apply-dud* you can apply changes to the initrd, boot options, or 
the installation ISO.
 
 *mkdud --show DUD_FILE* tells you which ways are available for a specific 
driver update.
 
@@ -446,6 +497,10 @@
 
 == See Also
 
+*mkmedia(1)*, *dracut.modules(7)*, *dracut.cmdline(7)*.
+
+== Links
+
 - more documentation: `/usr/share/doc/packages/mkdud` +
 - mkdud web site: https://github.com/openSUSE/mkdud +
 - Update Media HOWTO: 
http://ftp.suse.com/pub/people/hvogel/Update-Media-HOWTO/index.html

Reply via email to