Bug 2175229 - [RFE] [leapp] Add custom drivers during the IPU
Summary: [RFE] [leapp] Add custom drivers during the IPU
Keywords:
Status: ASSIGNED
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: leapp-repository
Version: 7.9
Hardware: All
OS: Linux
low
low
Target Milestone: rc
: ---
Assignee: Leapp Notifications Bot
QA Contact: upgrades-and-conversions
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2023-03-03 15:54 UTC by Christophe Besson
Modified: 2023-07-31 07:12 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Enhancement
Doc Text:
Clone Of:
Environment:
Last Closed:
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker OAMG-8625 0 None None None 2023-03-03 15:55:18 UTC
Red Hat Issue Tracker RHELPLAN-150633 0 None None None 2023-03-03 15:55:14 UTC

Description Christophe Besson 2023-03-03 15:54:30 UTC
Description of problem:
Using custom drivers is basically unsupported as it could be risky and in the worst case lead to a broken system.

That said, it would be a great feature and a customer requested how to do this. As they agreed to make some tests in their environment I suggested the below recipe.

Customer is using a NAS that uses arcmsr as a storage driver. This driver was present in the RHEL7 branch but has been removed from RHEL 8 and beyond.

The procedure worked for the customer.

Version-Release number of selected component (if applicable):
leapp-upgrade-el7toel8-0.17.0-1.el7_9

DISCLAIMER: it's not supported by Red Hat, play at your own risk!


0. Avoid the inhibitor and edit `/etc/leapp/files/device_driver_deprecation_data.json` to make Leapp believe it's still available and maintained:
    {
      "available_in_rhel": [
        7, 8
      ],
      "deprecation_announced": "",
      "device_id": "",
      "device_name": "",
      "device_type": "pci",
      "driver_name": "arcmsr",
      "maintained_in_rhel": [ 7, 8 ]
    },

1. Create an HTTP repo on *another* machine to share the RPM driver.
Ensure you can curl the metadata (repodata/repomd.xml) and the rpm from the target machine.

2. On the target machine, create an additional repo (replace 192.168.122.1 by the IP of the http server used above).

# cat << EOF > /etc/leapp/files/leapp_upgrade_repositories.repo
[drivers]
name=drivers
baseurl=http://192.168.122.1/drivers
EOF

3. Include the RPM in the el8 target userspace container used to create the UpgradeInitramfs (/var/lib/leapp/el8userspace). To do so, edit `/usr/share/leapp-repository/repositories/system_upgrade/common/actors/commonleappdracutmodules/libraries/modscan.py`, and add 'kmod-arcmsr' to the _REQUIRED_PACKAGES array.

 15 _REQUIRED_PACKAGES = [
 16     'binutils',
 17     'cifs-utils',
 18     'device-mapper-multipath',
 19     'dracut',
 20     'dracut-config-generic',
 21     'dracut-config-rescue',
 22     'dracut-network',
 23     'dracut-tools',
 24     'fcoe-utils',
 25     'hostname',
 26     'iscsi-initiator-utils',
 27     'kbd',
 28     'kernel',
 29     'kernel-core',
 30     'kernel-modules',
 31     'keyutils',
 32     'lldpad',
 33     'lvm2',
 34     'mdadm',
 35     'nfs-utils',
 36     'openssh-clients',
 37     'plymouth',
 38     'rpcbind',
 39     'systemd-container',
 40     'tar',
 41     'kmod-arcmsr',          # <<<<<
 42 ]

4. Edit `/usr/share/leapp-repository/repositories/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/files/generate-initram.sh` and insert the following line: --add-drivers arcmsr

 81     stage "Building initram disk for kernel: $KERNEL_VERSION"
 82     \dracut \
 83         -vvvv \
 84         --force \
 85         --conf "$DRACUT_CONF" \
 86         --confdir "$DRACUT_CONF_DIR" \
 87         --install "$DRACUT_INSTALL" \
 88         $DRACUT_MODULES_ADD \
 89         "$DRACUT_MDADMCONF_ARG" \
 90         "$DRACUT_LVMCONF_ARG" \
 91         --no-hostonly \
 92         --add-drivers arcmsr \                # <<<<<
 93         --kver "$KERNEL_VERSION" \
 94         --kernel-image "vmlinuz-upgrade.$KERNEL_ARCH" \
 95         "initramfs-upgrade.${KERNEL_ARCH}.img"

5. Tell Leapp to add this RPM to be installed during the DNF transaction on the final target system

# echo kmod-arcmsr >> /etc/leapp/transaction/to_install

6. Run `leapp upgrade --debug --enablerepo drivers`

Comment 2 Petr Stodulka 2023-06-08 19:21:41 UTC
Hi, just giving an update this is going to be delivered by upstream PR:
* https://github.com/oamg/leapp-repository/pull/1081

The solution expect creation of custom actor that generates required msgs to
* install the package inside the target userspace container (TargetUserspaceUpgradeTasks)
* install the package on the system during the upgrade (RpmTransactionTasks)
* install the driver inside the upgrade initramfs (UpgradeInitramfsTasks)
* install the driver inside the target initramfs - for the upgraded system (TargetInitramfsTasks

The example below expects the custom repository is defined alraedy inside
    /etc/leapp/files/leapp_upgrade_repositories.repo


Disclaimer:
The code of a possible custom actor below is untested and I am appending it here just to provide
a picture how this could be in future (most likely) solved with the upcoming changes. It's still
possible that some changes could happen yet before the release, but currently this is what we expect.

It seems little bit longer due to number of comments as I prepared it for the possible future template
for other similar cases. I understand that better would be the possibility to configure just configure
the upgrade in this case, but that's plan for another future feature.

~~~
from leapp.actors import Actor
from leapp.models import (
    KernelModule,
    RpmTransactionTasks,
    TargetInitramfsTasks,
    TargetUserSpaceUpgradeTasks,
    UpgradeInitramfsTasks
)
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


class AddKernelDriverArcmsr(Actor):
    """
    Install the driver arcmsr driver during the upgrade

    Install the arcmsr kernel module in the upgrade & target initramfs.
    In this scenario it requires the package with the module is installed
    on the target system and inside the target userspace container.

    In case of the scenario when the module should be copied from a directory
    existing on the host system, specify the path from where it should
    be copied/installed instead, e.g.:
        KernelModule(name='arcmsr', module_path='/path/to/the/module')
    """

    name = 'addkerneldriverarcmsr'
    consumes = ()
    produces = (RpmTransactionTasks, TargetInitramfsTasks, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks)
    tags = (IPUWorkflowTag, ChecksPhaseTag)

    def process(self):
        # IMPORTANT: For these package installations the (custom) repository
        # must be enabled! Ideal solution is to define the repos inside the
        # /etc/leapp/files/leapp_upgrade_repositories.repo file or using the
        # --enablerepo option when running leapp.
        # this will create task to install the package with desired driver
        # into the target userspace container
        self.produce(TargetUserSpaceUpgradeTasks(install_rpms=['kmod-arcmsr']))

        # and we want the package to be installed also during the upgrade,
        # so the driver can be used also on the upgraded system
        self.produce(RpmTransactionTasks(to_install=['kmod-arcmsr']))

        # this will require installation of the module in the upgrade and the
        # target initramfs
        k_module = KernelModule(name='arcmsr')
        self.produce(UpgradeInitramfsTasks(include_kernel_modules=[k_module]))
        self.produce(TargetInitramfsTasks(include_kernel_modules=[k_module]))
~~~


Note You need to log in before you can comment on or make changes to this bug.