Пример #1
0
    def resize_from_voldrv(volumename, volumesize, volumepath,
                           storagedriver_id):
        """
        Resize a disk
        Triggered by volumedriver messages on the queue

        @param volumepath: path on hypervisor to the volume
        @param volumename: volume id of the disk
        @param volumesize: size of the volume
        """
        pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id)
        storagedriver = StorageDriverList.get_by_storagedriver_id(
            storagedriver_id)
        hypervisor = Factory.get(pmachine)
        volumepath = hypervisor.clean_backing_disk_filename(volumepath)
        mutex = VolatileMutex('{}_{}'.format(volumename, volumepath))
        try:
            mutex.acquire(wait=30)
            disk = VDiskList.get_vdisk_by_volume_id(volumename)
            if disk is None:
                disk = VDiskList.get_by_devicename_and_vpool(
                    volumepath, storagedriver.vpool)
                if disk is None:
                    disk = VDisk()
        finally:
            mutex.release()
        disk.devicename = volumepath
        disk.volume_id = volumename
        disk.size = volumesize
        disk.vpool = storagedriver.vpool
        disk.save()
Пример #2
0
    def devicename_exists(self, vpool, name=None, names=None):
        """
        Checks whether a given name can be created on the vpool
        :param vpool: vPool object
        :type vpool: VPool
        :param name: Candidate name
        :type name: str
        :param names: Candidate names
        :type names: list
        :return: Whether the devicename exists
        :rtype: bool
        """
        error_message = None
        if not (name is None) ^ (names is None):
            error_message = 'Either the name (string) or the names (list of strings) parameter must be passed'
        if name is not None and not isinstance(name, basestring):
            error_message = 'The name parameter must be a string'
        if names is not None and not isinstance(names, list):
            error_message = 'The names parameter must be a list of strings'
        if error_message is not None:
            raise HttpNotAcceptableException(error_description=error_message,
                                             error='impossible_request')

        if name is not None:
            devicename = VDiskController.clean_devicename(name)
            return VDiskList.get_by_devicename_and_vpool(devicename,
                                                         vpool) is not None
        for name in names:
            devicename = VDiskController.clean_devicename(name)
            if VDiskList.get_by_devicename_and_vpool(devicename,
                                                     vpool) is not None:
                return True
        return False
Пример #3
0
    def devicename_exists(self, vpool, name=None, names=None):
        """
        Checks whether a given name can be created on the vpool
        :param vpool: vPool object
        :type vpool: VPool
        :param name: Candidate name
        :type name: str
        :param names: Candidate names
        :type names: list
        :return: Whether the devicename exists
        :rtype: bool
        """
        error_message = None
        if not (name is None) ^ (names is None):
            error_message = 'Either the name (string) or the names (list of strings) parameter must be passed'
        if name is not None and not isinstance(name, basestring):
            error_message = 'The name parameter must be a string'
        if names is not None and not isinstance(names, list):
            error_message = 'The names parameter must be a list of strings'
        if error_message is not None:
            raise HttpNotAcceptableException(error_description=error_message,
                                             error='impossible_request')

        if name is not None:
            devicename = VDiskController.clean_devicename(name)
            return VDiskList.get_by_devicename_and_vpool(devicename, vpool) is not None
        for name in names:
            devicename = VDiskController.clean_devicename(name)
            if VDiskList.get_by_devicename_and_vpool(devicename, vpool) is not None:
                return True
        return False
Пример #4
0
    def resize_from_voldrv(volumename, volumesize, volumepath, storagedriver_id):
        """
        Resize a disk
        Triggered by volumedriver messages on the queue

        @param volumepath: path on hypervisor to the volume
        @param volumename: volume id of the disk
        @param volumesize: size of the volume
        """
        pmachine = PMachineList.get_by_storagedriver_id(storagedriver_id)
        storagedriver = StorageDriverList.get_by_storagedriver_id(storagedriver_id)
        hypervisor = Factory.get(pmachine)
        volumepath = hypervisor.clean_backing_disk_filename(volumepath)
        mutex = VolatileMutex('{}_{}'.format(volumename, volumepath))
        try:
            mutex.acquire(wait=30)
            disk = VDiskList.get_vdisk_by_volume_id(volumename)
            if disk is None:
                disk = VDiskList.get_by_devicename_and_vpool(volumepath, storagedriver.vpool)
                if disk is None:
                    disk = VDisk()
        finally:
            mutex.release()
        disk.devicename = volumepath
        disk.volume_id = volumename
        disk.size = volumesize
        disk.vpool = storagedriver.vpool
        disk.save()
        VDiskController.sync_with_mgmtcenter(disk, pmachine, storagedriver)
        MDSServiceController.ensure_safety(disk)
Пример #5
0
def getVDisk(path, vpool=None, timeout=None):
    url = urlparse.urlparse(path)
    if url.netloc == "":
        path = path.replace("{}:".format(url.scheme),
                            "{}://".format(url.scheme))
        url = urlparse.urlparse(path)

    path = "/" + url.path.strip("/")
    path = path.split(":")[0]  # cause yeah putting nonestandard url params
    if not path.endswith(".raw"):
        path += ".raw"
    elif not url.scheme:
        parts = url.path.split("/")[1:]  # remove first slash
        if parts[0] == "mnt":
            vpool = parts[1]
            path = "/" + "/".join(parts[2:])

    vpool = _getVPoolByUrl(url, vpool)
    disk = VDiskList.get_by_devicename_and_vpool(path, vpool)
    if timeout is not None:
        start = time.time()
        while not disk and start + timeout > time.time():
            time.sleep(2)
            disk = VDiskList.get_by_devicename_and_vpool(path, vpool)
    return disk
