def _get_lun_map(self, path): """Gets the lun map by lun path.""" tag = None map_list = [] while True: lun_map_iter = NaElement('lun-map-get-iter') lun_map_iter.add_new_child('max-records', '100') if tag: lun_map_iter.add_new_child('tag', tag, True) query = NaElement('query') lun_map_iter.add_child_elem(query) query.add_node_with_children('lun-map-info', **{'path': path}) result = self.client.invoke_successfully(lun_map_iter, True) tag = result.get_child_content('next-tag') if result.get_child_content('num-records') and \ int(result.get_child_content('num-records')) >= 1: attr_list = result.get_child_by_name('attributes-list') lun_maps = attr_list.get_children() for lun_map in lun_maps: lun_m = dict() lun_m['initiator-group'] = lun_map.get_child_content( 'initiator-group') lun_m['lun-id'] = lun_map.get_child_content('lun-id') lun_m['vserver'] = lun_map.get_child_content('vserver') map_list.append(lun_m) if tag is None: break return map_list
def _get_lun_map(self, path): """Gets the lun map by lun path.""" tag = None map_list = [] while True: lun_map_iter = NaElement("lun-map-get-iter") lun_map_iter.add_new_child("max-records", "100") if tag: lun_map_iter.add_new_child("tag", tag, True) query = NaElement("query") lun_map_iter.add_child_elem(query) query.add_node_with_children("lun-map-info", **{"path": path}) result = self.client.invoke_successfully(lun_map_iter, True) tag = result.get_child_content("next-tag") if result.get_child_content("num-records") and int(result.get_child_content("num-records")) >= 1: attr_list = result.get_child_by_name("attributes-list") lun_maps = attr_list.get_children() for lun_map in lun_maps: lun_m = dict() lun_m["initiator-group"] = lun_map.get_child_content("initiator-group") lun_m["lun-id"] = lun_map.get_child_content("lun-id") lun_m["vserver"] = lun_map.get_child_content("vserver") map_list.append(lun_m) if tag is None: break return map_list
def _get_vol_luns(self, vol_name): """Gets the luns for a volume.""" api = NaElement('lun-list-info') if vol_name: api.add_new_child('volume-name', vol_name) result = self.client.invoke_successfully(api, True) luns = result.get_child_by_name('luns') return luns.get_children()
def _get_vol_luns(self, vol_name): """Gets the luns for a volume.""" api = NaElement("lun-list-info") if vol_name: api.add_new_child("volume-name", vol_name) result = self.client.invoke_successfully(api, True) luns = result.get_child_by_name("luns") return luns.get_children()
def _get_lun_by_args(self, **args): """Retrives lun with specified args.""" lun_iter = NaElement('lun-get-iter') lun_iter.add_new_child('max-records', '100') query = NaElement('query') lun_iter.add_child_elem(query) query.add_node_with_children('lun-info', **args) luns = self.client.invoke_successfully(lun_iter) attr_list = luns.get_child_by_name('attributes-list') return attr_list.get_children()
def _get_if_info_by_ip(self, ip): """Gets the network interface info by ip.""" net_if_iter = NaElement('net-interface-get-iter') net_if_iter.add_new_child('max-records', '10') query = NaElement('query') net_if_iter.add_child_elem(query) query.add_node_with_children('net-interface-info', **{'address': ip}) result = self._invoke_successfully(net_if_iter) if result.get_child_content('num-records') and\ int(result.get_child_content('num-records')) >= 1: attr_list = result.get_child_by_name('attributes-list') return attr_list.get_children() raise exception.NotFound( _('No interface found on cluster for ip %s') % (ip))
def _wait_for_clone_finish(self, clone_op_id, vol_uuid): """Waits till a clone operation is complete or errored out.""" clone_ls_st = NaElement('clone-list-status') clone_id = NaElement('clone-id') clone_ls_st.add_child_elem(clone_id) clone_id.add_node_with_children('clone-id-info', **{'clone-op-id': clone_op_id, 'volume-uuid': vol_uuid}) task_running = True while task_running: result = self._invoke_successfully(clone_ls_st, None) status = result.get_child_by_name('status') ops_info = status.get_children() if ops_info: state = ops_info[0].get_child_content('clone-state') if state == 'completed': task_running = False elif state == 'failed': code = ops_info[0].get_child_content('error') reason = ops_info[0].get_child_content('reason') raise NaApiError(code, reason) else: time.sleep(1) else: raise NaApiError( 'UnknownCloneId', 'No clone operation for clone id %s found on the filer' % (clone_id))
def _clone_lun(self, name, new_name, space_reserved): """Clone LUN with the given handle to the new name.""" metadata = self._get_lun_attr(name, 'metadata') path = metadata['Path'] (parent, splitter, name) = path.rpartition('/') clone_path = '%s/%s' % (parent, new_name) clone_start = NaElement.create_node_with_children( 'clone-start', **{'source-path': path, 'destination-path': clone_path, 'no-snap': 'true'}) result = self.client.invoke_successfully(clone_start, True) clone_id_el = result.get_child_by_name('clone-id') cl_id_info = clone_id_el.get_child_by_name('clone-id-info') vol_uuid = cl_id_info.get_child_content('volume-uuid') clone_id = cl_id_info.get_child_content('clone-op-id') if vol_uuid: self._check_clone_status(clone_id, vol_uuid, name, new_name) cloned_lun = self._get_lun_by_args(path=clone_path) if cloned_lun: self._set_space_reserve(clone_path, space_reserved) clone_meta = self._create_lun_meta(cloned_lun) handle = self._create_lun_handle(clone_meta) self._add_lun_to_table( NetAppLun(handle, new_name, cloned_lun.get_child_content('size'), clone_meta)) else: raise NaApiError('ENOLUNENTRY', 'No Lun entry found on the filer')
def _get_actual_path_for_export(self, export_path): """Gets the actual path on the filer for export path.""" storage_path = NaElement.create_node_with_children("nfs-exportfs-storage-path", **{"pathname": export_path}) result = self._invoke_successfully(storage_path, None) if result.get_child_content("actual-pathname"): return result.get_child_content("actual-pathname") raise exception.NotFound(_("No storage path found for export path %s") % (export_path))
def _add_igroup_initiator(self, igroup, initiator): """Adds initiators to the specified igroup.""" igroup_add = NaElement.create_node_with_children( 'igroup-add', **{'initiator-group-name': igroup, 'initiator': initiator}) self.client.invoke_successfully(igroup_add, True)
def _map_lun(self, name, initiator, initiator_type='iscsi', lun_id=None): """Maps lun to the initiator and returns lun id assigned.""" metadata = self._get_lun_attr(name, 'metadata') os = metadata['OsType'] path = metadata['Path'] if self._check_allowed_os(os): os = os else: os = 'default' igroup_name = self._get_or_create_igroup(initiator, initiator_type, os) lun_map = NaElement.create_node_with_children( 'lun-map', **{'path': path, 'initiator-group': igroup_name}) if lun_id: lun_map.add_new_child('lun-id', lun_id) try: result = self.client.invoke_successfully(lun_map, True) return result.get_child_content('lun-id-assigned') except NaApiError as e: code = e.code message = e.message msg = _('Error mapping lun. Code :%(code)s, Message:%(message)s') msg_fmt = {'code': code, 'message': message} exc_info = sys.exc_info() LOG.warn(msg % msg_fmt) (igroup, lun_id) = self._find_mapped_lun_igroup(path, initiator) if lun_id is not None: return lun_id else: raise exc_info[0], exc_info[1], exc_info[2]
def _map_lun(self, name, initiator, initiator_type="iscsi", lun_id=None): """Maps lun to the initiator and returns lun id assigned.""" metadata = self._get_lun_attr(name, "metadata") os = metadata["OsType"] path = metadata["Path"] if self._check_allowed_os(os): os = os else: os = "default" igroup_name = self._get_or_create_igroup(initiator, initiator_type, os) lun_map = NaElement.create_node_with_children("lun-map", **{"path": path, "initiator-group": igroup_name}) if lun_id: lun_map.add_new_child("lun-id", lun_id) try: result = self.client.invoke_successfully(lun_map, True) return result.get_child_content("lun-id-assigned") except NaApiError as e: code = e.code message = e.message msg = _("Error mapping lun. Code :%(code)s, Message:%(message)s") msg_fmt = {"code": code, "message": message} exc_info = sys.exc_info() LOG.warn(msg % msg_fmt) (igroup, lun_id) = self._find_mapped_lun_igroup(path, initiator) if lun_id is not None: return lun_id else: raise exc_info[0], exc_info[1], exc_info[2]
def _get_igroup_by_initiator(self, initiator): """Get igroups by initiator.""" igroup_list = NaElement('igroup-list-info') result = self.client.invoke_successfully(igroup_list, True) igroups = [] igs = result.get_child_by_name('initiator-groups') if igs: ig_infos = igs.get_children() if ig_infos: for info in ig_infos: initiators = info.get_child_by_name('initiators') init_infos = initiators.get_children() if init_infos: for init in init_infos: if init.get_child_content('initiator-name')\ == initiator: d = dict() d['initiator-group-os-type'] = \ info.get_child_content( 'initiator-group-os-type') d['initiator-group-type'] = \ info.get_child_content( 'initiator-group-type') d['initiator-group-name'] = \ info.get_child_content( 'initiator-group-name') igroups.append(d) return igroups
def _get_ontapi_version(self): """Gets the supported ontapi version.""" ontapi_version = NaElement('system-get-ontapi-version') res = self._invoke_successfully(ontapi_version, False) major = res.get_child_content('major-version') minor = res.get_child_content('minor-version') return (major, minor)
def _create_lun_on_eligible_vol(self, name, size, metadata, extra_specs=None): """Creates an actual lun on filer.""" req_size = float(size) *\ float(self.configuration.netapp_size_multiplier) volumes = self._get_avl_volumes(req_size, extra_specs) if not volumes: msg = _('Failed to get vol with required' ' size and extra specs for volume: %s') raise exception.VolumeBackendAPIException(data=msg % name) for volume in volumes: try: path = '/vol/%s/%s' % (volume.id['name'], name) lun_create = NaElement.create_node_with_children( 'lun-create-by-size', **{'path': path, 'size': size, 'ostype': metadata['OsType']}) self.client.invoke_successfully(lun_create, True) metadata['Path'] = '/vol/%s/%s' % (volume.id['name'], name) metadata['Volume'] = volume.id['name'] metadata['Qtree'] = None return except NaApiError: LOG.warn(_("Error provisioning vol %(name)s on %(volume)s") % {'name': name, 'volume': volume.id['name']}) finally: self._update_stale_vols(volume=volume)
def _get_cluster_file_usage(self, path, vserver): """Gets the file unique bytes.""" LOG.debug(_("Getting file usage for %s"), path) file_use = NaElement.create_node_with_children("file-usage-get", **{"path": path}) res = self._invoke_successfully(file_use, vserver) bytes = res.get_child_content("unique-bytes") LOG.debug(_("file-usage for path %(path)s is %(bytes)s") % {"path": path, "bytes": bytes}) return bytes
def _create_igroup(self, igroup, igroup_type='iscsi', os_type='default'): """Creates igoup with specified args.""" igroup_create = NaElement.create_node_with_children( 'igroup-create', **{'initiator-group-name': igroup, 'initiator-group-type': igroup_type, 'os-type': os_type}) self.client.invoke_successfully(igroup_create, True)
def _set_space_reserve(self, path, enable): """Sets the space reserve info.""" space_res = NaElement.create_node_with_children( 'lun-set-space-reservation-info', **{ 'path': path, 'enable': enable }) self.client.invoke_successfully(space_res, True)
def _get_lun_by_args(self, **args): """Retrives lun with specified args.""" lun_iter = NaElement("lun-get-iter") lun_iter.add_new_child("max-records", "100") query = NaElement("query") lun_iter.add_child_elem(query) query.add_node_with_children("lun-info", **args) luns = self.client.invoke_successfully(lun_iter) attr_list = luns.get_child_by_name("attributes-list") return attr_list.get_children()
def _get_actual_path_for_export(self, export_path): """Gets the actual path on the filer for export path.""" storage_path = NaElement.create_node_with_children( 'nfs-exportfs-storage-path', **{'pathname': export_path}) result = self._invoke_successfully(storage_path, None) if result.get_child_content('actual-pathname'): return result.get_child_content('actual-pathname') raise exception.NotFound(_('No storage path found for export path %s') % (export_path))
def check_apis_on_cluster(na_server, api_list=None): """Checks api availability and permissions on cluster. Checks api availability and permissions for executing user. Returns a list of failed apis. """ api_list = api_list or [] failed_apis = [] if api_list: api_version = na_server.get_api_version() if api_version: major, minor = api_version if major == 1 and minor < 20: for api_name in api_list: na_el = NaElement(api_name) try: na_server.invoke_successfully(na_el) except Exception as e: if isinstance(e, NaApiError): if (e.code == NaErrors['API_NOT_FOUND'].code or e.code == NaErrors['INSUFFICIENT_PRIVS'].code): failed_apis.append(api_name) elif major == 1 and minor >= 20: failed_apis = copy.copy(api_list) result = invoke_api(na_server, api_name='system-user-capability-get-iter', api_family='cm', additional_elems=None, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: capabilities = attr_list.get_children() for capability in capabilities: op_list = capability.get_child_by_name( 'operation-list') if op_list: ops = op_list.get_children() for op in ops: apis = op.get_child_content('api-name') if apis: api_list = apis.split(',') for api_name in api_list: if (api_name and api_name.strip() in failed_apis): failed_apis.remove(api_name) else: continue else: msg = _("Unsupported Clustered Data ONTAP version.") raise exception.VolumeBackendAPIException(data=msg) else: msg = _("Api version could not be determined.") raise exception.VolumeBackendAPIException(data=msg) return failed_apis
def _clone_file(self, volume, src_path, dest_path, vserver=None): """Clones file on vserver.""" LOG.debug(_("""Cloning with params volume %(volume)s,src %(src_path)s, dest %(dest_path)s, vserver %(vserver)s""") % locals()) clone_create = NaElement.create_node_with_children( 'clone-create', **{'volume': volume, 'source-path': src_path, 'destination-path': dest_path}) self._invoke_successfully(clone_create, vserver)
def _get_lun_by_args(self, **args): """Retrives lun with specified args.""" lun_info = NaElement.create_node_with_children('lun-list-info', **args) result = self.client.invoke_successfully(lun_info, True) luns = result.get_child_by_name('luns') if luns: infos = luns.get_children() if infos: return infos[0] return None
def _clone_file(self, volume, src_path, dest_path, vserver=None): """Clones file on vserver""" LOG.debug(_("""Cloning with params volume %(volume)s,src %(src_path)s, dest %(dest_path)s, vserver %(vserver)s""") % locals()) clone_create = NaElement.create_node_with_children( 'clone-create', **{'volume': volume, 'source-path': src_path, 'destination-path': dest_path}) self._invoke_successfully(clone_create, vserver)
def _check_vol_not_root(self, vol): """Checks if a volume is not root.""" vol_options = NaElement.create_node_with_children("volume-options-list-info", **{"volume": vol["name"]}) result = self.client.invoke_successfully(vol_options, True) options = result.get_child_by_name("options") ops = options.get_children() for op in ops: if op.get_child_content("name") == "root" and op.get_child_content("value") == "true": return False return True
def _get_lun_by_args(self, **args): """Retrives lun with specified args.""" lun_info = NaElement.create_node_with_children("lun-list-info", **args) result = self.client.invoke_successfully(lun_info, True) luns = result.get_child_by_name("luns") if luns: infos = luns.get_children() if infos: return infos[0] return None
def _get_if_info_by_ip(self, ip): """Gets the network interface info by ip.""" net_if_iter = NaElement("net-interface-get-iter") net_if_iter.add_new_child("max-records", "10") query = NaElement("query") net_if_iter.add_child_elem(query) query.add_node_with_children("net-interface-info", **{"address": ip}) result = self._invoke_successfully(net_if_iter) if result.get_child_content("num-records") and int(result.get_child_content("num-records")) >= 1: attr_list = result.get_child_by_name("attributes-list") return attr_list.get_children() raise exception.NotFound(_("No interface found on cluster for ip %s") % (ip))
def _get_iscsi_service_details(self): """Returns iscsi iqn.""" iscsi_service_iter = NaElement('iscsi-service-get-iter') result = self.client.invoke_successfully(iscsi_service_iter, True) if result.get_child_content('num-records') and\ int(result.get_child_content('num-records')) >= 1: attr_list = result.get_child_by_name('attributes-list') iscsi_service = attr_list.get_child_by_name('iscsi-service-info') return iscsi_service.get_child_content('node-name') LOG.debug(_('No iscsi service found for vserver %s') % (self.vserver)) return None
def _check_vol_not_root(self, vol): """Checks if a volume is not root.""" vol_options = NaElement.create_node_with_children( 'volume-options-list-info', **{'volume': vol['name']}) result = self.client.invoke_successfully(vol_options, True) options = result.get_child_by_name('options') ops = options.get_children() for op in ops: if op.get_child_content('name') == 'root' and\ op.get_child_content('value') == 'true': return False return True
def _clone_file(self, volume, src_path, dest_path, vserver=None): """Clones file on vserver.""" msg = _( """Cloning with params volume %(volume)s, src %(src_path)s, dest %(dest_path)s, vserver %(vserver)s""" ) msg_fmt = {"volume": volume, "src_path": src_path, "dest_path": dest_path, "vserver": vserver} LOG.debug(msg % msg_fmt) clone_create = NaElement.create_node_with_children( "clone-create", **{"volume": volume, "source-path": src_path, "destination-path": dest_path} ) self._invoke_successfully(clone_create, vserver)
def _check_clone_status(self, clone_id, vol_uuid, name, new_name): """Checks for the job till completed.""" clone_status = NaElement("clone-list-status") cl_id = NaElement("clone-id") clone_status.add_child_elem(cl_id) cl_id.add_node_with_children("clone-id-info", **{"clone-op-id": clone_id, "volume-uuid": vol_uuid}) running = True clone_ops_info = None while running: result = self.client.invoke_successfully(clone_status, True) status = result.get_child_by_name("status") ops_info = status.get_children() if ops_info: for info in ops_info: if info.get_child_content("clone-state") == "running": time.sleep(1) break else: running = False clone_ops_info = info break else: if clone_ops_info: fmt = {"name": name, "new_name": new_name} if clone_ops_info.get_child_content("clone-state") == "completed": LOG.debug(_("Clone operation with src %(name)s" " and dest %(new_name)s completed") % fmt) else: LOG.debug(_("Clone operation with src %(name)s" " and dest %(new_name)s failed") % fmt) raise NaApiError( clone_ops_info.get_child_content("error"), clone_ops_info.get_child_content("reason") )
def _get_cluster_file_usage(self, path, vserver): """Gets the file unique bytes.""" LOG.debug(_('Getting file usage for %s'), path) file_use = NaElement.create_node_with_children('file-usage-get', **{'path': path}) res = self._invoke_successfully(file_use, vserver) bytes = res.get_child_content('unique-bytes') LOG.debug( _('file-usage for path %(path)s is %(bytes)s') % { 'path': path, 'bytes': bytes }) return bytes
def delete_volume(self, volume): """Driver entry point for destroying existing volumes.""" name = volume["name"] metadata = self._get_lun_attr(name, "metadata") if not metadata: msg = _("No entry in LUN table for volume/snapshot %(name)s.") msg_fmt = {"name": name} LOG.warn(msg % msg_fmt) return lun_destroy = NaElement.create_node_with_children("lun-destroy", **{"path": metadata["Path"], "force": "true"}) self.client.invoke_successfully(lun_destroy, True) LOG.debug(_("Destroyed LUN %s") % name) self.lun_table.pop(name)
def _clear_clone(self, clone_id): """Clear the clone information. Invoke this in case of failed clone. """ clone_clear = NaElement.create_node_with_children( 'clone-clear', **{'clone-id': clone_id}) retry = 3 while retry: try: self._invoke_successfully(clone_clear, None) break except Exception as e: # Filer might be rebooting time.sleep(5) retry = retry - 1
def _unmap_lun(self, path, initiator): """Unmaps a lun from given initiator.""" (igroup_name, lun_id) = self._find_mapped_lun_igroup(path, initiator) lun_unmap = NaElement.create_node_with_children("lun-unmap", **{"path": path, "initiator-group": igroup_name}) try: self.client.invoke_successfully(lun_unmap, True) except NaApiError as e: msg = _("Error unmapping lun. Code :%(code)s," " Message:%(message)s") msg_fmt = {"code": e.code, "message": e.message} LOG.warn(msg % msg_fmt) # if the lun is already unmapped if e.code == "13115" or e.code == "9016": pass else: raise e
def delete_volume(self, volume): """Driver entry point for destroying existing volumes.""" name = volume['name'] metadata = self._get_lun_attr(name, 'metadata') if not metadata: msg = _("No entry in LUN table for volume/snapshot %(name)s.") msg_fmt = {'name': name} LOG.warn(msg % msg_fmt) return lun_destroy = NaElement.create_node_with_children( 'lun-destroy', **{'path': metadata['Path'], 'force': 'true'}) self.client.invoke_successfully(lun_destroy, True) LOG.debug(_("Destroyed LUN %s") % name) self.lun_table.pop(name)
def _get_target_details(self): """Gets the target portal details.""" iscsi_if_iter = NaElement('iscsi-portal-list-info') result = self.client.invoke_successfully(iscsi_if_iter, True) tgt_list = [] portal_list_entries = result.get_child_by_name( 'iscsi-portal-list-entries') if portal_list_entries: portal_list = portal_list_entries.get_children() for iscsi_if in portal_list: d = dict() d['address'] = iscsi_if.get_child_content('ip-address') d['port'] = iscsi_if.get_child_content('ip-port') d['tpgroup-tag'] = iscsi_if.get_child_content('tpgroup-tag') tgt_list.append(d) return tgt_list
def _start_clone(self, src_path, dest_path): """Starts the clone operation. Returns the clone-id """ LOG.debug(_("""Cloning with src %(src_path)s, dest %(dest_path)s""") % locals()) clone_start = NaElement.create_node_with_children( 'clone-start', **{'source-path': src_path, 'destination-path': dest_path, 'no-snap': 'true'}) result = self._invoke_successfully(clone_start, None) clone_id_el = result.get_child_by_name('clone-id') cl_id_info = clone_id_el.get_child_by_name('clone-id-info') vol_uuid = cl_id_info.get_child_content('volume-uuid') clone_id = cl_id_info.get_child_content('clone-op-id') return (clone_id, vol_uuid)
def _start_clone(self, src_path, dest_path): """Starts the clone operation. :returns: clone-id """ msg_fmt = {"src_path": src_path, "dest_path": dest_path} LOG.debug(_("""Cloning with src %(src_path)s, dest %(dest_path)s""") % msg_fmt) clone_start = NaElement.create_node_with_children( "clone-start", **{"source-path": src_path, "destination-path": dest_path, "no-snap": "true"} ) result = self._invoke_successfully(clone_start, None) clone_id_el = result.get_child_by_name("clone-id") cl_id_info = clone_id_el.get_child_by_name("clone-id-info") vol_uuid = cl_id_info.get_child_content("volume-uuid") clone_id = cl_id_info.get_child_content("clone-op-id") return (clone_id, vol_uuid)
def _get_target_details(self): """Gets the target portal details.""" iscsi_if_iter = NaElement('iscsi-interface-get-iter') result = self.client.invoke_successfully(iscsi_if_iter, True) tgt_list = [] if result.get_child_content('num-records')\ and int(result.get_child_content('num-records')) >= 1: attr_list = result.get_child_by_name('attributes-list') iscsi_if_list = attr_list.get_children() for iscsi_if in iscsi_if_list: d = dict() d['address'] = iscsi_if.get_child_content('ip-address') d['port'] = iscsi_if.get_child_content('ip-port') d['tpgroup-tag'] = iscsi_if.get_child_content('tpgroup-tag') d['interface-enabled'] = iscsi_if.get_child_content( 'is-interface-enabled') tgt_list.append(d) return tgt_list
def _start_clone(self, src_path, dest_path): """Starts the clone operation. :returns: clone-id """ LOG.debug(_("""Cloning with src %(src_path)s, dest %(dest_path)s""") % locals()) clone_start = NaElement.create_node_with_children( 'clone-start', **{'source-path': src_path, 'destination-path': dest_path, 'no-snap': 'true'}) result = self._invoke_successfully(clone_start, None) clone_id_el = result.get_child_by_name('clone-id') cl_id_info = clone_id_el.get_child_by_name('clone-id-info') vol_uuid = cl_id_info.get_child_content('volume-uuid') clone_id = cl_id_info.get_child_content('clone-op-id') return (clone_id, vol_uuid)
def _create_lun_on_eligible_vol(self, name, size, metadata, extra_specs=None): """Creates an actual lun on filer.""" req_size = float(size) *\ float(self.configuration.netapp_size_multiplier) volume = self._get_avl_volume_by_size(req_size) if not volume: msg = _('Failed to get vol with required size for volume: %s') raise exception.VolumeBackendAPIException(data=msg % name) path = '/vol/%s/%s' % (volume['name'], name) lun_create = NaElement.create_node_with_children( 'lun-create-by-size', **{'path': path, 'size': size, 'ostype': metadata['OsType'], 'space-reservation-enabled': metadata['SpaceReserved']}) self.client.invoke_successfully(lun_create, True) metadata['Path'] = '/vol/%s/%s' % (volume['name'], name) metadata['Volume'] = volume['name'] metadata['Qtree'] = None
def _create_lun_on_eligible_vol(self, name, size, metadata): """Creates an actual lun on filer.""" req_size = float(size) *\ float(self.configuration.netapp_size_multiplier) volume = self._get_avl_volume_by_size(req_size) if not volume: msg = _('Failed to get vol with required size for volume: %s') raise exception.VolumeBackendAPIException(data=msg % name) path = '/vol/%s/%s' % (volume['name'], name) lun_create = NaElement.create_node_with_children( 'lun-create-by-size', **{'path': path, 'size': size, 'ostype': metadata['OsType'], 'space-reservation-enabled': metadata['SpaceReserved']}) self.client.invoke_successfully(lun_create, True) metadata['Path'] = '/vol/%s/%s' % (volume['name'], name) metadata['Volume'] = volume['name'] metadata['Qtree'] = None
def _unmap_lun(self, path, initiator): """Unmaps a lun from given initiator.""" (igroup_name, lun_id) = self._find_mapped_lun_igroup(path, initiator) lun_unmap = NaElement.create_node_with_children( 'lun-unmap', **{'path': path, 'initiator-group': igroup_name}) try: self.client.invoke_successfully(lun_unmap, True) except NaApiError as e: msg = _("Error unmapping lun. Code :%(code)s," " Message:%(message)s") msg_fmt = {'code': e.code, 'message': e.message} exc_info = sys.exc_info() LOG.warn(msg % msg_fmt) # if the lun is already unmapped if e.code == '13115' or e.code == '9016': pass else: raise exc_info[0], exc_info[1], exc_info[2]
def _check_clone_status(self, clone_id, vol_uuid, name, new_name): """Checks for the job till completed.""" clone_status = NaElement('clone-list-status') cl_id = NaElement('clone-id') clone_status.add_child_elem(cl_id) cl_id.add_node_with_children( 'clone-id-info', **{ 'clone-op-id': clone_id, 'volume-uuid': vol_uuid }) running = True clone_ops_info = None while running: result = self.client.invoke_successfully(clone_status, True) status = result.get_child_by_name('status') ops_info = status.get_children() if ops_info: for info in ops_info: if info.get_child_content('clone-state') == 'running': time.sleep(1) break else: running = False clone_ops_info = info break else: if clone_ops_info: fmt = {'name': name, 'new_name': new_name} if clone_ops_info.get_child_content('clone-state')\ == 'completed': LOG.debug( _("Clone operation with src %(name)s" " and dest %(new_name)s completed") % fmt) else: LOG.debug( _("Clone operation with src %(name)s" " and dest %(new_name)s failed") % fmt) raise NaApiError( clone_ops_info.get_child_content('error'), clone_ops_info.get_child_content('reason'))
def _is_filer_ip(self, ip): """Checks whether ip is on the same filer.""" try: ifconfig = NaElement('net-ifconfig-get') res = self._invoke_successfully(ifconfig, None) if_info = res.get_child_by_name('interface-config-info') if if_info: ifs = if_info.get_children() for intf in ifs: v4_addr = intf.get_child_by_name('v4-primary-address') if v4_addr: ip_info = v4_addr.get_child_by_name('ip-address-info') if ip_info: address = ip_info.get_child_content('address') if ip == address: return True else: continue except Exception: return False return False
def _get_avl_volume_by_size(self, size): """Get the available volume by size.""" vol_request = NaElement('volume-list-info') res = self.client.invoke_successfully(vol_request, True) volumes = res.get_child_by_name('volumes') vols = volumes.get_children() for vol in vols: avl_size = vol.get_child_content('size-available') state = vol.get_child_content('state') if float(avl_size) >= float(size) and state == 'online': avl_vol = dict() avl_vol['name'] = vol.get_child_content('name') avl_vol['block-type'] = vol.get_child_content('block-type') avl_vol['type'] = vol.get_child_content('type') avl_vol['size-available'] = avl_size if self.volume_list: if avl_vol['name'] in self.volume_list: return avl_vol else: if self._check_vol_not_root(avl_vol): return avl_vol return None
def _clone_lun(self, name, new_name, space_reserved): """Clone LUN with the given handle to the new name.""" metadata = self._get_lun_attr(name, 'metadata') volume = metadata['Volume'] clone_create = NaElement.create_node_with_children( 'clone-create', **{'volume': volume, 'source-path': name, 'destination-path': new_name, 'space-reserve': space_reserved}) self.client.invoke_successfully(clone_create, True) LOG.debug(_("Cloned LUN with new name %s") % new_name) lun = self._get_lun_by_args(vserver=self.vserver, path='/vol/%s/%s' % (volume, new_name)) if len(lun) == 0: msg = _("No clonned lun named %s found on the filer") raise exception.VolumeBackendAPIException(data=msg % (new_name)) clone_meta = self._create_lun_meta(lun[0]) self._add_lun_to_table(NetAppLun('%s:%s' % (clone_meta['Vserver'], clone_meta['Path']), new_name, lun[0].get_child_content('size'), clone_meta))
def _find_mapped_lun_igroup(self, path, initiator, os=None): """Find the igroup for mapped lun with initiator.""" lun_map_list = NaElement.create_node_with_children( 'lun-map-list-info', **{'path': path}) result = self.client.invoke_successfully(lun_map_list, True) igroups = result.get_child_by_name('initiator-groups') if igroups: igroup = None lun_id = None found = False igroup_infs = igroups.get_children() for ig in igroup_infs: initiators = ig.get_child_by_name('initiators') init_infs = initiators.get_children() for info in init_infs: if info.get_child_content('initiator-name') == initiator: found = True igroup = ig.get_child_content('initiator-group-name') lun_id = ig.get_child_content('lun-id') break if found: break return (igroup, lun_id)