From 2c028c4a525105e900dde29b38f4c865be1fa3dc Mon Sep 17 00:00:00 2001 From: Kevin Carter Date: Fri, 24 Jan 2020 21:21:43 -0600 Subject: [PATCH] Convert the support deployment and workflow to ansible This change converts the support deployment and workflow process to use an ansible playbook instead of a mistral workflow. The overcloud_support module has been updated and moved to the V2 client and all tests in support of this new process have been updated. Story: 2007212 Task: 38431 Task: 38432 Depends-On: I606f1ee3bc323e5c83d09ca9bc8f7e4033e81e70 Change-Id: If47e1e64e251e72d5bc8d0eb253d931257fd2ca8 Signed-off-by: Kevin Carter --- .../notes/sos-reporting-fc36aa73c7c5b85a.yaml | 15 ++ setup.cfg | 2 +- tripleoclient/constants.py | 2 + .../test_overcloud_support.py | 133 -------------- .../{v1 => v2}/overcloud_support/__init__.py | 0 .../test_overcloud_support.py | 62 +++++++ tripleoclient/tests/workflows/test_support.py | 171 ------------------ tripleoclient/v1/overcloud_support.py | 107 ----------- tripleoclient/v2/overcloud_support.py | 97 ++++++++++ tripleoclient/workflows/support.py | 143 --------------- 10 files changed, 177 insertions(+), 555 deletions(-) create mode 100644 releasenotes/notes/sos-reporting-fc36aa73c7c5b85a.yaml delete mode 100644 tripleoclient/tests/v1/overcloud_support/test_overcloud_support.py rename tripleoclient/tests/{v1 => v2}/overcloud_support/__init__.py (100%) create mode 100644 tripleoclient/tests/v2/overcloud_support/test_overcloud_support.py delete mode 100644 tripleoclient/tests/workflows/test_support.py delete mode 100644 tripleoclient/v1/overcloud_support.py create mode 100644 tripleoclient/v2/overcloud_support.py delete mode 100644 tripleoclient/workflows/support.py diff --git a/releasenotes/notes/sos-reporting-fc36aa73c7c5b85a.yaml b/releasenotes/notes/sos-reporting-fc36aa73c7c5b85a.yaml new file mode 100644 index 000000000..decf8bff1 --- /dev/null +++ b/releasenotes/notes/sos-reporting-fc36aa73c7c5b85a.yaml @@ -0,0 +1,15 @@ +--- +features: + - ReportExecute has been moved to the V2 client version where it will now + execute an ansible playbook when running all log collection tasks. This + playbook will run `sosreport` and collect a log archive on the undercloud + host. +deprecations: + - The log collection process will no longer store logs within swift. All + collected logs will be stored in the `--output` path as provided by the + CLI switch, using a default of **/var/lib/tripleo/support**. + - The following ReportExecute CLI switches no longer have any effect; + `--container`, `--skip-container-delete`, `--timeout`, `--concurrency`, + `--collect-only`, `--download-only`. These options have been retained + to ensure we're not breaking legacy compatibility, however, they will + be removed in a future release. diff --git a/setup.cfg b/setup.cfg index 569f8493b..84bea4f5d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -93,7 +93,7 @@ openstack.tripleoclient.v2 = overcloud_roles_generate = tripleoclient.v1.overcloud_roles:RolesGenerate overcloud_roles_list = tripleoclient.v1.overcloud_plan_roles:ListRoles overcloud_roles_show = tripleoclient.v1.overcloud_plan_roles:ShowRole - overcloud_support_report_collect = tripleoclient.v1.overcloud_support:ReportExecute + overcloud_support_report_collect = tripleoclient.v2.overcloud_support:ReportExecute overcloud_update_prepare= tripleoclient.v1.overcloud_update:UpdatePrepare overcloud_update_run = tripleoclient.v1.overcloud_update:UpdateRun overcloud_update_converge= tripleoclient.v1.overcloud_update:UpdateConverge diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 3018bac00..c8512d735 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -80,6 +80,8 @@ ADDITIONAL_ARCHITECTURES = ['ppc64le'] DEFAULT_VALIDATIONS_BASEDIR = '/usr/share/openstack-tripleo-validations' DEFAULT_WORK_DIR = '/var/lib/mistral' +ANSIBLE_INVENTORY = \ + '/var/lib/mistral/overcloud/tripleo-ansible-inventory.yaml' ANSIBLE_VALIDATION_DIR = \ '/usr/share/openstack-tripleo-validations/playbooks' ANSIBLE_TRIPLEO_PLAYBOOKS = \ diff --git a/tripleoclient/tests/v1/overcloud_support/test_overcloud_support.py b/tripleoclient/tests/v1/overcloud_support/test_overcloud_support.py deleted file mode 100644 index 5b6596f45..000000000 --- a/tripleoclient/tests/v1/overcloud_support/test_overcloud_support.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright 2017 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import mock - - -from tripleoclient.tests.v1.overcloud_deploy import fakes -from tripleoclient.v1 import overcloud_support - - -class TestOvercloudSupportReport(fakes.TestDeployOvercloud): - - def setUp(self): - super(TestOvercloudSupportReport, self).setUp() - - self.cmd = overcloud_support.ReportExecute(self.app, None) - self.app.client_manager.workflow_engine = mock.Mock() - self.app.client_manager.tripleoclient = mock.Mock() - self.app.client_manager.object_store = mock.Mock() - self.workflow = self.app.client_manager.workflow_engine - self.swift = self.app.client_manager.object_store - - @mock.patch('tripleoclient.workflows.support.download_files') - @mock.patch('tripleoclient.workflows.support.delete_container') - @mock.patch('tripleoclient.workflows.support.fetch_logs') - def test_action(self, fetch_logs_mock, delete_container_mock, - download_files_mock): - arglist = ['-c', 'mycontainer', '-t', '60', 'control'] - verifylist = [ - ('server_name', 'control'), - ('container', 'mycontainer'), - ('timeout', 60) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.cmd.take_action(parsed_args) - - fetch_logs_mock.assert_called_once_with(self.app.client_manager, - parsed_args.container, - parsed_args.server_name, - timeout=60, - concurrency=None) - - download_files_mock.assert_called_once_with( - self.app.client_manager, parsed_args.container, - parsed_args.destination) - - delete_container_mock.assert_called_once_with(self.app.client_manager, - parsed_args.container, - timeout=60, - concurrency=None) - - @mock.patch('tripleoclient.workflows.support.download_files') - @mock.patch('tripleoclient.workflows.support.delete_container') - @mock.patch('tripleoclient.workflows.support.fetch_logs') - def test_action_skip_container_delete(self, fetch_logs_mock, - delete_container_mock, - download_files_mock): - arglist = ['-c', 'mycontainer', '--skip-container-delete', 'control'] - verifylist = [ - ('server_name', 'control'), - ('container', 'mycontainer') - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.cmd.take_action(parsed_args) - - fetch_logs_mock.assert_called_once_with(self.app.client_manager, - parsed_args.container, - parsed_args.server_name, - timeout=None, - concurrency=None) - - download_files_mock.assert_called_once_with( - self.app.client_manager, parsed_args.container, - parsed_args.destination) - - delete_container_mock.assert_not_called() - - @mock.patch('tripleoclient.workflows.support.delete_container') - @mock.patch('tripleoclient.workflows.support.fetch_logs') - def test_action_collect_logs_only(self, fetch_logs_mock, - delete_container_mock): - arglist = ['--collect-only', '-t', '60', '-n', '10', 'control'] - verifylist = [ - ('server_name', 'control'), - ('collect_only', True), - ('timeout', 60), - ('concurrency', 10) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.cmd.take_action(parsed_args) - - fetch_logs_mock.assert_called_once_with(self.app.client_manager, - parsed_args.container, - parsed_args.server_name, - timeout=60, - concurrency=10) - delete_container_mock.assert_not_called() - - @mock.patch('tripleoclient.workflows.support.download_files') - @mock.patch('tripleoclient.workflows.support.delete_container') - @mock.patch('tripleoclient.workflows.support.fetch_logs') - def test_action_download_logs_only(self, fetch_logs_mock, - delete_container_mock, - download_files_mock): - arglist = ['--download-only', 'control'] - verifylist = [ - ('server_name', 'control'), - ('download_only', True), - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - self.cmd.take_action(parsed_args) - - fetch_logs_mock.assert_not_called() - delete_container_mock.assert_not_called() - download_files_mock.assert_called_once_with( - self.app.client_manager, parsed_args.container, - parsed_args.destination) diff --git a/tripleoclient/tests/v1/overcloud_support/__init__.py b/tripleoclient/tests/v2/overcloud_support/__init__.py similarity index 100% rename from tripleoclient/tests/v1/overcloud_support/__init__.py rename to tripleoclient/tests/v2/overcloud_support/__init__.py diff --git a/tripleoclient/tests/v2/overcloud_support/test_overcloud_support.py b/tripleoclient/tests/v2/overcloud_support/test_overcloud_support.py new file mode 100644 index 000000000..6996fc7c5 --- /dev/null +++ b/tripleoclient/tests/v2/overcloud_support/test_overcloud_support.py @@ -0,0 +1,62 @@ +# Copyright 2020 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import mock + +from osc_lib.tests import utils + +from tripleoclient.v2 import overcloud_support + + +class TestOvercloudSupportReport(utils.TestCommand): + + def setUp(self): + super(TestOvercloudSupportReport, self).setUp() + + # Get the command object to test + self.cmd = overcloud_support.ReportExecute(self.app, None) + + @mock.patch('tripleoclient.utils.run_ansible_playbook', + autospec=True) + def test_overcloud_support_noargs(self, mock_playbook): + parsed_args = self.check_parser(self.cmd, ['all'], []) + self.cmd.take_action(parsed_args) + mock_playbook.assert_called_once_with( + workdir=mock.ANY, + playbook='cli-support-collect-logs.yaml', + inventory=mock.ANY, + playbook_dir=mock.ANY, + extra_vars={ + 'server_name': 'all', + 'sos_destination': '/var/lib/tripleo/support' + } + ) + + @mock.patch('tripleoclient.utils.run_ansible_playbook', + autospec=True) + def test_overcloud_support_args(self, mock_playbook): + arglist = ['server1', '--output', 'test'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + mock_playbook.assert_called_once_with( + workdir=mock.ANY, + playbook='cli-support-collect-logs.yaml', + inventory=mock.ANY, + playbook_dir=mock.ANY, + extra_vars={ + 'server_name': 'server1', + 'sos_destination': 'test' + } + ) diff --git a/tripleoclient/tests/workflows/test_support.py b/tripleoclient/tests/workflows/test_support.py deleted file mode 100644 index 429b61313..000000000 --- a/tripleoclient/tests/workflows/test_support.py +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright 2017 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import mock - -from tripleoclient.exceptions import DownloadError -from tripleoclient.tests.v1.overcloud_deploy import fakes -from tripleoclient.workflows import support - - -class TestSupportFetchLogs(fakes.TestDeployOvercloud): - - def setUp(self): - super(TestSupportFetchLogs, self).setUp() - self.app.client_manager = mock.Mock() - self.app.client_manager.workflow_engine = self.workflow = mock.Mock() - self.tripleoclient = mock.Mock() - self.websocket = mock.Mock() - self.websocket.__enter__ = lambda s: self.websocket - self.websocket.__exit__ = lambda s, *exc: None - self.tripleoclient.messaging_websocket.return_value = self.websocket - self.app.client_manager.tripleoclient = self.tripleoclient - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_fetch_logs(self, start_wf_mock, messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.fetch_logs' - fetch_input = { - 'server_name': 'test', - 'container': 'test' - } - support.fetch_logs(self.app.client_manager, 'test', 'test') - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_fetch_logs_with_timeout(self, start_wf_mock, messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.fetch_logs' - fetch_input = { - 'server_name': 'test', - 'container': 'test', - 'timeout': 59 - } - support.fetch_logs(self.app.client_manager, 'test', 'test', timeout=59) - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_fetch_logs_with_concurrency(self, start_wf_mock, messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.fetch_logs' - fetch_input = { - 'server_name': 'test', - 'container': 'test', - 'concurrency': 10 - } - support.fetch_logs(self.app.client_manager, 'test', 'test', - concurrency=10) - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - -class TestSupportDeleteContainer(fakes.TestDeployOvercloud): - - def setUp(self): - super(TestSupportDeleteContainer, self).setUp() - self.app.client_manager = mock.Mock() - self.app.client_manager.workflow_engine = self.workflow = mock.Mock() - self.tripleoclient = mock.Mock() - self.websocket = mock.Mock() - self.websocket.__enter__ = lambda s: self.websocket - self.websocket.__exit__ = lambda s, *exc: None - self.tripleoclient.messaging_websocket.return_value = self.websocket - self.app.client_manager.tripleoclient = self.tripleoclient - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_delete_container(self, start_wf_mock, messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.delete_container' - fetch_input = { - 'container': 'test' - } - support.delete_container(self.app.client_manager, 'test') - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_delete_container_with_timeout(self, start_wf_mock, messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.delete_container' - fetch_input = { - 'container': 'test', - 'timeout': 59 - } - support.delete_container(self.app.client_manager, 'test', timeout=59) - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - @mock.patch('tripleoclient.workflows.base.wait_for_messages') - @mock.patch('tripleoclient.workflows.base.start_workflow') - def test_delete_container_with_concurrency(self, start_wf_mock, - messages_mock): - messages_mock.return_value = [] - fetch_name = 'tripleo.support.v1.delete_container' - fetch_input = { - 'container': 'test', - 'concurrency': 10 - } - support.delete_container(self.app.client_manager, 'test', - concurrency=10) - start_wf_mock.assert_called_once_with(self.workflow, - fetch_name, - workflow_input=fetch_input) - - -class TestDownloadContainer(fakes.TestDeployOvercloud): - def setUp(self): - super(TestDownloadContainer, self).setUp() - - self.app.client_manager.workflow_engine = mock.Mock() - self.app.client_manager.tripleoclient = mock.Mock() - self.app.client_manager.object_store = mock.Mock() - - def test_download_files_not_enough_space(self): - support.check_local_space = mock.MagicMock() - support.check_local_space.return_value = False - oc = self.app.client_manager.object_store - oc.object_list.return_value = [{'bytes': 100}] - self.assertRaises(DownloadError, - support.download_files, - self.app.client_manager, - 'test', - 'test') - - @mock.patch('os.makedirs') - def test_download_files(self, makedirs_mock): - support.check_local_space = mock.MagicMock() - support.check_local_space.return_value = True - makedirs_mock.return_value = None - oc = self.app.client_manager.object_store - oc.object_list.return_value = [ - {'name': 'test1'} - ] - oc.object_save = mock.MagicMock() - support.download_files(self.app.client_manager, 'test', '/test') - oc.object_save.assert_called_with(container='test', - object='test1', - file='/test/test1') diff --git a/tripleoclient/v1/overcloud_support.py b/tripleoclient/v1/overcloud_support.py deleted file mode 100644 index a486c7c56..000000000 --- a/tripleoclient/v1/overcloud_support.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2017 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import logging - -from osc_lib.i18n import _ - -from tripleoclient import command -from tripleoclient.workflows import support - - -class ReportExecute(command.Command): - """Run sosreport on selected servers.""" - - log = logging.getLogger(__name__ + ".ReportExecute") - - def get_parser(self, prog_name): - parser = super(ReportExecute, self).get_parser(prog_name) - parser.add_argument('server_name', - help=_('Nova server_name or partial name to match.' - ' For example "controller" will match all ' - 'controllers for an environment.')) - parser.add_argument('-c', '--container', dest='container', - default='overcloud_support', - help=_('Swift Container to store logs to')) - parser.add_argument('-o', '--output', dest='destination', - default='support_logs', - help=_('Output directory for the report')) - parser.add_argument('--skip-container-delete', dest='skip_delete', - default=False, - help=_('Do not delete the container after the ' - 'files have been downloaded. Ignored ' - 'if --collect-only or --download-only ' - 'is provided.'), - action='store_true') - parser.add_argument('-t', '--timeout', dest='timeout', type=int, - default=None, - help=_('Maximum time to wait for the log ' - 'collection and container deletion ' - 'workflows to finish.')) - parser.add_argument('-n', '--concurrency', dest='concurrency', - type=int, default=None, - help=_('Number of parallel log collection and ' - 'object deletion tasks to run.')) - group = parser.add_mutually_exclusive_group(required=False) - group.add_argument('--collect-only', dest='collect_only', - help=_('Skip log downloads, only collect logs and ' - 'put in the container'), - default=False, - action='store_true') - group.add_argument('--download-only', dest='download_only', - help=_('Skip generation, only download from ' - 'the provided container'), - default=False, - action='store_true') - return parser - - def take_action(self, parsed_args): - self.log.debug('take_action({})'.format(parsed_args)) - - clients = self.app.client_manager - container = parsed_args.container - server_name = parsed_args.server_name - destination = parsed_args.destination - timeout = parsed_args.timeout - concurrency = parsed_args.concurrency - - if not server_name: - raise Exception(_('Please specify the server_name option.')) - - if not parsed_args.download_only: - print(_('Starting log collection... (This may take a while)')) - try: - support.fetch_logs(clients, container, server_name, - timeout=timeout, concurrency=concurrency) - except Exception as err: - self.log.error('Unable to fetch logs, {}'.format(err)) - raise err - - if not parsed_args.collect_only: - try: - support.download_files(clients, container, destination) - except Exception as err: - self.log.error('Unable to download files, {}'.format(err)) - raise err - - if not parsed_args.collect_only and not parsed_args.download_only and \ - not parsed_args.skip_delete: - print(_('Deleting container') + ' {}...'.format(container)) - try: - support.delete_container(clients, container, timeout=timeout, - concurrency=concurrency) - except Exception as err: - self.log.error('Unable to delete container, {}'.format(err)) - raise err diff --git a/tripleoclient/v2/overcloud_support.py b/tripleoclient/v2/overcloud_support.py new file mode 100644 index 000000000..4c852ec58 --- /dev/null +++ b/tripleoclient/v2/overcloud_support.py @@ -0,0 +1,97 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import logging + +from osc_lib.i18n import _ + +from tripleoclient import command +from tripleoclient import constants +from tripleoclient import utils + + +class ReportExecute(command.Command): + """Run sosreport on selected servers.""" + + log = logging.getLogger(__name__ + ".ReportExecute") + + def get_parser(self, prog_name): + parser = super(ReportExecute, self).get_parser(prog_name) + parser.add_argument('server_name', + help=_('Server name, group name, or partial name' + ' to match. For example "Controller" will' + ' match all controllers for an' + ' environment.')) + # Deprecated in U + parser.add_argument('-c', + '--container', + dest='container', + default=None, + help=_('This option no-longer has any effect.')) + parser.add_argument('-o', + '--output', + dest='destination', + default='/var/lib/tripleo/support', + help=_('Output directory for the report')) + # Deprecated in U + parser.add_argument('--skip-container-delete', + dest='skip_delete', + default=False, + help=_('This option no-longer has any effect.'), + action='store_true') + # Deprecated in U + parser.add_argument('-t', + '--timeout', + dest='timeout', + type=int, + default=None, + help=_('This option no-longer has any effect.')) + # Deprecated in U + parser.add_argument('-n', + '--concurrency', + dest='concurrency', + type=int, + default=None, + help=_('This option no-longer has any effect.')) + # Deprecated in U + parser.add_argument('--collect-only', + dest='collect_only', + help=_('This option no-longer has any effect.'), + default=False, + action='store_true') + # Deprecated in U + parser.add_argument('--download-only', + dest='download_only', + help=_('This option no-longer has any effect.'), + default=False, + action='store_true') + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action({})'.format(parsed_args)) + + extra_vars = { + 'server_name': parsed_args.server_name, + 'sos_destination': parsed_args.destination, + } + + with utils.TempDirs() as tmp: + utils.run_ansible_playbook( + playbook='cli-support-collect-logs.yaml', + inventory=constants.ANSIBLE_INVENTORY, + workdir=tmp, + playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, + extra_vars=extra_vars + ) diff --git a/tripleoclient/workflows/support.py b/tripleoclient/workflows/support.py deleted file mode 100644 index 4080bd5b4..000000000 --- a/tripleoclient/workflows/support.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2017 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import os - -from osc_lib.i18n import _ - -from tripleoclient.exceptions import ContainerDeleteFailed -from tripleoclient.exceptions import DownloadError -from tripleoclient.exceptions import LogFetchError -from tripleoclient import utils -from tripleoclient.workflows import base - - -def check_local_space(path, object_list): - required_space = sum([x['bytes'] for x in object_list]) - stats = os.statvfs(path) - free_space = stats.f_bavail * stats.f_frsize - return free_space >= required_space - - -def download_files(clients, container_name, destination): - """Downloads log files from a container action - - :param clients: openstack clients - :param container: name of the container to put the logs - :param destination: folder to download files to - """ - oc = clients.object_store - object_list = oc.object_list(container=container_name, all_data=True) - - # handle relative destination path - if not os.path.dirname(destination): - destination = os.path.join(os.sep, os.getcwd(), destination) - - if utils.makedirs(destination): - print('Created destination path: {}'.format(destination)) - else: - print('Destination path exists: {}'.format(destination)) - - if not check_local_space(destination, object_list): - raise DownloadError(_('Not enough local space to download files.')) - - for data in object_list: - print('Downloading file: {}'.format(data['name'])) - file_path = os.path.join(os.sep, destination, data['name']) - oc.object_save(container=container_name, - object=data['name'], - file=file_path) - - -def fetch_logs(clients, container, server_name, timeout=None, - concurrency=None): - """Executes fetch log action - - :param clients: openstack clients - :param container: name of the container to put the logs - :param server_name: server name to restrict where logs are pulled from - :param timeout: timeout for the log fetch operation - :param concurrency: max number of concurrent log collection tasks - """ - - workflow_input = { - "container": container, - "server_name": server_name, - } - - if timeout is not None: - workflow_input['timeout'] = timeout - if concurrency is not None: - workflow_input['concurrency'] = concurrency - - workflow_client = clients.workflow_engine - tripleoclients = clients.tripleoclient - - with tripleoclients.messaging_websocket() as ws: - execution = base.start_workflow( - workflow_client, - 'tripleo.support.v1.fetch_logs', - workflow_input=workflow_input - ) - - messages = base.wait_for_messages(workflow_client, - ws, - execution, - timeout) - - for message in messages: - if message['status'] != 'SUCCESS': - raise LogFetchError(message['message']) - if message['message']: - print('{}'.format(message['message'])) - - -def delete_container(clients, container, timeout=None, concurrency=None): - """Deletes container from swift - - :param clients: openstack clients - :param container: name of the container where the logs were stored - :param timeout: timeout for the delete operations - :param concurrency: max number of object deletion tasks to run at one time - """ - workflow_input = { - "container": container, - } - - if timeout is not None: - workflow_input['timeout'] = timeout - if concurrency is not None: - workflow_input['concurrency'] = concurrency - - workflow_client = clients.workflow_engine - tripleoclients = clients.tripleoclient - - with tripleoclients.messaging_websocket() as ws: - execution = base.start_workflow( - workflow_client, - 'tripleo.support.v1.delete_container', - workflow_input=workflow_input - ) - - messages = base.wait_for_messages(workflow_client, - ws, - execution, - timeout) - - for message in messages: - if message['status'] != 'SUCCESS': - raise ContainerDeleteFailed(message['message']) - if message['message']: - print('{}'.format(message['message']))