Пример #6
0
    def test_sync_vdisk_with_voldrv(self):
        clone_depth = 3

        def _make_clones(vdisks_map, depth=clone_depth):
            for level in range(depth):
                previous_vd = list(vdisks_map.itervalues())[-1]
                new_name = previous_vd.name + '_clone'
                new_guid = VDiskController.clone(previous_vd.guid,
                                                 new_name).get('vdisk_guid')
                vdisks_map[new_name] = VDisk(new_guid)

        structure = DalHelper.build_dal_structure({
            'vpools': [1],
            'storagerouters': [1],
            'storagedrivers':
            [(1, 1, 1)],  # (<id>, <vpool_id>, <storagerouter_id>)
            'mds_services': [(1, 1)]
        }  # (<id>, <storagedriver_id>)
                                                  )
        vdisk_name = 'vdisk_1'
        storagedriver = structure['storagedrivers'][1]
        vdisk_1 = VDisk(
            VDiskController.create_new(volume_name=vdisk_name,
                                       volume_size=1024**4,
                                       storagedriver_guid=storagedriver.guid))
        vdisks = OrderedDict()
        vdisks[vdisk_name] = vdisk_1

        _make_clones(vdisks)
        self.assertEquals(clone_depth + 1, len(list(VDiskList.get_vdisks())))
        delete_list = list(vdisks.itervalues(
        ))[::-1][:-1]  # These vDisks are clones and ought to be deleted
        for vdisk in delete_list:
            for mds_service in vdisk.mds_services:
                mds_service.delete()
            vdisk.delete()
        self.assertEquals(1, len(list(VDiskList.get_vdisks()))
                          )  # Make sure vDisk clones are properly removed
        self.assertEquals(
            VDiskList.get_vdisks()[0].name,
            vdisk_name)  # Make sure only item left is original vDisk

        VDiskController.sync_with_reality()
        self.assertEquals(clone_depth + 1, len(list(
            VDiskList.get_vdisks())))  # The clones should be in place now

        parents = 0
        for vdisk in VDiskList.get_vdisks():
            try:
                if vdisk.parent_vdisk.name:
                    parents += 1
            except AttributeError:
                pass
        self.assertEquals(
            clone_depth, parents
        )  # As much parents should be detected as the depth of the clones
Пример #7
0
    def test_event_resize_from_volumedriver(self):
        """
        Test resize from volumedriver event
            - Create a vDisk using the resize event
            - Resize the created vDisk using the same resize event
        """
        structure = Helper.build_service_structure(
            {'vpools': [1],
             'storagerouters': [1],
             'storagedrivers': [(1, 1, 1)],  # (<id>, <vpool_id>, <storagerouter_id>)
             'mds_services': [(1, 1)]}  # (<id>, <storagedriver_id>)
        )
        vpools = structure['vpools']
        storagedrivers = structure['storagedrivers']
        mds_service = structure['mds_services'][1]

        # Create volume using resize from voldrv
        device_name = '/vdisk.raw'
        srclient = StorageRouterClient(vpools[1].guid, None)
        mds_backend_config = Helper._generate_mdsmetadatabackendconfig([mds_service])
        volume_id = srclient.create_volume(device_name, mds_backend_config, 1024 ** 4, str(storagedrivers[1].storagedriver_id))
        VDiskController.resize_from_voldrv(volume_id=volume_id,
                                           volume_size=1024 ** 4,
                                           volume_path=device_name,
                                           storagedriver_id=storagedrivers[1].storagedriver_id)
        vdisks = VDiskList.get_vdisks()
        self.assertTrue(expr=len(vdisks) == 1,
                        msg='Expected to find 1 vDisk in model')
        self.assertEqual(first=vdisks[0].name,
                         second='vdisk',
                         msg='Volume name should be vdisk')
        self.assertEqual(first=vdisks[0].volume_id,
                         second=volume_id,
                         msg='Volume ID should be {0}'.format(volume_id))
        self.assertEqual(first=vdisks[0].devicename,
                         second=device_name,
                         msg='Device name should be {0}'.format(device_name))
        self.assertEqual(first=vdisks[0].size,
                         second=1024 ** 4,
                         msg='Size should be 1 TiB')

        # Resize volume using resize from voldrv
        VDiskController.resize_from_voldrv(volume_id=volume_id,
                                           volume_size=2 * 1024 ** 4,
                                           volume_path=device_name,
                                           storagedriver_id=storagedrivers[1].storagedriver_id)
        vdisks = VDiskList.get_vdisks()
        self.assertTrue(expr=len(vdisks) == 1,
                        msg='Expected to find 1 vDisk in model')
        self.assertEqual(first=vdisks[0].name,
                         second='vdisk',
                         msg='Volume name should be vdisk')
        self.assertEqual(first=vdisks[0].size,
                         second=2 * 1024 ** 4,
                         msg='Size should be 2 TiB')
Пример #8
0
    def test_clone_from_template_happypath(self):
        """
        Test clone from template - happy path
        """
        StorageDriverModule.use_good_client()
        vdisk_1_1, pmachine = self._prepare()

        VDiskController.create_from_template(vdisk_1_1.guid, 'vmachine_2', 'vdisk_1_1-clone', pmachine.guid)

        vdisks = VDiskList.get_vdisk_by_name('vdisk_1_1')
        self.assertEqual(len(vdisks), 1, 'Vdisk not modeled')
        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertEqual(len(clones), 1, 'Clone not modeled')
Пример #9
0
    def test_clone_from_template_happypath(self):
        """
        Test clone from template - happy path
        """
        StorageDriverModule.use_good_client()
        vdisk_1_1, pmachine = self._prepare()

        VDiskController.create_from_template(vdisk_1_1.guid, 'vmachine_2',
                                             'vdisk_1_1-clone', pmachine.guid)

        vdisks = VDiskList.get_vdisk_by_name('vdisk_1_1')
        self.assertEqual(len(vdisks), 1, 'Vdisk not modeled')
        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertEqual(len(clones), 1, 'Clone not modeled')
Пример #10
0
    def update_vdisk_name(volume_id, old_name, new_name):
        """
        Update a vDisk name using Management Center: set new name
        """
        vdisk = None
        for mgmt_center in MgmtCenterList.get_mgmtcenters():
            mgmt = Factory.get_mgmtcenter(mgmt_center = mgmt_center)
            try:
                disk_info = mgmt.get_vdisk_device_info(volume_id)
                device_path = disk_info['device_path']
                vpool_name = disk_info['vpool_name']
                vp = VPoolList.get_vpool_by_name(vpool_name)
                file_name = os.path.basename(device_path)
                vdisk = VDiskList.get_by_devicename_and_vpool(file_name, vp)
                if vdisk:
                    break
            except Exception as ex:
                logger.info('Trying to get mgmt center failed for disk {0} with volume_id {1}. {2}'.format(old_name, volume_id, ex))
        if not vdisk:
            logger.error('No vdisk found for name {0}'.format(old_name))
            return

        vpool = vdisk.vpool
        mutex = VolatileMutex('{}_{}'.format(old_name, vpool.guid if vpool is not None else 'none'))
        try:
            mutex.acquire(wait=5)
            vdisk.name = new_name
            vdisk.save()
        finally:
            mutex.release()
Пример #11
0
    def get_vdisk_by_name(vdisk_name, vpool_name):
        """
        Fetch disk partitions by disk guid

        :param vdisk_name: location of a vdisk on a vpool
                           (e.g. /mnt/vpool/test.raw = test.raw, /mnt/vpool/volumes/test.raw = volumes/test.raw )
        :type vdisk_name: str
        :param vpool_name: name of a existing vpool
        :type vpool_name: str
        :return: a vdisk object
        :rtype: ovs.dal.hybrids.vdisk
        """

        vpool = VPoolList.get_vpool_by_name(vpool_name)
        if vpool:
            if not vdisk_name.startswith("/"):
                vdisk_name = "/{0}".format(vdisk_name)
            if not vdisk_name.endswith('.raw'):
                vdisk_name = '{0}.raw'.format(vdisk_name)
            vdisk = VDiskList.get_by_devicename_and_vpool(vdisk_name, vpool)
            if vdisk:
                return vdisk
            else:
                raise VDiskNotFoundError(
                    "VDisk with name `{0}` not found on vPool `{1}`!".format(
                        vdisk_name, vpool_name))
        else:
            raise VPoolNotFoundError(
                "vPool with name `{0}` cannot be found!".format(vpool_name))
Пример #12
0
 def _find_ovs_model_disk_by_location(self, location, hostname, retry=3,
                                      timeout=3):
     """Find OVS disk object based on location and hostname
     :return VDisk: OVS DAL model object
     """
     hostname = self._get_real_hostname(hostname)
     LOG.debug('[_FIND OVS DISK] Location %s, hostname %s'
               % (location, hostname))
     attempt = 0
     while attempt <= retry:
         for vd in VDiskList.get_vdisks():
             if vd.vpool:
                 for vsr in vd.vpool.storagedrivers:
                     if vsr.storagerouter.name == hostname:
                         _location = "{0}/{1}".format(vsr.mountpoint,
                                                      vd.devicename)
                         if _location == location:
                             LOG.info('Location %s Disk found %s'
                                      % (location, vd.guid))
                             disk = VDisk(vd.guid)
                             return disk
         msg = ' NO RESULT Attempt %s timeout %s max attempts %s'
         LOG.debug(msg % (attempt, timeout, retry))
         if timeout:
             time.sleep(timeout)
         attempt += 1
     raise RuntimeError('No disk found for location %s' % location)
Пример #13
0
    def delete_volume(vdisk, vpool, loop_device=None, root_client=None, wait=True):
        """
        Delete a volume
        :param vdisk: Virtual disk to delete
        :param vpool: vPool which hosts the Virtual Disk
        :param loop_device: Loop device where volume is mounted on
        :param root_client: SSHClient object
        :param wait: Wait for the volume to be deleted from model
        :return: None
        """
        location = GeneralVDisk.get_filesystem_location(vpool=vpool,
                                                        vdisk_name=vdisk.name)
        if root_client is None:
            root_client = SSHClient('127.0.0.1', username='******')

        if loop_device is not None:
            GeneralVDisk.disconnect_volume(loop_device, root_client)
        root_client.file_delete(location)

        if wait is True:
            counter = 0
            timeout = 60
            volume_name = '/' + os.path.basename(location)
            while True and counter < timeout:
                time.sleep(1)
                vdisks = VDiskList.get_by_devicename_and_vpool(volume_name, vpool)
                if vdisks is None:
                    break
                counter += 1
            if counter == timeout:
                raise RuntimeError('Disk {0} was not deleted from model after {1} seconds'.format(volume_name, timeout))
Пример #14
0
 def list(self, vpoolguid=None, storagerouterguid=None, query=None):
     """
     Overview of all vDisks
     :param vpoolguid: Guid of the vPool to retrieve its disks
     :type vpoolguid: str
     :param storagerouterguid: Guid of the StorageRouter to retrieve its disks
     :type storagerouterguid: str
     :param query: A query to be executed if required
     :type query: DataQuery
     """
     if vpoolguid is not None:
         vpool = VPool(vpoolguid)
         vdisks = vpool.vdisks
     elif storagerouterguid is not None:
         storagerouter = StorageRouter(storagerouterguid)
         vdisks = DataList(
             VDisk, {
                 'type':
                 DataList.where_operator.AND,
                 'items': [('guid', DataList.operator.IN,
                            storagerouter.vdisks_guids)]
             })
     else:
         vdisks = VDiskList.get_vdisks()
     if query is not None:
         query_vdisk_guids = DataList(VDisk, query).guids
         vdisks = [
             vdisk for vdisk in vdisks if vdisk.guid in query_vdisk_guids
         ]
     return vdisks
Пример #15
0
    def update_vdisk_name(volume_id, old_name, new_name):
        """
        Update a vDisk name using Management Center: set new name
        """
        vdisk = None
        for mgmt_center in MgmtCenterList.get_mgmtcenters():
            mgmt = Factory.get_mgmtcenter(mgmt_center=mgmt_center)
            try:
                disk_info = mgmt.get_vdisk_device_info(volume_id)
                device_path = disk_info['device_path']
                vpool_name = disk_info['vpool_name']
                vp = VPoolList.get_vpool_by_name(vpool_name)
                file_name = os.path.basename(device_path)
                vdisk = VDiskList.get_by_devicename_and_vpool(file_name, vp)
                if vdisk:
                    break
            except Exception as ex:
                logger.info(
                    'Trying to get mgmt center failed for disk {0} with volume_id {1}. {2}'
                    .format(old_name, volume_id, ex))
        if not vdisk:
            logger.error('No vdisk found for name {0}'.format(old_name))
            return

        vpool = vdisk.vpool
        mutex = VolatileMutex('{}_{}'.format(
            old_name, vpool.guid if vpool is not None else 'none'))
        try:
            mutex.acquire(wait=5)
            vdisk.name = new_name
            vdisk.save()
        finally:
            mutex.release()
Пример #16
0
 def get_vdisk_by_name(name):
     """
     Retrieve the DAL vDisk object based on its name
     :param name: Name of the virtual disk
     :return: vDisk DAL object
     """
     return VDiskList.get_vdisk_by_name(vdiskname=name)
Пример #17
0
    def create_new(diskname, size, storagedriver_guid):
        """
        Create a new vdisk/volume using filesystem calls
        :param diskname: name of the disk
        :param size: size of the disk (GB)
        :param storagedriver_guid: guid of the Storagedriver
        :return: guid of the new disk
        """
        logger.info('Creating new empty disk {0} of {1} GB'.format(diskname, size))
        storagedriver = StorageDriver(storagedriver_guid)
        vp_mountpoint = storagedriver.mountpoint
        hypervisor = Factory.get(storagedriver.storagerouter.pmachine)
        disk_path = hypervisor.clean_backing_disk_filename(hypervisor.get_disk_path(None, diskname))
        location = os.path.join(vp_mountpoint, disk_path)
        VDiskController.create_volume(location, size)

        backoff = 1
        timeout = 30  # seconds
        start = time.time()
        while time.time() < start + timeout:
            vdisk = VDiskList.get_by_devicename_and_vpool(disk_path, storagedriver.vpool)
            if vdisk is None:
                logger.debug('Waiting for disk to be picked up by voldrv')
                time.sleep(backoff)
                backoff += 1
            else:
                return vdisk.guid
        raise RuntimeError('Disk {0} was not created in {1} seconds.'.format(diskname, timeout))
