Skip to content

Commit

Permalink
pes_events_scanner: ensure user's transaction cfg is reflected
Browse files Browse the repository at this point in the history
Previously, pes_events_scanner used transaction configuration to
only modify the way it initializes event application. As a consequence,
if a user specified to_remove=['pkg'], then the information would
not make it to pes_events_scanner's output. Similar situation would
arise with to_install/to_keep. This patch adds a post-processing to
explicitly add transaction configuration to the result of applying PES
events.
  • Loading branch information
Michal Hecko committed Nov 3, 2024
1 parent ed6e403 commit ddbe786
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,8 @@ def replace_pesids_with_repoids_in_packages(packages, source_pkgs_repoids):
return packages_with_repoid.union(packages_without_pesid)


def apply_transaction_configuration(source_pkgs):
def apply_transaction_configuration(source_pkgs, transaction_configuration):
source_pkgs_with_conf_applied = set(source_pkgs)
transaction_configuration = get_transaction_configuration()

source_pkgs_with_conf_applied = source_pkgs.union(transaction_configuration.to_install)

Expand Down Expand Up @@ -504,38 +503,76 @@ def remove_leapp_related_events(events):
return res


def include_instructions_from_transaction_configuration(rpm_tasks, transaction_configuration, installed_pkgs):
""" Extend rpm_tasks.to_remove with packages from transaction_configuration.to_remove """
# We don't want to try removing packages that are not installed
to_install_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_install)
to_remove_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_remove)
to_keep_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_keep)

installed_pkgs_requested_to_be_removed = transaction_configuration.to_remove.intersection(installed_pkgs)
pkgs_names_to_extend_to_remove_with = set(pkg.name for pkg in installed_pkgs_requested_to_be_removed)

pkgs_names_requested_to_be_installed = set(pkg.name for pkg in transaction_configuration.to_install)
to_install_pkgs_names_missing_from_tasks = pkgs_names_requested_to_be_installed - to_install_from_rpm_tasks

pkg_names_user_wants_to_keep = {pkg.name for pkg in transaction_configuration.to_keep}

new_to_remove_set = (to_remove_from_rpm_tasks | pkgs_names_to_extend_to_remove_with) - pkg_names_user_wants_to_keep
new_to_remove_list = sorted(new_to_remove_set)
new_to_install_list = sorted(to_install_from_rpm_tasks.union(to_install_pkgs_names_missing_from_tasks))
new_to_keep_list = sorted(to_keep_from_rpm_tasks | pkg_names_user_wants_to_keep)

if not any((new_to_remove_list, new_to_keep_list, new_to_install_list)): # Are all empty?
return rpm_tasks # We do not modify the original tasks

modules_to_enable = rpm_tasks.modules_to_enable if rpm_tasks else []
modules_to_reset = rpm_tasks.modules_to_reset if rpm_tasks else []

return PESRpmTransactionTasks(to_install=new_to_install_list,
to_remove=new_to_remove_list,
to_keep=new_to_keep_list,
modules_to_enable=modules_to_enable,
modules_to_reset=modules_to_reset)


def process():
# Retrieve data - installed_pkgs, transaction configuration, pes events
events = get_pes_events('/etc/leapp/files', 'pes-events.json')
if not events:
return

releases = get_relevant_releases(events)
source_pkgs = get_installed_pkgs()
source_pkgs = apply_transaction_configuration(source_pkgs)
installed_pkgs = get_installed_pkgs()
transaction_configuration = get_transaction_configuration()
pkgs_to_begin_computation_with = apply_transaction_configuration(installed_pkgs, transaction_configuration)

# Keep track of what repoids have the source packages to be able to determine what are the PESIDs of the computed
# packages of the target system, so we can distinguish what needs to be repomapped
repoids_of_source_pkgs = {pkg.repository for pkg in source_pkgs}
repoids_of_source_pkgs = {pkg.repository for pkg in pkgs_to_begin_computation_with}

events = remove_leapp_related_events(events)
events = remove_undesired_events(events, releases)

# Apply events - compute what packages should the target system have
target_pkgs, pkgs_to_demodularize = compute_packages_on_target_system(source_pkgs, events, releases)
target_pkgs, pkgs_to_demodularize = compute_packages_on_target_system(pkgs_to_begin_computation_with,
events, releases)

# Packages coming out of the events have PESID as their repository, however, we need real repoid
target_pkgs = replace_pesids_with_repoids_in_packages(target_pkgs, repoids_of_source_pkgs)

# Apply the desired repository blacklisting
blacklisted_repoids, target_pkgs = remove_new_packages_from_blacklisted_repos(source_pkgs, target_pkgs)
blacklisted_repoids, target_pkgs = remove_new_packages_from_blacklisted_repos(pkgs_to_begin_computation_with,
target_pkgs)

# Look at the target packages and determine what repositories to enable
target_repoids = sorted(set(p.repository for p in target_pkgs) - blacklisted_repoids - repoids_of_source_pkgs)
repos_to_enable = RepositoriesSetupTasks(to_enable=target_repoids)
api.produce(repos_to_enable)

