Handle config-download in progress in tripleoclient

This patch adds handling and checking of any instances of the workflow
tripleo.deployment.v1.config_download_deploy already in progress for the
current stack. It will prevent duplicate instances of the same workflow
being started and running at the same time.

It will allow for multiple instances of the workflow running at the same
time as long as they are for different stacks.

Change-Id: Ic8dbf28b5796ff998165b6b73b941f21c65f1dfa
Closes-Bug: #1852314
(cherry picked from commit 72f5762e45)
This commit is contained in:
James Slagle 2019-11-12 10:59:59 -05:00
parent ff9cd8b034
commit 6367d58c24
4 changed files with 81 additions and 1 deletions

View File

@ -0,0 +1,6 @@
---
fixes:
- The client (tripleoclient) now raises a new exception,
ConfigDownloadInProgress, if there is already an instance of the
tripleo.deployment.v1.config_download_deploy workflow in progress for the
current stack.

View File

@ -57,6 +57,17 @@ class StackInProgress(Base):
"""Unable to deploy as the stack is busy"""
class ConfigDownloadInProgress(Base):
"""Unable to deploy as config download already in progress"""
msg_format = ("Config download already in progress with "
"execution id {} for stack {}")
def __init__(self, execution_id='', stack=''):
message = self.msg_format.format(execution_id, stack)
super(ConfigDownloadInProgress, self).__init__(message)
class RootUserExecution(Base):
"""Command was executed by a root user"""

View File

@ -169,3 +169,44 @@ class TestDeploymentWorkflows(utils.TestCommand):
ips = deployment.get_overcloud_hosts(stack, 'external')
expected = ['4.4.4.4', '6.6.6.6', '11.11.11.11']
self.assertEqual(sorted(expected), sorted(ips))
def test_config_download_already_in_progress(
self):
log = mock.Mock()
stack = mock.Mock()
stack.stack_name = 'stacktest'
clients = mock.Mock()
mock_execution = mock.Mock()
mock_execution.input = '{"plan_name": "stacktest"}'
mock_return = mock.Mock(return_value=[mock_execution])
clients.workflow_engine.executions.find = mock_return
self.assertRaises(exceptions.ConfigDownloadInProgress,
deployment.config_download,
log, clients, stack, 'templates', 'ssh_user',
'ssh_key', 'ssh_networks', 'output_dir', False,
'timeout')
@mock.patch('tripleoclient.workflows.deployment.base')
def test_config_download_already_in_progress_for_diff_stack(
self, mock_base):
log = mock.Mock()
stack = mock.Mock()
stack.stack_name = 'stacktest'
clients = mock.Mock()
mock_execution = mock.Mock()
mock_execution.input = '{"plan_name": "someotherstack"}'
mock_return = mock.Mock(return_value=[mock_execution])
clients.workflow_engine.executions.find = mock_return
mock_exit = mock.Mock()
mock_exit.__exit__ = mock.Mock()
mock_exit.__enter__ = mock.Mock()
clients.tripleoclient.messaging_websocket = mock.Mock(
return_value=mock_exit)
mock_base.wait_for_messages = mock.Mock(
return_value=[dict(status='SUCCESS')])
deployment.config_download(
log, clients, stack, 'templates', 'ssh_user',
'ssh_key', 'ssh_networks', 'output_dir', False,
'timeout')

View File

@ -19,6 +19,7 @@ import socket
import subprocess
import tempfile
import time
import yaml
from heatclient.common import event_utils
from openstackclient import shell
@ -360,10 +361,31 @@ def config_download(log, clients, stack, templates,
workflow_input.update(
dict(override_ansible_cfg=override_ansible_cfg_contents))
workflow_name = 'tripleo.deployment.v1.config_download_deploy'
# Check to see if any existing executions for the same stack are already in
# progress.
log.info("Checking for existing executions of config_download for "
"%s" % stack.stack_name)
for execution in workflow_client.executions.find(
workflow_name=workflow_name,
state='RUNNING'):
try:
exec_input = yaml.safe_load(execution.input)
except yaml.YAMLError as ye:
log.error("YAML error loading input for execution %s: %s" %
(execution.id, str(ye)))
raise
if exec_input.get('plan_name', 'overcloud') == stack.stack_name:
raise exceptions.ConfigDownloadInProgress(execution.id,
stack.stack_name)
with tripleoclients.messaging_websocket() as ws:
execution = base.start_workflow(
workflow_client,
'tripleo.deployment.v1.config_download_deploy',
workflow_name,
workflow_input=workflow_input
)