210
210
missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
212
212
raise exception.MissingParameterValue(_(
213
"The following IPMI credentials are not supplied"
214
" to IPMI driver: %s."
213
"Missing the following IPMI credentials in node's"
214
" driver_info: %s.") % missing_info)
217
216
address = info.get('ipmi_address')
218
217
username = info.get('ipmi_username')
236
235
# check if ipmi_bridging has proper value
237
236
if bridging_type == 'no':
238
237
# if bridging is not selected, then set all bridging params to None
239
local_address = transit_channel = transit_address = \
240
target_channel = target_address = None
238
(local_address, transit_channel, transit_address, target_channel,
239
target_address) = (None,) * 5
241
240
elif bridging_type in bridging_types:
242
241
# check if the particular bridging option is supported on host
243
242
if not _is_option_supported('%s_bridge' % bridging_type):
547
547
return sensors_data_dict
550
@task_manager.require_exclusive_lock
551
def _send_raw(task, raw_bytes):
552
"""Send raw bytes to the BMC. Bytes should be a string of bytes.
554
:param task: a TaskManager instance.
555
:param raw_bytes: a string of raw bytes to send, e.g. '0x00 0x01'
556
:raises: IPMIFailure on an error from ipmitool.
557
:raises: MissingParameterValue if a required parameter is missing.
558
:raises: InvalidParameterValue when an invalid value is specified.
561
node_uuid = task.node.uuid
562
LOG.debug('Sending node %(node)s raw bytes %(bytes)s',
563
{'bytes': raw_bytes, 'node': node_uuid})
564
driver_info = _parse_driver_info(task.node)
565
cmd = 'raw %s' % raw_bytes
568
out, err = _exec_ipmitool(driver_info, cmd)
569
LOG.debug('send raw bytes returned stdout: %(stdout)s, stderr:'
570
' %(stderr)s', {'stdout': out, 'stderr': err})
571
except (exception.PasswordFileFailedToCreate,
572
processutils.ProcessExecutionError) as e:
573
LOG.exception(_LE('IPMI "raw bytes" failed for node %(node_id)s '
574
'with error: %(error)s.'),
575
{'node_id': node_uuid, 'error': e})
576
raise exception.IPMIFailure(cmd=cmd)
550
579
class IPMIPower(base.PowerInterface):
552
581
def __init__(self):
693
722
if device not in self.get_supported_boot_devices():
694
723
raise exception.InvalidParameterValue(_(
695
724
"Invalid boot device %s specified.") % device)
726
# note(JayF): IPMI spec indicates unless you send these raw bytes the
727
# boot device setting times out after 60s. Since it's possible it
728
# could be >60s before a node is rebooted, we should always send them.
729
# This mimics pyghmi's current behavior, and the "option=timeout"
730
# setting on newer ipmitool binaries.
731
timeout_disable = "0x00 0x08 0x03 0x08"
732
_send_raw(task, timeout_disable)
696
734
cmd = "chassis bootdev %s" % device
698
736
cmd = cmd + " options=persistent"
792
830
reason=_("Unable to locate usable ipmitool command in "
793
831
"the system path when checking ipmitool version"))
833
@base.passthru(['POST'])
795
834
@task_manager.require_exclusive_lock
796
def _send_raw_bytes(self, task, raw_bytes):
835
def send_raw(self, task, http_method, raw_bytes):
797
836
"""Send raw bytes to the BMC. Bytes should be a string of bytes.
799
838
:param task: a TaskManager instance.
839
:param http_method: the HTTP method used on the request.
800
840
:param raw_bytes: a string of raw bytes to send, e.g. '0x00 0x01'
801
841
:raises: IPMIFailure on an error from ipmitool.
802
842
:raises: MissingParameterValue if a required parameter is missing.
803
843
:raises: InvalidParameterValue when an invalid value is specified.
806
node_uuid = task.node.uuid
807
LOG.debug('Sending node %(node)s raw bytes %(bytes)s',
808
{'bytes': raw_bytes, 'node': node_uuid})
809
driver_info = _parse_driver_info(task.node)
810
cmd = 'raw %s' % raw_bytes
813
out, err = _exec_ipmitool(driver_info, cmd)
814
LOG.debug('send raw bytes returned stdout: %(stdout)s, stderr:'
815
' %(stderr)s', {'stdout': out, 'stderr': err})
816
except (exception.PasswordFileFailedToCreate,
817
processutils.ProcessExecutionError) as e:
818
LOG.exception(_LE('IPMI "raw bytes" failed for node %(node_id)s '
819
'with error: %(error)s.'),
820
{'node_id': node_uuid, 'error': e})
821
raise exception.IPMIFailure(cmd=cmd)
846
_send_raw(task, raw_bytes)
848
@base.passthru(['POST'])
823
849
@task_manager.require_exclusive_lock
824
def _bmc_reset(self, task, warm=True):
850
def bmc_reset(self, task, http_method, warm=True):
825
851
"""Reset BMC with IPMI command 'bmc reset (warm|cold)'.
827
853
:param task: a TaskManager instance.
854
:param http_method: the HTTP method used on the request.
828
855
:param warm: boolean parameter to decide on warm or cold reset.
829
856
:raises: IPMIFailure on an error from ipmitool.
830
857
:raises: MissingParameterValue if a required parameter is missing.
869
896
:param task: a task from TaskManager.
870
897
:param kwargs: info for action.
871
:raises: InvalidParameterValue if **kwargs does not contain 'method',
872
'method' is not supported or a byte string is not given for
898
:raises: InvalidParameterValue when an invalid parameter value is
874
900
:raises: MissingParameterValue if a required parameter is missing.
877
903
method = kwargs['method']
878
904
if method == 'send_raw':
879
905
if not kwargs.get('raw_bytes'):
880
raise exception.InvalidParameterValue(_(
906
raise exception.MissingParameterValue(_(
881
907
'Parameter raw_bytes (string of bytes) was not '
883
elif method == 'bmc_reset':
884
# no additional parameters needed
887
raise exception.InvalidParameterValue(_(
888
"Unsupported method (%s) passed to IPMItool driver.")
890
910
_parse_driver_info(task.node)
892
def vendor_passthru(self, task, **kwargs):
893
"""Receive requests for vendor-specific actions.
899
:param task: a task from TaskManager.
900
:param kwargs: info for action.
902
:raises: InvalidParameterValue if required IPMI credentials
904
:raises: IPMIFailure if ipmitool fails for any method.
905
:raises: MissingParameterValue when a required parameter is missing
909
method = kwargs['method']
910
if method == 'send_raw':
911
return self._send_raw_bytes(task,
912
kwargs.get('raw_bytes'))
913
elif method == 'bmc_reset':
914
return self._bmc_reset(task,
915
warm=kwargs.get('warm', True))
918
913
class IPMIShellinaboxConsole(base.ConsoleInterface):
919
914
"""A ConsoleInterface that uses ipmitool and shellinabox."""
943
938
driver_info = _parse_driver_info(task.node)
944
939
if not driver_info['port']:
945
940
raise exception.MissingParameterValue(_(
946
"IPMI terminal port not supplied to IPMI driver."))
941
"Missing 'ipmi_terminal_port' parameter in node's"
948
944
def start_console(self, task):
949
945
"""Start a remote console for the node.
962
958
pw_file = console_utils.make_persistent_password_file(
963
959
path, driver_info['password'])
965
ipmi_cmd = "/:%(uid)s:%(gid)s:HOME:ipmitool -H %(address)s" \
966
" -I lanplus -U %(user)s -f %(pwfile)s" \
967
% {'uid': os.getuid(),
969
'address': driver_info['address'],
970
'user': driver_info['username'],
961
ipmi_cmd = ("/:%(uid)s:%(gid)s:HOME:ipmitool -H %(address)s"
962
" -I lanplus -U %(user)s -f %(pwfile)s"
963
% {'uid': os.getuid(),
965
'address': driver_info['address'],
966
'user': driver_info['username'],
973
969
for name, option in BRIDGING_OPTIONS:
974
970
if driver_info[name] is not None: