Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RHELC-1672, RHELC-1707, RHELC-1708] Detect a newer version of RHEL kernel in the main transaction #1323

Merged
merged 9 commits into from
Aug 21, 2024

Conversation

danmyway
Copy link
Member

@danmyway danmyway commented Jul 25, 2024

In this PR we try to detect, if a RHEL kernel was installed during the main transaction.
We compare which of the installed kernel packages has a higher version.

  • If the installed RHEL kernel has a higher version than the original vendor kernel, we do not perform any further action and set such kernel as default.
  • If there is no non-RHEL kernel detected, we assume that the main transaction handled the whole kernel replacement by itself.
  • If the latest available RHEL kernel package is the same version as the currently running non-RHEL kernel, we fall back to the original procedure of trying to install an older version and subsequently updating it.

Jira Issues:

Checklist

  • PR has been tested manually in a VM (either author or reviewer)
  • Jira issue has been made public if possible
  • [RHELC-] or [HMS-] is part of the PR title
  • GitHub label has been added to help with Release notes
  • PR title explains the change from the user's point of view
  • Code and tests are documented properly
  • The commits are squashed to as few commits as possible (without losing data)
  • When merged: Jira issue has been updated to Release Pending if relevant

@danmyway danmyway added kind/bug-fix A bug has been fixed tests/skip This PR does not require integration tests to be run. labels Jul 25, 2024
@has-bot
Copy link
Member

has-bot commented Jul 25, 2024

This PR does not require integration tests to be run.


Comment generated by an automation.

@danmyway danmyway requested a review from Venefilyn July 25, 2024 17:30
@bocekm
Copy link
Member

bocekm commented Jul 26, 2024

