Create commands for configuring BIOS on given nodes
This commit introduces two new commands to configure BIOS: 1) openstack overcloud node bios configure --configuration <..> [--all-manageable|uuid1,uuid2,..] 2) openstack overcloud node bios reset [--all-manageable|uuid1,uuid2,..] The first command applys BIOS configuration on given nodes or all manageable nodes; the second command resets BIOS configuration to factory default on given nodes or all manageable nodes; Depends-On: Icdaa734a44c55c830c0109d25488b68838e8736f Change-Id: I809883e0e54a66bca58a0e45c035c69bcc39dcd1
This commit is contained in:
parent
9fd5b3ce6b
commit
aa3d6adb4b
14
releasenotes/notes/overcloud-node-bios-c9ae89e35a96c7b1.yaml
Normal file
14
releasenotes/notes/overcloud-node-bios-c9ae89e35a96c7b1.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds new commands to run BIOS cleaning on nodes::
|
||||
|
||||
openstack overcloud node bios configure \
|
||||
--configuration <..> [--all-manageable|uuid1,uuid2,..]
|
||||
|
||||
openstack overcloud node bios reset \
|
||||
[--all-manageable|uuid1,uuid2,..]
|
||||
|
||||
The first command configures given BIOS settings on given nodes or all
|
||||
manageable nodes; the second command reset BIOS settings to factory
|
||||
default on given nodes or all manageable nodes.
|
@ -72,6 +72,8 @@ openstack.tripleoclient.v1 =
|
||||
overcloud_node_provide = tripleoclient.v1.overcloud_node:ProvideNode
|
||||
overcloud_node_discover = tripleoclient.v1.overcloud_node:DiscoverNode
|
||||
overcloud_node_clean = tripleoclient.v1.overcloud_node:CleanNode
|
||||
overcloud_node_bios_configure = tripleoclient.v1.overcloud_bios:ConfigureBIOS
|
||||
overcloud_node_bios_reset = tripleoclient.v1.overcloud_bios:ResetBIOS
|
||||
overcloud_parameters_set = tripleoclient.v1.overcloud_parameters:SetParameters
|
||||
overcloud_plan_create = tripleoclient.v1.overcloud_plan:CreatePlan
|
||||
overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan
|
||||
|
264
tripleoclient/tests/v1/test_overcloud_bios.py
Normal file
264
tripleoclient/tests/v1/test_overcloud_bios.py
Normal file
@ -0,0 +1,264 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
|
||||
from osc_lib.tests import utils as test_utils
|
||||
|
||||
from tripleoclient.tests.v1.baremetal import fakes
|
||||
from tripleoclient.v1 import overcloud_bios
|
||||
|
||||
|
||||
class Base(fakes.TestBaremetal):
|
||||
def setUp(self):
|
||||
super(Base, self).setUp()
|
||||
self.workflow = self.app.client_manager.workflow_engine
|
||||
self.conf = {
|
||||
"settings": [
|
||||
{"name": "virtualization", "value": "on"},
|
||||
{"name": "hyperthreading", "value": "on"}
|
||||
]
|
||||
}
|
||||
tripleoclient = self.app.client_manager.tripleoclient
|
||||
self.websocket = tripleoclient.messaging_websocket()
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
'status': "SUCCESS",
|
||||
'execution_id': 'fake id',
|
||||
'root_execution_id': 'fake id',
|
||||
}])
|
||||
|
||||
self.execution = self.workflow.executions.create.return_value
|
||||
self.execution.id = 'fake id'
|
||||
self.execution.output = '{"result": null}'
|
||||
|
||||
|
||||
class TestConfigureBIOS(Base):
|
||||
|
||||
def setUp(self):
|
||||
super(TestConfigureBIOS, self).setUp()
|
||||
self.cmd = overcloud_bios.ConfigureBIOS(self.app, None)
|
||||
|
||||
def test_configure_specified_nodes_ok(self):
|
||||
conf = json.dumps(self.conf)
|
||||
arglist = ['--configuration', conf, 'node_uuid1', 'node_uuid2']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', conf)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.apply_bios_settings',
|
||||
workflow_input={
|
||||
'node_uuids': ['node_uuid1', 'node_uuid2'],
|
||||
'configuration': self.conf,
|
||||
}
|
||||
)
|
||||
|
||||
def test_configure_specified_nodes_and_configuration_from_file(self):
|
||||
with tempfile.NamedTemporaryFile('w+t') as fp:
|
||||
json.dump(self.conf, fp)
|
||||
fp.flush()
|
||||
arglist = ['--configuration', fp.name, 'node_uuid1', 'node_uuid2']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', fp.name)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.apply_bios_settings',
|
||||
workflow_input={
|
||||
'node_uuids': ['node_uuid1', 'node_uuid2'],
|
||||
'configuration': self.conf,
|
||||
}
|
||||
)
|
||||
|
||||
def test_configure_no_nodes(self):
|
||||
arglist = ['--configuration', '{}']
|
||||
verifylist = [
|
||||
('configuration', '{}')
|
||||
]
|
||||
self.assertRaises(test_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertFalse(self.workflow.executions.create.called)
|
||||
|
||||
def test_configure_specified_nodes_and_configuration_not_yaml(self):
|
||||
arglist = ['--configuration', ':', 'node_uuid1', 'node_uuid2']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', ':')
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaisesRegex(RuntimeError, 'cannot be parsed as YAML',
|
||||
self.cmd.take_action, parsed_args)
|
||||
self.assertFalse(self.workflow.executions.create.called)
|
||||
|
||||
def test_configure_specified_nodes_and_configuration_bad_type(self):
|
||||
for conf in ('[]', '{"settings": 42}', '{settings: [42]}'):
|
||||
arglist = ['--configuration', conf, 'node_uuid1', 'node_uuid2']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', conf)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(TypeError, self.cmd.take_action, parsed_args)
|
||||
self.assertFalse(self.workflow.executions.create.called)
|
||||
|
||||
def test_configure_specified_nodes_and_configuration_bad_value(self):
|
||||
conf = '{"another_key": [{}]}'
|
||||
arglist = ['--configuration', conf, 'node_uuid1', 'node_uuid2']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', conf)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.assertRaises(ValueError, self.cmd.take_action, parsed_args)
|
||||
self.assertFalse(self.workflow.executions.create.called)
|
||||
|
||||
def test_configure_uuids_and_all_both_specified(self):
|
||||
conf = json.dumps(self.conf)
|
||||
arglist = ['--configuration', conf, 'node_uuid1', 'node_uuid2',
|
||||
'--all-manageable']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('configuration', conf),
|
||||
('all-manageable', True)
|
||||
]
|
||||
self.assertRaises(test_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
|
||||
def test_configure_all_manageable_nodes_ok(self):
|
||||
conf = json.dumps(self.conf)
|
||||
arglist = ['--configuration', conf, '--all-manageable']
|
||||
verifylist = [
|
||||
('all_manageable', True),
|
||||
('configuration', conf)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.apply_bios_settings_on_manageable_nodes',
|
||||
workflow_input={'configuration': self.conf})
|
||||
|
||||
def test_configure_all_manageable_nodes_fail(self):
|
||||
conf = json.dumps(self.conf)
|
||||
arglist = ['--configuration', conf, '--all-manageable']
|
||||
verifylist = [
|
||||
('all_manageable', True),
|
||||
('configuration', conf)
|
||||
]
|
||||
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
"status": "FAILED",
|
||||
"message": "Test failure.",
|
||||
'execution_id': 'fake id',
|
||||
'root_execution_id': 'fake id',
|
||||
}])
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.assertRaisesRegex(RuntimeError, 'Failed to apply BIOS settings',
|
||||
self.cmd.take_action, parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.apply_bios_settings_on_manageable_nodes',
|
||||
workflow_input={'configuration': self.conf})
|
||||
|
||||
|
||||
class TestResetBIOS(Base):
|
||||
|
||||
def setUp(self):
|
||||
super(TestResetBIOS, self).setUp()
|
||||
self.cmd = overcloud_bios.ResetBIOS(self.app, None)
|
||||
|
||||
def test_reset_specified_nodes_ok(self):
|
||||
arglist = ['node_uuid1', 'node_uuid2']
|
||||
verifylist = [('node_uuids', ['node_uuid1', 'node_uuid2'])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.reset_bios_settings',
|
||||
workflow_input={'node_uuids': ['node_uuid1', 'node_uuid2']})
|
||||
|
||||
def test_reset_specified_nodes_fail(self):
|
||||
arglist = ['node_uuid1', 'node_uuid2']
|
||||
verifylist = [('node_uuids', ['node_uuid1', 'node_uuid2'])]
|
||||
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
"status": "FAILED",
|
||||
"message": "Test failure.",
|
||||
'execution_id': 'fake id',
|
||||
'root_execution_id': 'fake id',
|
||||
}])
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.assertRaisesRegex(RuntimeError, 'Failed to reset BIOS settings',
|
||||
self.cmd.take_action, parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.reset_bios_settings',
|
||||
workflow_input={'node_uuids': ['node_uuid1', 'node_uuid2']})
|
||||
|
||||
def test_reset_all_manageable_nodes_ok(self):
|
||||
arglist = ['--all-manageable']
|
||||
verifylist = [('all_manageable', True)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.reset_bios_settings_on_manageable_nodes',
|
||||
workflow_input={})
|
||||
|
||||
def test_reset_all_manageable_nodes_fail(self):
|
||||
arglist = ['--all-manageable']
|
||||
verifylist = [('all_manageable', True)]
|
||||
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
"status": "FAILED",
|
||||
"message": "Test failure.",
|
||||
'execution_id': 'fake id',
|
||||
'root_execution_id': 'fake id',
|
||||
}])
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.assertRaisesRegex(RuntimeError, 'Failed to reset BIOS settings',
|
||||
self.cmd.take_action, parsed_args)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.reset_bios_settings_on_manageable_nodes',
|
||||
workflow_input={})
|
||||
|
||||
def test_reset_no_nodes(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
self.assertRaises(test_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
||||
self.assertFalse(self.workflow.executions.create.called)
|
||||
|
||||
def test_reset_uuids_and_all_both_specified(self):
|
||||
arglist = ['node_uuid1', 'node_uuid2', '--all-manageable']
|
||||
verifylist = [
|
||||
('node_uuids', ['node_uuid1', 'node_uuid2']),
|
||||
('all-manageable', True)
|
||||
]
|
||||
self.assertRaises(test_utils.ParserException, self.check_parser,
|
||||
self.cmd, arglist, verifylist)
|
119
tripleoclient/v1/overcloud_bios.py
Normal file
119
tripleoclient/v1/overcloud_bios.py
Normal file
@ -0,0 +1,119 @@
|
||||
# Copyright 2018 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from osc_lib.i18n import _
|
||||
import yaml
|
||||
|
||||
from tripleoclient import command
|
||||
from tripleoclient.workflows import baremetal
|
||||
|
||||
|
||||
class ConfigureBIOS(command.Command):
|
||||
"""Apply BIOS configuration on given nodes"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".ConfigureBIOS")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ConfigureBIOS, self).get_parser(prog_name)
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('node_uuids',
|
||||
nargs="*",
|
||||
metavar="<node_uuid>",
|
||||
default=[],
|
||||
help=_('Baremetal Node UUIDs for the node(s) to '
|
||||
'configure BIOS'))
|
||||
group.add_argument("--all-manageable",
|
||||
action='store_true',
|
||||
help=_("Configure BIOS for all nodes currently in "
|
||||
"'manageable' state"))
|
||||
parser.add_argument('--configuration', metavar='<configuration>',
|
||||
dest='configuration',
|
||||
help=_('BIOS configuration (YAML/JSON string or '
|
||||
'file name).'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action({args})".format(args=parsed_args))
|
||||
|
||||
if os.path.exists(parsed_args.configuration):
|
||||
with open(parsed_args.configuration, 'r') as fp:
|
||||
configuration = yaml.safe_load(fp.read())
|
||||
else:
|
||||
try:
|
||||
configuration = yaml.safe_load(parsed_args.configuration)
|
||||
except yaml.YAMLError as exc:
|
||||
raise RuntimeError(
|
||||
_('Configuration is not an existing file and cannot be '
|
||||
'parsed as YAML: %s') % exc)
|
||||
|
||||
# Basic sanity check, we defer the full check to Ironic
|
||||
try:
|
||||
settings = configuration['settings']
|
||||
except KeyError:
|
||||
raise ValueError(
|
||||
_('Configuration must contain key "settings"'))
|
||||
except TypeError:
|
||||
raise TypeError(
|
||||
_('Configuration must be an object, got %r instead')
|
||||
% configuration)
|
||||
|
||||
if (not isinstance(settings, list) or
|
||||
not all(isinstance(item, dict) for item in settings)):
|
||||
raise TypeError(
|
||||
_('BIOS settings list is expected to be a list of '
|
||||
'objects, got %r instead') % settings)
|
||||
|
||||
clients = self.app.client_manager
|
||||
if parsed_args.node_uuids:
|
||||
baremetal.apply_bios_configuration(
|
||||
clients, node_uuids=parsed_args.node_uuids,
|
||||
configuration=configuration)
|
||||
else:
|
||||
baremetal.apply_bios_configuration_on_manageable_nodes(
|
||||
clients, configuration=configuration)
|
||||
|
||||
|
||||
class ResetBIOS(command.Command):
|
||||
"""Reset BIOS configuration to factory default"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".ResetBIOS")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ResetBIOS, self).get_parser(prog_name)
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('node_uuids',
|
||||
nargs="*",
|
||||
metavar="<node_uuid>",
|
||||
default=[],
|
||||
help=_('Baremetal Node UUIDs for the node(s) to '
|
||||
'reset BIOS'))
|
||||
group.add_argument("--all-manageable",
|
||||
action='store_true',
|
||||
help=_("Reset BIOS on all nodes currently in "
|
||||
"'manageable' state"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action({args})".format(args=parsed_args))
|
||||
|
||||
clients = self.app.client_manager
|
||||
if parsed_args.node_uuids:
|
||||
baremetal.reset_bios_configuration(
|
||||
clients, node_uuids=parsed_args.node_uuids)
|
||||
else:
|
||||
baremetal.reset_bios_configuration_on_manageable_nodes(clients)
|
@ -392,3 +392,121 @@ def clean_manageable_nodes(clients, **workflow_input):
|
||||
'Error cleaning nodes: {}'.format(payload['message']))
|
||||
|
||||
print('Cleaned %d node(s)' % len(payload['cleaned_nodes']))
|
||||
|
||||
|
||||
def apply_bios_configuration(clients, **workflow_input):
|
||||
"""Apply BIOS settings on nodes.
|
||||
|
||||
Run the tripleo.baremetal.v1.apply_bios_settings Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
ooo_client = clients.tripleoclient
|
||||
|
||||
print('Applying BIOS settings for given nodes, this may take time')
|
||||
|
||||
with ooo_client.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.apply_bios_settings',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print('Success')
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'Failed to apply BIOS settings: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def apply_bios_configuration_on_manageable_nodes(clients, **workflow_input):
|
||||
"""Apply BIOS settings on manageable nodes.
|
||||
|
||||
Run the tripleo.baremetal.v1.apply_bios_settings_on_manageable_nodes
|
||||
Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
ooo_client = clients.tripleoclient
|
||||
|
||||
print('Applying BIOS settings for manageable nodes, this may take time')
|
||||
|
||||
with ooo_client.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.apply_bios_settings_on_manageable_nodes',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print('Success')
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'Failed to apply BIOS settings: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def reset_bios_configuration(clients, **workflow_input):
|
||||
"""Reset BIOS settings on nodes.
|
||||
|
||||
Run the tripleo.baremetal.v1.reset_bios_settings Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
ooo_client = clients.tripleoclient
|
||||
|
||||
print('Reset BIOS settings on given nodes, this may take time')
|
||||
|
||||
with ooo_client.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.reset_bios_settings',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print('Success')
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'Failed to reset BIOS settings: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def reset_bios_configuration_on_manageable_nodes(clients, **workflow_input):
|
||||
"""Reset BIOS settings on manageable nodes.
|
||||
|
||||
Run the tripleo.baremetal.v1.reset_bios_settings_on_manageable_nodes
|
||||
Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
ooo_client = clients.tripleoclient
|
||||
|
||||
print('Reset BIOS settings on manageable nodes, this may take time')
|
||||
|
||||
with ooo_client.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.reset_bios_settings_on_manageable_nodes',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print('Success')
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'Failed to reset BIOS settings: {}'.format(payload['message']))
|
||||
|
Loading…
Reference in New Issue
Block a user