Ejemplo n.º 1
0
class VolumeOperations(object):

    def __init__(self):
        self.MetadataHandler = MetadataHandler()

    def create(self, dbg, uri, size):
        raise NotImplementedError('Override in VolumeOperations specifc class')

    def destroy(self, dbg, uri):
        raise NotImplementedError('Override in VolumeOperations specifc class')

    def resize(self, dbg, uri, size):
        raise NotImplementedError('Override in VolumeOperations specifc class')

    def swap(self, dbg, uri1, uri2):
        log.debug("%s: xcpng.volume.VolumeOperations.swap: uri1: %s uri2: %s" % (dbg, uri1, uri2))
        volume1_meta = self.MetadataHandler.get_vdi_meta(dbg, uri1)
        volume2_meta = self.MetadataHandler.get_vdi_meta(dbg, uri2)
        log.debug("%s: xcpng.volume.VolumeOperations.swap: before image_uuid1: %s image_uudi2: %s" %
                  (dbg, volume1_meta[IMAGE_UUID_TAG], volume2_meta[IMAGE_UUID_TAG]))
        image1_uuid = volume1_meta[IMAGE_UUID_TAG]
        image2_uuid = volume2_meta[IMAGE_UUID_TAG]
        volume1_meta = {IMAGE_UUID_TAG: image2_uuid}
        volume2_meta = {IMAGE_UUID_TAG: image1_uuid}
        log.debug("%s: xcpng.volume.VolumeOperations.swap: after image_uuid1: %s image_uudi2: %s" %
                  (dbg, volume1_meta[IMAGE_UUID_TAG], volume2_meta[IMAGE_UUID_TAG]))
        self.MetadataHandler.update_vdi_meta(dbg, uri1, volume1_meta)
        self.MetadataHandler.update_vdi_meta(dbg, uri2, volume2_meta)

    def get_phisical_utilization(self, dbg, uri):
        raise NotImplementedError('Override in VolumeOperations specifc class')

    def roundup_size(self, dbg, size):
        raise NotImplementedError('Override in VolumeOperations specifc class')
Ejemplo n.º 2
0
class Volume(object):

    def __init__(self):
        self.MetadataHandler = MetadataHandler()
        self.VolOpsHendler = _VolumeOperations_()
        self.Datapathes = DATAPATHES

        for k, v in DATAPATHES.iteritems():
            self.Datapathes[k] = v()

    def _create(self, dbg, sr, name, description, size, sharable, volume_meta):
        raise NotImplementedError('Override in Volume specifc class')

    def create(self, dbg, sr, name, description, size, sharable):
        log.debug("%s: xcpng.volume.Volume.create: SR: %s Name: %s Description: %s Size: %s, Sharable: %s"
                  % (dbg, sr, name, description, size, sharable))

        vdi_uuid = str(uuid.uuid4())
        image_uuid = str(uuid.uuid4())
        vdi_uri = "%s/%s" % (sr, vdi_uuid)

        volume_meta = {
            KEY_TAG: vdi_uuid,
            VDI_UUID_TAG: vdi_uuid,
            IMAGE_UUID_TAG: image_uuid,
            TYPE_TAG: get_vdi_type_by_uri(dbg, vdi_uri),
            NAME_TAG: name,
            DESCRIPTION_TAG: description,
            READ_WRITE_TAG: True,
            VIRTUAL_SIZE_TAG: size,
            PHYSICAL_UTILISATION_TAG: 0,
            URI_TAG: [vdi_uri],
            SHARABLE_TAG: sharable,
            CUSTOM_KEYS_TAG: {}
        }

        try:
            self.MetadataHandler.update_vdi_meta(dbg, vdi_uri, volume_meta)
            volume_meta = self._create(dbg, sr, name, description, size, sharable, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.create: Failed to create volume: key %s: SR: %s" % (dbg, vdi_uuid, sr))
            try:
                self.destroy(dbg, sr, vdi_uuid)
                self.MetadataHandler.remove_vdi_meta(dbg, vdi_uri)
            except:
                pass
            raise Exception(e)

        return volume_meta

    def set(self, dbg, sr, key, k, v):
        log.debug("%s: xcpng.volume.Volume.set: SR: %s Key: %s Custom_key: %s Value: %s"
                  % (dbg, sr, key, k, v))

        uri = "%s/%s" % (sr, key)

        volume_meta = {CUSTOM_KEYS_TAG: {}}

        try:
            volume_meta[CUSTOM_KEYS_TAG][k] = v
            self.MetadataHandler.update_vdi_meta(dbg, uri, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to set volume param: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def unset(self, dbg, sr, key, k):
        log.debug("%s: xcpng.volume.Volume.unset: SR: %s Key: %s Custom_key: %s"
                  % (dbg, sr, key, k))

        uri = "%s/%s" % (sr, key)

        volume_meta = {CUSTOM_KEYS_TAG: {}}

        try:
            volume_meta[CUSTOM_KEYS_TAG][k] = None
            self.MetadataHandler.update_vdi_meta(dbg, uri, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to unset volume param: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def _stat(self, dbg, sr, key, volume_meta):
        # Override in Volume specific class
        return volume_meta

    def stat(self, dbg, sr, key):
        log.debug("%s: xcpng.volume.Volume.stat: SR: %s Key: %s"
                  % (dbg, sr, key))

        uri = "%s/%s" % (sr, key)

        try:
            volume_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)
            volume_meta[PHYSICAL_UTILISATION_TAG] = self.VolOpsHendler.get_phisical_utilization(dbg, uri)
            log.debug("%s: xcpng.volume.Volume.stat: SR: %s Key: %s Metadata: %s"
                      % (dbg, sr, key, volume_meta))
            return self._stat(dbg, sr, key, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.stat: Failed to get volume stat: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def _destroy(self, dbg, sr, key):
        # Override in Volume specifc class
        pass

    def destroy(self, dbg, sr, key):
        log.debug("%s: xcpng.volume.Volume.destroy: SR: %s Key: %s"
                  % (dbg, sr, key))

        uri = "%s/%s" % (sr, key)

        try:
            self._destroy(dbg, sr, key)
            self.VolOpsHendler.destroy(dbg, uri)
            self.MetadataHandler.remove_vdi_meta(dbg, uri)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.destroy: Failed to destroy volume: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def set_description(self, dbg, sr, key, new_description):
        log.debug("%s: xcpng.volume.Volume.set_description: SR: %s Key: %s New_description: %s"
                  % (dbg, sr, key, new_description))

        uri = "%s/%s" % (sr, key)

        volume_meta = {
            'description': new_description,
        }

        try:
            self.MetadataHandler.update_vdi_meta(dbg, uri, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to set volume description: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def set_name(self, dbg, sr, key, new_name):
        log.debug("%s: xcpng.volume.Volume.set_name: SR: %s Key: %s New_name: %s"
                  % (dbg, sr, key, new_name))

        uri = "%s/%s" % (sr, key)

        volume_meta = {
            'name': new_name,
        }

        try:
            self.MetadataHandler.update_vdi_meta(dbg, uri, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to set volume name: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def _resize(self, dbg, sr, key, new_size):
        raise NotImplementedError('Override in Volume specifc class')

    def resize(self, dbg, sr, key, new_size):
        log.debug("%s: xcpng.volume.Volume.resize: SR: %s Key: %s New_size: %s"
                  % (dbg, sr, key, new_size))

        uri = "%s/%s" % (sr, key)

        volume_meta = {
            'virtual_size': new_size,
        }

        try:
            self._resize(dbg, sr, key, new_size)
            self.MetadataHandler.update_vdi_meta(dbg, uri, volume_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to resize volume: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def _clone(self, dbg, sr, key, mode, volume_meta):
        raise NotImplementedError('Override in Volume specifc class')

    def clone(self, dbg, sr, key, mode):
        log.debug("%s: xcpng.volume.Volume.clone: SR: %s Key: %s Mode: %s"
                  % (dbg, sr, key, mode))

        orig_uri = "%s/%s" % (sr, key)

        try:
            orig_meta = self.MetadataHandler.get_vdi_meta(dbg, orig_uri)

            if SNAPSHOT_OF_TAG in orig_meta[CUSTOM_KEYS_TAG]:
                base_uri = orig_meta[PARENT_URI_TAG][0]
                base_meta = self.MetadataHandler.get_vdi_meta(dbg, base_uri)
            else:
                base_meta = deepcopy(orig_meta)

            if ACTIVE_ON_TAG in base_meta:
                current_host = get_current_host_uuid()
                if base_meta[ACTIVE_ON_TAG] != current_host:
                    log.debug("%s: librbd.Volume.clone: SR: %s Key: %s Can not snapshot on %s as VDI already active on %s"
                              % (dbg, sr, base_meta[VDI_UUID_TAG],
                                 current_host, base_meta[ACTIVE_ON_TAG]))
                    raise Activated_on_another_host(base_meta[ACTIVE_ON_TAG])

            return self._clone(dbg, sr, key, mode, base_meta)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to clone volume: key %s: SR: %s" % (dbg, key, sr))
            raise Exception(e)

    def _commit(self, dbg, sr, child, parent):
        raise NotImplementedError('Coalesce is not supported')

    def _set_parent(self, dbg, sr, child, parent):
        raise NotImplementedError('Coalesce is not supported')

    def commit(self, dbg, sr, child, parent):
        self._commit(dbg, sr, child, parent)

    def set_parent(self, dbg, sr, child, parent):
        self._set_parent(dbg, sr, child, parent)

    def coalesce(self, dbg, sr, key):

        uri = "%s/%s" % (sr, key)

        try:
            volume_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)
            children = self.MetadataHandler.find_vdi_children(dbg, uri)

            self._commit(dbg, sr, uri, volume_meta[PARENT_URI_TAG])

            for child in children:
                self._set_parent(dbg, sr, child[URI_TAG], volume_meta[PARENT_URI_TAG])
                meta = {PARENT_URI_TAG: volume_meta[PARENT_URI_TAG]}
                self.MetadataHandler.update_vdi_meta(dbg, child[URI_TAG], meta)

            self.destroy(dbg, sr, key)
            self.MetadataHandler.remove_vdi_meta(dbg, uri)
        except Exception as e:
            log.error("%s: xcpng.volume.Volume.set: Failed to coalesce volume with parent: key %s: SR: %s"
                      % (dbg, key, sr))
            raise Exception(e)
class Datapath(object):
    def __init__(self):
        self.MetadataHandler = MetadataHandler()
        self.DatapathOpsHandler = _DatapathOperations_()

    def _relink(self, dbg, uri, child, parent, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def relink(self, dbg, uri, child, parent, domain):
        log.debug(
            "%s: xcpng.datapath.Datapath.relink: uri: %s child: %s parent: %s domain: %s"
            % (dbg, uri, child, parent, domain))

        try:
            self._relink(dbg, uri, child, parent, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.relink: Failed to relink: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _commit(self, dbg, uri, child, parent, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def commit(self, dbg, uri, child, parent, domain):
        log.debug(
            "%s: xcpng.datapath.Datapath.commit: uri: %s child: %s parent: %s domain: %s"
            % (dbg, uri, child, parent, domain))

        try:
            self._commit(dbg, uri, child, parent, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.commit: Failed to commit: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _open(self, dbg, uri, persistent):
        raise NotImplementedError('Override in Datapath specifc class')

    def open(self, dbg, uri, persistent):
        log.debug("%s: xcpng.datapath.Datapath.open: uri: %s persistent: %s" %
                  (dbg, uri, persistent))

        try:
            image_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)

            if NON_PERSISTENT_TAG in image_meta:
                vdi_non_persistent = image_meta[NON_PERSISTENT_TAG]
            else:
                vdi_non_persistent = False

            if persistent:
                log.debug(
                    "%s: xcpng.Datapath.open: uri: %s will be marked as persistent"
                    % (dbg, uri))
                if vdi_non_persistent:
                    # unmark as non-peristent
                    image_meta = {
                        NON_PERSISTENT_TAG: None,
                    }
                    self.MetadataHandler.update_vdi_meta(dbg, uri, image_meta)
                    # on detach remove special snapshot to rollback to
            elif vdi_non_persistent:
                log.debug(
                    "%s: xcpng.Datapath.open: uri: %s already marked as non-persistent"
                    % (dbg, uri))
            else:
                log.debug(
                    "%s: xcpng.Datapath.open: uri: %s will be marked as non-persistent"
                    % (dbg, uri))
                # mark as non-peristent
                image_meta = {
                    NON_PERSISTENT_TAG: True,
                }
                self.MetadataHandler.update_vdi_meta(dbg, uri, image_meta)
                # on attach create special snapshot to rollback to on detach

            self._open(dbg, uri, persistent)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.open: Failed to open datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _close(self, dbg, uri):
        raise NotImplementedError('Override in Datapath specifc class')

    def close(self, dbg, uri):
        log.debug("%s: xcpng.datapath.Datapath.close: uri: %s" % (dbg, uri))

        try:
            image_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)

            if NON_PERSISTENT_TAG in image_meta:
                vdi_non_persistent = image_meta[NON_PERSISTENT_TAG]
            else:
                vdi_non_persistent = False

            log.debug(
                "%s: xcpng.Datapath.close: uri: %s will be marked as persistent"
                % (dbg, uri))
            if vdi_non_persistent:
                # unmark as non-peristent
                image_meta = {
                    NON_PERSISTENT_TAG: None,
                }
                self.MetadataHandler.update_vdi_meta(dbg, uri, image_meta)

            self._close(dbg, uri)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.close: Failed to close datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _attach(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def attach(self, dbg, uri, domain):
        log.debug("%s: xcpng.datapath.Datapath.attach: uri: %s domain: %s" %
                  (dbg, uri, domain))

        try:
            self.DatapathOpsHandler.map_vol(dbg, uri, chained=True)

            if platform.linux_distribution()[1] == '7.5.0':
                protocol, params = self._attach(dbg, uri, domain)
                return {
                    'domain_uuid': '0',
                    'implementation': [protocol, params]
                }
            elif platform.linux_distribution(
            )[1] == '7.6.0' or platform.linux_distribution()[1] == '8.0.0':
                return {'implementations': self._attach(dbg, uri, domain)}
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.attach: Failed to attach datapath for volume: uri: %s"
                % (dbg, uri))
            try:
                self.DatapathOpsHandler.unmap_vol(dbg, uri, chained=True)
            except:
                pass
            raise Exception(e)

    def _detach(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def detach(self, dbg, uri, domain):
        log.debug("%s: xcpng.datapath.Datapath.detach: uri: %s domain: %s" %
                  (dbg, uri, domain))

        try:
            self.DatapathOpsHandler.unmap_vol(dbg, uri, chained=True)
            self._detach(dbg, uri, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.detach: Failed to detach datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _activate(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def activate(self, dbg, uri, domain):
        log.debug("%s: xcpng.datapath.Datapath.activate: uri: %s domain: %s" %
                  (dbg, uri, domain))

        # TODO: Check that VDI is not active on other host

        try:
            self._activate(dbg, uri, domain)

            image_meta = {ACTIVE_ON_TAG: get_current_host_uuid()}

            self.MetadataHandler.update_vdi_meta(dbg, uri, image_meta)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.activate: Failed to activate datapath for volume: uri: %s"
                % (dbg, uri))
            try:
                self._deactivate(dbg, uri, domain)
            except:
                pass
            raise Exception(e)

    def _deactivate(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def deactivate(self, dbg, uri, domain):
        log.debug(
            "%s: xcpng.datapath.Datapath.deactivate: uri: %s domain: %s" %
            (dbg, uri, domain))

        try:
            self._deactivate(dbg, uri, domain)

            image_meta = {ACTIVE_ON_TAG: None}

            self.MetadataHandler.update_vdi_meta(dbg, uri, image_meta)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.deactivate: Failed to deactivate datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _suspend(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def suspend(self, dbg, uri, domain):
        log.debug("%s: xcpng.datapath.Datapath.suspend: uri: %s domain: %s" %
                  (dbg, uri, domain))
        try:
            self._suspend(dbg, uri, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.suspend: Failed to suspend datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _resume(self, dbg, uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def resume(self, dbg, uri, domain):
        log.debug("%s: xcpng.datapath.Datapath.resume: uri: %s domain: %s" %
                  (dbg, uri, domain))
        try:
            self._resume(dbg, uri, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.resume: Failed to resume datapath for volume: uri: %s"
                % (dbg, uri))
            raise Exception(e)

    def _snapshot(self, dbg, base_uri, snap_uri, domain):
        raise NotImplementedError('Override in Datapath specifc class')

    def snapshot(self, dbg, base_uri, snap_uri, domain):
        log.debug(
            "%s: xcpng.Datapath.snapshot: base_uri: %s snap_uri: %s domain: %s"
            % (dbg, base_uri, snap_uri, domain))
        try:
            self._snapshot(dbg, base_uri, snap_uri, domain)
        except Exception as e:
            log.error(
                "%s: xcpng.datapath.Datapath.snapshot: Failed to set backing file for live volume: uri: %s"
                % (dbg, snap_uri))
            raise Exception(e)
class DatapathOperations(object):
    def __init__(self):
        self.MetadataHandler = MetadataHandler()
        self.blkdev = None

    def gen_vol_path(self, dbg, uri):
        volume_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)
        return "%s/%s/%s" % (SR_PATH_PREFIX, get_sr_uuid_by_uri(
            dbg, uri), volume_meta[IMAGE_UUID_TAG])

    def gen_vol_uri(self, dbg, uri):
        return "file:%s" % self.gen_vol_path(dbg, uri)

    def map_vol(self, dbg, uri, chained=False):
        if self.blkdev:
            log.debug(
                "%s: xcpng.datapath.DatapathOperations.map_vol: uri: %s" %
                (dbg, uri))
            _blkdev_ = self.blkdev

            try:
                volume_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)

                if chained is True:
                    if PARENT_URI_TAG in volume_meta:
                        self.map_vol(dbg, volume_meta[PARENT_URI_TAG][0],
                                     chained)

                if REF_COUNT_TAG in volume_meta:
                    new_meta = {}
                    new_meta[REF_COUNT_TAG] = volume_meta[REF_COUNT_TAG] + 1
                    self.MetadataHandler.update_vdi_meta(dbg, uri, new_meta)
                else:
                    new_meta = {}
                    new_meta[REF_COUNT_TAG] = 1
                    call(dbg,
                         ['ln', '-s', _blkdev_,
                          self.gen_vol_path(dbg, uri)])
                    self.MetadataHandler.update_vdi_meta(dbg, uri, new_meta)
            except Exception as e:
                log.error(
                    "%s: xcpng.datapath.DatapathOperations.map_vol: Failed to map volume: uri: %s device: %s"
                    % (dbg, uri, _blkdev_))
                raise Exception(e)

    def unmap_vol(self, dbg, uri, chained=False):
        path = self.gen_vol_path(dbg, uri)

        if exists(path):
            log.debug(
                "%s: xcpng.datapath.DatapathOperations.unmap_vol: uri: %s" %
                (dbg, uri))
            try:
                volume_meta = self.MetadataHandler.get_vdi_meta(dbg, uri)
                if REF_COUNT_TAG in volume_meta:
                    new_meta = {}
                    if volume_meta[REF_COUNT_TAG] == 1:
                        new_meta[REF_COUNT_TAG] = None
                        call(dbg, ['unlink', path])
                    else:
                        new_meta[
                            REF_COUNT_TAG] = volume_meta[REF_COUNT_TAG] - 1
                    self.MetadataHandler.update_vdi_meta(dbg, uri, new_meta)

                if chained:
                    if PARENT_URI_TAG in volume_meta:
                        self.unmap_vol(dbg, volume_meta[PARENT_URI_TAG][0],
                                       chained)
            except Exception as e:
                log.error(
                    "%s: xcpng.datapath.DatapathOperations.unmap_vol: Failed to unmap volume: uri: %s"
                    % (dbg, uri))
                raise Exception(e)
Ejemplo n.º 5
0
class SR(object):
    def __init__(self):
        self.MetadataHandler = MetadataHandler()
        self.SROpsHendler = _SROperations_()
        self.sr_type = xapi.storage.libs.xcpng.globalvars.plugin_type

    def probe(self, dbg, configuration):
        log.debug("{}: xcpng.sr.SR.probe: configuration={}".format(
            dbg, configuration))

        if IMAGE_FORMAT_TAG in configuration:
            _uri_ = "%s+%s" % (self.sr_type, configuration[IMAGE_FORMAT_TAG])
            if DATAPATH_TAG in configuration:
                _uri_ = "%s+%s://" % (_uri_, configuration[DATAPATH_TAG])
        else:
            _uri_ = "%s://" % self.sr_type

        _uri_ = self.SROpsHendler.extend_uri(dbg, _uri_, configuration)

        uri = "%s/%s" % (_uri_, configuration[SR_UUID_TAG]
                         ) if SR_UUID_TAG in configuration else _uri_

        log.debug("{}: xcpng.sr.SR.probe: uri to probe: {}".format(dbg, uri))

        result = []
        known_srs = get_known_srs()

        try:
            srs = self.SROpsHendler.get_sr_list(dbg, uri, configuration)

            log.debug("%s: xcpng.sr.SR.probe: Available Pools" % dbg)
            log.debug(
                "%s: xcpng.sr.SR.probe: ---------------------------------------------------"
                % dbg)

            for _sr_ in srs:
                sr_uuid = get_sr_uuid_by_uri(dbg, _sr_)
                if sr_uuid not in known_srs:
                    sr_found = True

                    log.debug("%s: xcpng.sr.SR.probe: %s" % (dbg, _sr_))

                    configuration['mountpoint'] = "%s/%s" % (SR_PATH_PREFIX,
                                                             sr_uuid)

                    try:
                        self.SROpsHendler.sr_import(dbg, _sr_, configuration)
                        sr_meta = self.MetadataHandler.get_sr_meta(dbg, _sr_)
                    except Exception:
                        try:
                            self.SROpsHendler.sr_export(dbg, _sr_)
                        except:
                            pass
                        break

                    if (IMAGE_FORMAT_TAG in configuration and
                        ((CONFIGURATION_TAG in sr_meta
                          and IMAGE_FORMAT_TAG in sr_meta[CONFIGURATION_TAG]
                          and configuration[IMAGE_FORMAT_TAG] !=
                          sr_meta[CONFIGURATION_TAG][IMAGE_FORMAT_TAG]) or
                         (CONFIGURATION_TAG in sr_meta and IMAGE_FORMAT_TAG
                          not in sr_meta[CONFIGURATION_TAG])
                         or CONFIGURATION_TAG not in sr_meta)):
                        sr_found = False

                    if (DATAPATH_TAG in configuration and
                        ((CONFIGURATION_TAG in sr_meta
                          and DATAPATH_TAG in sr_meta[CONFIGURATION_TAG]
                          and configuration[DATAPATH_TAG] !=
                          sr_meta[CONFIGURATION_TAG][DATAPATH_TAG]) or
                         (CONFIGURATION_TAG in sr_meta
                          and DATAPATH_TAG not in sr_meta[CONFIGURATION_TAG])
                         or CONFIGURATION_TAG not in sr_meta)):
                        sr_found = False

                    if (SR_UUID_TAG in configuration and (
                        (CONFIGURATION_TAG in sr_meta
                         and SR_UUID_TAG in sr_meta[CONFIGURATION_TAG]
                         and configuration[SR_UUID_TAG] !=
                         sr_meta[CONFIGURATION_TAG][SR_UUID_TAG]) or
                        (CONFIGURATION_TAG in sr_meta
                         and SR_UUID_TAG not in sr_meta[CONFIGURATION_TAG]
                         and SR_UUID_TAG in sr_meta and
                         configuration[SR_UUID_TAG] != sr_meta[SR_UUID_TAG]) or
                        (CONFIGURATION_TAG not in sr_meta
                         and SR_UUID_TAG in sr_meta and
                         configuration[SR_UUID_TAG] != sr_meta[SR_UUID_TAG])
                            or SR_UUID_TAG not in sr_meta)):
                        sr_found = False

                    if SR_UUID_TAG in sr_meta and sr_meta[
                            SR_UUID_TAG] in known_srs:
                        sr_found = False

                    if SR_UUID_TAG not in sr_meta:
                        sr_found = False

                    if sr_found:
                        _result_ = {}
                        _result_['complete'] = True
                        _result_['configuration'] = {}
                        _result_['configuration'] = deepcopy(
                            sr_meta[CONFIGURATION_TAG])
                        # _result_['configuration'] = deepcopy(configuration)
                        _result_['extra_info'] = {}

                        sr = {}
                        sr['sr'] = _sr_
                        sr['name'] = sr_meta[NAME_TAG] if NAME_TAG in sr_meta \
                            else self.SROpsHendler.DEFAULT_SR_NAME
                        sr['description'] = sr_meta[DESCRIPTION_TAG] if DESCRIPTION_TAG in sr_meta \
                            else self.SROpsHendler.DEFAULT_SR_DESCRIPTION
                        sr['free_space'] = self.SROpsHendler.get_free_space(
                            dbg, _sr_)
                        sr['total_space'] = self.SROpsHendler.get_size(
                            dbg, _sr_)
                        sr['datasources'] = self.SROpsHendler.get_datasources(
                            dbg, _sr_)
                        sr['clustered'] = self.SROpsHendler.get_clustered(
                            dbg, _sr_)
                        sr['health'] = self.SROpsHendler.get_health(dbg, _sr_)

                        _result_['sr'] = sr
                        # _result_['configuration']['sr_uuid'] = sr_meta[SR_UUID_TAG]

                        result.append(_result_)

                        self.SROpsHendler.sr_export(dbg, _sr_)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.probe: Failed to probe SRs for configuration: %s"
                % (dbg, configuration))
            raise Exception(e)

        return result

    def create(self, dbg, sr_uuid, configuration, name, description):
        log.debug(
            "%s: xcpng.sr.SR.create: sr_uuid %s configuration %s name '%s' description: '%s'"
            % (dbg, sr_uuid, configuration, name, description))

        if IMAGE_FORMAT_TAG in configuration:
            uri = "%s+%s" % (self.sr_type, configuration[IMAGE_FORMAT_TAG])
            if DATAPATH_TAG in configuration:
                uri = "%s+%s://" % (uri, configuration[DATAPATH_TAG])
        else:
            uri = "%s://" % self.sr_type

        uri = self.SROpsHendler.extend_uri(dbg, uri, configuration)
        uri = "%s/%s" % (uri, sr_uuid)

        log.debug("%s: xcpng.sr.SR.create: uri %s" % (dbg, uri))

        configuration['mountpoint'] = "%s/%s" % (SR_PATH_PREFIX,
                                                 get_sr_uuid_by_uri(dbg, uri))

        try:
            call(dbg, ['mkdir', '-p', configuration['mountpoint']])

            self.SROpsHendler.create(dbg, uri, configuration)
            self.MetadataHandler.create(dbg, uri)

            configuration['sr_uuid'] = sr_uuid
            sr_meta = {
                SR_UUID_TAG: sr_uuid,
                NAME_TAG: name,
                DESCRIPTION_TAG: description,
                #CONFIGURATION_TAG: json.dumps(configuration)
                CONFIGURATION_TAG: configuration
            }

            self.MetadataHandler.update_sr_meta(dbg, uri, sr_meta)
            self.MetadataHandler.dump(dbg, uri)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.create: Failed to create SR - sr_uuid: %s" %
                (dbg, sr_uuid))
            try:
                self.SROpsHendler.destroy(dbg, uri)
            except:
                pass
            raise Exception(e)

        try:
            self.SROpsHendler.sr_export(dbg, uri)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.create: Created but failed to export SR after creation - sr_uuid: %s"
                "Please check and export SR manually before attaching the SR" %
                (dbg, sr_uuid))

        return configuration

    def destroy(self, dbg, uri):
        log.debug("%s: xcpng.sr.SR.destroy: uri: %s" % (dbg, uri))
        try:
            self.MetadataHandler.destroy(dbg, uri)
            self.SROpsHendler.destroy(dbg, uri)
            call(dbg, [
                'rm', '-rf',
                "%s/%s" % (SR_PATH_PREFIX, get_sr_uuid_by_uri(dbg, uri))
            ])
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.destroy: Failed to destroy SR - sr_uuid: %s" %
                (dbg, get_sr_uuid_by_uri(dbg, uri)))
            raise Exception(e)

    def attach(self, dbg, configuration):
        log.debug("%s: xcpng.sr.SR.attach: configuration: %s" %
                  (dbg, configuration))

        if IMAGE_FORMAT_TAG in configuration:
            uri = "%s+%s" % (self.sr_type, configuration[IMAGE_FORMAT_TAG])
            if DATAPATH_TAG in configuration:
                uri = "%s+%s://" % (uri, configuration[DATAPATH_TAG])
        else:
            uri = "%s://" % self.sr_type

        uri = self.SROpsHendler.extend_uri(dbg, uri, configuration)
        uri = "%s/%s" % (uri, configuration[SR_UUID_TAG]
                         ) if SR_UUID_TAG in configuration else uri

        log.debug("%s: xcpng.sr.SR.attach: uri: %s" % (dbg, uri))

        configuration['mountpoint'] = "%s/%s" % (SR_PATH_PREFIX,
                                                 get_sr_uuid_by_uri(dbg, uri))

        try:
            call(dbg, ['mkdir', '-p', configuration['mountpoint']])
            self.SROpsHendler.sr_import(dbg, uri, configuration)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.attach: Failed to attach SR - sr_uuid: %s" %
                (dbg, get_sr_uuid_by_uri(dbg, uri)))
            try:
                self.SROpsHendler.sr_export(dbg, uri)
                call(dbg, ['rm', '-rf', configuration['mountpoint']])
            except:
                pass
            raise Exception(e)

        return uri

    def detach(self, dbg, uri):
        log.debug("%s: xcpng.sr.SR.detach: uri: %s" % (dbg, uri))
        try:
            self.SROpsHendler.sr_export(dbg, uri)
            call(dbg, [
                'rm', '-rf',
                "%s/%s" % (SR_PATH_PREFIX, get_sr_uuid_by_uri(dbg, uri))
            ])
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.detach: Failed to detach SR - sr_uuid: %s" %
                (dbg, get_sr_uuid_by_uri(dbg, uri)))
            raise Exception(e)

    def stat(self, dbg, uri):
        log.debug("%s: xcpng.sr.SR.stat: uri: %s" % (dbg, uri))

        try:
            sr_meta = self.MetadataHandler.get_sr_meta(dbg, uri)
            log.debug("%s: xcpng.sr.SR.stat: pool_meta: %s" % (dbg, sr_meta))

            # Get the sizes
            tsize = self.SROpsHendler.get_size(dbg, uri)
            fsize = self.SROpsHendler.get_free_space(dbg, uri)
            log.debug(
                "%s: xcpng.sr.SR.stat total_space = %Ld free_space = %Ld" %
                (dbg, tsize, fsize))
        except Exception as e:
            log.error("%s: xcpng.sr.SR.stat: Failed to get stat for SR: %s" %
                      (dbg, uri))
            raise Exception(e)

        overprovision = 0

        return {
            'sr':
            uri,
            'uuid':
            get_sr_uuid_by_uri(dbg, uri),
            'name':
            sr_meta[NAME_TAG] if sr_meta[NAME_TAG] is not None else
            '' if NAME_TAG in sr_meta else self.SROpsHendler.DEFAULT_SR_NAME,
            'description':
            sr_meta[DESCRIPTION_TAG]
            if sr_meta[DESCRIPTION_TAG] is not None else '' if DESCRIPTION_TAG
            in sr_meta else self.SROpsHendler.DEFAULT_SR_DESCRIPTION,
            'total_space':
            tsize,
            'free_space':
            fsize,
            'overprovision':
            overprovision,
            'datasources':
            self.SROpsHendler.get_datasources(dbg, uri),
            'clustered':
            self.SROpsHendler.get_clustered(dbg, uri),
            'health':
            self.SROpsHendler.get_health(dbg, uri)
        }

    def set_name(self, dbg, uri, new_name):
        log.debug("%s: xcpng.sr.SR.set_name: SR: %s New_name: %s" %
                  (dbg, uri, new_name))

        sr_meta = {
            NAME_TAG: new_name,
        }

        try:
            self.MetadataHandler.update_sr_meta(dbg, uri, sr_meta)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.set_name: Failed to set name for SR: %s" %
                (dbg, uri))
            raise Exception(e)

    def set_description(self, dbg, uri, new_description):
        log.debug(
            "%s: xcpng.sr.SR.set_description: SR: %s New_description: %s" %
            (dbg, uri, new_description))

        sr_meta = {
            DESCRIPTION_TAG: new_description,
        }

        try:
            self.MetadataHandler.update_sr_meta(dbg, uri, sr_meta)
        except Exception as e:
            log.error(
                "%s: xcpng.sr.SR.set_description: Failed to set description for SR: %s"
                % (dbg, uri))
            raise Exception(e)

    def ls(self, dbg, uri):
        log.debug("%s: xcpng.sr.SR.ls: uri: %s" % (dbg, uri))

        results = []
        key = ''

        try:
            for volume in self.SROpsHendler.get_vdi_list(dbg, uri):
                log.debug("%s: xcpng.sr.SR.ls: SR: %s Volume: %s" %
                          (dbg, uri, volume))

                key = get_vdi_uuid_by_name(dbg, volume)

                log.debug("%s: xcpng.sr.SR.ls: SR: %s vdi : %s" %
                          (dbg, uri, key))

                volume_meta = self.MetadataHandler.get_vdi_meta(
                    dbg, "%s/%s" % (uri, key))

                results.append({
                    VDI_UUID_TAG:
                    volume_meta[VDI_UUID_TAG],
                    KEY_TAG:
                    volume_meta[KEY_TAG],
                    NAME_TAG:
                    volume_meta[NAME_TAG],
                    DESCRIPTION_TAG:
                    volume_meta[DESCRIPTION_TAG],
                    READ_WRITE_TAG:
                    volume_meta[READ_WRITE_TAG],
                    VIRTUAL_SIZE_TAG:
                    volume_meta[VIRTUAL_SIZE_TAG],
                    PHYSICAL_UTILISATION_TAG:
                    volume_meta[PHYSICAL_UTILISATION_TAG],
                    URI_TAG:
                    volume_meta[URI_TAG],
                    CUSTOM_KEYS_TAG:
                    volume_meta[CUSTOM_KEYS_TAG],
                    SHARABLE_TAG:
                    volume_meta[SHARABLE_TAG]
                })
            return results
        except Exception as e:
            log.error("%s: xcpng.sr.SR.ls: Failed to list of vdis for SR: %s" %
                      (dbg, uri))
            raise Exception(e)