Пример #18
0
 def delete_from_voldrv(volumename, storagedriver_id):
     """
     Delete a disk
     Triggered by volumedriver messages on the queue
     @param volumename: volume id of the disk
     """
     _ = storagedriver_id  # For logging purposes
     disk = VDiskList.get_vdisk_by_volume_id(volumename)
     if disk is not None:
         mutex = VolatileMutex('{}_{}'.format(volumename, disk.devicename))
         try:
             mutex.acquire(wait=20)
             pmachine = None
             try:
                 pmachine = PMachineList.get_by_storagedriver_id(disk.storagedriver_id)
             except RuntimeError as ex:
                 if 'could not be found' not in str(ex):
                     raise
                 # else: pmachine can't be loaded, because the volumedriver doesn't know about it anymore
             if pmachine is not None:
                 limit = 5
                 hypervisor = Factory.get(pmachine)
                 exists = hypervisor.file_exists(disk.vpool, disk.devicename)
                 while limit > 0 and exists is True:
                     time.sleep(1)
                     exists = hypervisor.file_exists(disk.vpool, disk.devicename)
                     limit -= 1
                 if exists is True:
                     logger.info('Disk {0} still exists, ignoring delete'.format(disk.devicename))
                     return
             logger.info('Delete disk {}'.format(disk.name))
             disk.delete()
         finally:
             mutex.release()
Пример #19
0
 def snapshot_all_vdisks():
     """
     Snapshots all vDisks
     """
     GenericController._logger.info('[SSA] started')
     success = []
     fail = []
     for vdisk in VDiskList.get_vdisks():
         if vdisk.is_vtemplate is True:
             continue
         try:
             metadata = {
                 'label': '',
                 'is_consistent': False,
                 'timestamp': str(int(time.time())),
                 'is_automatic': True,
                 'is_sticky': False
             }
             VDiskController.create_snapshot(vdisk_guid=vdisk.guid,
                                             metadata=metadata)
             success.append(vdisk.guid)
         except Exception:
             GenericController._logger.exception(
                 'Error taking snapshot for vDisk {0}'.format(vdisk.guid))
             fail.append(vdisk.guid)
     GenericController._logger.info(
         '[SSA] Snapshot has been taken for {0} vDisks, {1} failed.'.format(
             len(success), len(fail)))
     return success, fail
Пример #20
0
 def list(self, vpoolguid=None, storagerouterguid=None, query=None):
     """
     Overview of all vDisks
     :param vpoolguid: Guid of the vPool to retrieve its disks
     :type vpoolguid: str
     :param storagerouterguid: Guid of the StorageRouter to retrieve its disks
     :type storagerouterguid: str
     :param query: A query to be executed if required
     :type query: DataQuery
     """
     if vpoolguid is not None:
         vpool = VPool(vpoolguid)
         vdisks = vpool.vdisks
     elif storagerouterguid is not None:
         storagerouter = StorageRouter(storagerouterguid)
         vdisks = DataList(
             VDisk,
             {
                 "type": DataList.where_operator.AND,
                 "items": [("guid", DataList.operator.IN, storagerouter.vdisks_guids)],
             },
         )
     else:
         vdisks = VDiskList.get_vdisks()
     if query is not None:
         query_vdisk_guids = DataList(VDisk, query).guids
         vdisks = [vdisk for vdisk in vdisks if vdisk.guid in query_vdisk_guids]
     return vdisks
Пример #21
0
 def list(self, vpoolguid=None, storagerouterguid=None):
     """
     Overview of all vDisks
     :param vpoolguid: Guid of the vPool to retrieve its disks
     :type vpoolguid: str
     :param storagerouterguid: Guid of the StorageRouter to retrieve its disks
     :type storagerouterguid: str
     :return: List of vDisks matching the parameters specified
     :rtype: list[ovs.dal.hybrids.vdisk.VDisk]
     """
     if vpoolguid is not None:
         vpool = VPool(vpoolguid)
         vdisks = vpool.vdisks
     elif storagerouterguid is not None:
         storagerouter = StorageRouter(storagerouterguid)
         vdisks = DataList(
             VDisk, {
                 'type':
                 DataList.where_operator.AND,
                 'items': [('guid', DataList.operator.IN,
                            storagerouter.vdisks_guids)]
             })
     else:
         vdisks = VDiskList.get_vdisks()
     return vdisks
Пример #22
0
 def _find_ovs_model_disk_by_location(self,
                                      location,
                                      hostname,
                                      retry=3,
                                      timeout=3):
     """Find OVS disk object based on location and hostname
     :return VDisk: OVS DAL model object
     """
     hostname = self._get_real_hostname(hostname)
     LOG.debug('[_FIND OVS DISK] Location %s, hostname %s' %
               (location, hostname))
     attempt = 0
     while attempt <= retry:
         for vd in VDiskList.get_vdisks():
             if vd.vpool:
                 for vsr in vd.vpool.storagedrivers:
                     if vsr.storagerouter.name == hostname:
                         _location = "{0}/{1}".format(
                             vsr.mountpoint, vd.devicename)
                         if _location == location:
                             LOG.info('Location %s Disk found %s' %
                                      (location, vd.guid))
                             disk = VDisk(vd.guid)
                             return disk
         msg = ' NO RESULT Attempt %s timeout %s max attempts %s'
         LOG.debug(msg % (attempt, timeout, retry))
         if timeout:
             time.sleep(timeout)
         attempt += 1
     raise RuntimeError('No disk found for location %s' % location)
Пример #23
0
 def volumedriver_error(code, volumename):
     """
     Handles error messages/events from the volumedriver
     """
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volumename)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #24
0
 def volumedriver_error(code, volumename, storagedriver_id):
     """
     Handles error messages/events from the volumedriver
     """
     _ = storagedriver_id  # Required for the @log decorator
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volumename)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #25
0
 def volumedriver_error(code, volumename, storagedriver_id):
     """
     Handles error messages/events from the volumedriver
     """
     _ = storagedriver_id  # Required for the @log decorator
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volumename)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #26
0
    def test_delete(self):
        """
        Test the delete of a vDisk
            - Create 2 vDisks with identical names on 2 different vPools
            - Delete 1st vDisk and verify other still remains on correct vPool
            - Delete 2nd vDisk and verify no more volumes left
        """
        structure = DalHelper.build_dal_structure({
            'vpools': [1, 2],
            'domains': [1],
            'storagerouters': [1],
            'storagedrivers':
            [(1, 1, 1), (2, 2, 1)],  # (<id>, <vpool_id>, <storagerouter_id>)
            'mds_services': [(1, 1), (2, 2)]
        }  # (<id>, <storagedriver_id>)
                                                  )
        domains = structure['domains']
        storagedrivers = structure['storagedrivers']

        vdisk1 = VDisk(
            VDiskController.create_new(
                volume_name='vdisk_1',
                volume_size=1024**3,
                storagedriver_guid=storagedrivers[1].guid))
        vdisk2 = VDisk(
            VDiskController.create_new(
                volume_name='vdisk_1',
                volume_size=1024**3,
                storagedriver_guid=storagedrivers[2].guid))

        vdisk_domain = VDiskDomain()
        vdisk_domain.domain = domains[1]
        vdisk_domain.vdisk = vdisk1
        vdisk_domain.save()

        # Delete vDisk1 and make some assertions
        VDiskController.delete(vdisk_guid=vdisk1.guid)
        with self.assertRaises(ObjectNotFoundException):
            VDisk(vdisk1.guid)
        self.assertEqual(
            first=len(VDiskController.list_volumes()),
            second=1,
            msg='Expected to find only 1 volume in Storage Driver list_volumes'
        )
        self.assertIn(member=vdisk2,
                      container=VDiskList.get_vdisks(),
                      msg='vDisk2 should still be modeled')

        # Delete vDisk2 and make some assertions
        VDiskController.delete(vdisk_guid=vdisk2.guid)
        with self.assertRaises(ObjectNotFoundException):
            VDisk(vdisk2.guid)
        self.assertEqual(
            first=len(VDiskController.list_volumes()),
            second=0,
            msg=
            'Expected to find no more volumes in Storage Driver list_volumes')
Пример #27
0
 def _snapshot_has_children(self, snapshotid):
     """Find if snapshot has children, in OVS Model
     :return True/False
     """
     LOG.debug('[_FIND CHILDREN OF SNAPSHOT] Snapshotid %s' % snapshotid)
     for vdisk in VDiskList.get_vdisks():
         if vdisk.parentsnapshot == snapshotid:
             return True
     return False
Пример #28
0
 def _snapshot_has_children(self, snapshotid):
     """Find if snapshot has children, in OVS Model
     :return True/False
     """
     LOG.debug('[_FIND CHILDREN OF SNAPSHOT] Snapshotid %s' % snapshotid)
     for vdisk in VDiskList.get_vdisks():
         if vdisk.parentsnapshot == snapshotid:
             return True
     return False
Пример #29
0
 def volumedriver_error(code, volumename):
     """
     Handles error messages/events from the volumedriver
     :param code: Volumedriver error code
     :param volumename: Name of the volume throwing the error
     """
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volumename)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #30
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageDriver.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     volume_ids = []
     for entry in self.vpool.objectregistry_client.get_all_registrations():
         if entry.node_id() == self.storagedriver_id:
             volume_ids.append(entry.object_id())
     return VDiskList.get_in_volume_ids(volume_ids).guids
Пример #31
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageRouter.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     vdisk_guids = []
     for storagedriver in self.storagedrivers:
         storagedriver_client = storagedriver.vpool.storagedriver_client
         vdisk_guids += VDiskList.get_in_volume_ids(storagedriver_client.list_volumes(str(storagedriver.storagedriver_id))).guids
     return vdisk_guids
Пример #32
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageRouter.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     vdisk_guids = []
     for storagedriver in self.storagedrivers:
         storagedriver_client = storagedriver.vpool.storagedriver_client
         vdisk_guids += VDiskList.get_in_volume_ids(storagedriver_client.list_volumes(str(storagedriver.storagedriver_id))).guids
     return vdisk_guids
Пример #33
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageDriver.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     volume_ids = []
     for entry in self.vpool.objectregistry_client.get_all_registrations():
         if entry.node_id() == self.storagedriver_id:
             volume_ids.append(entry.object_id())
     return VDiskList.get_in_volume_ids(volume_ids).guids
Пример #34
0
    def test_clone_from_template_error_handling(self):
        """
        Test clone from template - error during create
        """
        StorageDriverModule.use_bad_client()
        vdisk_1_1, pmachine = self._prepare()

        self.assertRaises(RuntimeError, VDiskController.create_from_template, vdisk_1_1.guid, 'vmachine_2', 'vdisk_1_1-clone', pmachine.guid)

        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertIsNone(clones, 'Clone not deleted after exception')
Пример #35
0
 def list(self, vmachineguid=None, vpoolguid=None):
     """
     Overview of all vDisks
     """
     if vmachineguid is not None:
         vmachine = VMachine(vmachineguid)
         return vmachine.vdisks
     elif vpoolguid is not None:
         vpool = VPool(vpoolguid)
         return vpool.vdisks
     return VDiskList.get_vdisks()
 def _find_ovs_model_disk_by_snapshot_id(self, snapshotid):
     """Find OVS disk object based on snapshot id
     :return VDisk: OVS DAL model object
     """
     LOG.debug("[_FIND OVS DISK] Snapshotid %s" % snapshotid)
     for disk in VDiskList.get_vdisks():
         snaps_guid = [s["guid"] for s in disk.snapshots]
         if str(snapshotid) in snaps_guid:
             LOG.info("[_FIND OVS DISK] Snapshot id %s Disk found %s" % (snapshotid, disk.name))
             return disk
     raise RuntimeError("No disk found for snapshotid %s" % snapshotid)
Пример #37
0
 def _ovs_snapshot_id_in_vdisklist_snapshots(self, snapshot_id, retry=10):
     attempt = 0
     while attempt <= int(retry):
         snap_map = dict((vd.guid, vd.snapshots) for vd in VDiskList.get_vdisks())
         for guid, snapshots in snap_map.items():
             snaps = [snap['guid'] for snap in snapshots if snap['guid'] == snapshot_id]
             if len(snaps) == 1:
                 return True
         attempt += 1
         time.sleep(2)
     return False
Пример #38
0
    def test_list_volumes(self):
        """
        Test the list volumes functionality
            - Create 1 vDisk on vPool1 and create 3 vDisks on vPool2
            - List all volumes
            - List the volumes on vPool1
            - List the volumes on vPool2
        """
        structure = Helper.build_service_structure(
            {'vpools': [1, 2],
             'storagerouters': [1],
             'storagedrivers': [(1, 1, 1), (2, 2, 1)],  # (<id>, <vpool_id>, <storagerouter_id>)
             'mds_services': [(1, 1), (2, 2)]}  # (<id>, <storagedriver_id>)
        )
        vpools = structure['vpools']
        storagedrivers = structure['storagedrivers']

        vpool1 = vpools[1]
        vpool2 = vpools[2]
        VDiskController.create_new(volume_name='vdisk_1', volume_size=1024 ** 4, storagedriver_guid=storagedrivers[1].guid)
        VDiskController.create_new(volume_name='vdisk_1', volume_size=1024 ** 4, storagedriver_guid=storagedrivers[2].guid)
        VDiskController.create_new(volume_name='vdisk_2', volume_size=1024 ** 4, storagedriver_guid=storagedrivers[2].guid)
        VDiskController.create_new(volume_name='vdisk_3', volume_size=1024 ** 4, storagedriver_guid=storagedrivers[2].guid)
        all_vdisks = VDiskList.get_vdisks()

        # List all volumes
        sd_volume_ids = set(VDiskController.list_volumes())
        model_volume_ids = set([vdisk.volume_id for vdisk in all_vdisks])
        self.assertEqual(first=len(sd_volume_ids),
                         second=4,
                         msg='Expected to retrieve all 4 volumes')
        self.assertEqual(first=sd_volume_ids,
                         second=model_volume_ids,
                         msg='Volume IDs from Storage Driver not identical to volume IDs in model. SD: {0}  -  Model: {1}'.format(sd_volume_ids, model_volume_ids))

        # List all volumes of vpools[1]
        sd_vpool1_volume_ids = set(VDiskController.list_volumes(vpool_guid=vpool1.guid))
        model_vpool1_volume_ids = set([vdisk.volume_id for vdisk in all_vdisks if vdisk.vpool == vpool1])
        self.assertEqual(first=len(sd_vpool1_volume_ids),
                         second=1,
                         msg='Expected to retrieve 1 volume')
        self.assertEqual(first=sd_vpool1_volume_ids,
                         second=model_vpool1_volume_ids,
                         msg='Volume IDs for vPool1 from Storage Driver not identical to volume IDs in model. SD: {0}  -  Model: {1}'.format(sd_vpool1_volume_ids, model_vpool1_volume_ids))

        # List all volumes of vpools[2]
        sd_vpool2_volume_ids = set(VDiskController.list_volumes(vpool_guid=vpool2.guid))
        model_vpool2_volume_ids = set([vdisk.volume_id for vdisk in all_vdisks if vdisk.vpool == vpool2])
        self.assertEqual(first=len(sd_vpool2_volume_ids),
                         second=3,
                         msg='Expected to retrieve 3 volumes')
        self.assertEqual(first=sd_vpool2_volume_ids,
                         second=model_vpool2_volume_ids,
                         msg='Volume IDs for vPool2 from Storage Driver not identical to volume IDs in model. SD: {0}  -  Model: {1}'.format(sd_vpool2_volume_ids, model_vpool2_volume_ids))
Пример #39
0
 def list(self, vmachineguid=None, vpoolguid=None):
     """
     Overview of all vDisks
     """
     if vmachineguid is not None:
         vmachine = VMachine(vmachineguid)
         return vmachine.vdisks
     elif vpoolguid is not None:
         vpool = VPool(vpoolguid)
         return vpool.vdisks
     return VDiskList.get_vdisks()
Пример #40
0
 def _ovs_snapshot_id_in_vdisklist_snapshots(self, snapshot_id, retry=10):
     attempt = 0
     while attempt <= int(retry):
         snap_map = dict((vd.guid, vd.snapshots) for vd in VDiskList.get_vdisks())
         for guid, snapshots in snap_map.items():
             snaps = [snap['guid'] for snap in snapshots if snap['guid'] == snapshot_id]
             if len(snaps) == 1:
                 return True
         attempt += 1
         time.sleep(2)
     return False
Пример #41
0
 def volumedriver_error(code, volumename, storagedriver_id):
     """
     Handles error messages/events from the volumedriver
     :param code: Volumedriver error code
     :param volumename: Name of the volume throwing the error
     :param storagedriver_id: ID of the storagedriver hosting the volume
     """
     _ = storagedriver_id  # Required for the @log decorator
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volumename)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #42
0
 def _find_ovs_model_disk_by_snapshot_id(self, snapshotid):
     """Find OVS disk object based on snapshot id
     :return VDisk: OVS DAL model object
     """
     LOG.debug('[_FIND OVS DISK] Snapshotid %s' % snapshotid)
     for disk in VDiskList.get_vdisks():
         snaps_guid = [s['guid'] for s in disk.snapshots]
         if str(snapshotid) in snaps_guid:
             LOG.info('[_FIND OVS DISK] Snapshot id %s Disk found %s' %
                      (snapshotid, disk))
             return disk
     raise RuntimeError('No disk found for snapshotid %s' % snapshotid)
    def get_vdisks_stats():
        """
        Send vdisks statistics to InfluxDB
        """
        vdisks = VDiskList.get_vdisks()
        if len(vdisks) == 0:
            StatsmonkeyScheduledTaskController._logger.info("No vdisks found")
            return None

        for vdisk in vdisks:
            try:
                points = []
                metrics = StatsmonkeyScheduledTaskController._pop_realtime_info(vdisk.statistics)

                disk_name = vdisk.name
                failover_mode = vdisk.info['failover_mode']

                if failover_mode in ['OK_STANDALONE', 'OK_SYNC']:
                    failover_status = 0
                elif failover_mode == 'CATCHUP':
                    failover_status = 1
                elif failover_mode == 'DEGRADED':
                    failover_status = 2
                else:
                    failover_status = 3

                metrics['failover_mode_status'] = failover_status

                if vdisk.vmachine:
                    vm_name = vdisk.vmachine.name
                else:
                    vm_name = None

                vpool_name = VPool(vdisk.vpool_guid).name

                entry = {
                    'measurement': 'vdisk_stats',
                    'tags': {
                        'disk_name': disk_name,
                        'vm_name': vm_name,
                        'storagerouter_name': StorageRouter(vdisk.storagerouter_guid).name,
                        'vpool_name': vpool_name,
                        'failover_mode': vdisk.info['failover_mode']
                    },
                    'fields': metrics
                }
                points.append(entry)
                StatsmonkeyScheduledTaskController._send_stats(points)
                return points
            except Exception as ex:
                StatsmonkeyScheduledTaskController._logger.error(ex.message)
                return None
            return None
Пример #44
0
 def _vmachines_guids(self):
     """
     Gets the vMachine guids served by this StorageRouter.
     Definition of "served by": vMachine whose disks are served by a given StorageRouter
     """
     from ovs.dal.lists.vdisklist import VDiskList
     vmachine_guids = set()
     for storagedriver in self.storagedrivers:
         storagedriver_client = storagedriver.vpool.storagedriver_client
         for vdisk in VDiskList.get_in_volume_ids(storagedriver_client.list_volumes(str(storagedriver.storagedriver_id))):
             if vdisk.vmachine_guid is not None:
                 vmachine_guids.add(vdisk.vmachine_guid)
     return list(vmachine_guids)
