diff --git a/zun/compute/manager.py b/zun/compute/manager.py index 923424225..9f4ca3247 100644 --- a/zun/compute/manager.py +++ b/zun/compute/manager.py @@ -49,10 +49,29 @@ class Manager(periodic_task.PeriodicTasks): else: self.use_sandbox = False + def restore_running_container(self, context, container, db_container): + if (container.status == consts.RUNNING and + db_container.status == consts.STOPPED): + try: + self.container_reboot(context, container, 10) + except Exception: + LOG.exception("Failed to complete a restart for container %s", + container.uuid) + def init_containers(self, context): containers = objects.Container.list_by_host(context, self.host) + db_containers = self.driver.list(context) + db_container_map = {container.container_id: container + for container in db_containers + if container.container_id is not None} for container in containers: self._init_container(context, container) + if CONF.compute.resume_container_state and \ + container.container_id is not None: + db_container = db_container_map[container.container_id] + self.restore_running_container(context, + container, + db_container) def _init_container(self, context, container): '''Initialize this container during zun-compute init.''' diff --git a/zun/conf/compute.py b/zun/conf/compute.py index e0ae8fce3..19e06356e 100644 --- a/zun/conf/compute.py +++ b/zun/conf/compute.py @@ -15,6 +15,14 @@ from oslo_config import cfg +compute_opts = [ + cfg.BoolOpt( + 'resume_container_state', + default=True, + help='restart the containers which are running' + 'before the host reboots.'), +] + service_opts = [ cfg.StrOpt( 'topic', @@ -47,7 +55,7 @@ Possible values: opt_group = cfg.OptGroup( name='compute', title='Options for the zun-compute service') -ALL_OPTS = (service_opts + db_opts) +ALL_OPTS = (service_opts + db_opts + compute_opts) def register_opts(conf): diff --git a/zun/tests/unit/compute/test_compute_manager.py b/zun/tests/unit/compute/test_compute_manager.py index cb96124a4..8084984e3 100644 --- a/zun/tests/unit/compute/test_compute_manager.py +++ b/zun/tests/unit/compute/test_compute_manager.py @@ -110,6 +110,21 @@ class TestManager(base.TestCase): mock_container_start.assert_called_once_with(self.context, container) + @mock.patch.object(manager.Manager, 'container_reboot') + @mock.patch.object(Container, 'save') + def test_container_reboot_after_host_reboot(self, mock_save, + mock_container_reboot): + container_1 = Container(self.context, **utils.get_test_container()) + container_2 = Container(self.context, **utils.get_test_container()) + container_1.status = consts.RUNNING + container_2.status = consts.STOPPED + self.compute_manager.restore_running_container(self.context, + container_1, + container_2) + mock_container_reboot.assert_called_once_with(self.context, + container_1, + 10) + @mock.patch.object(Container, 'save') def test_init_container_retries_start_already(self, mock_save): container = Container(self.context, **utils.get_test_container())