コード例 #1
0
ファイル: cinder.py プロジェクト: drngsl/fuxi
    def _create_from_existing_volume(self, docker_volume_name,
                                     cinder_volume_id, volume_opts):
        try:
            cinder_volume = self.cinderclient.volumes.get(cinder_volume_id)
        except cinder_exception.ClientException as e:
            msg = _LE("Failed to get volume %(vol_id)s from Cinder. "
                      "Error: %(err)s")
            LOG.error(msg, {'vol_id': cinder_volume_id, 'err': e})
            raise

        status = cinder_volume.status
        if status not in ('available', 'in-use'):
            LOG.error(
                _LE("Current volume %(vol)s status %(status)s not in "
                    "desired states"), {
                        'vol': cinder_volume,
                        'status': status
                    })
            raise exceptions.NotMatchedState('Cinder volume is unavailable')
        elif status == 'in-use' and not cinder_volume.multiattach:
            if not self._check_attached_to_this(cinder_volume):
                msg = _LE("Current volume %(vol)s status %(status)s not "
                          "in desired states")
                LOG.error(msg, {'vol': cinder_volume, 'status': status})
                raise exceptions.NotMatchedState(
                    'Cinder volume is unavailable')

        if cinder_volume.name != docker_volume_name:
            LOG.error(
                _LE("Provided volume name %(d_name)s does not match "
                    "with existing Cinder volume name %(c_name)s"), {
                        'd_name': docker_volume_name,
                        'c_name': cinder_volume.name
                    })
            raise exceptions.InvalidInput('Volume name does not match')

        fstype = volume_opts.pop('fstype', cinder_conf.fstype)
        vol_fstype = cinder_volume.metadata.get('fstype', cinder_conf.fstype)
        if fstype != vol_fstype:
            LOG.error(
                _LE("Volume already exists with fstype %(c_fstype)s, "
                    "but currently provided fstype is %(fstype)s, not "
                    "match"), {
                        'c_fstype': vol_fstype,
                        'fstype': fstype
                    })
            raise exceptions.InvalidInput('FSType does not match')

        try:
            metadata = {consts.VOLUME_FROM: CONF.volume_from, 'fstype': fstype}
            self.cinderclient.volumes.set_metadata(cinder_volume, metadata)
        except cinder_exception.ClientException as e:
            LOG.error(
                _LE("Failed to update volume %(vol)s information. "
                    "Error: %(err)s"), {
                        'vol': cinder_volume_id,
                        'err': e
                    })
            raise
        return cinder_volume
コード例 #2
0
    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)
コード例 #3
0
 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
コード例 #4
0
ファイル: cinder.py プロジェクト: drngsl/fuxi
    def mount(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
        })

        connector = self._get_connector()
        if state == NOT_ATTACH:
            connector.connect_volume(cinder_volume)
        elif state == ATTACH_TO_OTHER:
            if cinder_volume.multiattach:
                connector.connect_volume(cinder_volume)
            else:
                msg = _("Volume {0} {1} is not shareable").format(
                    docker_volume_name, cinder_volume)
                raise exceptions.FuxiException(msg)
        elif state != ATTACH_TO_THIS:
            msg = _("Volume %(vol_name)s %(c_vol)s is not in correct state, "
                    "current state is %(state)s")
            LOG.error(
                msg, {
                    'vol_name': docker_volume_name,
                    'c_vol': cinder_volume,
                    'state': state
                })
            raise exceptions.NotMatchedState()

        link_path = connector.get_device_path(cinder_volume)
        if not os.path.exists(link_path):
            LOG.warning(
                _LW("Could not find device link file, "
                    "so rebuild it"))
            connector.disconnect_volume(cinder_volume)
            connector.connect_volume(cinder_volume)

        devpath = os.path.realpath(link_path)
        if not devpath or not os.path.exists(devpath):
            msg = _("Can't find volume device path")
            LOG.error(msg)
            raise exceptions.FuxiException(msg)

        mountpoint = self._get_mountpoint(docker_volume_name)
        self._create_mountpoint(mountpoint)

        fstype = cinder_volume.metadata.get('fstype', cinder_conf.fstype)

        mount.do_mount(devpath, mountpoint, fstype)

        return mountpoint
コード例 #5
0
ファイル: cinder.py プロジェクト: drngsl/fuxi
    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)
コード例 #6
0
    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()