@danmyway, the install_rhel_kernel() function used to be called before the main transaction. Nowadays it's called after it. For that reason it should IMHO be refactored a bit more. Here's a proposal of what should it be doing (https://miro.com/app/board/uXjVKvQvEEY=/):
Convert2RHEL_ Install RHEL kernel
The key difference is not trying to install a RHEL kernel when it might very well be already installed from the main transaction.

@hosekadam
Copy link
Member

@danmyway Do you want to implement the refactor Michal mentioned, or should I take care of it? It seems it will be a bit more work :D

@danmyway
Copy link
Member Author

@hosekadam we can discuss the approach, and I'll see if I'll keep it as a "side quest" for myself 😄

convert2rhel/pkghandler.py Fixed Show fixed Hide fixed
@danmyway danmyway force-pushed the fix-latest-kernel-default branch 2 times, most recently from 6f54983 to 7b3d7f9 Compare August 13, 2024 13:42
@danmyway danmyway marked this pull request as ready for review August 13, 2024 13:43
@danmyway danmyway requested a review from a team as a code owner August 13, 2024 13:43
convert2rhel/pkghandler.py Fixed Show fixed Hide fixed
@danmyway danmyway changed the title [RHELC-1672] Detect a newer version of kernel in main transaction [RHELC-1672] Detect a newer version of RHEL kernel in the main transaction Aug 13, 2024
# Example output from yum and dnf:
# "Package kernel-4.18.0-193.el8.x86_64 is already installed."
already_installed = re.search(r" (.*?)(?: is)? already installed", output, re.MULTILINE)
if already_installed:
Copy link
Member Author

@danmyway danmyway Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping this condition, since it will always match something.
I can't imagine a case, where yum install kernel won't return, that some kernel version is already installed at that point.

Comment on lines 1068 to 1077
:rtype: str

:raises ValueError: If the list is empty, raise a ValueError.
"""
try:
return max(pkgs[1])
except ValueError:
loggerinst.debug("The list of %s packages is empty." % pkgs[0])

return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:rtype: str
:raises ValueError: If the list is empty, raise a ValueError.
"""
try:
return max(pkgs[1])
except ValueError:
loggerinst.debug("The list of %s packages is empty." % pkgs[0])
return
:rtype: str|None
:raises ValueError: If the list is empty, raise a ValueError.
"""
try:
return max(pkgs[1])
except ValueError:
loggerinst.debug("The list of %s packages is empty." % pkgs[0])
return None

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would vote to continue without the return statement. It does not add anything to the current implementation.

Also, not needed to explicitly say that it returns None. An empty return will always be None

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going by this, and it makes sense IMO. When returns have some explicit return then we should be explicit everywhere

https://github.com/oamg/convert2rhel/security/code-scanning/926

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll go with the exception.
Given the context where it's used, if the list is indeed empty, there is something very wrong, and it should raise the exception.
If we ever decide to use the function elsewhere, it can be refactored

convert2rhel/pkghandler.py Show resolved Hide resolved
Comment on lines 72 to 90
info_message = "Conflict of kernels: The running kernel has the same version as the latest RHEL kernel."
loggerinst.info("\n%s" % info_message)
self.add_message(
level="INFO",
id="CONFLICT_OF_KERNELS",
title="Conflict of installed kernel versions",
description=info_message,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also reword this to be easier to understand what this means, why it matters, and how to try to fix it. Atm the comment above gives more detail than the message

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try.

Comment on lines 72 to 90
info_message = (
"Conflict of kernels: The running kernel has the same version as the latest RHEL kernel. "
"The kernel package could not be replaced during the main transaction. "
"We will try to install a lower version of the package, "
"remove the conflicting kernel and then update to the latest security patched version."
)
loggerinst.info("\n%s" % info_message)
self.add_message(
level="INFO",
id="CONFLICT_OF_KERNELS",
title="Conflict of installed kernel versions",
description=info_message,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the info_message talks about doing something but the action message won't be displayed until it's done means it's a bit confusing. We could reword it a bit as a refactor (not a blocker on this PR as it's out of scope, only change if you feel like it)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, it's kind of mind-bending to figure out the wording 🤯

@Venefilyn
Copy link
Member

Unit test failing with this, which seems like something that shouldn't happen. Is there something with the implementation?

version1 = 'kernel-2.6.32-754.33.1.el7.x86_64'
version2 = 'kernel-uek-headers-0.1-1.x86_64'

    def compare_package_versions(version1, version2):
        """Compare two package versions against each other, including name and arch.
        This function will receive packages in any of the following formats:
            * ENVR
            * ENVRA
            * NVR
            * NEVR
            * NVRA
            * NEVRA
        :param version1: The version to be compared.
        :type version1: str
        :param version2: The version to compare against.
        :type version2: str
    
        .. example::
            >>> match = compare_package_versions("kernel-core-5.14.10-300.fc35", "kernel-core-5.14.15-300.fc35")
            >>> print(match) # -1
    
        .. note::
            Since the return type is a int, this could be difficult to understand
            the meaning of each number, so here is a list that represents
            every possible number:
                * -1 if the version1 is less then version2 version
                * 0 if the version1 is equal version2 version
                * 1 if the version1 is greater than version2 version
    
        :raises ValueError: In case of packages name being different.
        :raises ValueError: In case of architectures being different.
    
        :return: Return a number indicating if the versions match, are less or greater then.
        :rtype: int
        """
        # call parse_pkg_string to obtain a list containing name, epoch, release, version and arch fields
        # order of fields returned: name, epoch, version, release, arch
        version1_components = parse_pkg_string(version1)
        version2_components = parse_pkg_string(version2)
    
        # ensure package names match, error if not
        if version1_components[0] != version2_components[0]:
            raise ValueError(
                "The package names ('%s' and '%s') do not match. Can only compare versions for the same packages."
>               % (version1_components[0], version2_components[0])
            )
E           ValueError: The package names ('kernel' and 'kernel-uek-headers') do not match. Can only compare versions for the same packages.

Copy link

codecov bot commented Aug 20, 2024

Codecov Report

Attention: Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.

Project coverage is 96.43%. Comparing base (e9936c7) to head (2366043).
Report is 1 commits behind head on main.

Files Patch % Lines
convert2rhel/pkghandler.py 66.66% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1323      +/-   ##
==========================================
- Coverage   96.51%   96.43%   -0.09%     
==========================================
  Files          66       66              
  Lines        4970     4996      +26     
  Branches      871      876       +5     
==========================================
+ Hits         4797     4818      +21     
- Misses         97      101       +4     
- Partials       76       77       +1     
Flag Coverage Δ
centos-linux-7 91.86% <92.50%> (-0.06%) ⬇️
centos-linux-8 92.74% <92.50%> (-0.07%) ⬇️
centos-linux-9 92.78% <92.50%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@danmyway danmyway requested a review from a team as a code owner August 21, 2024 14:05
@danmyway danmyway requested review from SerCantus and kokesak and removed request for SerCantus August 21, 2024 14:05
@danmyway danmyway changed the title [RHELC-1672] Detect a newer version of RHEL kernel in the main transaction [RHELC-1672, RHELC-1707, RHELC-1708] Detect a newer version of RHEL kernel in the main transaction Aug 21, 2024
@danmyway
Copy link
Member Author

/packit test --labels sanity

Copy link
Member

@kokesak kokesak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qe ack

@danmyway
Copy link
Member Author

Sanity suit passed:

+--------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------+--------+
| UUID                                 | Target                                  | Test Plan                                                                                | Result |
+--------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------+--------+
| dd148f6d-f68c-48a0-bcca-be847b6c88b0 | AlmaLinux OS 8.10.20240530 x86_64       |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| cd7d8d4f-8e98-425c-93f9-148bf07610ac | AlmaLinux OS 8.8.20230524 x86_64        |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| 824313ff-ef5f-4920-a46f-671745b933e3 | OL7.9-x86_64-HVM-2023-01-05             |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| 180bb850-0d16-457e-aa33-0ab07d35696e | OL8.9-x86_64-HVM-2024-02-02             |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| fa109008-bb49-4fba-84a1-af5c3a850d85 | Rocky-8-EC2-Base-8.10-20240528.0.x86_64 |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| 678b80a6-584d-4d96-836c-8ade09d3ffca | Rocky-8-EC2-Base-8.8-20230518.0.x86_64  |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| de0a6860-8b17-4edd-ac35-0e1039996805 | CentOS-7-latest                         |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/one_key_satellite_conversion     | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
| a832297e-500b-43d0-a29c-fe5f22a74d7e | CentOS-8-latest                         |                                                                                          |        |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/activation_key_conversion        | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/pre_registered_system_conversion | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/rhsm_conversion                  | PASSED |
|                                      |                                         | plans/tier0/sanity/destructive/basic_conversion_methods/satellite_conversion             | PASSED |
|                                      |                                         | plans/tier0/sanity/non-destructive                                                       | PASSED |
+--------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------+--------+

danmyway and others added 9 commits August 21, 2024 18:29
* detect if the installed RHEL kernel either replaces all original
  kernel packages or if a newer version is installed

Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
* the function was not complete and the evaluation was wrong (e.g.
  "9" > "10")

Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
After Daniel's fix of the InstallRhelKernel, the new unit test are
needed to cover those changes.
* drop the distutils and packaging libraries, use the
  compare_package_version function instead
* address review comments

Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
* fix the formatting of info message for conflicting kernel version
* add debug loggerinst for highest found kernel version
* add integration test verifying the latest kernel is installed after
  the conversion
* revert if not non_rhel_kernels back to elif not non_rhel_kernels

Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
Due regression RHELC-1707 was found, we needed to change place where
kernel update is called. Without this change the system could end up with
outdated kernel installed.
* use wildcard asterisk to check all kernel related packages
* document which packages are verified

Signed-off-by: Daniel Diblik <ddiblik@redhat.com>
Copy link
Member

@r0x0d r0x0d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good.

We are okay with having the global keyword for now, but we will open a ticket to refactor this in the future. No need to block the PR because of it.

@danmyway danmyway merged commit 40d0fd6 into oamg:main Aug 21, 2024
25 of 28 checks passed
This was referenced Aug 21, 2024
@danmyway danmyway deleted the fix-latest-kernel-default branch September 3, 2024 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug-fix A bug has been fixed tests/skip This PR does not require integration tests to be run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants