Skip to content

Commit

Permalink
feat: support for remote virtual media on nfs
Browse files Browse the repository at this point in the history
closes: #228
  • Loading branch information
dominikvagner committed Aug 17, 2022
1 parent edc815a commit 96ab059
Show file tree
Hide file tree
Showing 4 changed files with 429 additions and 7 deletions.
27 changes: 27 additions & 0 deletions README.md
Expand Up @@ -57,6 +57,9 @@
* [Mount Virtual Media](#mount-virtual-media)
* [Unmount Virtual Media](#unmount-virtual-media)
* [Boot to Virtual Media](#boot-to-virtual-media)
* [Check Remote Image](#check-remote-image)
* [Boot to Remote Image](#boot-to-remote-image)
* [Detach Remote Image](#detach-remote-image)
* [Get SRIOV mode](#get-sriov-mode)
* [Set SRIOV mode](#set-sriov-mode)
* [Get BIOS attributes](#get-bios-attributes)
Expand Down Expand Up @@ -445,6 +448,30 @@ If you would like to boot to virtual media (Virtual CD) you can run ```badfish``
badfish -H mgmt-your-server.example.com -u root -p yourpass --boot-to-virtual-media
```

### Check Remote Image
If you would like to check the attach status of a remote ISO in DellOSDeployment service you can run ```badfish``` with the ```--check-remote-image``` option.
```bash
badfish -H mgmt-your-server.example.com -u root -p yourpass --check-remote-image
```
NOTE:
* This is only supported on DELL devices.

### Boot to Remote Image
If you would like to boot to a remote ISO on NFS with DellOSDeployment service you can run ```badfish``` with the ```--boot-remote-image``` option which will attach the image and reboot the server to it. Expects the NFS path to the ISO as the argument.
```bash
badfish -H mgmt-your-server.example.com -u root -p yourpass --boot-remote-image nfs-storage.example.com:/mnt/folder/linux.iso
```
NOTE:
* This is only supported on DELL devices.

### Detach Remote Image
If you would like to detach an ISO from DellOSDeployment service you can run ```badfish``` with the ```--detach-remote-image``` option.
```bash
badfish -H mgmt-your-server.example.com -u root -p yourpass --detach-remote-image
```
NOTE:
* This is only supported on DELL devices.

### Get SRIOV mode
For checking if the global SRIOV mode is enabled you can use ```--get-sriov```
```bash
Expand Down
115 changes: 115 additions & 0 deletions src/badfish/main.py
Expand Up @@ -1400,6 +1400,97 @@ async def boot_to_virtual_media(self):
return False
return True

async def check_os_deployment_support(self):
_uri = "%s/redfish/v1/Dell/Systems/System.Embedded.1/DellOSDeploymentService" % self.host_uri
_response = await self.get_request(_uri)
await _response.text("utf-8", "ignore")
if _response.status != 200:
self.logger.error(
"iDRAC version installed doesn't support DellOSDeploymentService needed for this feature."
)
return False
return True

async def check_remote_image(self):
if not await self.check_os_deployment_support():
return False
_uri = (
"%s/redfish/v1/Dell/Systems/System.Embedded.1/DellOSDeploymentService/Actions/DellOSDeploymentService."
"GetAttachStatus" % self.host_uri
)
_headers = {"Content-Type": "application/json"}
_response = await self.post_request(_uri, payload={}, headers=_headers)
try:
raw = await _response.text("utf-8", "ignore")
data = json.loads(raw.strip())
if _response.status == 200:
self.logger.info("Current ISO attach status: %s" % data.get("ISOAttachStatus"))
if data.get("ISOAttachStatus") == "Attached":
return True
else:
self.logger.error("Command failed to get attach status of the remote mounted ISO.")
except ValueError:
raise BadfishException("There was something wrong trying to check remote image attach status.")
return False

async def boot_remote_image(self, nfs_path):
if not await self.check_os_deployment_support():
return False
_uri = (
"%s/redfish/v1/Dell/Systems/System.Embedded.1/DellOSDeploymentService/Actions/DellOSDeploymentService"
".BootToNetworkISO" % self.host_uri
)
_headers = {"Content-Type": "application/json"}
try:
split_path = str(nfs_path).split(":")
last_slash_pos = split_path[1].rindex("/") + 1
_payload = {
"ShareType": "NFS",
"IPAddress": split_path[0],
"ShareName": split_path[1][:last_slash_pos],
"ImageName": split_path[1][last_slash_pos:],
}
if len(_payload.get("ImageName")) == 0:
raise ValueError
except (ValueError, IndexError):
self.logger.error("Wrong NFS path format.")
return False
_response = await self.post_request(_uri, payload=_payload, headers=_headers)
if _response.status == 202:
self.logger.info("Command for booting to remote ISO was successful, job was created.")
try:
task_path = _response.headers.get("Location")
response = await self.get_request(f"{self.host_uri}{task_path}")
raw = await response.text("utf-8", "ignore")
data = json.loads(raw.strip())
if data.get("TaskStatus") == "OK":
self.logger.info("OSDeployment task status is OK.")
else:
self.logger.error("OSDeployment task failed and couldn't be completed.")
return False
except (ValueError, AttributeError):
raise BadfishException("There was something wrong trying to check remote image attach status.")
return True
else:
self.logger.error("Command failed to boot to remote ISO. No job was created.")
return False

async def detach_remote_image(self):
if not await self.check_os_deployment_support():
return False
_uri = (
"%s/redfish/v1/Dell/Systems/System.Embedded.1/DellOSDeploymentService/Actions/DellOSDeploymentService"
".DetachISOImage" % self.host_uri
)
_headers = {"Content-Type": "application/json"}
_response = await self.post_request(_uri, payload={}, headers=_headers)
if _response.status == 200:
self.logger.info("Command to detach remote ISO was successful.")
return True
else:
self.logger.error("Command failed to detach remote mounted ISO.")
return False

async def get_network_adapters(self):
_url = "%s%s/NetworkAdapters" % (self.host_uri, self.system_resource)
_response = await self.get_request(_url)
Expand Down Expand Up @@ -1908,6 +1999,9 @@ async def execute_badfish(_host, _args, logger, format_handler=None):
unmount_virtual_media = _args["unmount_virtual_media"]
mount_virtual_media = _args["mount_virtual_media"]
boot_to_virtual_media = _args["boot_to_virtual_media"]
check_remote_image = _args["check_remote_image"]
boot_remote_image = _args["boot_remote_image"]
detach_remote_image = _args["detach_remote_image"]
get_sriov = _args["get_sriov"]
enable_sriov = _args["enable_sriov"]
disable_sriov = _args["disable_sriov"]
Expand Down Expand Up @@ -1989,6 +2083,12 @@ async def execute_badfish(_host, _args, logger, format_handler=None):
await badfish.unmount_virtual_media()
elif boot_to_virtual_media:
await badfish.boot_to_virtual_media()
elif check_remote_image:
await badfish.check_remote_image()
elif boot_remote_image:
await badfish.boot_remote_image(boot_remote_image)
elif detach_remote_image:
await badfish.detach_remote_image()
elif get_sriov:
sriov_mode = await badfish.get_sriov_mode()
if sriov_mode:
Expand Down Expand Up @@ -2175,6 +2275,21 @@ def main(argv=None):
help="Boot to virtual media (Cd).",
action="store_true",
)
parser.add_argument(
"--check-remote-image",
help="Check the attach status of network ISO.",
action="store_true",
)
parser.add_argument(
"--boot-remote-image",
help="Boot to network ISO, through NFS, takes two arguments 'hostname:path' and name of the ISO 'linux.iso'.",
default="",
)
parser.add_argument(
"--detach-remote-image",
help="Remove attached network ISO.",
action="store_true",
)
parser.add_argument(
"--get-sriov",
help="Gets global SRIOV mode state",
Expand Down
82 changes: 81 additions & 1 deletion tests/config.py
Expand Up @@ -824,12 +824,92 @@ def render_device_dict(index, device):
}
}
"""

VMEDIA_CHECK_DISC_VALUE_ERROR = (
"- ERROR - There was something wrong getting values for VirtualMedia\n"
)
VMEDIA_NO_ENDPOINT_ERROR = "- ERROR - No VirtualMedia endpoint found\n"

VMEDIA_OS_DEPLOYMENT_NOT_SUPPORTED = (
"- ERROR - iDRAC version installed doesn't support DellOSDeploymentService needed for this feature.\n"
)
VMEDIA_REMOTE_CHECK_RESP = """
{
"@Message.ExtendedInfo": [{
"Message":"Successfully Completed Request",
"MessageArgs":[],
"MessageArgs@odata.count":0,
"MessageId":"Base.1.5.Success",
"RelatedProperties":[],
"RelatedProperties@odata.count":0,
"Resolution":"None"
,"Severity":"OK"
}],
"DriversAttachStatus":"NotAttached",
"ISOAttachStatus":"Attached"
}
"""
VMEDIA_REMOTE_CHECK_GOOD = "- INFO - Current ISO attach status: Attached\n"
VMEDIA_REMOTE_CHECK_FAIL = "- ERROR - Command failed to get attach status of the remote mounted ISO.\n"
VMEDIA_REMOTE_CHECK_ERROR = "- ERROR - There was something wrong trying to check remote image attach status.\n"
VMEDIA_REMOTE_BOOT_TASK_RESP = """
{
"@odata.context":"/redfish/v1/$metadata#Task.Task",
"@odata.id":"/redfish/v1/TaskService/Tasks/OSDeployment",
"@odata.type":"#Task.v1_4_2.Task",
"Description":"Server Configuration and other Tasks running on iDRAC are listed here",
"EndTime":"",
"Id":"OSDeployment",
"Messages":[{
"Message":"",
"MessageArgs":[],
"MessageArgs@odata.count":0,
"MessageId":""
}],
"Messages@odata.count":1,
"Name":"BootToNetworkISO",
"PercentComplete":null,
"TaskState":"Running",
"TaskStatus":"OK"
}
"""
VMEDIA_REMOTE_BOOT_TASK_FAILED_RESP = """
{
"@odata.context":"/redfish/v1/$metadata#Task.Task",
"@odata.id":"/redfish/v1/TaskService/Tasks/OSDeployment",
"@odata.type":"#Task.v1_4_2.Task",
"Description":"Server Configuration and other Tasks running on iDRAC are listed here",
"EndTime":"",
"Id":"OSDeployment",
"Messages":[{
"Message":"",
"MessageArgs":[],
"MessageArgs@odata.count":0,
"MessageId":""
}],
"Messages@odata.count":1,
"Name":"BootToNetworkISO",
"PercentComplete":null,
"TaskState":"Failed",
"TaskStatus":"Error"
}
"""
VMEDIA_REMOTE_BOOT_GOOD = (
"- INFO - Command for booting to remote ISO was successful, job was created.\n"
"- INFO - OSDeployment task status is OK.\n"
)
VMEDIA_REMOTE_BOOT_WRONG_PATH = "- ERROR - Wrong NFS path format.\n"
VMEDIA_REMOTE_BOOT_COMMAND_FAIL = "- ERROR - Command failed to boot to remote ISO. No job was created.\n"
VMEDIA_REMOTE_BOOT_TASK_FAIL = (
"- INFO - Command for booting to remote ISO was successful, job was created.\n"
"- ERROR - OSDeployment task failed and couldn't be completed.\n"
)
VMEDIA_REMOTE_BOOT_SOMETHING_WRONG = (
"- INFO - Command for booting to remote ISO was successful, job was created.\n"
"- ERROR - There was something wrong trying to check remote image attach status.\n"
)
VMEDIA_REMOTE_DETACH_GOOD = "- INFO - Command to detach remote ISO was successful.\n"
VMEDIA_REMOTE_DETACH_FAIL = "- ERROR - Command failed to detach remote mounted ISO.\n"

BIOS_PASS_SET_GOOD = f"""\
- INFO - Command passed to set BIOS password.
- WARNING - Host will now be rebooted for changes to take place.
Expand Down

0 comments on commit 96ab059

Please sign in to comment.