Пример #45
0
 def list(self, vmachineguid=None, vpoolguid=None):
     """
     Overview of all vDisks
     :param vmachineguid: Guid of the virtual machine to retrieve its disks
     :param vpoolguid: Guid of the vPool to retrieve its disks
     """
     if vmachineguid is not None:
         vmachine = VMachine(vmachineguid)
         return vmachine.vdisks
     elif vpoolguid is not None:
         vpool = VPool(vpoolguid)
         return vpool.vdisks
     return VDiskList.get_vdisks()
Пример #46
0
 def list(self, vmachineguid=None, vpoolguid=None):
     """
     Overview of all vDisks
     :param vmachineguid: Guid of the virtual machine to retrieve its disks
     :param vpoolguid: Guid of the vPool to retrieve its disks
     """
     if vmachineguid is not None:
         vmachine = VMachine(vmachineguid)
         return vmachine.vdisks
     elif vpoolguid is not None:
         vpool = VPool(vpoolguid)
         return vpool.vdisks
     return VDiskList.get_vdisks()
Пример #47
0
    def test_clone_from_template_error_handling(self):
        """
        Test clone from template - error during create
        """
        StorageDriverModule.use_bad_client()
        vdisk_1_1, pmachine = self._prepare()

        self.assertRaises(RuntimeError, VDiskController.create_from_template,
                          vdisk_1_1.guid, 'vmachine_2', 'vdisk_1_1-clone',
                          pmachine.guid)

        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertIsNone(clones, 'Clone not deleted after exception')
Пример #48
0
 def _vmachines_guids(self):
     """
     Gets the vMachine guids served by this StorageRouter.
     Definition of "served by": vMachine whose disks are served by a given StorageRouter
     """
     from ovs.dal.lists.vdisklist import VDiskList
     vmachine_guids = set()
     for storagedriver in self.storagedrivers:
         storagedriver_client = storagedriver.vpool.storagedriver_client
         for vdisk in VDiskList.get_in_volume_ids(storagedriver_client.list_volumes(str(storagedriver.storagedriver_id))):
             if vdisk.vmachine_guid is not None:
                 vmachine_guids.add(vdisk.vmachine_guid)
     return list(vmachine_guids)
Пример #49
0
 def volumedriver_error(code, volume_id):
     """
     Handles error messages/events from the volumedriver
     :param code: Volumedriver error code
     :type code: int
     :param volume_id: Name of the volume throwing the error
     :type volume_id: str
     :return: None
     """
     if code == VolumeDriverEvents.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volume_id)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #50
0
 def volumedriver_error(code, volume_id):
     """
     Handles error messages/events from the volumedriver
     :param code: Volumedriver error code
     :type code: int
     :param volume_id: Name of the volume throwing the error
     :type volume_id: str
     :return: None
     """
     if code == VolumeDriverEvents_pb2.MDSFailover:
         disk = VDiskList.get_vdisk_by_volume_id(volume_id)
         if disk is not None:
             MDSServiceController.ensure_safety(disk)
Пример #51
0
def getVDisk(path, vpool=None, timeout=None):
    url = urlparse.urlparse(path)
    if url.netloc == '':
        path = path.replace('{}:'.format(url.scheme), '{}://'.format(url.scheme))
        url = urlparse.urlparse(path)

    path = '/' + url.path.strip('/')
    path = path.split(':')[0] # cause yeah putting nonestandard url params 
    if not path.endswith('.raw'):
        path += '.raw'
    elif not url.scheme:
        parts = url.path.split('/')[1:]  # remove first slash
        if parts[0] == 'mnt':
            vpool = parts[1]
            path = '/' + '/'.join(parts[2:])

    vpool = _getVPoolByUrl(url, vpool)
    disk = VDiskList.get_by_devicename_and_vpool(path, vpool)
    if timeout is not None:
        start = time.time()
        while not disk and start + timeout > time.time():
            time.sleep(2)
            disk = VDiskList.get_by_devicename_and_vpool(path, vpool)
    return disk
Пример #52
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageRouter.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     volume_ids = []
     vpools = set()
     storagedriver_ids = []
     for storagedriver in self.storagedrivers:
         vpools.add(storagedriver.vpool)
         storagedriver_ids.append(storagedriver.storagedriver_id)
     for vpool in vpools:
         for entry in vpool.objectregistry_client.get_all_registrations():
             if entry.node_id() in storagedriver_ids:
                 volume_ids.append(entry.object_id())
     return VDiskList.get_in_volume_ids(volume_ids).guids
Пример #53
0
 def _vdisks_guids(self):
     """
     Gets the vDisk guids served by this StorageRouter.
     """
     from ovs.dal.lists.vdisklist import VDiskList
     volume_ids = []
     vpools = set()
     storagedriver_ids = []
     for storagedriver in self.storagedrivers:
         vpools.add(storagedriver.vpool)
         storagedriver_ids.append(storagedriver.storagedriver_id)
     for vpool in vpools:
         for entry in vpool.objectregistry_client.get_all_registrations():
             if entry.node_id() in storagedriver_ids:
                 volume_ids.append(entry.object_id())
     return VDiskList.get_in_volume_ids(volume_ids).guids
Пример #54
0
    def create_volume(size, vpool, name=None, loop_device=None, root_client=None, wait=True):
        """
        Create a volume
        :param size: Size of the volume (in GB)
        :param vpool: vPool to create a volume for
        :param name: Name for the volume
        :param loop_device: Loop device to use to mount volume on
        :param root_client: SSHClient object
        :param wait: Wait for the volume to be created on volumedriver and in model
        :return: Newly created Virtual Disk
        """
        location = GeneralVDisk.get_filesystem_location(vpool=vpool,
                                                        vdisk_name=name if name is not None else uuid.uuid4())
        if root_client is None:
            root_client = SSHClient('127.0.0.1', username='******')

        try:
            if loop_device is not None:
                root_client.run('umount /mnt/{0}'.format(loop_device), allow_nonzero=True, allow_insecure=True)
                root_client.run(['truncate', '-s', '{0}G'.format(size), location])
                root_client.dir_create(['/mnt/{0}'.format(loop_device)])
                root_client.run(['mkfs.ext4', '-F', location])
                root_client.run(['mount', '-o', 'loop', location, '/mnt/{0}'.format(loop_device)])
            else:
                root_client.run(['truncate', '-s', '{0}G'.format(size), location])
        except CalledProcessError as cpe:
            GeneralVDisk.logger.error(str(cpe))
            if loop_device is not None:
                root_client.run('umount /mnt/{0}'.format(loop_device), allow_nonzero=True, allow_insecure=True)
                root_client.run('rm {0}'.format(location), allow_nonzero=True, allow_insecure=True)
                root_client.run('rmdir /mnt/{0}'.format(loop_device), allow_nonzero=True, allow_insecure=True)
            raise

        vdisk = None
        if wait is True:
            counter = 0
            timeout = 60
            volume_name = '/' + os.path.basename(location)
            while True and counter < timeout:
                time.sleep(1)
                vdisk = VDiskList.get_by_devicename_and_vpool(volume_name, vpool)
                if vdisk is not None:
                    break
                counter += 1
            if counter == timeout:
                raise RuntimeError('Disk {0} did not show up in model after {1} seconds'.format(volume_name, timeout))
        return vdisk
