openstack overcloud failures
Add a new command to tripleoclient: openstack overcloud failures The command shows the deployment failures based on a plan name and makes use of the tripleo.deployment.v1.get_plan_deployment_failures workflow. Change-Id: I9ce4ab9e6c690abb5aed887f8fe6add4bbf52167 Depends-On: I16d2dd0b3022cd5964919d07dd0ec603490a3ed7
This commit is contained in:
parent
afed9c44a2
commit
d25d360185
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- A new command, openstack overcloud failures, is added to show
|
||||||
|
the failures from a deployment plan when using config-download.
|
@ -58,6 +58,7 @@ openstack.tripleoclient.v1 =
|
|||||||
overcloud_delete = tripleoclient.v1.overcloud_delete:DeleteOvercloud
|
overcloud_delete = tripleoclient.v1.overcloud_delete:DeleteOvercloud
|
||||||
overcloud_credentials = tripleoclient.v1.overcloud_credentials:OvercloudCredentials
|
overcloud_credentials = tripleoclient.v1.overcloud_credentials:OvercloudCredentials
|
||||||
overcloud_deploy = tripleoclient.v1.overcloud_deploy:DeployOvercloud
|
overcloud_deploy = tripleoclient.v1.overcloud_deploy:DeployOvercloud
|
||||||
|
overcloud_failures = tripleoclient.v1.overcloud_deploy:GetDeploymentFailures
|
||||||
overcloud_status = tripleoclient.v1.overcloud_deploy:GetDeploymentStatus
|
overcloud_status = tripleoclient.v1.overcloud_deploy:GetDeploymentStatus
|
||||||
overcloud_image_build = tripleoclient.v1.overcloud_image:BuildOvercloudImage
|
overcloud_image_build = tripleoclient.v1.overcloud_image:BuildOvercloudImage
|
||||||
overcloud_image_upload = tripleoclient.v1.overcloud_image:UploadOvercloudImage
|
overcloud_image_upload = tripleoclient.v1.overcloud_image:UploadOvercloudImage
|
||||||
|
@ -1960,3 +1960,56 @@ class TestGetDeploymentStatus(utils.TestCommand):
|
|||||||
'+-----------+-----------+---------+-------------------+\n')
|
'+-----------+-----------+---------+-------------------+\n')
|
||||||
|
|
||||||
self.assertEqual(expected, self.cmd.app.stdout.getvalue())
|
self.assertEqual(expected, self.cmd.app.stdout.getvalue())
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetDeploymentFailures(utils.TestCommand):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestGetDeploymentFailures, self).setUp()
|
||||||
|
self.cmd = overcloud_deploy.GetDeploymentFailures(self.app, None)
|
||||||
|
self.app.client_manager = mock.Mock()
|
||||||
|
self.clients = self.app.client_manager
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'tripleoclient.workflows.deployment.get_deployment_failures',
|
||||||
|
autospec=True)
|
||||||
|
def test_plan_get_deployment_status(self, mock_get_deployment_failures):
|
||||||
|
parsed_args = self.check_parser(self.cmd, [], [])
|
||||||
|
self.cmd.app.stdout = six.StringIO()
|
||||||
|
|
||||||
|
failures = {
|
||||||
|
'host0': [
|
||||||
|
['Task1', dict(key1=1, key2=2, key3=3)],
|
||||||
|
['Task2', dict(key4=4, key5=5, key3=5)]
|
||||||
|
],
|
||||||
|
'host1': [
|
||||||
|
['Task1', dict(key1=1, key2=2, key3=['a', 'b', 'c'])]
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
mock_get_deployment_failures.return_value = failures
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
expected = (
|
||||||
|
'|-> Failures for host: host0\n'
|
||||||
|
'|--> Task: Task1\n'
|
||||||
|
'|---> key1: 1\n'
|
||||||
|
'|---> key2: 2\n'
|
||||||
|
'|---> key3: 3\n'
|
||||||
|
'|--> Task: Task2\n'
|
||||||
|
'|---> key3: 5\n'
|
||||||
|
'|---> key4: 4\n'
|
||||||
|
'|---> key5: 5\n'
|
||||||
|
'\n'
|
||||||
|
'|-> Failures for host: host1\n'
|
||||||
|
'|--> Task: Task1\n'
|
||||||
|
'|---> key1: 1\n'
|
||||||
|
'|---> key2: 2\n'
|
||||||
|
'|---> key3: [\n'
|
||||||
|
' "a",\n'
|
||||||
|
' "b",\n'
|
||||||
|
' "c"\n'
|
||||||
|
']\n\n')
|
||||||
|
|
||||||
|
self.assertEqual(expected, self.cmd.app.stdout.getvalue())
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
@ -947,7 +948,7 @@ class DeployOvercloud(command.Command):
|
|||||||
|
|
||||||
|
|
||||||
class GetDeploymentStatus(command.Command):
|
class GetDeploymentStatus(command.Command):
|
||||||
"""Check status of a deployment plan"""
|
"""Get deployment status"""
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + ".GetDeploymentStatus")
|
log = logging.getLogger(__name__ + ".GetDeploymentStatus")
|
||||||
|
|
||||||
@ -977,3 +978,51 @@ class GetDeploymentStatus(command.Command):
|
|||||||
execution['updated_at'],
|
execution['updated_at'],
|
||||||
payload['deployment_status']])
|
payload['deployment_status']])
|
||||||
print(table, file=self.app.stdout)
|
print(table, file=self.app.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class GetDeploymentFailures(command.Command):
|
||||||
|
"""Get deployment failures"""
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__ + ".GetDeploymentFailures")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(GetDeploymentFailures, self).get_parser(prog_name)
|
||||||
|
parser.add_argument('--plan', '--stack',
|
||||||
|
help=_('Name of the stack/plan. '
|
||||||
|
'(default: overcloud)'),
|
||||||
|
default='overcloud')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)" % parsed_args)
|
||||||
|
plan = parsed_args.plan
|
||||||
|
|
||||||
|
failures = deployment.get_deployment_failures(
|
||||||
|
self.app.client_manager,
|
||||||
|
plan=plan
|
||||||
|
)
|
||||||
|
|
||||||
|
out = self.app.stdout
|
||||||
|
|
||||||
|
hosts = list(failures.keys())
|
||||||
|
hosts.sort()
|
||||||
|
|
||||||
|
for host in hosts:
|
||||||
|
host_failures = failures[host]
|
||||||
|
host_failures = sorted(host_failures, key=lambda k: k[0])
|
||||||
|
out.write("|-> Failures for host: %s\n" % host)
|
||||||
|
for task_name, task in host_failures:
|
||||||
|
out.write('|--> Task: %s\n' % task_name)
|
||||||
|
task_keys = sorted(task.keys())
|
||||||
|
for task_key in task_keys:
|
||||||
|
task_value = task[task_key]
|
||||||
|
out.write('|---> %s: ' % task_key)
|
||||||
|
try:
|
||||||
|
value = json.dumps(task_value,
|
||||||
|
sort_keys=True,
|
||||||
|
separators=(',', ': '),
|
||||||
|
indent=4)
|
||||||
|
except ValueError:
|
||||||
|
value = task_value
|
||||||
|
out.write('%s\n' % value)
|
||||||
|
out.write('\n')
|
||||||
|
@ -302,3 +302,27 @@ def get_deployment_status(clients, **workflow_input):
|
|||||||
raise exceptions.WorkflowServiceError(
|
raise exceptions.WorkflowServiceError(
|
||||||
'Exception getting deployment status: {}'.format(
|
'Exception getting deployment status: {}'.format(
|
||||||
payload.get('message', '')))
|
payload.get('message', '')))
|
||||||
|
|
||||||
|
|
||||||
|
def get_deployment_failures(clients, **workflow_input):
|
||||||
|
workflow_client = clients.workflow_engine
|
||||||
|
tripleoclients = clients.tripleoclient
|
||||||
|
|
||||||
|
execution = base.start_workflow(
|
||||||
|
workflow_client,
|
||||||
|
'tripleo.deployment.v1.get_deployment_failures',
|
||||||
|
workflow_input=workflow_input
|
||||||
|
)
|
||||||
|
|
||||||
|
with tripleoclients.messaging_websocket() as ws:
|
||||||
|
for payload in base.wait_for_messages(workflow_client, ws, execution,
|
||||||
|
_WORKFLOW_TIMEOUT):
|
||||||
|
if 'message' in payload:
|
||||||
|
print(payload['message'])
|
||||||
|
|
||||||
|
if payload['status'] == 'SUCCESS':
|
||||||
|
return payload['deployment_failures']['failures']
|
||||||
|
else:
|
||||||
|
raise exceptions.WorkflowServiceError(
|
||||||
|
'Exception getting deployment failures: {}'.format(
|
||||||
|
payload.get('message', '')))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user