def show(self, docker_volume_name): cinder_volume, state = self._get_docker_volume(docker_volume_name) LOG.info(_LI("Get docker volume {0} {1} with state " "{2}").format(docker_volume_name, cinder_volume, state)) if state == ATTACH_TO_THIS: devpath = os.path.realpath( self._get_connector().get_device_path(cinder_volume)) mp = self._get_mountpoint(docker_volume_name) LOG.info("Expected devpath: {0} and mountpoint: {1} for volume: " "{2} {3}".format(devpath, mp, docker_volume_name, cinder_volume)) mounter = mount.Mounter() return {"Name": docker_volume_name, "Mountpoint": mp if mp in mounter.get_mps_by_device( devpath) else ''} elif state in (NOT_ATTACH, ATTACH_TO_OTHER): return {'Name': docker_volume_name, 'Mountpoint': ''} elif state == UNKNOWN: msg = _LW("Can't find this volume '{0}' in " "OpenSDS").format(docker_volume_name) LOG.warning(msg) raise exceptions.NotFound(msg) else: msg = _LE("Volume '{0}' exists, but not attached to this volume," "and current state is {1}").format(docker_volume_name, state) raise exceptions.NotMatchedState(msg)
def list(self): LOG.info(_LI("Start to retrieve all docker volumes from OpenSDS")) docker_volumes = [] try: for vol in self.opensdsclient.list(): # LOG.info(_LI("Retrieve docker volumes {0} from OpenSDS " # "successfully").format(vol)) docker_volume_name = vol['name'] if not docker_volume_name: continue mountpoint = self._get_mountpoint(docker_volume_name) vol = APIDictWrapper(vol) devpath = os.path.realpath( self._get_connector().get_device_path(vol)) mps = mount.Mounter().get_mps_by_device(devpath) mountpoint = mountpoint if mountpoint in mps else '' docker_vol = {'Name': docker_volume_name, 'Mountpoint': mountpoint} docker_volumes.append(docker_vol) except cinder_exception.ClientException as e: LOG.error(_LE("Retrieve volume list failed. Error: {0}").format(e)) raise LOG.info(_LI("Retrieve docker volumes {0} from OpenSDS " "successfully").format(docker_volumes)) return docker_volumes
def list(self): LOG.info(_LI("Start to retrieve all docker volumes from Cinder")) docker_volumes = [] try: search_opts = {'metadata': {consts.VOLUME_FROM: CONF.volume_from}} for vol in self.cinderclient.volumes.list(search_opts=search_opts): docker_volume_name = vol.name if not docker_volume_name: continue mountpoint = self._get_mountpoint(vol.name) devpath = os.path.realpath( self._get_connector().get_device_path(vol)) mps = mount.Mounter().get_mps_by_device(devpath) mountpoint = mountpoint if mountpoint in mps else '' docker_vol = { 'Name': docker_volume_name, 'Mountpoint': mountpoint } docker_volumes.append(docker_vol) except cinder_exception.ClientException as e: LOG.error(_LE("Retrieve volume list failed. Error: %s"), e) raise LOG.info(_LI("Retrieve docker volumes %s from Cinder " "successfully"), docker_volumes) return docker_volumes
def disconnect_volume(self, share, **disconnect_opts): mountpoint = self.get_mountpoint(share) mount.Mounter().unmount(mountpoint) self._access_deny(share) def _check_access_binded(s): sal = self.manilaclient.shares.access_list(s) share_proto = s.share_proto access_type = self.proto_access_type_map.get(share_proto) access_to = self._get_access_to(access_type) for a in sal: if a.access_type == access_type and a.access_to == access_to: if a.state in ('error', 'error_deleting'): raise exceptions.NotMatchedState( "Revoke access {0} failed".format(a)) return True return False start_time = time.time() while time.time() - start_time < consts.ACCSS_DENY_TIMEOUT: if not _check_access_binded(share): LOG.info("Disconnect share %s successfully", share) return time.sleep(consts.SCAN_INTERVAL) raise exceptions.TimeoutException("Disconnect volume timeout")
def show(self, docker_volume_name): cinder_volume, state = self._get_docker_volume(docker_volume_name) LOG.info(_LI("Get docker volume %(d_v)s %(vol)s with state %(st)s"), { 'd_v': docker_volume_name, 'vol': cinder_volume, 'st': state }) if state == ATTACH_TO_THIS: devpath = os.path.realpath( self._get_connector().get_device_path(cinder_volume)) mp = self._get_mountpoint(docker_volume_name) LOG.info( _LI("Expected devpath: %(dp)s and mountpoint: %(mp)s for" " volume: %(d_v)s %(vol)s"), { 'dp': devpath, 'mp': mp, 'd_v': docker_volume_name, 'vol': cinder_volume }) mounter = mount.Mounter() return { "Name": docker_volume_name, "Mountpoint": mp if mp in mounter.get_mps_by_device(devpath) else '' } elif state in (NOT_ATTACH, ATTACH_TO_OTHER): return {'Name': docker_volume_name, 'Mountpoint': ''} elif state == UNKNOWN: msg = _LW("Can't find this volume '{0}' in " "Cinder").format(docker_volume_name) LOG.warning(msg) raise exceptions.NotFound(msg) else: msg = _LE("Volume '{0}' exists, but not attached to this volume," "and current state is {1}").format( docker_volume_name, state) raise exceptions.NotMatchedState(msg)
def delete(self, docker_volume_name): cinder_volume, state = self._get_docker_volume(docker_volume_name) LOG.info(_LI("Get docker volume {0} {1} with state " "{2}").format(docker_volume_name, cinder_volume, state)) if state == ATTACH_TO_THIS: link_path = self._get_connector().get_device_path(cinder_volume) if not link_path or not os.path.exists(link_path): msg = _LE( "Could not find device link path for volume {0} {1} " "in host").format(docker_volume_name, cinder_volume) LOG.error(msg) raise exceptions.FuxiException(msg) devpath = os.path.realpath(link_path) if not os.path.exists(devpath): msg = _LE("Could not find device path for volume {0} {1} in " "host").format(docker_volume_name, cinder_volume) LOG.error(msg) raise exceptions.FuxiException(msg) mounter = mount.Mounter() mps = mounter.get_mps_by_device(devpath) ref_count = len(mps) if ref_count > 0: mountpoint = self._get_mountpoint(docker_volume_name) if mountpoint in mps: mounter.unmount(mountpoint) self._clear_mountpoint(mountpoint) # If this volume is still mounted on other mount point, # then return. if ref_count > 1: return True else: return True # Detach device from this server. self._get_connector().disconnect_volume(cinder_volume) available_volume = self.opensdsclient.get(cinder_volume.id) # If this volume is not used by other server any more, # than delete it from Cinder. available_volume = APIDictWrapper(available_volume) if not available_volume.attachments: msg = _LW("No other servers still use this volume {0} " "{1} any more, so delete it from OpenSDS" "").format(docker_volume_name, cinder_volume) LOG.warning(msg) self._delete_volume(available_volume) return True elif state == NOT_ATTACH: self._delete_volume(cinder_volume) return True elif state == ATTACH_TO_OTHER: msg = _LW("Volume %s is still in use, could not delete it") LOG.warning(msg, cinder_volume) return True elif state == UNKNOWN: return False else: msg = _LE("Volume %(vol_name)s %(c_vol)s " "state %(state)s is invalid") LOG.error(msg, {'vol_name': docker_volume_name, 'c_vol': cinder_volume, 'state': state}) raise exceptions.NotMatchedState()