Skip to content

Commit

Permalink
Enable upgrades on AWS and Azure
Browse files Browse the repository at this point in the history
- add actor to check for particular cloud package (provided from
special repository) to determine whether we are on public
cloud.

- disable DNF plugin with a message

- use the resolved mirrorlist on AWS

- copy RHUI data from special Leapp package when on
  public cloud and running without RHSM

- add hybrid (BIOS, UEFI) image grubby workaround
  • Loading branch information
Rezney committed Jul 31, 2020
1 parent 45e644e commit d6e2a88
Show file tree
Hide file tree
Showing 17 changed files with 511 additions and 93 deletions.
16 changes: 13 additions & 3 deletions repos/system_upgrade/el7toel8/actors/addupgradebootentry/actor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from leapp.actors import Actor
from leapp.libraries.actor.addupgradebootentry import add_boot_entry, fix_grub_config_error
from leapp.models import BootContent, GrubConfigError
from leapp.models import BootContent, GrubConfigError, FirmwareFacts
from leapp.tags import InterimPreparationPhaseTag, IPUWorkflowTag


Expand All @@ -12,7 +14,7 @@ class AddUpgradeBootEntry(Actor):
"""

name = 'add_upgrade_boot_entry'
consumes = (BootContent, GrubConfigError)
consumes = (BootContent, GrubConfigError, FirmwareFacts)
produces = ()
tags = (IPUWorkflowTag, InterimPreparationPhaseTag)

Expand All @@ -21,4 +23,12 @@ def process(self):
if grub_config_error_detected:
fix_grub_config_error('/etc/default/grub')

add_boot_entry()
config = None
ff = next(self.consume(FirmwareFacts), None)

# related to issue with hybrid BIOS and UEFI images
# https://bugzilla.redhat.com/show_bug.cgi?id=1667028
if ff and ff.firmware == 'bios' and os.path.ismount('/boot/efi'):
config = '/boot/grub2/grub.cfg'

add_boot_entry(config=config)
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@
from leapp.models import BootContent


def add_boot_entry():
def add_boot_entry(config=None):
debug = 'debug' if os.getenv('LEAPP_DEBUG', '0') == '1' else ''

kernel_dst_path, initram_dst_path = get_boot_file_paths()
try:
_remove_old_upgrade_boot_entry(kernel_dst_path)
run([
_remove_old_upgrade_boot_entry(kernel_dst_path, config=config)
cmd = [
'/usr/sbin/grubby',
'--add-kernel', '{0}'.format(kernel_dst_path),
'--initrd', '{0}'.format(initram_dst_path),
'--title', 'RHEL-Upgrade-Initramfs',
'--copy-default',
'--make-default',
'--args', '{DEBUG} enforcing=0 rd.plymouth=0 plymouth.enable=0'.format(DEBUG=debug)
])
]
if config:
cmd += ['-c', config]
run(cmd)

if architecture.matches_architecture(architecture.ARCH_S390X):
# on s390x we need to call zipl explicitly because of issue in grubby,
Expand All @@ -35,17 +38,20 @@ def add_boot_entry():
)


def _remove_old_upgrade_boot_entry(kernel_dst_path):
def _remove_old_upgrade_boot_entry(kernel_dst_path, config=None):
"""
Remove entry referring to the upgrade kernel.
We have to ensure there are no duplicit boot entries. Main reason is crash
of zipl when duplicit entries exist.
"""
run([
cmd = [
'/usr/sbin/grubby',
'--remove-kernel', '{0}'.format(kernel_dst_path)
])
]
if config:
cmd += ['-c', config]
run(cmd)


def get_boot_file_paths():
Expand Down
59 changes: 59 additions & 0 deletions repos/system_upgrade/el7toel8/actors/checkrhui/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from leapp.actors import Actor
from leapp.libraries.common.rpms import has_package
from leapp.models import (
InstalledRPM,
RHUIInfo,
RequiredTargetUserspacePackages,
DNFPluginInfo
)
from leapp.reporting import Report, create_report
from leapp import reporting
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
from leapp.libraries.common import rhsm, rhui


class CheckRHUI(Actor):
"""
Check if system is using RHUI infrastructure (on public cloud) and send messages to
provide additional data needed for upgrade.
"""

name = 'checkrhui'
consumes = (InstalledRPM)
produces = (RHUIInfo, RequiredTargetUserspacePackages, Report, DNFPluginInfo)
tags = (ChecksPhaseTag, IPUWorkflowTag)

def process(self):
for k, v in rhui.RHUI_CLOUD_MAP.items():
if has_package(InstalledRPM, v['el7_pkg']):
if not rhsm.skip_rhsm():
create_report([
reporting.Title('Upgrade initiated with RHSM on public cloud with RHUI infrastructure'),
reporting.Summary(
'Leapp detected this system is on public cloud with RHUI infrastructure '
'but the process was initiated without "--no-rhsm" command line option. '
),
reporting.Severity(reporting.Severity.INFO),
reporting.Tags([reporting.Tags.PUBLIC_CLOUD]),
])
return
# AWS RHUI package is provided and signed by RH but the Azure one not
if not has_package(InstalledRPM, v['leapp_pkg']):
create_report([
reporting.Title('Package "{}" is missing'.format(v['leapp_pkg'])),
reporting.Summary(
'On {} using RHUI infrastructure, a package "{}" is needed for'
'in-place upgrade'.format(k, v['leapp_pkg'])
),
reporting.Severity(reporting.Severity.HIGH),
reporting.RelatedResource('package', v['leapp_pkg']),
reporting.Flags([reporting.Flags.INHIBITOR]),
reporting.Tags([reporting.Tags.PUBLIC_CLOUD, reporting.Tags.RHUI]),
reporting.Remediation(commands=[['yum', 'install', '-y', v['leapp_pkg']]])
])
return
if k == 'aws':
self.produce(DNFPluginInfo(name='amazon-id', disable_in=['upgrade']))
self.produce(RHUIInfo(provider=k))
self.produce(RequiredTargetUserspacePackages(packages=[v['el8_pkg']]))
return
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import pytest

from leapp.snactor.fixture import current_actor_context
from leapp.models import (
InstalledRedHatSignedRPM,
InstalledRPM,
RPM,
RHUIInfo,
RequiredTargetUserspacePackages,
)
from leapp.reporting import Report
from leapp.libraries.common.config import mock_configs
from leapp.libraries.common import rhsm


RH_PACKAGER = 'Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>'

NO_RHUI = [
RPM(name='yolo', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch',
pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51'),
]

ON_AWS_WITHOUT_LEAPP_PKG = [
RPM(name='rh-amazon-rhui-client', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER,
arch='noarch', pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51'),
]

ON_AWS_WITH_LEAPP_PKG = [
RPM(name='rh-amazon-rhui-client', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER,
arch='noarch', pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51'),
RPM(name='leapp-rhui-aws', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER,
arch='noarch', pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51')
]


def create_modulesfacts(installed_rpm):
return InstalledRPM(items=installed_rpm)


def test_actor_no_rhui(current_actor_context):
current_actor_context.feed(create_modulesfacts(installed_rpm=NO_RHUI))
current_actor_context.run(config_model=mock_configs.CONFIG)
assert not current_actor_context.consume(Report)
assert not current_actor_context.consume(RHUIInfo)
assert not current_actor_context.consume(RequiredTargetUserspacePackages)


def test_actor_rhui_without_leapp_package(monkeypatch, current_actor_context):
monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: True)

current_actor_context.feed(create_modulesfacts(installed_rpm=ON_AWS_WITHOUT_LEAPP_PKG))
current_actor_context.run(config_model=mock_configs.CONFIG)
assert current_actor_context.consume(Report)
assert not current_actor_context.consume(RHUIInfo)
assert not current_actor_context.consume(RequiredTargetUserspacePackages)


def test_actor_rhui_with_leapp_package(monkeypatch, current_actor_context):
monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: True)

current_actor_context.feed(create_modulesfacts(installed_rpm=ON_AWS_WITH_LEAPP_PKG))
current_actor_context.run(config_model=mock_configs.CONFIG)
assert not current_actor_context.consume(Report)
assert current_actor_context.consume(RHUIInfo)
assert current_actor_context.consume(RequiredTargetUserspacePackages)


def test_actor_without_no_rhsm(monkeypatch, current_actor_context):
monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: False)

current_actor_context.feed(create_modulesfacts(installed_rpm=ON_AWS_WITH_LEAPP_PKG))
current_actor_context.run(config_model=mock_configs.CONFIG)
assert current_actor_context.consume(Report)
assert not current_actor_context.consume(RHUIInfo)
assert not current_actor_context.consume(RequiredTargetUserspacePackages)
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def process():
)),
reporting.Severity(reporting.Severity.HIGH),
reporting.Tags([reporting.Tags.SANITY]),
reporting.Flags([reporting.Flags.INHIBITOR]),
# quick WIP hack
reporting.ExternalLink(url=_IPU_DOC_URL, title='UPGRADING TO RHEL 8'),
reporting.RelatedResource('file', CUSTOM_REPO_PATH),
])
Expand Down
30 changes: 25 additions & 5 deletions repos/system_upgrade/el7toel8/actors/dnfpackagedownload/actor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from leapp.actors import Actor
from leapp.libraries.common import dnfplugin
from leapp.models import (FilteredRpmTransactionTasks, StorageInfo, TargetUserSpaceInfo, UsedTargetRepositories,
XFSPresence)
from leapp.models import (
FilteredRpmTransactionTasks,
StorageInfo,
TargetUserSpaceInfo,
UsedTargetRepositories,
XFSPresence,
DNFPluginInfo,
RHUIInfo
)
from leapp.tags import DownloadPhaseTag, IPUWorkflowTag


Expand All @@ -14,16 +21,29 @@ class DnfPackageDownload(Actor):
"""