Пример #55
0
    def mds_catchup():
        """
        Looks to catch up all MDS slaves which are too far behind
        Only one catch for every storagedriver is invoked
        """

        # Only for caching purposes
        def storagedriver_worker(queue, error_list):
            # type: (Queue.Queue, List[str]) -> None
            while not queue.empty():
                mds_catch_up = queue.get()  # type: MDSCatchUp
                try:
                    mds_catch_up.catch_up(async=False)
                except Exception as ex:
                    MDSServiceController._logger.exception(
                        'Exceptions while catching for vDisk {0}'.format(
                            mds_catch_up.vdisk.guid))
                    error_list.append(str(ex))
                finally:
                    queue.task_done()

        storagedriver_queues = {}
        for vdisk in VDiskList.get_vdisks():
            if vdisk.storagedriver_id not in storagedriver_queues:
                storagedriver_queues[vdisk.storagedriver_id] = Queue.Queue()
            # Putting it in the Queue ensures that the reference is still there so the caching is used optimally
            catch_up = MDSCatchUp(vdisk.guid)
            storagedriver_queues[vdisk.storagedriver_id].put(catch_up)

        errors = []
        threads = []
        for storadriver_id, storagedriver_queue in storagedriver_queues.iteritems(
        ):
            thread = Thread(target=storagedriver_worker,
                            args=(
                                storagedriver_queue,
                                errors,
                            ))
            thread.start()
            threads.append(thread)
        for thread in threads:
            thread.join()

        if len(errors) > 0:
            raise RuntimeError(
                'Exception occurred while catching up: \n - {0}'.format(
                    '\n - '.join(errors)))
Пример #56
0
    def test_clone_from_template_error_handling2(self):
        """
        Test clone from template - error during create, then error during delete
        """
        StorageDriverModule.use_bad_client()
        global VDisk
        def delete(self, *args, **kwargs):
            raise RuntimeError('DAL Error')
        _delete = VDisk.delete
        VDisk.delete = delete
        vdisk_1_1, pmachine = self._prepare()

        self.assertRaises(RuntimeError, VDiskController.create_from_template, vdisk_1_1.guid, 'vmachine_2', 'vdisk_1_1-clone', pmachine.guid)

        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertEqual(len(clones), 1, 'Clone deleted')
        VDisk.delete = _delete
Пример #57
0
 def dtl_state_transition(volume_name, old_state, new_state, storagedriver_id):
     """
     Triggered by volumedriver when DTL state changes
     :param volume_name: ID of the volume
     :param old_state: Previous DTL status
     :param new_state: New DTL status
     :param storagedriver_id: ID of the storagedriver hosting the volume
     :return: None
     """
     if new_state == VolumeDriverEvents_pb2.Degraded and old_state != VolumeDriverEvents_pb2.Standalone:
         vdisk = VDiskList.get_vdisk_by_volume_id(volume_name)
         if vdisk:
             logger.info('Degraded DTL detected for volume {0} with guid {1}'.format(vdisk.name, vdisk.guid))
             storagedriver = StorageDriverList.get_by_storagedriver_id(storagedriver_id)
             VDiskController.dtl_checkup(vdisk_guid=vdisk.guid,
                                         storagerouters_to_exclude=[storagedriver.storagerouter.guid],
                                         chain_timeout=600)
Пример #58
0
 def _ovs_devicename_in_vdisklist(self, devicename, exists = True, retry=10):
     if devicename is None:
         raise RuntimeError('Devicename is None, expecting a string.')
     self._debug('find device {0} in ovs model'.format(devicename))
     attempt = 0
     while attempt <= int(retry):
         self._get_vpool()
         vdisk = VDiskList.get_by_devicename_and_vpool(devicename, self.vpool)
         if exists:
             if vdisk is not None:
                 return True
         else:
             if vdisk is None:
                 return True
         self._debug('not found, sleep 1')
         attempt += 1
         time.sleep(2)
     self._debug('still not found, return')
     return False
Пример #59
0
 def delete_from_voldrv(volumename, storagedriver_id):
     """
     Delete a disk
     Triggered by volumedriver messages on the queue
     @param volumename: volume id of the disk
     """
     _ = storagedriver_id  # For logging purposes
     disk = VDiskList.get_vdisk_by_volume_id(volumename)
     if disk is not None:
         mutex = VolatileMutex('{}_{}'.format(volumename, disk.devicename))
         try:
             mutex.acquire(wait=20)
             pmachine = None
             try:
                 pmachine = PMachineList.get_by_storagedriver_id(
                     disk.storagedriver_id)
             except RuntimeError as ex:
                 if 'could not be found' not in str(ex):
                     raise
                 # else: pmachine can't be loaded, because the volumedriver doesn't know about it anymore
             if pmachine is not None:
                 limit = 5
                 storagedriver = StorageDriverList.get_by_storagedriver_id(
                     storagedriver_id)
                 hypervisor = Factory.get(pmachine)
                 exists = hypervisor.file_exists(storagedriver,
                                                 disk.devicename)
                 while limit > 0 and exists is True:
                     time.sleep(1)
                     exists = hypervisor.file_exists(
                         storagedriver, disk.devicename)
                     limit -= 1
                 if exists is True:
                     logger.info(
                         'Disk {0} still exists, ignoring delete'.format(
                             disk.devicename))
                     return
             logger.info('Delete disk {}'.format(disk.name))
             for mds_service in disk.mds_services:
                 mds_service.delete()
             disk.delete()
         finally:
             mutex.release()
Пример #60
0
    def test_clone_from_template_error_handling2(self):
        """
        Test clone from template - error during create, then error during delete
        """
        StorageDriverModule.use_bad_client()
        global VDisk

        def delete(self, *args, **kwargs):
            raise RuntimeError('DAL Error')

        _delete = VDisk.delete
        VDisk.delete = delete
        vdisk_1_1, pmachine = self._prepare()

        self.assertRaises(RuntimeError, VDiskController.create_from_template,
                          vdisk_1_1.guid, 'vmachine_2', 'vdisk_1_1-clone',
                          pmachine.guid)

        clones = VDiskList.get_vdisk_by_name('vdisk_1_1-clone')
        self.assertEqual(len(clones), 1, 'Clone deleted')
        VDisk.delete = _delete