ansible: split waiting from provisioning

Introduces a new command 'wait' for this purpose.

Change-Id: I52ef0228cce2be276046b93c284743c4067da0a6
Story: #2002186
Task: #20058
This commit is contained in:
Dmitry Tantsur 2018-06-12 14:56:02 +02:00
parent ef7521e294
commit cbf7294be9
5 changed files with 80 additions and 11 deletions

View File

@ -78,6 +78,12 @@ def _do_show(api, args, formatter):
formatter.show(instances)
def _do_wait(api, args, formatter):
instances = api.wait_for_provisioning(args.instance,
timeout=args.timeout)
formatter.show(instances)
def _parse_args(args, config):
parser = argparse.ArgumentParser(
description='Deployment and Scheduling tool for Bare Metal')
@ -102,12 +108,12 @@ def _parse_args(args, config):
deploy = subparsers.add_parser('deploy')
deploy.set_defaults(func=_do_deploy)
wait = deploy.add_mutually_exclusive_group()
wait.add_argument('--wait', type=int, default=1800,
help='time (in seconds) to wait for node to become '
'active')
wait.add_argument('--no-wait', action='store_true',
help='disable waiting for deploy to finish')
wait_grp = deploy.add_mutually_exclusive_group()
wait_grp.add_argument('--wait', type=int, default=1800,
help='time (in seconds) to wait for node to become '
'active')
wait_grp.add_argument('--no-wait', action='store_true',
help='disable waiting for deploy to finish')
deploy.add_argument('--image', help='image to use (name or UUID)',
required=True)
deploy.add_argument('--network', help='network to use (name or UUID)',
@ -141,6 +147,12 @@ def _parse_args(args, config):
show.set_defaults(func=_do_show)
show.add_argument('instance', nargs='+', help='instance UUID(s)')
wait = subparsers.add_parser('wait')
wait.set_defaults(func=_do_wait)
wait.add_argument('instance', nargs='+', help='instance UUID(s)')
wait.add_argument('--timeout', type=int,
help='time (in seconds) to wait for provisioning.')
return parser.parse_args(args)

View File

@ -679,9 +679,9 @@ class TestUndeploy(testtools.TestCase):
@mock.patch.object(_provisioner, 'Provisioner', autospec=True)
@mock.patch.object(_cmd.os_config, 'OpenStackConfig', autospec=True)
class TestShow(testtools.TestCase):
class TestShowWait(testtools.TestCase):
def setUp(self):
super(TestShow, self).setUp()
super(TestShowWait, self).setUp()
self.print_fixture = self.useFixture(fixtures.MockPatch(
'metalsmith._format._print', autospec=True))
self.mock_print = self.print_fixture.mock
@ -708,6 +708,36 @@ class TestShow(testtools.TestCase):
mock.call(mock.ANY, ips='private=1.2.3.4'),
mock.call(mock.ANY, node='name-2 (UUID 2)', state='deploying'),
])
mock_pr.return_value.show_instances.assert_called_once_with(
['uuid1', 'hostname2'])
def test_wait(self, mock_os_conf, mock_pr):
mock_pr.return_value.wait_for_provisioning.return_value = (
self.instances)
args = ['wait', 'uuid1', 'hostname2']
_cmd.main(args)
self.mock_print.assert_has_calls([
mock.call(mock.ANY, node='name-1 (UUID 1)', state='active'),
mock.call(mock.ANY, ips='private=1.2.3.4'),
mock.call(mock.ANY, node='name-2 (UUID 2)', state='deploying'),
])
mock_pr.return_value.wait_for_provisioning.assert_called_once_with(
['uuid1', 'hostname2'], timeout=None)
def test_wait_custom_timeout(self, mock_os_conf, mock_pr):
mock_pr.return_value.wait_for_provisioning.return_value = (
self.instances)
args = ['wait', '--timeout', '42', 'uuid1', 'hostname2']
_cmd.main(args)
self.mock_print.assert_has_calls([
mock.call(mock.ANY, node='name-1 (UUID 1)', state='active'),
mock.call(mock.ANY, ips='private=1.2.3.4'),
mock.call(mock.ANY, node='name-2 (UUID 2)', state='deploying'),
])
mock_pr.return_value.wait_for_provisioning.assert_called_once_with(
['uuid1', 'hostname2'], timeout=42)
def test_show_json(self, mock_os_conf, mock_pr):
mock_pr.return_value.show_instances.return_value = self.instances
@ -719,3 +749,15 @@ class TestShow(testtools.TestCase):
self.assertEqual(json.loads(fake_io.getvalue()),
{'hostname1': {'1': 'name-1'},
'hostname2': {'2': 'name-2'}})
def test_wait_json(self, mock_os_conf, mock_pr):
mock_pr.return_value.wait_for_provisioning.return_value = (
self.instances)
args = ['--format', 'json', 'wait', 'uuid1', 'hostname2']
fake_io = six.StringIO()
with mock.patch('sys.stdout', fake_io):
_cmd.main(args)
self.assertEqual(json.loads(fake_io.getvalue()),
{'hostname1': {'1': 'name-1'},
'hostname2': {'2': 'name-2'}})

View File

@ -18,6 +18,7 @@
include_role:
name: metalsmith_deployment
vars:
metalsmith_extra_args: -vv
metalsmith_resource_class: baremetal
metalsmith_instances:
- hostname: test
@ -28,7 +29,6 @@
root_size: 9
ssh_public_keys:
- "{{ ssh_key_file }}"
extra_args: -vv
- name: Get instance info via CLI
command: metalsmith --format=json show test

View File

@ -6,3 +6,6 @@ metalsmith_nics: []
metalsmith_root_size:
metalsmith_ssh_public_keys: []
metalsmith_user_name: metalsmith
# Wait parameters
metalsmith_provisioning_timeout:

View File

@ -1,8 +1,8 @@
---
- name: Provision instances
- name: Start provisioning of instances
command: >
metalsmith {{ extra_args }} deploy
metalsmith {{ extra_args }} deploy --no-wait
{% for cap_name, cap_value in capabilities.items() %}
--capability {{ cap_name }}={{ cap_value }}
{% endfor %}
@ -42,3 +42,15 @@
loop_control:
label: "{{ instance.hostname or instance }}"
loop_var: instance
- name: Wait for provisioning of instances
command: >
metalsmith {{ metalsmith_extra_args }} wait
{% if metalsmith_provisioning_timeout %}
--timeout {{ metalsmith_provisioning_timeout }}
{% endif %}
{% for instance in metalsmith_instances %}
{% if (instance.state | default('present')) == 'present' %}
{{ instance.hostname }}
{% endif %}
{% endfor %}