name = 'dnf_package_download'
consumes = (UsedTargetRepositories, FilteredRpmTransactionTasks, StorageInfo, TargetUserSpaceInfo, XFSPresence)
consumes = (
UsedTargetRepositories,
FilteredRpmTransactionTasks,
StorageInfo,
TargetUserSpaceInfo,
XFSPresence,
DNFPluginInfo,
RHUIInfo
)
produces = ()
tags = (IPUWorkflowTag, DownloadPhaseTag)

def process(self):
xfs_info = next(self.consume(XFSPresence), XFSPresence())
storage_info = next(self.consume(StorageInfo), StorageInfo())
used_repos = self.consume(UsedTargetRepositories)
plugin_info = list(self.consume(DNFPluginInfo))
tasks = next(self.consume(FilteredRpmTransactionTasks), FilteredRpmTransactionTasks())
target_userspace_info = next(self.consume(TargetUserSpaceInfo), None)
rhui_info = next(self.consume(RHUIInfo), None)
on_aws = bool(rhui_info and rhui_info.provider == 'aws')

dnfplugin.perform_rpm_download(tasks=tasks, used_repos=used_repos, target_userspace_info=target_userspace_info,
xfs_info=xfs_info, storage_info=storage_info)
dnfplugin.perform_rpm_download(
tasks=tasks, used_repos=used_repos, target_userspace_info=target_userspace_info,
xfs_info=xfs_info, storage_info=storage_info, plugin_info=plugin_info, on_aws=on_aws
)
27 changes: 21 additions & 6 deletions repos/system_upgrade/el7toel8/actors/dnftransactioncheck/actor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from leapp.actors import Actor
from leapp.libraries.common import dnfplugin
from leapp.models import (FilteredRpmTransactionTasks, StorageInfo, TargetUserSpaceInfo, UsedTargetRepositories,
XFSPresence)
from leapp.models import (
FilteredRpmTransactionTasks,
StorageInfo,
TargetUserSpaceInfo,
UsedTargetRepositories,
XFSPresence,
DNFPluginInfo
)
from leapp.tags import TargetTransactionChecksPhaseTag, IPUWorkflowTag


