Skip to content

Commit

Permalink
Expanding support for yum install --assumeno cmd to include yum4
Browse files Browse the repository at this point in the history
  • Loading branch information
rane-rajasi committed Oct 17, 2024
1 parent 82f45bb commit 04e5642
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 13 deletions.
122 changes: 113 additions & 9 deletions src/core/src/package_managers/YumPackageManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def is_package_version_installed(self, package_name, package_version):
return False

def extract_dependencies(self, output, packages):
# Sample output for the cmd 'sudo yum update --assumeno selinux-policy.noarch' is :
# In Yum 3: Sample output for the cmd 'sudo yum update --assumeno selinux-policy.noarch' is :
#
# Loaded plugins: langpacks, product-id, search-disabled-repos
# Resolving Dependencies
Expand All @@ -325,26 +325,126 @@ def extract_dependencies(self, output, packages):
# ---> Package selinux-policy-targeted.noarch 0:3.13.1-102.el7_3.16 will be an update
# --> Finished Dependency Resolution

# In Yum 4: Sample 1 (Upgrades are available, no installation required):
# Sample output for the cmd 'sudo yum update --assumeno selinux-policy.noarch' is :
#
# Last metadata expiration check: 0:08:56 ago on Tue 25 Jul 2023 02:14:28 PM UTC.
# Package selinux-policy-3.14.3-95.el8_6.6.noarch is already installed.
# Dependencies resolved.
# ==================================================================================================
# Package Arch Version Repository Size
# ==================================================================================================
# Upgrading:
# selinux-policy noarch 3.14.3-95.el8_6.8 rhel-8-for-x86_64-baseos-eus-rhui-rpms 651 k
# selinux-policy-targeted noarch 3.14.3-95.el8_6.8 rhel-8-for-x86_64-baseos-eus-rhui-rpms 15 M
#
# Transaction Summary
# ==================================================================================================
# Upgrade 2 Packages
#
# Total download size: 16 M
# Operation aborted..

# In Yum 4: Sample 2 (No upgrades available, installations required):
# Sample output for the cmd 'sudo yum update --assumeno kernel-modules.x86_64' is :
#
# Last metadata expiration check: 0:09:14 ago on Tue 25 Jul 2023 02:14:28 PM UTC.
# Package kernel-modules-4.18.0-372.9.1.el8.x86_64 is already installed.
# Package kernel-modules-4.18.0-372.52.1.el8_6.x86_64 is already installed.
# Dependencies resolved.
# =============================================================================================
# Package Arch Version Repository Size
# =============================================================================================
# Installing dependencies:
# kernel-core x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 40 M
# kernel-modules x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 32 M
#
# Transaction Summary
# =============================================================================================
# Install 2 Packages
#
# Total download size: 72 M
# Installed size: 93 M
# Operation aborted.

# In Yum 4: Sample 3 (Both upgrades and installations required):
# Sample output for the cmd 'sudo yum update --assumeno kernel-modules.x86_64' is :
#
# Last metadata expiration check: 0:01:56 ago on Tue 25 Jul 2023 12:01:47 PM UTC.
# Dependencies resolved.
# ================================================================================================
# Package Arch Version Repository Size
# ================================================================================================
# Upgrading:
# kernel-tools x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 8.4 M
# kernel-tools-libs x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 8.2 M
# openssl x86_64 1:1.1.1k-9.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 710 k
# openssl-libs x86_64 1:1.1.1k-9.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 1.5 M
# Installing dependencies:
# kernel-core x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 40 M
# kernel-modules x86_64 4.18.0-372.64.1.el8_6 rhel-8-for-x86_64-baseos-eus-rhui-rpms 32 M
#
# Transaction Summary
# ================================================================================================
# Install 2 Packages
# Upgrade 4 Packages

# In Yum 4: Sample 4 (dependent patch detail split over 2 lines):
# Sample output for the cmd 'sudo yum update --assumeno polkit.x86_64' is :
#
# Last metadata expiration check: 0:08:47 ago on Tue 25 Jul 2023 02:14:28 PM UTC.
# Package polkit-0.115-13.el8_5.2.x86_64 is already installed.
# Dependencies resolved.
# ================================================================================
# Package Arch Version Repository Size
# ================================================================================
# Upgrading:
# polkit x86_64 0.115-14.el8_6.1 rhel-8-for-x86_64-baseos-eus-rhui-rpms 154 k
# polkit-libs
# x86_64 0.115-14.el8_6.1 rhel-8-for-x86_64-baseos-eus-rhui-rpms 77 k
#
# Transaction Summary
# ================================================================================
# Upgrade 2 Packages
#
# Total download size: 231 k
# Operation aborted.

dependencies = []
package_arch_to_look_for = ["x86_64", "noarch", "i686"]

lines = output.strip().split('\n')

for line in lines:
if line.find(" will be updated") < 0 and line.find(" will be an update") < 0 and line.find(" will be installed") < 0:
self.composite_logger.log_debug(" - Inapplicable line: " + str(line))
continue
for line_index in range(0, len(lines)):
line = re.split(r'\s+', (lines[line_index].replace("--->", "")).strip())
next_line = []
dependent_package_name = ""

