Skip to content

Commit

Permalink
Avoid bootloader to run the migration
Browse files Browse the repository at this point in the history
Instead of a reboot the customer should run the migration
by calling run_migration. This commit adds a service utility
to run the migration. The concept is based on kexec and
avoids the modification to the bootloader setup. This allows
more flexibility for clouds that runs instances not directly
through a bootloader and also avoids infinite boot/reboot
cycles in case of an early error of the migration mount
service. This Fixes #108
  • Loading branch information
schaefi committed Jul 17, 2019
1 parent 35f2dee commit 3f10a66
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 132 deletions.
3 changes: 1 addition & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Manifest describing source package contents

prune grub.d

graft tools
graft suse_migration_services/units
graft package
graft systemd
Expand Down
9 changes: 0 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,6 @@ build: check test
# provide rpm rpmlintrc
cp package/suse-migration-services-rpmlintrc dist

sle15_activation: check
rm -f dist/*
git log grub.d | helper/changelog_generator |\
helper/changelog_descending > \
dist/suse-migration-sle15-activation.changes
cp package/suse-migration-sle15-activation-spec-template \
dist/suse-migration-sle15-activation.spec
tar -czf dist/suse-migration-sle15-activation.tar.gz grub.d

.PHONY: test
test:
tox -e unit_py3
Expand Down
23 changes: 12 additions & 11 deletions doc/adoc/user_guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Marcus Schäfer; Jesús Velázquez

:Authors: Marcus Schäfer and Jesús Bermúdez Velázquez
:Publication_Date: TBD
:Latest_Version: 0.6.1
:Latest_Version: 0.7.0
:Contributors:
:Repo: https://github.com/SUSE/suse-migration-services[suse-migration-services]

Expand Down Expand Up @@ -48,15 +48,15 @@ The migration implementation also supports an upgrade mode that works with
systems not registered to a repository service. For details
see <<Optional Customization of the Upgrade Process>>

The upgrade to a new major versions requires the system to be offline
The upgrade to a new major version requires the system to be offline
during the upgrade to avoid system inconsistencies that may leave the
system in a state that does not allow recovery. This behavior is implemented
using a Live Migration Image.

The distribution migration system provides the live image and a component
that modifies the bootloader configuration such that on the next boot the
system will boot into the upgrade image. Once booted into the upgrade
live image the following chain of services will be executed:
The distribution migration system provides the live image and a startup
utility named: `run_migration` which reboots the running system into the
upgrade live image. Once booted into the upgrade live image the following
chain of services will be executed:

1. Detect the system to be upgraded
2. Mount the necessary file systems
Expand Down Expand Up @@ -100,7 +100,7 @@ version installation media.
To install the distribution migration system run:

[listing]
tux > sudo zypper in SLES15-Migration suse-migration-sle15-activation
tux > sudo zypper in SLES15-Migration

== Optional Customization of the Upgrade Process
The upgrade live image is pre-configured to run without any further
Expand Down Expand Up @@ -170,10 +170,11 @@ be debugged.
debug: true|false

== Run the Migration
The `suse-migration-sle15-activation package` configures the boot loader
to boot into the live image which will start the upgrade automatically.
After the installation of the packages is complete, reboot the system to
start the upgrade process.
After the install of the `SLES15-Migration` package, start the migration
by calling the following command:

[listing]
tux > sudo run_migration

After the upgrade has started, the only way to access the system during the
upgrade process is via ssh with a user called `migration`:
Expand Down
44 changes: 0 additions & 44 deletions grub.d/99_migration

This file was deleted.

3 changes: 3 additions & 0 deletions package/suse-migration-services-rpmlintrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ addFilter("systemd-service-without-service_del_preun .*")

# Migration services runs once and never manually
addFilter("suse-missing-rclink .*")

# don't check for file duplicates, python stub
addFilter("files-duplicate .*")
5 changes: 5 additions & 0 deletions package/suse-migration-services-spec-template
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ python3 setup.py build
%install
python3 setup.py install --prefix=%{_prefix} --root=%{buildroot}

install -D -m 755 tools/run_migration \
%{buildroot}%{_sbindir}/run_migration

install -D -m 644 systemd/suse-migration-mount-system.service \
%{buildroot}%{_unitdir}/suse-migration-mount-system.service

Expand Down Expand Up @@ -95,6 +98,8 @@ install -D -m 644 systemd/suse-migration-console-log.service \
%defattr(-,root,root,-)
%{python3_sitelib}/*

%{_sbindir}/run_migration

%{_bindir}/suse-migration-ssh-keys
%{_unitdir}/suse-migration-ssh-keys.service

Expand Down
58 changes: 0 additions & 58 deletions package/suse-migration-sle15-activation-spec-template

This file was deleted.

6 changes: 2 additions & 4 deletions suse_migration_services/units/grub_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ def main():
DistMigration update grub to migrated version
Setup and update grub with content from the migrated system
Uninstall activation and live migration packages such that
a subsequent call of grub2-mkconfig will delete the migration
menu entry
Uninstall live migration packages such that they are no longer
part of the now migrated system.
"""
root_path = Defaults.get_system_root_path()
grub_config_file = Defaults.get_grub_config_file()
Expand All @@ -43,7 +42,6 @@ def main():
log.info('Running grub setup service')
migration_packages = [
'SLE*-Migration',
'suse-migration-*-activation',
]
log.info(
'Uninstalling migration: {0}{1}'.format(
Expand Down
4 changes: 3 additions & 1 deletion suse_migration_services/units/kernel_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ def _get_cmdline(kernel_name):
)
with open(grub_config_file_path) as grub_config_file:
grub_content = grub_config_file.read()
pattern = r'(?<=linux)[ \t]+{0}([{1}|boot/{1}].*)'.format(os.sep, kernel_name)
pattern = r'(?<=linux)[ \t]+{0}([{1}|boot/{1}].*)'.format(
os.sep, kernel_name
)
cmd_line = re.findall(pattern, grub_content)[0]
cmd_line = cmd_line.split()
cmd_line_options = []
Expand Down
3 changes: 1 addition & 2 deletions test/unit/units/grub_setup_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ def test_main(
[
'chroot', '/system-root',
'zypper', '--non-interactive', '--no-gpg-checks',
'remove', 'SLE*-Migration',
'suse-migration-*-activation'
'remove', 'SLE*-Migration'
], raise_on_error=False
),
call(
Expand Down
115 changes: 115 additions & 0 deletions tools/run_migration
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/bin/bash
# Copyright (c) 2019 SUSE Software Solutions Germany GmbH. All rights reserved.
#
# This file is part of suse-migration-services.
#
# suse-migration-services is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# suse-migration-services is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with suse-migration-services. If not, see <http://www.gnu.org/licenses/>
#
# Enable shell globbing
set +o noglob

logfile=/var/log/migration_startup.log

function setup_logging {
rm -f "${logfile}"
exec 2>>"${logfile}"
set -x
}

function cleanup {
# shellcheck disable=SC2181
if [ ! $? = 0 ];then
echo "Migration run failed: see ${logfile} for details"
fi
umount /mnt &>/dev/null
}

function get_migration_image {
# """
# Search for migration ISO file
# """
echo /usr/share/migration-image/*-Migration.*.iso
}

function get_system_root_device {
# """
# Looking for running system root device
# """
lsblk -p -n -r -o NAME,MOUNTPOINT | grep -E "/$" | uniq | cut -f1 -d" "
}

function get_boot_options {
# """
# Create boot options list for kexec
# """
local boot_options
boot_options="iso-scan/filename=$1 root=live:CDLABEL=CDROM rd.live.image"
if mdadm --detail "$(get_system_root_device)" &>/dev/null; then
boot_options="${boot_options} rd.auto"
fi
echo "${boot_options}"
}

function extract_kernel_and_initrd {
# """
# Extract kernel and initrd for kexec load operation
#
# The method assumes EFI layout of the live image
# """
local migration_image=$1
local boot_data_dir
if mount -o ro "${migration_image}" /mnt; then
boot_data_dir=$(mktemp -d -t migration_XXXX)
if \
cp /mnt/boot/*/loader/initrd /mnt/boot/*/loader/linux \
"${boot_data_dir}"
then
umount /mnt &>/dev/null
echo "${boot_data_dir}"
fi
fi
}

# Check on permissions
if (( EUID != 0 )); then
echo "Migration startup requires root permissions"
exit 1
fi

# Set signal handler on EXIT
trap cleanup EXIT

# Setup logging
setup_logging

# Lookup installed migration ISO image
migration_iso=$(get_migration_image)
if [ ! -e "${migration_iso}" ];then
echo "Migration image ISO file not found: ${migration_iso}"
exit 1
fi

# Extract kexec boot data from migration ISO image
boot_dir=$(extract_kernel_and_initrd "${migration_iso}")
if [ ! -e "${boot_dir}" ];then
echo "Failed to extract boot files"
exit 1
fi

# Run Migration
kexec \
--load "${boot_dir}/linux" \
--initrd "${boot_dir}/initrd" \
--command-line "$(get_boot_options "${migration_iso}")"
kexec --exec
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ usedevelop = True
commands =
flake8 --statistics -j auto --count {toxinidir}/suse_migration_services
flake8 --statistics -j auto --count {toxinidir}/test/unit
bash -c 'shellcheck -e SC1091,SC1090,SC2001,SC2174,SC1117 {toxinidir}/grub.d/* -s bash'
bash -c 'shellcheck -e SC1091,SC1090,SC2001,SC2174,SC1117 {toxinidir}/tools/* -s bash'

0 comments on commit 3f10a66

Please sign in to comment.