Add --wait to OSC provisioning commands

This change adds the --wait flag to all provisioning commands, except
for abort which is not supported.

Change-Id: I6182ff919e60053eb39e71e3be6b757c2d2c0f44
Closes-Bug: #1590752
Co-Authored-By: Mike Turek <mjturek@linux.vnet.ibm.com>
This commit is contained in:
Michael Turek 2016-08-31 20:12:05 +00:00
parent d23c02f64f
commit 09774ad3fc
3 changed files with 510 additions and 8 deletions

View File

@ -69,6 +69,55 @@ class ProvisionStateBaremetalNode(command.Command):
cleansteps=clean_steps)
class ProvisionStateWithWait(ProvisionStateBaremetalNode):
"""Provision state class adding --wait flag."""
log = logging.getLogger(__name__ + ".ProvisionStateWithWait")
def get_parser(self, prog_name):
parser = super(ProvisionStateWithWait, self).get_parser(prog_name)
desired_state = v1_utils.PROVISION_ACTIONS.get(
self.PROVISION_STATE)['expected_state']
parser.add_argument(
'--wait',
type=int,
dest='wait_timeout',
default=None,
metavar='<time-out>',
const=0,
nargs='?',
help=("Wait for a node to reach the desired state, %(state)s. "
"Optionally takes a timeout value (in seconds). The "
"default value is 0, meaning it will wait indefinitely.") %
{'state': desired_state})
return parser
def take_action(self, parsed_args):
super(ProvisionStateWithWait, self).take_action(parsed_args)
self.log.debug("take_action(%s)", parsed_args)
if (parsed_args.wait_timeout is None):
return
baremetal_client = self.app.client_manager.baremetal
wait_args = v1_utils.PROVISION_ACTIONS.get(
parsed_args.provision_state)
if wait_args is None:
# This should never happen in reality, but checking just in case
raise exc.CommandError(
_("'--wait is not supported for provision state '%s'")
% parsed_args.provision_state)
print(_('Waiting for provision state %(state)s on node %(node)s') %
{'state': wait_args['expected_state'], 'node': parsed_args.node})
baremetal_client.node.wait_for_provision_state(
parsed_args.node,
timeout=parsed_args.wait_timeout,
**wait_args)
class AbortBaremetalNode(ProvisionStateBaremetalNode):
"""Set provision state of baremetal node to 'abort'"""
@ -76,7 +125,7 @@ class AbortBaremetalNode(ProvisionStateBaremetalNode):
PROVISION_STATE = 'abort'
class AdoptBaremetalNode(ProvisionStateBaremetalNode):
class AdoptBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'adopt'"""
log = logging.getLogger(__name__ + ".AdoptBaremetalNode")
@ -157,7 +206,7 @@ class BootdeviceShowBaremetalNode(command.ShowOne):
return zip(*sorted(info.items()))
class CleanBaremetalNode(ProvisionStateBaremetalNode):
class CleanBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'clean'"""
log = logging.getLogger(__name__ + ".CleanBaremetalNode")
@ -374,7 +423,7 @@ class DeleteBaremetal(DeleteBaremetalNode):
super(DeleteBaremetal, self).take_action(parsed_args)
class DeployBaremetalNode(ProvisionStateBaremetalNode):
class DeployBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'deploy'"""
log = logging.getLogger(__name__ + ".DeployBaremetalNode")
@ -394,7 +443,7 @@ class DeployBaremetalNode(ProvisionStateBaremetalNode):
return parser
class InspectBaremetalNode(ProvisionStateBaremetalNode):
class InspectBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'inspect'"""
log = logging.getLogger(__name__ + ".InspectBaremetalNode")
@ -599,7 +648,7 @@ class MaintenanceUnsetBaremetalNode(command.Command):
False)
class ManageBaremetalNode(ProvisionStateBaremetalNode):
class ManageBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'manage'"""
log = logging.getLogger(__name__ + ".ManageBaremetalNode")
@ -741,7 +790,7 @@ class PowerBaremetalNode(command.Command):
timeout=parsed_args.power_timeout)
class ProvideBaremetalNode(ProvisionStateBaremetalNode):
class ProvideBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'provide'"""
log = logging.getLogger(__name__ + ".ProvideBaremetalNode")
@ -789,7 +838,7 @@ class RebootBaremetalNode(command.Command):
timeout=parsed_args.power_timeout)
class RebuildBaremetalNode(ProvisionStateBaremetalNode):
class RebuildBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'rebuild'"""
log = logging.getLogger(__name__ + ".RebuildBaremetalNode")
@ -1015,7 +1064,7 @@ class ShowBaremetal(ShowBaremetalNode):
return super(ShowBaremetal, self).take_action(parsed_args)
class UndeployBaremetalNode(ProvisionStateBaremetalNode):
class UndeployBaremetalNode(ProvisionStateWithWait):
"""Set provision state of baremetal node to 'deleted'"""
log = logging.getLogger(__name__ + ".UndeployBaremetalNode")

View File

@ -57,6 +57,55 @@ class TestAdopt(TestBaremetal):
self.baremetal_mock.node.set_provision_state.assert_called_once_with(
'node_uuid', 'adopt', cleansteps=None, configdrive=None)
def test_adopt_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'adopt')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_adopt_baremetal_provision_state_active_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'adopt'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=2, timeout=15)
def test_adopt_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'adopt'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=2, timeout=0)
class TestBootdeviceSet(TestBaremetal):
def setUp(self):
@ -999,6 +1048,52 @@ class TestDeployBaremetalProvisionState(TestBaremetal):
'node_uuid', 'active',
cleansteps=None, configdrive='path/to/drive')
def test_deploy_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'active')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_deploy_baremetal_provision_state_active_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'active'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=10, timeout=15)
def test_deploy_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'active'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=10, timeout=0)
def test_deploy_baremetal_provision_state_mismatch(self):
arglist = ['node_uuid',
'--provision-state', 'abort']
@ -1012,6 +1107,353 @@ class TestDeployBaremetalProvisionState(TestBaremetal):
self.cmd, arglist, verifylist)
class TestManageBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestManageBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.ManageBaremetalNode(self.app, None)
def test_manage_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'manage')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_manage_baremetal_provision_state_manageable_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'manage'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=2, timeout=15)
def test_manage_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'manage'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=2, timeout=0)
class TestCleanBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestCleanBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.CleanBaremetalNode(self.app, None)
def test_clean_no_wait(self):
arglist = ['node_uuid', '--clean-steps', '-']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'clean'),
('clean_steps', '-')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_clean_baremetal_provision_state_manageable_and_wait(self):
arglist = ['node_uuid',
'--wait', '15',
'--clean-steps', '-']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'clean'),
('wait_timeout', 15),
('clean_steps', '-')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=10, timeout=15)
def test_clean_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait',
'--clean-steps', '-']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'clean'),
('wait_timeout', 0),
('clean_steps', '-')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=10, timeout=0)
class TestInspectBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestInspectBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.InspectBaremetalNode(self.app, None)
def test_inspect_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'inspect')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_inspect_baremetal_provision_state_managable_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'inspect'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=2, timeout=15)
def test_inspect_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'inspect'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='manageable',
poll_interval=2, timeout=0)
class TestProvideBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestProvideBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.ProvideBaremetalNode(self.app, None)
def test_provide_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'provide')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_provide_baremetal_provision_state_available_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'provide'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='available',
poll_interval=10, timeout=15)
def test_provide_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'provide'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='available',
poll_interval=10, timeout=0)
class TestRebuildBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestRebuildBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.RebuildBaremetalNode(self.app, None)
def test_rebuild_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'rebuild')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_rebuild_baremetal_provision_state_active_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'rebuild'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=10, timeout=15)
def test_rebuild_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'rebuild'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='active',
poll_interval=10, timeout=0)
class TestUndeployBaremetalProvisionState(TestBaremetal):
def setUp(self):
super(TestUndeployBaremetalProvisionState, self).setUp()
# Get the command object to test
self.cmd = baremetal_node.UndeployBaremetalNode(self.app, None)
def test_undeploy_no_wait(self):
arglist = ['node_uuid']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'deleted')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.baremetal_mock.node.wait_for_provision_state.assert_not_called()
def test_undeploy_baremetal_provision_state_available_and_wait(self):
arglist = ['node_uuid',
'--wait', '15']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'deleted'),
('wait_timeout', 15)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='available',
poll_interval=10, timeout=15)
def test_undeploy_baremetal_provision_state_default_wait(self):
arglist = ['node_uuid',
'--wait']
verifylist = [
('node', 'node_uuid'),
('provision_state', 'deleted'),
('wait_timeout', 0)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
test_node = self.baremetal_mock.node
test_node.wait_for_provision_state.assert_called_once_with(
'node_uuid', expected_state='available',
poll_interval=10, timeout=0)
class TestBaremetalReboot(TestBaremetal):
def setUp(self):
super(TestBaremetalReboot, self).setUp()

View File

@ -0,0 +1,11 @@
---
features:
- |
Adds an option ``--wait [<time-out>]`` to all of the
OSC provisioning commands, except for abort which is not
supported. When specified, provisioning commands will
wait for the node to reach the desired state before
returning. An optional argument, time-out, can be specified
which will end the waiting after the specified amount of
time (in seconds). The default value for this timeout is
0, which means it will wait indefinitely.