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

s390x fixes #373

Merged
merged 4 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,49 @@
import re

from leapp.exceptions import StopActorExecutionError
from leapp.libraries.stdlib import api, run
from leapp.libraries.common.config import architecture
from leapp.libraries.stdlib import api, run, CalledProcessError
from leapp.models import BootContent


def add_boot_entry():
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)
pirat89 marked this conversation as resolved.
Show resolved Hide resolved
run([
'/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 architecture.matches_architecture(architecture.ARCH_S390X):
# on s390x we need to call zipl explicitly because of issue in grubby,
# otherwise the new boot entry will not be set as default
# See https://bugzilla.redhat.com/show_bug.cgi?id=1764306
run(['/usr/sbin/zipl'])
except CalledProcessError as e:
raise StopActorExecutionError(
'Cannot configure bootloader.',
details={'details': '{}: {}'.format(str(e), e.stderr)}
)


def _remove_old_upgrade_boot_entry(kernel_dst_path):
"""
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([
'/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)
'--remove-kernel', '{0}'.format(kernel_dst_path)
])


Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
from collections import namedtuple

import pytest

from leapp.exceptions import StopActorExecutionError
from leapp.libraries.actor import library
from leapp.libraries.common.config import architecture
from leapp.libraries.stdlib import api
from leapp.models import BootContent


class run_mocked(object):
def __init__(self):
self.args = None
self.args = []

def __call__(self, args, split=False):
self.args = args
self.args.append(args)


class write_to_file_mocked(object):
Expand All @@ -21,23 +25,59 @@ def __call__(self, filename, content):
self.content = content


def test_add_boot_entry(monkeypatch):
class CurrentActorMocked(object):
def __init__(self, arch):
self.configuration = namedtuple('configuration', ['architecture'])(arch)

def __call__(self):
return self


def test_add_boot_entry_non_s390x(monkeypatch):
def get_boot_file_paths_mocked():
return '/abc', '/def'
monkeypatch.setattr(library, 'get_boot_file_paths', get_boot_file_paths_mocked)
monkeypatch.setenv('LEAPP_DEBUG', '1')
monkeypatch.setattr(library, 'run', run_mocked())
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(architecture.ARCH_X86_64))

library.add_boot_entry()

assert len(library.run.args) == 2
assert library.run.args[0] == ['/usr/sbin/grubby',
'--remove-kernel', '/abc']
assert library.run.args[1] == ['/usr/sbin/grubby',
'--add-kernel', '/abc',
'--initrd', '/def',
'--title', 'RHEL-Upgrade-Initramfs',
'--copy-default',
'--make-default',
'--args',
'debug enforcing=0 rd.plymouth=0 plymouth.enable=0']


def test_add_boot_entry_s390x(monkeypatch):
def get_boot_file_paths_mocked():
return '/abc', '/def'
monkeypatch.setattr(library, 'get_boot_file_paths', get_boot_file_paths_mocked)
monkeypatch.setenv('LEAPP_DEBUG', '1')
monkeypatch.setattr(library, 'run', run_mocked())
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(architecture.ARCH_S390X))

library.add_boot_entry()

assert library.run.args == ['/usr/sbin/grubby',
'--add-kernel', '/abc',
'--initrd', '/def',
'--title', 'RHEL-Upgrade-Initramfs',
'--copy-default',
'--make-default',
'--args',
'debug enforcing=0 rd.plymouth=0 plymouth.enable=0']
assert len(library.run.args) == 3
assert library.run.args[0] == ['/usr/sbin/grubby',
'--remove-kernel', '/abc']
assert library.run.args[1] == ['/usr/sbin/grubby',
'--add-kernel', '/abc',
'--initrd', '/def',
'--title', 'RHEL-Upgrade-Initramfs',
'--copy-default',
'--make-default',
'--args',
'debug enforcing=0 rd.plymouth=0 plymouth.enable=0']
assert library.run.args[2] == ['/usr/sbin/zipl']


def test_get_boot_file_paths(monkeypatch):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections import namedtuple

from leapp.libraries import stdlib
from leapp.libraries.common.config import architecture
from leapp.libraries.stdlib import api
from leapp.models import InstalledTargetKernelVersion

Expand Down Expand Up @@ -40,6 +41,11 @@ def update_default_kernel(kernel_info):
else:
try:
stdlib.run(['grubby', '--set-default', kernel_info.kernel_path])
if architecture.matches_architecture(architecture.ARCH_S390X):
# on s390x we need to call zipl explicitly because of issue in grubby,
pirat89 marked this conversation as resolved.
Show resolved Hide resolved
# otherwise the new boot entry will not be set as default
# See https://bugzilla.redhat.com/show_bug.cgi?id=1764306
stdlib.run(['/usr/sbin/zipl'])
except (OSError, stdlib.CalledProcessError):
api.current_logger().error('Failed to set default kernel to: %s', kernel_info.kernel_path, exc_info=True)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

from leapp.libraries import stdlib
from leapp.libraries.actor import forcedefaultboot
from leapp.libraries.common.config import architecture
from leapp.libraries.stdlib import api
from leapp.models import InstalledTargetKernelVersion

Expected = namedtuple(
'Expected', (
'grubby_setdefault'
'grubby_setdefault',
'zipl_called'
)
)

Expand All @@ -20,7 +22,8 @@
'kernel_exists',
'entry_default',
'entry_exists',
'message_available'
'message_available',
'arch_s390x'
)
)

Expand All @@ -32,20 +35,48 @@
OLD_KERNEL_PATH = '/boot/vmlinuz-{}'.format(OLD_KERNEL_VERSION)

CASES = (
(Case(initrd_exists=True, kernel_exists=True, entry_default=True, entry_exists=True, message_available=True),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=False, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=True, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=False, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=False),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=False, message_available=False),
Expected(grubby_setdefault=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True),
Expected(grubby_setdefault=True))
(Case(initrd_exists=True, kernel_exists=True, entry_default=True, entry_exists=True, message_available=True,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=False, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=False, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=False,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=False, message_available=False,
arch_s390x=False),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=False),
Expected(grubby_setdefault=True, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=True, entry_exists=True, message_available=True,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=False, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=False, kernel_exists=False, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=False,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=False, message_available=False,
arch_s390x=True),
Expected(grubby_setdefault=False, zipl_called=False)),
(Case(initrd_exists=True, kernel_exists=True, entry_default=False, entry_exists=True, message_available=True,
arch_s390x=True),
Expected(grubby_setdefault=True, zipl_called=True))
)

_GRUBBY_INFO_TEMPLATE = '''index={entry_index}
Expand All @@ -60,12 +91,15 @@ class MockedRun(object):
def __init__(self, case):
self.case = case
self.called_setdefault = False
self.called_zipl = False

def __call__(self, cmd, *args, **kwargs):
if cmd and cmd[0] == 'grubby':
target = getattr(self, 'grubby_{}'.format(cmd[1].strip('--').replace('-', '_')), None)
assert target and 'Unsupport grubby command called'
return target(cmd) # pylint: disable=not-callable
if cmd and cmd[0] == '/usr/sbin/zipl':
self.called_zipl = True
return None

def grubby_info(self, cmd):
Expand Down Expand Up @@ -109,12 +143,45 @@ def impl(path):
return impl


class mocked_logger(object):
pirat89 marked this conversation as resolved.
Show resolved Hide resolved
def __init__(self):
self.errmsg = None
self.warnmsg = None
self.dbgmsg = None

def error(self, *args):
self.errmsg = args

def warning(self, *args):
self.warnmsg = args

def debug(self, *args):
self.dbgmsg = args

def __call__(self):
return self


class CurrentActorMocked(object):
def __init__(self, case):
if case.arch_s390x:
self.configuration = namedtuple('configuration', ['architecture'])(architecture.ARCH_S390X)
else:
self.configuration = namedtuple('configuration', ['architecture'])(architecture.ARCH_X86_64)

def __call__(self):
return self


@pytest.mark.parametrize('case_result', CASES)
def test_force_default_boot_target_scenario(case_result, monkeypatch):
case, result = case_result
mocked_run = MockedRun(case)
monkeypatch.setattr(api, 'consume', mocked_consume(case))
monkeypatch.setattr(stdlib, 'run', mocked_run)
monkeypatch.setattr(os.path, 'exists', mocked_exists(case, os.path.exists))
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(case))
monkeypatch.setattr(api, 'current_logger', mocked_logger())
forcedefaultboot.process()
assert result.grubby_setdefault == mocked_run.called_setdefault
assert result.zipl_called == mocked_run.called_zipl
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,38 @@ build() {
DRACUT_CONF_DIR=${LEAPP_DRACUT_CONF:-/var/empty}

DRACUT_LVMCONF_ARG="--nolvmconf"
if [[ ! -z LEAPP_DRACUT_LVMCONF ]]; then
if [[ ! -z "$LEAPP_DRACUT_LVMCONF" ]]; then
DRACUT_LVMCONF_ARG="--lvmconf"
fi
DRACUT_MDADMCONF_ARG="--nomdadmconf"
if [[ ! -z LEAPP_DRACUT_MDADMCONF ]]; then
if [[ ! -z "$LEAPP_DRACUT_MDADMCONF" ]]; then
# include local /etc/mdadm.conf
DRACUT_MDADMCONF_ARG="--mdadmconf"
fi

KERNEL_VERSION=$LEAPP_KERNEL_VERSION
if [[ -z $KERNEL_VERSION ]]; then
if [[ -z "$KERNEL_VERSION" ]]; then
KERNEL_VERSION=$(get_kernel_version)
fi

KERNEL_ARCH='x86_64'
if [[ ! -z $LEAPP_KERNEL_ARCH ]]; then
if [[ ! -z "$LEAPP_KERNEL_ARCH" ]]; then
KERNEL_ARCH=$LEAPP_KERNEL_ARCH
fi

DRACUT_MODULES_ADD=""
if [[ -z $LEAPP_ADD_DRACUT_MODULES ]]; then
if [[ -z "$LEAPP_ADD_DRACUT_MODULES" ]]; then
echo 'ERROR: No dracut modules to add'
exit 1;
else
DRACUT_MODULES_ADD=$(echo "--add $LEAPP_ADD_DRACUT_MODULES" | sed 's/,/ --add /g')
fi

DRACUT_INSTALL="systemd-nspawn"
if [[ -n "$LEAPP_DRACUT_INSTALL_FILES" ]]; then
DRACUT_INSTALL="$DRACUT_INSTALL $LEAPP_DRACUT_INSTALL_FILES"
fi

pushd /artifacts
\cp /lib/modules/$KERNEL_VERSION/vmlinuz vmlinuz-upgrade.$KERNEL_ARCH

Expand All @@ -73,7 +78,7 @@ build() {
--force \
--conf $DRACUT_CONF \
--confdir $DRACUT_CONF_DIR \
--install systemd-nspawn \
--install "$DRACUT_INSTALL" \
$DRACUT_MODULES_ADD \
$DRACUT_MDADMCONF_ARG \
$DRACUT_LVMCONF_ARG \
Expand Down
Loading