X-Git-Url: https://gerrit.akraino.org/r/gitweb?p=ta%2Fironic-virtmedia-driver.git;a=blobdiff_plain;f=src%2Fironic_virtmedia_driver%2Fvendors%2Fhp%2Fhp.py;fp=src%2Fironic_virtmedia_driver%2Fvendors%2Fhp%2Fhp.py;h=a1ff242589d4309ac52879984ecd60cb47abedda;hp=0000000000000000000000000000000000000000;hb=be2fb9459b65bb8b07b23adebadc16530d26e231;hpb=aaec6775b13b0c694235c80e6dfbca8696307af9 diff --git a/src/ironic_virtmedia_driver/vendors/hp/hp.py b/src/ironic_virtmedia_driver/vendors/hp/hp.py new file mode 100644 index 0000000..a1ff242 --- /dev/null +++ b/src/ironic_virtmedia_driver/vendors/hp/hp.py @@ -0,0 +1,149 @@ +# Copyright 2019 Nokia +# +# 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 + +from ironic.common.i18n import _ + +from ironic_virtmedia_driver.vendors.ironic_virtmedia_hw import IronicVirtMediaHW +from ironic_virtmedia_driver import virtmedia_exception + +import redfish.ris.tpdefs +from redfish import AuthMethod, redfish_client +from redfish.rest.v1 import ServerDownOrUnreachableError + +class HP(IronicVirtMediaHW): + def __init__(self, log): + super(HP, self).__init__(log) + self.remote_share = '/bootimages/' + self.typepath = None + + def _init_connection(self, driver_info): + """Get connection info and init rest_object""" + host = 'https://' + driver_info['address'] + user = driver_info['username'] + password = driver_info['password'] + redfishclient = None + try: + redfishclient = redfish_client(base_url=host, \ + username=user, password=password, \ + default_prefix="/redfish/v1") + redfishclient.login(auth=AuthMethod.SESSION) + self._init_typepath(redfishclient) + except ServerDownOrUnreachableError as error: + operation = _("iLO not responding") + raise virtmedia_exception.VirtmediaOperationError( + operation=operation, error=error) + except Exception as error: + operation = _("Failed to login to iLO") + raise virtmedia_exception.VirtmediaOperationError( + operation=operation, error=error) + return redfishclient + + def _init_typepath(self, connection): + typepath = redfish.ris.tpdefs.Typesandpathdefines() + typepath.getgen(url=connection.get_base_url()) + typepath.defs.redfishchange() + self.typepath = typepath + + def _search_for_type(self, typename, resources): + instances = [] + nosettings = [item for item in resources["resources"] if "/settings/" not in item["@odata.id"]] + for item in nosettings: + if "@odata.type" in item and \ + typename.lower() in item["@odata.type"].lower(): + instances.append(item) + return instances + + def _get_instances(self, connection): + resources = {} + + response = connection.get("/redfish/v1/resourcedirectory/") + if response.status == 200: + resources["resources"] = response.dict["Instances"] + else: + return [] + + return self._search_for_type("Manager.", resources) + + def _get_error(self, response): + message = json.loads(response.text) + error = message["error"]["@Message.ExtendedInfo"][0]["MessageId"].split(".") + return error + + + def _umount_virtual_cd(self, connection, cd_location): + unmount_path = cd_location + unmount_body = {"Action": "EjectVirtualMedia", "Target": self.typepath.defs.oempath} + resp = connection.post(path=unmount_path, body=unmount_body) + if resp.status != 200: + self.log.error("Unmounting cd failed: %r, cd location: %r", resp, unmount_path) + operation = _("Failed to unmount image") + error = self._get_error(resp) + raise virtmedia_exception.VirtmediaOperationError( + operation=operation, error=error) + + + def _get_virtual_media_devices(self, connection, instance): + rsp = connection.get(instance["@odata.id"]) + rsp = connection.get(rsp.dict["VirtualMedia"]["@odata.id"]) + return rsp.dict['Members'] + + def _mount_virtual_cd(self, connection, image_location): + instances = self._get_instances(connection) + for instance in instances: + for vmlink in self._get_virtual_media_devices(connection, instance): + response = connection.get(vmlink["@odata.id"]) + + if response.status == 200 and "DVD" in response.dict["MediaTypes"]: + if response.dict['Inserted']: + self._umount_virtual_cd(connection, vmlink["@odata.id"]) + + body = {"Image": image_location} + + if image_location: + body["Oem"] = {self.typepath.defs.oemhp: {"BootOnNextServerReset": \ + True}} + + response = connection.patch(path=vmlink["@odata.id"], body=body) + elif response.status != 200: + self.log.error("Failed to mount image") + error = self._get_error(response) + operation = _("Failed to mount image") + raise virtmedia_exception.VirtmediaOperationError( + operation=operation, error=error) + + def attach_virtual_cd(self, image_filename, driver_info, task): + connection = self._init_connection(driver_info) + image_location = 'http://' + driver_info['provisioning_server'] + ':' + driver_info['provisioning_server_http_port'] + self.remote_share + image_filename + self._mount_virtual_cd(connection, image_location) + connection.logout() + return True + + def detach_virtual_cd(self, driver_info, task): + connection = self._init_connection(driver_info) + instances = self._get_instances(connection) + for instance in instances: + for vmlink in self._get_virtual_media_devices(connection, instance): + response = connection.get(vmlink["@odata.id"]) + if response.status == 200 and "DVD" in response.dict["MediaTypes"]: + if response.dict['Inserted']: + self._umount_virtual_cd(connection, vmlink["@odata.id"]) + connection.logout() + return True + + def set_boot_device(self, task): + """ This is done during the mounting""" + pass