# Compare the packages on source system and the computed packages on target system and determine what to install
rpm_tasks = compute_rpm_tasks_from_pkg_set_diff(source_pkgs, target_pkgs, pkgs_to_demodularize)
rpm_tasks = compute_rpm_tasks_from_pkg_set_diff(pkgs_to_begin_computation_with, target_pkgs, pkgs_to_demodularize)
rpm_tasks = include_instructions_from_transaction_configuration(rpm_tasks, transaction_configuration,
installed_pkgs)
if rpm_tasks:
api.produce(rpm_tasks)
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,14 @@ def test_actor_performs(monkeypatch):
def test_transaction_configuration_has_effect(monkeypatch):
_Pkg = partial(Package, repository=None, modulestream=None)

def mocked_transaction_conf():
return TransactionConfiguration(
to_install=[_Pkg('pkg-a'), _Pkg('pkg-b')],
to_remove=[_Pkg('pkg-c'), _Pkg('pkg-d')],
to_keep=[]
)

monkeypatch.setattr(pes_events_scanner, 'get_transaction_configuration', mocked_transaction_conf)
transaction_cfg = TransactionConfiguration(
to_install=[_Pkg('pkg-a'), _Pkg('pkg-b')],
to_remove=[_Pkg('pkg-c'), _Pkg('pkg-d')],
to_keep=[]
)

packages = {_Pkg('pkg-a'), _Pkg('pkg-c')}
_result = pes_events_scanner.apply_transaction_configuration(packages)
_result = pes_events_scanner.apply_transaction_configuration(packages, transaction_cfg)
result = {(p.name, p.repository, p.modulestream) for p in _result}
expected = {('pkg-a', None, None), ('pkg-b', None, None)}

Expand Down Expand Up @@ -338,7 +335,7 @@ def test_blacklisted_repoid_is_not_produced(monkeypatch):

monkeypatch.setattr(pes_events_scanner, 'get_installed_pkgs', lambda: installed_pkgs)
monkeypatch.setattr(pes_events_scanner, 'get_pes_events', lambda folder, filename: events)
monkeypatch.setattr(pes_events_scanner, 'apply_transaction_configuration', lambda pkgs: pkgs)
monkeypatch.setattr(pes_events_scanner, 'apply_transaction_configuration', lambda pkgs, transaction_cfg: pkgs)
monkeypatch.setattr(pes_events_scanner, 'get_blacklisted_repoids', lambda: {'blacklisted-rhel8'})
monkeypatch.setattr(pes_events_scanner, 'replace_pesids_with_repoids_in_packages',
lambda pkgs, src_pkgs_repoids: pkgs)
Expand Down Expand Up @@ -479,6 +476,7 @@ def test_transaction_configuration_is_applied(monkeypatch):
installed_pkgs = {
Package(name='moved-in', repository='rhel7-base', modulestream=None),
Package(name='split-in', repository='rhel7-base', modulestream=None),
Package(name='pkg-not-in-events', repository='rhel7-base', modulestream=None),
}
monkeypatch.setattr(pes_events_scanner, 'get_installed_pkgs', lambda *args, **kwags: installed_pkgs)

Expand All @@ -503,8 +501,10 @@ def test_transaction_configuration_is_applied(monkeypatch):
lambda source_pkgs, target_pkgs: (set(), target_pkgs))

msgs = [
RpmTransactionTasks(to_remove=['split-in', 'split-in']),
RpmTransactionTasks(to_remove=['split-in'])
RpmTransactionTasks(to_remove=['pkg-not-in-events']),
RpmTransactionTasks(to_remove=['pkg-not-in-events', 'pkg-not-in-events']),
RpmTransactionTasks(to_install=['pkg-to-install']),
RpmTransactionTasks(to_keep=['keep-me']),
]
mocked_actor = CurrentActorMocked(arch='x86_64', src_ver='7.9', dst_ver='8.8', msgs=msgs)
monkeypatch.setattr(api, 'current_actor', mocked_actor)
Expand All @@ -521,4 +521,7 @@ def test_transaction_configuration_is_applied(monkeypatch):

assert len(produced_rpm_transaction_tasks) == 1
rpm_transaction_tasks = produced_rpm_transaction_tasks[0]
assert sorted(rpm_transaction_tasks.to_remove) == ['moved-in', 'split-in']
# It is important to see 'pkg-not-in-events' in the list - if the user says remove pkg A, we really remove it
assert sorted(rpm_transaction_tasks.to_remove) == ['moved-in', 'pkg-not-in-events', 'split-in']
assert sorted(rpm_transaction_tasks.to_install) == ['moved-out', 'pkg-to-install', 'split-out0', 'split-out1']
assert sorted(rpm_transaction_tasks.to_keep) == ['keep-me']

0 comments on commit ddbe786

Please sign in to comment.