Merge "TRAIN-ONLY Fix overcloud support report for T" into stable/train
This commit is contained in:
commit
118e8a88f3
|
@ -23,6 +23,11 @@ WS_URL = "ws://0.0.0.0"
|
|||
WSS_URL = "wss://0.0.0.0"
|
||||
|
||||
|
||||
class FakeOptions(object):
|
||||
def __init__(self):
|
||||
self.debug = True
|
||||
|
||||
|
||||
class FakeApp(object):
|
||||
def __init__(self):
|
||||
_stdout = None
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Red Hat, Inc.
|
||||
# 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
|
||||
|
@ -15,119 +15,134 @@
|
|||
|
||||
import mock
|
||||
|
||||
from osc_lib.tests import utils
|
||||
|
||||
from tripleoclient.tests.v1.overcloud_deploy import fakes
|
||||
from tripleoclient.tests import fakes
|
||||
from tripleoclient.v1 import overcloud_support
|
||||
|
||||
|
||||
class TestOvercloudSupportReport(fakes.TestDeployOvercloud):
|
||||
class TestOvercloudSupportReport(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestOvercloudSupportReport, self).setUp()
|
||||
|
||||
self.cmd = overcloud_support.ReportExecute(self.app, None)
|
||||
# Get the command object to test
|
||||
app_args = mock.Mock()
|
||||
app_args.verbose_level = 1
|
||||
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
|
||||
self.app.options = fakes.FakeOptions()
|
||||
self.cmd = overcloud_support.ReportExecute(self.app, app_args)
|
||||
|
||||
@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)
|
||||
@mock.patch('os.chmod')
|
||||
@mock.patch('tripleoclient.workflows.package_update.get_key')
|
||||
@mock.patch('tripleoclient.utils.get_tripleo_ansible_inventory')
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_overcloud_support_noargs(self, mock_playbook, mock_inventory,
|
||||
mock_key, mock_chmod):
|
||||
parsed_args = self.check_parser(self.cmd, ['all'], [])
|
||||
self.key = mock_key
|
||||
mock_inventory.return_value = '/home/stack/tripleo-ansible-inventory'
|
||||
playbook = ('/usr/share/ansible/tripleo-playbooks'
|
||||
'/cli-support-collect-logs.yaml')
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
with mock.patch('builtins.open', mock.mock_open()):
|
||||
with open('/home/stack/.ssh/id_rsa_tripleo', 'w') as key_file:
|
||||
key_file.write(self.key)
|
||||
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)
|
||||
mock_playbook.assert_called_once_with(
|
||||
logger=mock.ANY,
|
||||
ansible_config='/etc/ansible/ansible.cfg',
|
||||
workdir=mock.ANY,
|
||||
python_interpreter='/usr/bin/python3',
|
||||
playbook=playbook,
|
||||
inventory=mock_inventory(),
|
||||
verbosity=1,
|
||||
timeout=None,
|
||||
forks=None,
|
||||
extra_vars={
|
||||
'server_name': 'all',
|
||||
'sos_destination': '/var/lib/tripleo/support'
|
||||
}
|
||||
)
|
||||
|
||||
download_files_mock.assert_called_once_with(
|
||||
self.app.client_manager, parsed_args.container,
|
||||
parsed_args.destination)
|
||||
@mock.patch('os.chmod')
|
||||
@mock.patch('tripleoclient.workflows.package_update.get_key')
|
||||
@mock.patch('tripleoclient.utils.get_tripleo_ansible_inventory')
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_overcloud_support_args(self, mock_playbook, mock_inventory,
|
||||
mock_key, mock_chmod):
|
||||
arglist = ['server1', '--output', 'test']
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
self.key = mock_key
|
||||
mock_inventory.return_value = '/home/stack/tripleo-ansible-inventory'
|
||||
playbook = ('/usr/share/ansible/tripleo-playbooks'
|
||||
'/cli-support-collect-logs.yaml')
|
||||
|
||||
delete_container_mock.assert_called_once_with(self.app.client_manager,
|
||||
parsed_args.container,
|
||||
timeout=60,
|
||||
concurrency=None)
|
||||
with mock.patch('builtins.open', mock.mock_open()):
|
||||
with open('/home/stack/.ssh/id_rsa_tripleo', 'w') as key_file:
|
||||
key_file.write(self.key)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
@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)
|
||||
mock_playbook.assert_called_once_with(
|
||||
logger=mock.ANY,
|
||||
ansible_config='/etc/ansible/ansible.cfg',
|
||||
workdir=mock.ANY,
|
||||
python_interpreter='/usr/bin/python3',
|
||||
playbook=playbook,
|
||||
inventory=mock_inventory(),
|
||||
verbosity=1,
|
||||
timeout=None,
|
||||
forks=None,
|
||||
extra_vars={
|
||||
'server_name': 'server1',
|
||||
'sos_destination': 'test'
|
||||
}
|
||||
)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
@mock.patch('os.chmod')
|
||||
@mock.patch('tripleoclient.workflows.package_update.get_key')
|
||||
@mock.patch('tripleoclient.utils.get_tripleo_ansible_inventory')
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_overcloud_support_args_stack(self, mock_playbook, mock_inventory,
|
||||
mock_key, mock_chmod):
|
||||
arglist = ['server1', '--output', 'test', '--stack', 'notovercloud']
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
self.key = mock_key
|
||||
|
||||
fetch_logs_mock.assert_called_once_with(self.app.client_manager,
|
||||
parsed_args.container,
|
||||
parsed_args.server_name,
|
||||
timeout=None,
|
||||
concurrency=None)
|
||||
with mock.patch('builtins.open', mock.mock_open()):
|
||||
with open('/home/stack/.ssh/id_rsa_tripleo', 'w') as key_file:
|
||||
key_file.write(self.key)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
download_files_mock.assert_called_once_with(
|
||||
self.app.client_manager, parsed_args.container,
|
||||
parsed_args.destination)
|
||||
playbook = ('/usr/share/ansible/tripleo-playbooks'
|
||||
'/cli-support-collect-logs.yaml')
|
||||
|
||||
delete_container_mock.assert_not_called()
|
||||
mock_inventory.assert_called_once_with(
|
||||
inventory_file='/home/stack/'
|
||||
'tripleo-ansible-inventory.yaml',
|
||||
ssh_user='tripleo-admin',
|
||||
stack='notovercloud',
|
||||
return_inventory_file_path=True)
|
||||
|
||||
@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)
|
||||
mock_playbook.assert_called_once_with(
|
||||
logger=mock.ANY,
|
||||
ansible_config='/etc/ansible/ansible.cfg',
|
||||
workdir=mock.ANY,
|
||||
python_interpreter='/usr/bin/python3',
|
||||
playbook=playbook,
|
||||
inventory=mock_inventory(),
|
||||
verbosity=1,
|
||||
timeout=None,
|
||||
forks=None,
|
||||
extra_vars={
|
||||
'server_name': 'server1',
|
||||
'sos_destination': 'test'
|
||||
}
|
||||
)
|
||||
|
|
|
@ -95,7 +95,7 @@ class TempDirs(object):
|
|||
|
||||
def __init__(self, dir_path=None, dir_prefix='tripleo', cleanup=True,
|
||||
chdir=True):
|
||||
"""This context manager will create, push, and cleanup temp directories.
|
||||
"""This context manager will create, push, and cleanup temp directories
|
||||
|
||||
>>> with TempDirs() as t:
|
||||
... with open('file', 'w') as f:
|
||||
|
@ -197,7 +197,8 @@ def run_ansible_playbook(logger,
|
|||
extra_vars=None,
|
||||
plan='overcloud',
|
||||
gathering_policy=None,
|
||||
forks=None):
|
||||
forks=None,
|
||||
timeout=None):
|
||||
"""Simple wrapper for ansible-playbook
|
||||
|
||||
:param logger: logger instance
|
||||
|
@ -266,6 +267,10 @@ def run_ansible_playbook(logger,
|
|||
When not specified, the policy will be the default Ansible one, ie.
|
||||
'implicit'.
|
||||
:type gathering_facts: String
|
||||
|
||||
:param timeout: This sets the timeout for the ansible-playbook
|
||||
command.
|
||||
:type timeout: Integer
|
||||
"""
|
||||
env = os.environ.copy()
|
||||
|
||||
|
@ -388,6 +393,11 @@ def run_ansible_playbook(logger,
|
|||
|
||||
cmd.extend(['-c', connection, play])
|
||||
|
||||
if timeout:
|
||||
cmd.extend([
|
||||
'--timeout %s' % timeout
|
||||
])
|
||||
|
||||
if run_command_and_log(logger, cmd, env=env) != 0:
|
||||
logger.warning(
|
||||
"{} did not complete successfully.".format(play)
|
||||
|
|
|
@ -14,11 +14,14 @@
|
|||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from osc_lib.i18n import _
|
||||
|
||||
from tripleoclient import command
|
||||
from tripleoclient.workflows import support
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import utils
|
||||
from tripleoclient.workflows import package_update
|
||||
|
||||
|
||||
class ReportExecute(command.Command):
|
||||
|
@ -29,21 +32,29 @@ class ReportExecute(command.Command):
|
|||
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.'))
|
||||
help=_('Server name, group 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',
|
||||
action='store_true',
|
||||
help=_('DEPRECATED: Swift Container to store'
|
||||
' logs to'))
|
||||
parser.add_argument('-o',
|
||||
'--output',
|
||||
dest='destination',
|
||||
default='/var/lib/tripleo/support',
|
||||
help=_('Output directory for the report'))
|
||||
parser.add_argument('--stack',
|
||||
help=_("Stack name to use for log collection."),
|
||||
default='overcloud')
|
||||
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.'),
|
||||
help=_('DEPRECATED: 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,
|
||||
|
@ -56,52 +67,63 @@ class ReportExecute(command.Command):
|
|||
'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'),
|
||||
help=_('DEPRECATED: 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'),
|
||||
help=_('DEPRECATED: Skip generation, only '
|
||||
'download from the provided container'),
|
||||
default=False,
|
||||
action='store_true')
|
||||
parser.add_argument('-v',
|
||||
'--verbose',
|
||||
dest='verbosity',
|
||||
type=int,
|
||||
default=1)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action({})'.format(parsed_args))
|
||||
|
||||
playbook = os.path.join(
|
||||
constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
'cli-support-collect-logs.yaml')
|
||||
|
||||
inventory = utils.get_tripleo_ansible_inventory(
|
||||
inventory_file='/home/stack/'
|
||||
'tripleo-ansible-inventory.yaml',
|
||||
ssh_user='tripleo-admin',
|
||||
stack=parsed_args.stack,
|
||||
return_inventory_file_path=True)
|
||||
|
||||
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
|
||||
key = package_update.get_key(clients)
|
||||
|
||||
if not server_name:
|
||||
raise Exception(_('Please specify the server_name option.'))
|
||||
# The playbook we're using for this relies on this file
|
||||
# existing in this location. So we need to write it and
|
||||
# set the permissions appropriately. Not required after
|
||||
# Train.
|
||||
with open('/home/stack/.ssh/id_rsa_tripleo', 'w') as key_file:
|
||||
key_file.write(key)
|
||||
|
||||
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
|
||||
os.chmod('/home/stack/.ssh/id_rsa_tripleo', 0o600)
|
||||
|
||||
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
|
||||
extra_vars = {
|
||||
'server_name': parsed_args.server_name,
|
||||
'sos_destination': parsed_args.destination,
|
||||
}
|
||||
|
||||
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
|
||||
with utils.TempDirs() as tmp:
|
||||
utils.run_ansible_playbook(
|
||||
logger=self.log,
|
||||
ansible_config='/etc/ansible/ansible.cfg',
|
||||
playbook=playbook,
|
||||
inventory=inventory,
|
||||
python_interpreter='/usr/bin/python3',
|
||||
workdir=tmp,
|
||||
verbosity=parsed_args.verbosity,
|
||||
forks=parsed_args.concurrency,
|
||||
timeout=parsed_args.timeout,
|
||||
extra_vars=extra_vars
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue