diff --git a/paunch/builder/base.py b/paunch/builder/base.py index 40d74bb..f9fee2a 100644 --- a/paunch/builder/base.py +++ b/paunch/builder/base.py @@ -11,8 +11,10 @@ # under the License. # +import distutils.spawn import json import re +import shutil import tenacity from paunch.utils import common @@ -57,6 +59,13 @@ class BaseBuilder(object): and action == 'run') start_cmd = 'create' if systemd_managed else 'run' + # When upgrading from Docker to Podman, we want to stop the + # container that runs under Docker first before starting it with + # Podman. The container will be removed later in THT during + # upgrade_tasks. + if self.runner.cont_cmd == 'podman' and self.which('docker'): + self.runner.stop_container(container, 'docker') + if action == 'run': if container in desired_names: self.log.debug('Skipping existing container: %s' % @@ -251,6 +260,13 @@ class BaseBuilder(object): def lower(self, a): return str(a).lower() + def which(self, program): + try: + pgm = shutil.which(program) + except AttributeError: + pgm = distutils.spawn.find_executable(program) + return pgm + def duration(self, a): if isinstance(a, (int, float)): return a diff --git a/paunch/runner.py b/paunch/runner.py index f751bee..14abbf8 100644 --- a/paunch/runner.py +++ b/paunch/runner.py @@ -169,6 +169,14 @@ class BaseRunner(object): self.log.error('Error removing container: %s' % container) self.log.error(cmd_stderr) + def stop_container(self, container, cont_cmd=None): + cont_cmd = cont_cmd or self.cont_cmd + cmd = [cont_cmd, 'stop', container] + cmd_stdout, cmd_stderr, returncode = self.execute(cmd) + if returncode != 0: + self.log.error('Error stopping container: %s' % container) + self.log.error(cmd_stderr) + def rename_containers(self): current_containers = [] need_renaming = {} diff --git a/paunch/tests/test_runner.py b/paunch/tests/test_runner.py index 40bfbb3..0a71e16 100644 --- a/paunch/tests/test_runner.py +++ b/paunch/tests/test_runner.py @@ -212,6 +212,24 @@ class TestBaseRunner(base.TestCase): popen, ['docker', 'rm', '-f', 'one'] ) + @mock.patch('subprocess.Popen') + def test_stop_container(self, popen): + self.mock_execute(popen, '', '', 0) + + self.runner.stop_container('one') + self.assert_execute( + popen, ['docker', 'stop', 'one'] + ) + + @mock.patch('subprocess.Popen') + def test_stop_container_override(self, popen): + self.mock_execute(popen, '', '', 0) + + self.runner.stop_container('one', 'podman') + self.assert_execute( + popen, ['podman', 'stop', 'one'] + ) + @mock.patch('subprocess.Popen') def test_container_names(self, popen): ps_result = '''one one