Add --config-download
Add a new cli option to tripleoclient called --config-download that will trigger using the config download mechanism to apply the overcloud configuration via ansible. When using --config-download, an additional workflow called tripleo.deployment.v1.config_download_deploy is run after the deploy_play workflow. This new workflow does the necessary setup and then executes the software configuration steps via ansible. Change-Id: If3114a6fda75ee502d80e4ba27b5f2e81ba44085 implements: blueprint ansible-config-download Depends-On: I738c78b32590c58ae8b721289ad8103ee09e9956
This commit is contained in:
parent
de93935379
commit
c14d21d549
@ -1592,6 +1592,36 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||
parsed_args)
|
||||
self.assertFalse(mock_deploy_tmpdir.called)
|
||||
|
||||
@mock.patch('tripleoclient.workflows.deployment.config_download')
|
||||
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.utils.get_overcloud_endpoint', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
|
||||
@mock.patch('tripleoclient.workflows.deployment.overcloudrc',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_deploy_tripleo_heat_templates_tmpdir', autospec=True)
|
||||
def test_config_download(
|
||||
self, mock_deploy_tmpdir,
|
||||
mock_overcloudrc, mock_write_overcloudrc,
|
||||
mock_overcloud_endpoint,
|
||||
mock_create_tempest_deployer_input,
|
||||
mock_config_download):
|
||||
clients = self.app.client_manager
|
||||
orchestration_client = clients.orchestration
|
||||
orchestration_client.stacks.get.return_value = mock.Mock()
|
||||
|
||||
arglist = ['--templates', '--config-download']
|
||||
verifylist = [
|
||||
('templates', '/usr/share/openstack-tripleo-heat-templates/'),
|
||||
('config_download', True),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.assertTrue(mock_deploy_tmpdir.called)
|
||||
self.assertTrue(mock_config_download.called)
|
||||
|
||||
|
||||
class TestArgumentValidation(fakes.TestDeployOvercloud):
|
||||
|
||||
|
@ -342,6 +342,18 @@ def get_role_config(stack):
|
||||
return role_data
|
||||
|
||||
|
||||
def get_role_net_hostname_map(stack):
|
||||
for output in stack.to_dict().get('outputs', {}):
|
||||
if output['output_key'] == 'RoleNetHostnameMap':
|
||||
return output['output_value']
|
||||
|
||||
|
||||
def get_hosts_entry(stack):
|
||||
for output in stack.to_dict().get('outputs', {}):
|
||||
if output['output_key'] == 'HostsEntry':
|
||||
return output['output_value']
|
||||
|
||||
|
||||
def get_endpoint(key, stack):
|
||||
endpoint_map = get_endpoint_map(stack)
|
||||
if endpoint_map:
|
||||
|
@ -18,6 +18,7 @@ import argparse
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import pwd
|
||||
import re
|
||||
import shutil
|
||||
import six
|
||||
@ -736,6 +737,11 @@ class DeployOvercloud(command.Command):
|
||||
default='heat-admin',
|
||||
help=_('User for ssh access to overcloud nodes')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--overcloud-ssh-key',
|
||||
default=pwd.getpwuid(os.getuid()).pw_name,
|
||||
help=_('Key path for ssh access to overcloud nodes.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--environment-file', '-e', metavar='<HEAT ENVIRONMENT FILE>',
|
||||
action='append', dest='environment_files',
|
||||
@ -890,7 +896,12 @@ class DeployOvercloud(command.Command):
|
||||
'undercloud node. Must only be used with the'
|
||||
'--disable-validations.')
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--config-download',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Run deployment via config-download mechanism')
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -980,6 +991,15 @@ class DeployOvercloud(command.Command):
|
||||
# wont do anything.
|
||||
return
|
||||
|
||||
if parsed_args.config_download:
|
||||
print("Deploying overcloud configuration")
|
||||
|
||||
deployment.config_download(self.log, self.clients, stack,
|
||||
parsed_args.templates,
|
||||
parsed_args.deployed_server,
|
||||
parsed_args.overcloud_ssh_user,
|
||||
parsed_args.overcloud_ssh_key)
|
||||
|
||||
# Force fetching of attributes
|
||||
stack.get()
|
||||
|
||||
|
@ -11,7 +11,10 @@
|
||||
# under the License.
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from heatclient.common import event_utils
|
||||
@ -91,3 +94,62 @@ def deploy_and_wait(log, clients, stack, plan_name, verbose_level,
|
||||
def overcloudrc(workflow_client, **input_):
|
||||
return base.call_action(workflow_client, 'tripleo.deployment.overcloudrc',
|
||||
**input_)
|
||||
|
||||
|
||||
def config_download(log, clients, stack, templates, deployed_server,
|
||||
ssh_user, ssh_key):
|
||||
role_net_hostname_map = utils.get_role_net_hostname_map(stack)
|
||||
hostnames = []
|
||||
for role in role_net_hostname_map:
|
||||
hostnames.extend(role_net_hostname_map[role]['ctlplane'])
|
||||
|
||||
ips = []
|
||||
hosts_entry = utils.get_hosts_entry(stack)
|
||||
for hostname in hostnames:
|
||||
for line in hosts_entry.split('\n'):
|
||||
match = re.search('\s*%s\s*' % hostname, line)
|
||||
if match:
|
||||
ips.append(line.split(' ')[0])
|
||||
|
||||
if deployed_server:
|
||||
script_path = os.path.join(templates,
|
||||
'deployed-server',
|
||||
'scripts',
|
||||
'enable-ssh-admin.sh')
|
||||
|
||||
env = os.environ.copy()
|
||||
env.update(dict(OVERCLOUD_HOSTS=' '.join(ips),
|
||||
OVERCLOUD_SSH_USER=ssh_user,
|
||||
OVERCLOUD_SSH_KEY=ssh_key))
|
||||
|
||||
proc = subprocess.Popen([script_path], env=env, shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
while True:
|
||||
line = proc.stdout.readline().decode('utf-8')
|
||||
if line:
|
||||
log.info(line.rstrip())
|
||||
if line == '' and proc.poll() is not None:
|
||||
break
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError('%s failed.' % script_path)
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
|
||||
with tripleoclients.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.deployment.v1.config_download_deploy',
|
||||
workflow_input={}
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution,
|
||||
3600):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print("Overcloud configuration completed.")
|
||||
else:
|
||||
raise exceptions.DeploymentError("Overcloud configuration failed.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user