diff --git a/ansible/docker-registry.yml b/ansible/docker-registry.yml index d7ae8d3db..f76ab78a9 100644 --- a/ansible/docker-registry.yml +++ b/ansible/docker-registry.yml @@ -1,5 +1,5 @@ --- -# Deploy/pull/reconfigure/upgrade Docker registry. +# Deploy/pull/reconfigure/stop/upgrade Docker registry. # # Follows kolla-ansible service deployment patterns. # diff --git a/ansible/inspection-store.yml b/ansible/inspection-store.yml index a4f8e7bad..d33968e6c 100644 --- a/ansible/inspection-store.yml +++ b/ansible/inspection-store.yml @@ -1,5 +1,5 @@ --- -# Deploy/pull/reconfigure/upgrade inspection data store. +# Deploy/pull/reconfigure/stop/upgrade inspection data store. # # Follows kolla-ansible service deployment patterns. # diff --git a/ansible/opensm.yml b/ansible/opensm.yml index 160fa77b0..bee7e5175 100644 --- a/ansible/opensm.yml +++ b/ansible/opensm.yml @@ -1,5 +1,5 @@ --- -# Deploy/pull/reconfigure/upgrade OpenSM Infiniband subnet manager. +# Deploy/pull/reconfigure/stop/upgrade OpenSM Infiniband subnet manager. # # Follows kolla-ansible service deployment patterns. # diff --git a/ansible/overcloud-extras.yml b/ansible/overcloud-extras.yml index ab1d80e38..ad16dc86b 100644 --- a/ansible/overcloud-extras.yml +++ b/ansible/overcloud-extras.yml @@ -1,5 +1,5 @@ --- -# Deploy/pull/reconfigure/upgrade overcloud services not managed by +# Deploy/pull/reconfigure/stop/upgrade overcloud services not managed by # kolla-ansible. # # Follows kolla-ansible service deployment patterns. diff --git a/ansible/roles/docker-registry/defaults/main.yml b/ansible/roles/docker-registry/defaults/main.yml index 2cb859c62..110a0e896 100644 --- a/ansible/roles/docker-registry/defaults/main.yml +++ b/ansible/roles/docker-registry/defaults/main.yml @@ -2,7 +2,7 @@ # Roughly follows kolla-ansible's service deployment patterns. # Action to perform. One of 'deploy', 'destroy', 'pull', 'reconfigure', -# 'upgrade'. +# 'stop', 'upgrade'. docker_registry_action: deploy # Whether a docker registry is enabled. diff --git a/ansible/roles/docker-registry/tasks/stop.yml b/ansible/roles/docker-registry/tasks/stop.yml new file mode 100644 index 000000000..6e52175d1 --- /dev/null +++ b/ansible/roles/docker-registry/tasks/stop.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure Docker registry container is stopped + docker_container: + image: "{{ item.value.image }}" + name: "{{ item.value.container_name }}" + state: "stopped" + with_dict: "{{ docker_registry_services }}" + when: + - item.value.enabled | bool diff --git a/ansible/roles/inspection-store/defaults/main.yml b/ansible/roles/inspection-store/defaults/main.yml index d6d6c3998..abdbf3671 100644 --- a/ansible/roles/inspection-store/defaults/main.yml +++ b/ansible/roles/inspection-store/defaults/main.yml @@ -2,7 +2,7 @@ # Roughly follows kolla-ansible's service deployment patterns. # Action to perform. One of 'deploy', 'destroy', 'pull', 'reconfigure', -# 'upgrade'. +# 'stop', 'upgrade'. inspection_store_action: deploy # Whether an inspection store is enabled. diff --git a/ansible/roles/inspection-store/tasks/stop.yml b/ansible/roles/inspection-store/tasks/stop.yml new file mode 100644 index 000000000..f60cdb375 --- /dev/null +++ b/ansible/roles/inspection-store/tasks/stop.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure inspection store container is stopped + docker_container: + image: "{{ item.value.image }}" + name: "{{ item.value.container_name }}" + state: "stopped" + with_dict: "{{ inspection_store_services }}" + when: + - item.value.enabled | bool diff --git a/ansible/roles/opensm/defaults/main.yml b/ansible/roles/opensm/defaults/main.yml index 0880822fb..17698cd15 100644 --- a/ansible/roles/opensm/defaults/main.yml +++ b/ansible/roles/opensm/defaults/main.yml @@ -2,7 +2,7 @@ # Roughly follows kolla-ansible's service deployment patterns. # Action to perform. One of 'deploy', 'destroy', 'pull', 'reconfigure', -# 'upgrade'. +# 'stop', 'upgrade'. opensm_action: deploy # Whether OpenSM is enabled. diff --git a/ansible/roles/opensm/tasks/stop.yml b/ansible/roles/opensm/tasks/stop.yml new file mode 100644 index 000000000..ddb2f6782 --- /dev/null +++ b/ansible/roles/opensm/tasks/stop.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure OpenSM container is stopped + docker_container: + image: "{{ item.value.image }}" + name: "{{ item.value.container_name }}" + state: stopped + with_dict: "{{ opensm_services }}" + when: + - item.value.enabled | bool diff --git a/doc/source/administration/overcloud.rst b/doc/source/administration/overcloud.rst index 46d620910..3bab4b89f 100644 --- a/doc/source/administration/overcloud.rst +++ b/doc/source/administration/overcloud.rst @@ -129,6 +129,27 @@ and/or kolla-ansible:: (kayobe) $ kayobe overcloud service upgrade --tags config --kolla-tags keystone +Stopping the Overcloud Services +=============================== + +.. note:: + + This step will stop all containers on the overcloud hosts. + +To stop the overcloud services:: + + (kayobe) $ kayobe overcloud service stop --yes-i-really-really-mean-it + +It should be noted that this state is persistent - containers will remain +stopped after a reboot of the host on which they are running. + +It is possible to limit the operation to particular hosts via +``--kolla-limit``, or to particular services via ``--kolla-tags``. It is also +possible to avoid stopping the common containers via ``--kolla-skip-tags +common``. For example: + + (kayobe) $ kayobe overcloud service stop --kolla-tags glance,nova --kolla-skip-tags common + Destroying the Overcloud Services ================================= diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index 751234a7a..281079737 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -1313,6 +1313,52 @@ class OvercloudServiceReconfigure(KollaAnsibleMixin, KayobeAnsibleMixin, self.run_kayobe_playbooks(parsed_args, playbooks, ignore_limit=True) +class OvercloudServiceStop(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, + Command): + """Stop the overcloud services. + + * Configure kolla-ansible. + * Configure overcloud services in kolla-ansible. + * Perform a kolla-ansible stop of the overcloud services. + * Stop kayobe extra services. + + This can be used in conjunction with the --tags and --kolla-tags arguments + to stop specific services. + """ + + def get_parser(self, prog_name): + parser = super(OvercloudServiceStop, self).get_parser(prog_name) + group = parser.add_argument_group("Services") + group.add_argument("--yes-i-really-really-mean-it", + action='store_true', + help="confirm that you understand that this will " + "stop running services.") + return parser + + def take_action(self, parsed_args): + if not parsed_args.yes_i_really_really_mean_it: + self.app.LOG.error("This will stop running services. Specify " + "--yes-i-really-really-mean-it to confirm that " + "you understand this.") + sys.exit(1) + + self.app.LOG.debug("Stopping overcloud services") + + # First prepare configuration. + self.generate_kolla_ansible_config(parsed_args) + + # Perform the kolla-ansible stop. + extra_args = ["--yes-i-really-really-mean-it"] + self.run_kolla_ansible_overcloud(parsed_args, "stop", + extra_args=extra_args) + + # Stop kayobe extra services. + playbooks = _build_playbook_list("overcloud-extras") + extra_vars = {"kayobe_action": "stop"} + self.run_kayobe_playbooks(parsed_args, playbooks, + extra_vars=extra_vars, limit="overcloud") + + class OvercloudServiceUpgrade(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin, Command): """Upgrade the overcloud services. diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index 1242b17c9..7a480f082 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -1681,6 +1681,70 @@ class TestCase(unittest.TestCase): ] self.assertEqual(expected_calls, mock_kolla_run.call_args_list) + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + @mock.patch.object(commands.KollaAnsibleMixin, + "run_kolla_ansible_overcloud") + def test_overcloud_service_stop(self, mock_kolla_run, mock_run): + command = commands.OvercloudServiceStop(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args(["--yes-i-really-really-mean-it"]) + + result = command.run(parsed_args) + self.assertEqual(0, result) + + expected_calls = [ + mock.call( + mock.ANY, + [utils.get_data_files_path("ansible", "kolla-ansible.yml")], + ignore_limit=True, + tags="config", + ), + mock.call( + mock.ANY, + [ + utils.get_data_files_path("ansible", + "kolla-openstack.yml"), + ], + ignore_limit=True, + ), + mock.call( + mock.ANY, + [ + utils.get_data_files_path("ansible", + "overcloud-extras.yml"), + ], + limit="overcloud", + extra_vars={ + "kayobe_action": "stop", + }, + ), + ] + self.assertEqual(expected_calls, mock_run.call_args_list) + + expected_calls = [ + mock.call( + mock.ANY, + "stop", + extra_args=["--yes-i-really-really-mean-it"], + ), + ] + self.assertEqual(expected_calls, mock_kolla_run.call_args_list) + + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + @mock.patch.object(commands.KollaAnsibleMixin, + "run_kolla_ansible_overcloud") + def test_overcloud_service_stop_no_disclaimer(self, mock_kolla_run, + mock_run): + command = commands.OvercloudServiceStop(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args([]) + + self.assertRaises( + SystemExit, + command.run, parsed_args) + @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") @mock.patch.object(commands.KollaAnsibleMixin, diff --git a/releasenotes/notes/add-stop-command-8f66235870720f31.yaml b/releasenotes/notes/add-stop-command-8f66235870720f31.yaml new file mode 100644 index 000000000..5341a5ec2 --- /dev/null +++ b/releasenotes/notes/add-stop-command-8f66235870720f31.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds a ``kayobe overcloud service stop`` command. This can be used to stop + containerised services running on overcloud hosts. diff --git a/setup.cfg b/setup.cfg index 3092250b8..02ef66126 100644 --- a/setup.cfg +++ b/setup.cfg @@ -72,6 +72,7 @@ kayobe.cli= overcloud_service_deploy_containers = kayobe.cli.commands:OvercloudServiceDeployContainers overcloud_service_destroy = kayobe.cli.commands:OvercloudServiceDestroy overcloud_service_reconfigure = kayobe.cli.commands:OvercloudServiceReconfigure + overcloud_service_stop = kayobe.cli.commands:OvercloudServiceStop overcloud_service_upgrade = kayobe.cli.commands:OvercloudServiceUpgrade overcloud_swift_rings_generate = kayobe.cli.commands:OvercloudSwiftRingsGenerate physical_network_configure = kayobe.cli.commands:PhysicalNetworkConfigure