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 _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 _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 _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 _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 _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 _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_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 _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 _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 _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 _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.""" 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 _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 _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 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 _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 _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 _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 _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 """ 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 _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 _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)
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)
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 _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 _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 _create_file_usage_req(self, path): """Creates the request element for file_usage_get.""" file_use = NaElement.create_node_with_children('file-usage-get', **{'path': path}) return file_use
def _create_file_usage_req(self, path): """Creates the request element for file_usage_get.""" file_use = NaElement.create_node_with_children("file-usage-get", **{"path": path}) return file_use
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)