Expand All @@ -11,18 +17,27 @@ class DnfTransactionCheck(Actor):
"""

name = 'dnf_transaction_check'
consumes = (UsedTargetRepositories, FilteredRpmTransactionTasks, StorageInfo, TargetUserSpaceInfo, XFSPresence)
consumes = (
UsedTargetRepositories,
FilteredRpmTransactionTasks,
StorageInfo,
TargetUserSpaceInfo,
XFSPresence,
DNFPluginInfo,
)
produces = ()
tags = (IPUWorkflowTag, TargetTransactionChecksPhaseTag)

def process(self):
xfs_info = next(self.consume(XFSPresence), XFSPresence())
storage_info = next(self.consume(StorageInfo), StorageInfo())
used_repos = self.consume(UsedTargetRepositories)
plugin_info = next(self.consume(DNFPluginInfo), None)
tasks = next(self.consume(FilteredRpmTransactionTasks), FilteredRpmTransactionTasks())
target_userspace_info = next(self.consume(TargetUserSpaceInfo), None)

if target_userspace_info:
dnfplugin.perform_transaction_check(tasks=tasks, used_repos=used_repos,
target_userspace_info=target_userspace_info, xfs_info=xfs_info,
storage_info=storage_info)
dnfplugin.perform_transaction_check(
tasks=tasks, used_repos=used_repos, target_userspace_info=target_userspace_info,
xfs_info=xfs_info, storage_info=storage_info, plugin_info=plugin_info
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
from leapp.actors import Actor
from leapp.libraries.common import dnfplugin
from leapp.libraries.stdlib import run
from leapp.models import (FilteredRpmTransactionTasks, RHSMInfo, StorageInfo, TargetUserSpaceInfo,
TransactionCompleted, UsedTargetRepositories)
from leapp.models import (
FilteredRpmTransactionTasks,
RHSMInfo,
StorageInfo,
TargetUserSpaceInfo,
TransactionCompleted,
UsedTargetRepositories,
DNFPluginInfo
)
from leapp.tags import IPUWorkflowTag, RPMUpgradePhaseTag


Expand All @@ -17,7 +24,14 @@ class DnfUpgradeTransaction(Actor):
"""