if line_index < len(lines) - 1:
next_line = re.split(r'\s+', (lines[line_index + 1].replace("--->", "")).strip())

updates_line = re.split(r'\s+', line.strip())
if len(updates_line) != 7:
if self.is_valid_update(line, package_arch_to_look_for):
dependent_package_name = self.get_product_name_with_arch(line, package_arch_to_look_for)
elif self.is_valid_update(line+next_line, package_arch_to_look_for):
dependent_package_name = self.get_product_name_with_arch(line+next_line, package_arch_to_look_for)
else:
self.composite_logger.log_debug(" - Inapplicable line: " + str(line))
continue

dependent_package_name = self.get_product_name(updates_line[2])
if len(dependent_package_name) != 0 and dependent_package_name not in packages:
if len(dependent_package_name) != 0 and dependent_package_name not in packages and dependent_package_name not in dependencies:
self.composite_logger.log_debug(" - Dependency detected: " + dependent_package_name)
dependencies.append(dependent_package_name)

return dependencies

def is_valid_update(self, package_details_in_output, package_arch_to_look_for):
return len(package_details_in_output) == 6 and self.is_arch_in_package_details(package_details_in_output[1], package_arch_to_look_for)

@staticmethod
def is_arch_in_package_details(package_detail, package_arch_to_look_for):
# Using a list comprehension to determine if chunk is a package
return len([p for p in package_arch_to_look_for if p in package_detail]) == 1

def get_dependent_list(self, packages):
package_names = ""
for index, package in enumerate(packages):
Expand Down Expand Up @@ -380,6 +480,10 @@ def get_product_arch(self, package_name):
product_name, arch = self.get_product_name_and_arch(package_name)
return arch

def get_product_name_with_arch(self, package_detail, package_arch_to_look_for):
"""Retrieve product name with arch separated by '.'. Note: This format is default in yum3. Refer samples noted within func extract_dependencies() for more clarity"""
return package_detail[0] + "." + package_detail[1] if package_detail[1] in package_arch_to_look_for else package_detail[1]

def get_package_version_without_epoch(self, package_version):
"""Returns the package version stripped of any epoch"""
package_version_split = str(package_version).split(':', 1)
Expand Down
41 changes: 41 additions & 0 deletions src/core/tests/Test_YumPackageManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,5 +676,46 @@ def __assert_test_rhel8_image(self):
self.assertEqual(available_updates[1], "tcpdump.x86_64")
self.assertEqual(package_versions[1], "14:4.9.2-3.el7")

def test_get_dependent_list_yum_version_4(self):
# Creating new RuntimeCompositor with test_type YumVersion4Dependency because there are some command runs in constructor of YumPackageManager
# for which the sample output is in the test_type YumVersion4Dependency.
self.runtime.stop() # First stopping the existing runtime
self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), True, Constants.YUM, test_type="YumVersion4Dependency")

self.container = self.runtime.container
package_manager = self.container.get('package_manager')
#self.assertEqual(package_manager.yum_version, 4)
dependent_list = package_manager.get_dependent_list(["iptables.x86_64"])
self.assertEqual(len(dependent_list), 2)
self.assertEqual(dependent_list[0], "iptables-ebtables.x86_64")
self.assertEqual(dependent_list[1], "iptables-libs.x86_64")

def test_get_dependent_list_yum_version_4_update_in_two_lines(self):
# Creating new RuntimeCompositor with test_type YumVersion4Dependency because there are some command runs in constructor of YumPackageManager
# for which the sample output is in the test_type YumVersion4Dependency.
self.runtime.stop() # First stopping the existing runtime
self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), True, Constants.YUM, test_type="YumVersion4DependencyInTwoLines")

self.container = self.runtime.container
package_manager = self.container.get('package_manager')
dependent_list = package_manager.get_dependent_list(["polkit.x86_64"])
self.assertEqual(len(dependent_list), 1)
self.assertEqual(dependent_list[0], "polkit-libs.x86_64")

def test_get_dependent_list_yum_version_4_update_in_two_lines_with_unexpected_output(self):
# This test is for adding code coverage for code handling unexpected output in the command for get dependencies.
# There are two packages in the output and for the second package i.e. polkit-libs, the package name is not present. Only other package details are present.
# So, there are 0 dependencies expected.

# Creating new RuntimeCompositor with test_type YumVersion4Dependency because there are some command runs in constructor of YumPackageManager
# for which the sample output is in the test_type YumVersion4Dependency.
self.runtime.stop() # First stopping the existing runtime
self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), True, Constants.YUM, test_type="YumVersion4DependencyInTwoLinesWithUnexpectedOutput")

self.container = self.runtime.container
package_manager = self.container.get('package_manager')
dependent_list = package_manager.get_dependent_list(["polkit.x86_64"])
self.assertEqual(len(dependent_list), 0)

if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 04e5642

Please sign in to comment.