Beispiel #1
0
class Identity(csi.IdentityServicer):
    backend = None
    PROBE_RESP = types.ProbeResp()
    CAPABILITIES = types.CapabilitiesResponse(
        [types.ServiceType.CONTROLLER_SERVICE])
    manifest = None

    def __init__(self, server):
        if self.manifest is not None:
            return

        manifest = {
            'cinderlib-version': cinderlib.__version__,
            'cinder-version': CINDER_VERSION,
        }
        if self.persistence:
            manifest['persistence'] = type(self.persistence).__name__

        if self.backend:
            manifest['cinder-driver-version'] = self.backend.get_version()
            manifest['cinder-driver'] = type(self.backend.driver).__name__
            manifest['cinder-driver-supported'] = str(self.backend.supported)

        self.INFO = types.InfoResp(name=NAME,
                                   vendor_version=VENDOR_VERSION,
                                   manifest=manifest)

        csi.add_IdentityServicer_to_server(self, server)
        self.manifest = manifest

    def GetPluginInfo(self, request, context):
        return self.INFO

    def GetPluginCapabilities(self, request, context):
        return self.CAPABILITIES

    def Probe(self, request, context):
        failure = False
        # check configuration
        # check_persistence
        if self.backend:
            # check driver
            pass

        if failure:
            context.abort(grpc.StatusCode.FAILED_PRECONDITION,
                          'Persistence is not accessible')

        return self.PROBE_RESP

    def _get_vol(self, volume_id=None, **filters):
        res = self.persistence.get_volumes(volume_id=volume_id,
                                           backend_name=self.backend.id,
                                           **filters)
        if res and len(res) == 1 and (volume_id or filters):
            return res[0]
        return res

    def sudo(self, *cmd):
        putils.execute(*cmd, run_as_root=True, root_helper='sudo')
Beispiel #2
0
class Identity(csi.IdentityServicer):
    backend = None
    # NOTE(geguileo): For now let's only support single reader/writer modes
    SUPPORTED_ACCESS = (types.AccessModeType.SINGLE_NODE_WRITER,
                        types.AccessModeType.SINGLE_NODE_READER_ONLY)
    PROBE_RESP = types.ProbeResp()
    CAPABILITIES = types.CapabilitiesResponse(
        [types.ServiceType.CONTROLLER_SERVICE])
    manifest = None
    MKFS = '/sbin/mkfs.'
    DEFAULT_MKFS_ARGS = tuple()
    MKFS_ARGS = {'ext4': ('-F', )}

    def __init__(self, server, cinderlib_cfg):
        if self.manifest is not None:
            return

        self.root_helper = (cinderlib_cfg or {}).get('root_helper') or 'sudo'

        manifest = {
            'cinderlib-version': cinderlib.__version__,
            'cinder-version': CINDER_VERSION,
        }
        self.persistence = cinderlib.Backend.persistence
        manifest['persistence'] = type(self.persistence).__name__

        manifest['mode'] = type(self).__name__.lower()

        if self.backend:
            manifest['cinder-driver-version'] = self.backend.get_version()
            manifest['cinder-driver'] = type(self.backend.driver).__name__
            manifest['cinder-driver-supported'] = str(self.backend.supported)

        self.INFO = types.InfoResp(name=NAME,
                                   vendor_version=VENDOR_VERSION,
                                   manifest=manifest)

        csi.add_IdentityServicer_to_server(self, server)
        self.manifest = manifest
        self.supported_fs_types = self._get_system_fs_types()
        if DEFAULT_MOUNT_FS not in self.supported_fs_types:
            sys.stderr.write('Invalid default mount filesystem %s\n' %
                             DEFAULT_MOUNT_FS)
            exit(1)

    @classmethod
    def _get_system_fs_types(cls):
        fs_types = glob.glob(cls.MKFS + '*')
        start = len(cls.MKFS)
        result = [fst[start:] for fst in fs_types]
        print('Supported filesystems are: %s' % ', '.join(result))
        return result

    def _unsupported_mode(self, capability):
        return capability.access_mode.mode not in self.SUPPORTED_ACCESS

    def _unsupported_fs_type(self, capability):
        # TODO: validate mount_flags
        return (capability.HasField('mount') and capability.mount.fs_type
                and capability.mount.fs_type not in self.supported_fs_types)

    def _validate_capabilities(self, capabilities, context=None):
        msg = ''

        for capability in capabilities:
            # TODO(geguileo): Find out what is the right status code
            if self._unsupported_mode(capability):
                msg = 'Unsupported access mode'
                break

            if self._unsupported_fs_type(capability):
                msg = 'Unsupported file system type'
                break

        if context and msg:
            context.abort(grpc.StatusCode.INVALID_ARGUMENT, msg)

        return msg

    @debuggable
    @logrpc
    def GetPluginInfo(self, request, context):
        return self.INFO

    @debuggable
    @logrpc
    def GetPluginCapabilities(self, request, context):
        return self.CAPABILITIES

    @debuggable
    @logrpc
    def Probe(self, request, context):
        failure = False
        # check configuration
        # check_persistence
        if self.backend:
            # check driver
            pass

        if failure:
            context.abort(grpc.StatusCode.FAILED_PRECONDITION,
                          'Persistence is not accessible')

        return self.PROBE_RESP

    def _get_vol(self, volume_id=None, **filters):
        backend_name = self.backend.id if self.backend else None
        res = self.persistence.get_volumes(volume_id=volume_id,
                                           backend_name=backend_name,
                                           **filters)
        if res and len(res) == 1 and (volume_id or filters):
            return res[0]
        return res

    def sudo(self, *cmd, **kwargs):
        retries = kwargs.pop('retries', 1)
        delay = kwargs.pop('delay', 1)
        backoff = kwargs.pop('backoff', 2)
        errors = kwargs.pop('errors', [32])
        while retries:
            try:
                return putils.execute(*cmd,
                                      run_as_root=True,
                                      root_helper=self.root_helper)
            except putils.ProcessExecutionError as exc:
                retries -= 1
                if exc.exit_code not in errors or not retries:
                    raise
                time.sleep(delay)
                delay *= backoff