Add iDrac virtual cd/floppy
iDRAC does not support standard redfish boot devices, provide oem override in such case to use the OEM interface. Change-Id: I53d7bb1d82035e621802c20f46000760cc8631a8
This commit is contained in:
parent
51eebd39fc
commit
4cfaf03d6c
|
@ -51,22 +51,6 @@ powerstates = {
|
|||
'boot': None,
|
||||
}
|
||||
|
||||
boot_devices_write = {
|
||||
'net': 'Pxe',
|
||||
'network': 'Pxe',
|
||||
'pxe': 'Pxe',
|
||||
'hd': 'Hdd',
|
||||
'usb': 'Usb',
|
||||
'cd': 'Cd',
|
||||
'cdrom': 'Cd',
|
||||
'optical': 'Cd',
|
||||
'dvd': 'Cd',
|
||||
'floppy': 'Floppy',
|
||||
'default': 'None',
|
||||
'setup': 'BiosSetup',
|
||||
'bios': 'BiosSetup',
|
||||
'f1': 'BiosSetup',
|
||||
}
|
||||
|
||||
boot_devices_read = {
|
||||
'BiosSetup': 'setup',
|
||||
|
@ -684,31 +668,7 @@ class Command(object):
|
|||
:raises: PyghmiException on an error.
|
||||
:returns: dict or True -- If callback is not provided, the response
|
||||
"""
|
||||
reqbootdev = bootdev
|
||||
if (bootdev not in boot_devices_write
|
||||
and bootdev not in boot_devices_read):
|
||||
raise exc.InvalidParameterValue('Unsupported device %s'
|
||||
% repr(bootdev))
|
||||
bootdev = boot_devices_write.get(bootdev, bootdev)
|
||||
if bootdev == 'None':
|
||||
payload = {'Boot': {'BootSourceOverrideEnabled': 'Disabled'}}
|
||||
else:
|
||||
payload = {'Boot': {
|
||||
'BootSourceOverrideEnabled': 'Continuous' if persist
|
||||
else 'Once',
|
||||
'BootSourceOverrideTarget': bootdev,
|
||||
}}
|
||||
if uefiboot is not None:
|
||||
uefiboot = 'UEFI' if uefiboot else 'Legacy'
|
||||
payload['BootSourceOverrideMode'] = uefiboot
|
||||
try:
|
||||
self._do_web_request(self.sysurl, payload, method='PATCH')
|
||||
return {'bootdev': reqbootdev}
|
||||
except Exception:
|
||||
del payload['BootSourceOverrideMode']
|
||||
thetag = self.sysinfo.get('@odata.etag', None)
|
||||
self._do_web_request(self.sysurl, payload, method='PATCH', etag=thetag)
|
||||
return {'bootdev': reqbootdev}
|
||||
return self.oem.set_bootdev(bootdev, persist, uefiboot, self)
|
||||
|
||||
@property
|
||||
def _biosurl(self):
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2022 Lenovo Corporation
|
||||
#
|
||||
# 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 pyghmi.redfish.oem.generic as generic
|
||||
|
||||
|
||||
class OEMHandler(generic.OEMHandler):
|
||||
|
||||
def __init__(self, sysinfo, sysurl, webclient, cache, gpool=None):
|
||||
super(OEMHandler, self).__init__(sysinfo, sysurl, webclient, cache,
|
||||
gpool)
|
||||
|
||||
def set_bootdev(self, bootdev, persist=False, uefiboot=None,
|
||||
fishclient=None):
|
||||
# gleaned from web console, under configuration, system settings,
|
||||
# hardware, first boot device. iDrac presumes that the standard
|
||||
# explicitly refers only to physical devices. I think the intent
|
||||
# is the exact opposite for 'removable' media, and thus redirect
|
||||
# the 'physical' standard to the vFDD/VCD-DVD seen in the idrac
|
||||
# web gui
|
||||
if bootdev not in ('floppy', 'cd'):
|
||||
return super(OEMHandler, self).set_bootdev(bootdev, persist,
|
||||
uefiboot, fishclient)
|
||||
payload = {'Attributes': {}}
|
||||
if persist:
|
||||
payload['Attributes']['ServerBoot.1.BootOnce'] = 'Disabled'
|
||||
else:
|
||||
payload['Attributes']['ServerBoot.1.BootOnce'] = 'Enabled'
|
||||
if bootdev == 'floppy':
|
||||
payload['Attributes']['ServerBoot.1.FirstBootDevice'] = 'vFDD'
|
||||
elif bootdev == 'cd':
|
||||
payload['Attributes']['ServerBoot.1.FirstBootDevice'] = 'VCD-DVD'
|
||||
fishclient._do_web_request(
|
||||
'/redfish/v1/Managers/iDRAC.Embedded.1/Attributes',
|
||||
payload, method='PATCH')
|
||||
return {'bootdev': bootdev}
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright 2022 Lenovo Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
from pyghmi.redfish.oem.dell import idrac
|
||||
|
||||
|
||||
def get_handler(sysinfo, sysurl, webclient, cache, cmd):
|
||||
return idrac.OEMHandler(sysinfo, sysurl, webclient, cache,
|
||||
gpool=cmd._gpool)
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2019 Lenovo Corporation
|
||||
# Copyright 2019-2022 Lenovo Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -18,6 +18,34 @@ import os
|
|||
import pyghmi.exceptions as exc
|
||||
import pyghmi.media as media
|
||||
|
||||
boot_devices_write = {
|
||||
'net': 'Pxe',
|
||||
'network': 'Pxe',
|
||||
'pxe': 'Pxe',
|
||||
'hd': 'Hdd',
|
||||
'usb': 'Usb',
|
||||
'cd': 'Cd',
|
||||
'cdrom': 'Cd',
|
||||
'optical': 'Cd',
|
||||
'dvd': 'Cd',
|
||||
'floppy': 'Floppy',
|
||||
'default': 'None',
|
||||
'setup': 'BiosSetup',
|
||||
'bios': 'BiosSetup',
|
||||
'f1': 'BiosSetup',
|
||||
}
|
||||
|
||||
boot_devices_read = {
|
||||
'BiosSetup': 'setup',
|
||||
'Cd': 'optical',
|
||||
'Floppy': 'floppy',
|
||||
'Hdd': 'hd',
|
||||
'None': 'default',
|
||||
'Pxe': 'network',
|
||||
'Usb': 'usb',
|
||||
'SDCard': 'sdcard',
|
||||
}
|
||||
|
||||
|
||||
class OEMHandler(object):
|
||||
hostnic = None
|
||||
|
@ -29,6 +57,54 @@ class OEMHandler(object):
|
|||
self._urlcache = cache
|
||||
self.webclient = webclient
|
||||
|
||||
def set_bootdev(self, bootdev, persist=False, uefiboot=None,
|
||||
fishclient=None):
|
||||
"""Set boot device to use on next reboot
|
||||
|
||||
:param bootdev:
|
||||
*network -- Request network boot
|
||||
*hd -- Boot from hard drive
|
||||
*safe -- Boot from hard drive, requesting 'safe mode'
|
||||
*optical -- boot from CD/DVD/BD drive
|
||||
*setup -- Boot into setup utility
|
||||
*default -- remove any directed boot device request
|
||||
:param persist: If true, ask that system firmware use this device
|
||||
beyond next boot. Be aware many systems do not honor
|
||||
this
|
||||
:param uefiboot: If true, request UEFI boot explicitly. If False,
|
||||
request BIOS style boot.
|
||||
None (default) does not modify the boot mode.
|
||||
:raises: PyghmiException on an error.
|
||||
:returns: dict or True -- If callback is not provided, the response
|
||||
"""
|
||||
reqbootdev = bootdev
|
||||
if (bootdev not in boot_devices_write
|
||||
and bootdev not in boot_devices_read):
|
||||
raise exc.InvalidParameterValue('Unsupported device %s'
|
||||
% repr(bootdev))
|
||||
bootdev = boot_devices_write.get(bootdev, bootdev)
|
||||
if bootdev == 'None':
|
||||
payload = {'Boot': {'BootSourceOverrideEnabled': 'Disabled'}}
|
||||
else:
|
||||
payload = {'Boot': {
|
||||
'BootSourceOverrideEnabled': 'Continuous' if persist
|
||||
else 'Once',
|
||||
'BootSourceOverrideTarget': bootdev,
|
||||
}}
|
||||
if uefiboot is not None:
|
||||
uefiboot = 'UEFI' if uefiboot else 'Legacy'
|
||||
payload['BootSourceOverrideMode'] = uefiboot
|
||||
try:
|
||||
fishclient._do_web_request(self.sysurl, payload,
|
||||
method='PATCH')
|
||||
return {'bootdev': reqbootdev}
|
||||
except Exception:
|
||||
del payload['BootSourceOverrideMode']
|
||||
thetag = fishclient.sysinfo.get('@odata.etag', None)
|
||||
fishclient._do_web_request(fishclient.sysurl, payload, method='PATCH',
|
||||
etag=thetag)
|
||||
return {'bootdev': reqbootdev}
|
||||
|
||||
def _get_cache(self, url):
|
||||
now = os.times()[4]
|
||||
cachent = self._urlcache.get(url, None)
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import pyghmi.redfish.oem.dell.main as dell
|
||||
import pyghmi.redfish.oem.generic as generic
|
||||
import pyghmi.redfish.oem.lenovo.main as lenovo
|
||||
|
||||
OEMMAP = {
|
||||
'Lenovo': lenovo,
|
||||
'Dell': dell,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,6 @@ setuptools.setup(
|
|||
packages=['pyghmi', 'pyghmi.util', 'pyghmi.ipmi', 'pyghmi.cmd',
|
||||
'pyghmi.redfish', 'pyghmi.ipmi.private', 'pyghmi.ipmi.oem',
|
||||
'pyghmi.ipmi.oem.lenovo', 'pyghmi.redfish.oem',
|
||||
'pyghmi.redfish.oem.lenovo'],
|
||||
'pyghmi.redfish.oem.dell', 'pyghmi.redfish.oem.lenovo'],
|
||||
license='Apache License, Version 2.0')
|
||||
|
||||
|
|
Loading…
Reference in New Issue