name = 'dnf_upgrade_transaction'
consumes = (FilteredRpmTransactionTasks, RHSMInfo, StorageInfo, TargetUserSpaceInfo, UsedTargetRepositories)
consumes = (
FilteredRpmTransactionTasks,
RHSMInfo,
StorageInfo,
TargetUserSpaceInfo,
UsedTargetRepositories,
DNFPluginInfo
)
produces = (TransactionCompleted,)
tags = (RPMUpgradePhaseTag, IPUWorkflowTag)

Expand All @@ -29,11 +43,14 @@ def process(self):

used_repos = self.consume(UsedTargetRepositories)
storage_info = next(self.consume(StorageInfo), None)
plugin_info = list(self.consume(DNFPluginInfo))
tasks = next(self.consume(FilteredRpmTransactionTasks), FilteredRpmTransactionTasks())
target_userspace_info = next(self.consume(TargetUserSpaceInfo), None)

dnfplugin.perform_transaction_install(tasks=tasks, used_repos=used_repos, storage_info=storage_info,
target_userspace_info=target_userspace_info)
dnfplugin.perform_transaction_install(
tasks=tasks, used_repos=used_repos, storage_info=storage_info, target_userspace_info=target_userspace_info,
plugin_info=plugin_info
)
self.produce(TransactionCompleted())
userspace = next(self.consume(TargetUserSpaceInfo), None)
if userspace:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from leapp.models import (CustomTargetRepositoryFile, RepositoriesMap, RequiredTargetUserspacePackages,
RHSMInfo, StorageInfo, TargetRepositories,
TargetUserSpaceInfo, UsedTargetRepositories,
XFSPresence, Report)
XFSPresence, Report, RHUIInfo)
from leapp.tags import IPUWorkflowTag, TargetTransactionFactsPhaseTag


Expand All @@ -21,7 +21,7 @@ class TargetUserspaceCreator(Actor):

name = 'target_userspace_creator'
consumes = (CustomTargetRepositoryFile, RepositoriesMap, RequiredTargetUserspacePackages,
StorageInfo, RHSMInfo, TargetRepositories, XFSPresence)
StorageInfo, RHSMInfo, TargetRepositories, XFSPresence, RHUIInfo)
produces = (TargetUserSpaceInfo, UsedTargetRepositories, Report)
tags = (IPUWorkflowTag, TargetTransactionFactsPhaseTag)

Expand Down
Loading

0 comments on commit d6e2a88

Please sign in to comment.