Пример #1
0
 def create_vdisks(cls,
                   storagedriver,
                   amount_vdisks=AMOUNT_VDISKS_TO_SCRUB,
                   size=SIZE_VDISK,
                   cloned=False):
     vpool = storagedriver.vpool
     cls.LOGGER.info(
         "Start deploying vdisks for scrubbing with clone status: {0}".
         format(cloned))
     vdisks = {
         'parents': [],  # Non cloned
         'clones': []
     }  # Cloned
     if cloned is True:
         parent_vdisk_name = '{0}_clone_parent_{1}'.format(
             cls.PREFIX,
             str(0).zfill(3))
         parent_vdisk_guid = VDiskSetup.create_vdisk(
             vdisk_name=parent_vdisk_name,
             vpool_name=vpool.name,
             size=size,
             storagerouter_ip=storagedriver.storagerouter.ip)
         parent_vdisk = VDiskHelper.get_vdisk_by_guid(parent_vdisk_guid)
         vdisks['parents'].append(parent_vdisk)
         for vdisk_nr in xrange(amount_vdisks):
             clone_vdisk_name = '{0}_clone{1}'.format(
                 parent_vdisk.name,
                 str(len(vdisks['clones']) + 1).zfill(3))
             cloned_vdisk = VDiskHelper.get_vdisk_by_guid(
                 VDiskSetup.create_clone(
                     vdisk_name=parent_vdisk_name,
                     vpool_name=vpool.name,
                     new_vdisk_name=clone_vdisk_name,
                     storagerouter_ip=storagedriver.storagerouter.ip)
                 ['vdisk_guid'])
             vdisks['clones'].append(cloned_vdisk)
     else:
         for vdisk_nr in xrange(amount_vdisks):
             vdisk_name = '{0}_{1}'.format(cls.PREFIX,
                                           str(vdisk_nr).zfill(3))
             vdisk_guid = VDiskSetup.create_vdisk(
                 vdisk_name=vdisk_name,
                 vpool_name=vpool.name,
                 size=size,
                 storagerouter_ip=storagedriver.storagerouter.ip)
             vdisk = VDiskHelper.get_vdisk_by_guid(vdisk_guid)
             vdisks['parents'].append(vdisk)
     return vdisks
Пример #2
0
    def create_cloned_volume(self, volume, src_vref):
        """
        Creates a clone of the specified volume.

        :param volume: new volume object
        :param src_vref: source volume object
        """
        source_volume_name = self.VOLUME_PREFIX + str(src_vref.id)
        new_volume_name = self.VOLUME_PREFIX + str(volume.id)
        LOG.debug('libovsvolumedriver.ovs_clone new={0} source={1}'.format(
            volume.id, src_vref.id))

        api = self._setup_ovs_client()
        # pick a random storagerouter to deploy the new clone on
        storagerouter_ip = random.choice([
            sr
            for sr in StoragerouterHelper.get_storagerouters(api=api).values()
            if self.vpool_guid in sr['vpools_guids']
        ])
        VDiskSetup.create_clone(vdisk_name=source_volume_name,
                                new_vdisk_name=new_volume_name,
                                storagerouter_ip=storagerouter_ip,
                                api=api,
                                vpool_guid=self.vpool_guid)

        # return volume location
        storage_ip = VDiskHelper.get_vdisk_location_by_name(
            vdisk_name=new_volume_name, vpool_guid=self.vpool_guid,
            api=api)['storage_ip']
        location = self._get_volume_location(volume_name=new_volume_name,
                                             storage_ip=storage_ip)
        volume['provider_location'] = location
        return {'provider_location': volume['provider_location']}
Пример #3
0
 def _validate_dal(values):
     """
     Validates the move test. Checks for dal changes
     :param values: dict with values to validate if they updated
     :type values: dict
     :return:
     """
     # Fetch them from the dal
     source_std = StoragedriverHelper.get_storagedriver_by_guid(values['source_std']['guid'])
     target_std = StoragedriverHelper.get_storagedriver_by_guid(values['target_std']['guid'])  # Should not have moved to here
     for serialized_vdisk in values['vdisks']:
         vdisk = VDiskHelper.get_vdisk_by_guid(serialized_vdisk['guid'])
         # Expecting no changes in vdisks_guids
         if vdisk.guid in source_std.vdisks_guids:
             EdgeTester.LOGGER.info('Vdisks were not moved according the DAL.')
         else:
             raise ValueError('Vdisks were moved according the DAL.')
         if vdisk.guid not in target_std.vdisks_guids:
             EdgeTester.LOGGER.info('Vdisks were not moved to the target according the DAL.')
         else:
             raise ValueError('Vdisks guids were updated after move for target storagedriver.')
         if vdisk.storagerouter_guid == source_std.storagerouter.guid:
             EdgeTester.LOGGER.info('Owner has remained the same.')
         else:
             ValueError('Expected {0} but found {1} for vdisk.storagerouter_guid'.format(source_std.storagerouter.guid, vdisk.storagerouter_guid))
Пример #4
0
    def create_volume_from_snapshot(self, volume, snapshot):
        """
        Creates a volume from a snapshot.

        :param volume: new volume object
        :param snapshot: existing snapshot object
        """

        new_volume_name = self.VOLUME_PREFIX + str(volume.id)

        api = self._setup_ovs_client()
        # pick a random storagerouter to deploy the new clone on
        storagerouter_ip = random.choice([
            sr
            for sr in StoragerouterHelper.get_storagerouters(api=api).values()
            if self.vpool_guid in sr['vpools_guids']
        ])
        VDiskSetup.create_clone(new_vdisk_name=new_volume_name,
                                storagerouter_ip=storagerouter_ip,
                                api=api,
                                vpool_guid=self.vpool_guid,
                                snapshot_name=snapshot['name'])

        # return volume location
        storage_ip = VDiskHelper.get_vdisk_location_by_name(
            vdisk_name=new_volume_name, vpool_guid=self.vpool_guid,
            api=api)['storage_ip']
        location = self._get_volume_location(volume_name=new_volume_name,
                                             storage_ip=storage_ip)
        volume['provider_location'] = location

        LOG.debug('libovsvolumedriver.ovs_clone_from_snapshot {0} '.format(
            volume.id))
        return {'provider_location': volume['provider_location']}
Пример #5
0
 def _validate_dal(values):
     """
     Validates the move test. Checks for dal changes
     :param values: dict with values to validate if they updated
     :type values: dict
     :return:
     """
     # Fetch them from the dal
     source_std = StoragedriverHelper.get_storagedriver_by_guid(
         values['source_std']['guid'])
     target_std = StoragedriverHelper.get_storagedriver_by_guid(
         values['target_std']['guid'])
     vdisk = VDiskHelper.get_vdisk_by_guid(values['vdisk']['guid'])
     if values['source_std'] == source_std.serialize():
         # DAL values did not update - expecting a change in vdisks_guids
         raise ValueError(
             'Expecting the target Storagedriver to change but nothing happened...'
         )
     else:
         # Expecting changes in vdisks_guids
         if vdisk.guid in source_std.vdisks_guids:
             raise ValueError(
                 'Vdisks guids were not updated after move for source storagedriver.'
             )
         else:
             MigrateTester.LOGGER.info(
                 'All properties are updated for source storagedriver.')
     if values['target_std'] == target_std.serialize():
         raise ValueError(
             'Expecting changes in the target Storagedriver but nothing changed.'
         )
     else:
         if vdisk.guid not in target_std.vdisks_guids:
             raise ValueError(
                 'Vdisks guids were not updated after move for target storagedriver.'
             )
         else:
             MigrateTester.LOGGER.info(
                 'All properties are updated for target storagedriver.')
     if values["vdisk"] == vdisk.serialize():
         raise ValueError(
             'Expecting changes in the vdisk but nothing changed.')
     else:
         if vdisk.storagerouter_guid == target_std.storagerouter.guid:
             MigrateTester.LOGGER.info(
                 'All properties are updated for vdisk.')
         else:
             ValueError(
                 'Expected {0} but found {1} for vdisk.storagerouter_guid'.
                 format(vdisk.storagerouter_guid, vdisk.storagerouter_guid))
     MigrateTester.LOGGER.info(
         'Move vdisk was successful according to the dal (which fetches volumedriver info).'
     )
Пример #6
0
    def restore_backup(self, context, backup, volume, backup_service):
        """
        Restore an existing backup to a new or existing volume.
        """

        volume_name = self.VOLUME_PREFIX + str(volume.id)
        backup_snapshot_name = self.SNAPSHOT_BACKUP_PREFIX + str(backup['id'])
        LOG.debug('libovsvolumedriver.ovs_backup_restore {0} {1}'.format(
            volume_name, backup_snapshot_name))

        api = self._setup_ovs_client()
        snapshot, vdisk_guid, vdisk_name = VDiskHelper.get_snapshot_by_name(
            snapshot_name=backup_snapshot_name,
            vpool_guid=self.vpool_guid,
            api=api)
        if vdisk_name == volume_name:
            # rollback
            VDiskSetup.rollback_to_snapshot(vpool_guid=self.vpool_guid,
                                            snapshot_name=backup_snapshot_name,
                                            api=api)
        else:
            # to new volume
            storagerouter_ip = random.choice([
                sr for sr in StoragerouterHelper.get_storagerouters(
                    api=api).values() if self.vpool_guid in sr['vpools_guids']
            ])
            VDiskSetup.create_clone(vpool_guid=self.vpool_guid,
                                    new_vdisk_name=volume_name,
                                    storagerouter_ip=storagerouter_ip,
                                    api=api,
                                    snapshot_name=backup_snapshot_name)

            # return volume location
            storage_ip = VDiskHelper.get_vdisk_location_by_name(
                vdisk_name=volume_name, vpool_guid=self.vpool_guid,
                api=api)['storage_ip']
            location = self._get_volume_location(volume_name=volume_name,
                                                 storage_ip=storage_ip)
            volume['provider_location'] = location
            return {'provider_location': volume['provider_location']}
Пример #7
0
    def _check_vdisk(vdisk_name,
                     vpool_name,
                     timeout=VDISK_CHECK_TIMEOUT,
                     times=VDISK_CHECK_AMOUNT):
        """
        Check if a certain vdisk exists

        :param vdisk_name: name of a created vdisk (without file extension suffix)
        :type vdisk_name: str
        :param vpool_name: name of existing vpool
        :type vpool_name: str
        :param timeout: timeout during check of a newly created vdisk
        :type timeout: int
        :param times: check x amount of times with a timeout (total max time = timeout * times)
        :type times: int
        :return: does the vdisk exists after total max time
        :rtype: bool
        """

        for i in xrange(times):
            try:
                VDiskHelper.get_vdisk_by_name(vdisk_name=vdisk_name + '.raw',
                                              vpool_name=vpool_name)
            except VDiskNotFoundError:
                VDiskDeploymentChecks.LOGGER.info(
                    "VDisk with name `{0}` on vPool `{1}` not yet found, "
                    "sleeping for {2} seconds. Try {3}/{4}".format(
                        vdisk_name, vpool_name, timeout, i + 1, times))
                time.sleep(timeout)
            else:
                VDiskDeploymentChecks.LOGGER.info(
                    "VDisk with name `{0}` on vPool `{1}` found on try {2}/{3} "
                    "after {4} seconds".format(vdisk_name, vpool_name, i + 1,
                                               times, i + 1 * timeout))
                return True
        raise VDiskNotFoundError(
            "VDisk with name {0} has not been found on vPool {1} after {2} seconds"
            .format(vdisk_name, vpool_name, times * timeout))
Пример #8
0
 def _validate_scrubbing(vdisk_stored_mapper,
                         amount_checks=MAX_SCRUBBING_CHECKS,
                         timeout=SCRUBBING_TIMEOUT):
     """
     Execute and validate if given vdisks have been scrubbed
     :param vdisk_stored_mapper: vdisks that have been deployed to be scrubbed
     :type vdisk_stored_mapper: dict
     :param amount_checks: amount of times to check if stored data has changed
     :type amount_checks: int
     :param timeout: specify a timeout
     :type timeout: int
     :return:
     """
     # start scrubbing and check if scrubbed
     ScrubbingChecks.LOGGER.info("Execute scrub command.")
     VPoolSetup.execute_scrubbing()
     for vdisk_guid, vdisk_stored in vdisk_stored_mapper.iteritems():
         # check if scrubbing has worked
         vdisk = VDiskHelper.get_vdisk_by_guid(vdisk_guid)
         tries = 0
         while tries < amount_checks:
             current_statistics = vdisk.storagedriver_client.info_volume(
                 str(vdisk.volume_id)).stored
             if current_statistics < vdisk_stored:
                 ScrubbingChecks.LOGGER.info(
                     "VDisk `{0}` matched the requirements for scrubbing with {1} < {2}"
                     .format(vdisk_guid, current_statistics, vdisk_stored))
                 break
             else:
                 tries += 1
                 ScrubbingChecks.LOGGER.warning(
                     "Try `{0}` when checking stored data on volumedriver for VDisk `{1}`,"
                     " with currently `{2}` but it should be less than `{3}`. "
                     "Now sleeping for `{4}` seconds ...".format(
                         tries, vdisk_guid, current_statistics,
                         vdisk_stored, timeout))
                 time.sleep(timeout)
         # check if amount of tries has exceeded
         if tries == amount_checks:
             error_msg = "VDisk `{0}` should have been scrubbed but stored data > {1}`".format(
                 vdisk_guid, vdisk_stored)
             ScrubbingChecks.LOGGER.error(error_msg)
             raise RuntimeError(error_msg)
Пример #9
0
 def _start_scrubbing(cls, volume_bundle, logger):
     """
     Starts scrubbing and will be offloaded into a seperate thread
     :param volume_bundle: volume information
     :return: Asynchronous result of a CeleryTask
     :rtype: celery.result.AsyncResult
     """
     vdisk_task_mapping = {}
     error_msgs = []
     for vdisk_name, vdisk_object in volume_bundle.iteritems():
         vdisk_task_mapping[vdisk_object.guid] = VDiskHelper.scrub_vdisk(vdisk_object.guid, wait=False)  # Tasks are launched but not checked upon
     for vdisk_name, vdisk_object in volume_bundle.iteritems():
         logger.debug('Waiting for vdisk {0}s task to finish scrubbing.'.format(vdisk_name))
         task_result = cls.api.wait_for_task(vdisk_task_mapping[vdisk_object.guid])
         if not task_result[0]:
             error_msg = "Scrubbing vDisk `{0}` has failed with error {1}".format(vdisk_name, task_result[1])
             logger.error(error_msg)
             error_msgs.append(error_msg)
     return error_msgs
Пример #10
0
 def _get_vdisk(vdisk_name, vpool_name, timeout=60, logger=LOGGER):
     """
     Gets a vdisk that might take a while to be registered in the DAL due to events or other reasons
     Keeps polling until the timeout has been reached before throwing
     :param vdisk_name: devicename of the vdisk
     :param vpool_name: name of the vpool
     :param timeout: time to poll before raising
     :param logger: logging instance
     :return: 
     """
     vdisk = None
     start = time.time()
     while vdisk is None:
         if time.time() - start > timeout:
             raise VDiskNotFoundError(
                 'Could not fetch the vdisk after {}s'.format(time.time() -
                                                              start))
         try:
             vdisk = VDiskHelper.get_vdisk_by_name(vdisk_name, vpool_name)
         except VDiskNotFoundError:
             logger.warning('Could not fetch the vdisk after {0}s.'.format(
                 time.time() - start))
         time.sleep(0.5)
     return vdisk
Пример #11
0
    def validate_vdisk_clone(cls):
        """
        Validate if vdisk deployment works via various ways
        INFO: 1 vPool should be available on 2 storagerouters
        :return:
        """
        cls.LOGGER.info("Starting to validate clone vdisks")
        vpools = VPoolHelper.get_vpools()
        assert len(vpools) >= 1, "Not enough vPools to test"
        try:
            vpool = next(
                (vpool for vpool in vpools if len(vpool.storagedrivers) >= 2))
        except StopIteration:
            assert False, "Not enough Storagedrivers to test"
        # Setup base information
        storagedriver_source = vpool.storagedrivers[0]
        storagedriver_destination = vpool.storagedrivers[1]

        vdisks = []
        try:
            # Create required vdisk for test
            original_vdisk_name = '{0}_{1}'.format(cls.PREFIX, str(1).zfill(3))
            cls.LOGGER.info(
                "Creating the vdisk: {0} to clone".format(original_vdisk_name))
            original_vdisk = VDiskHelper.get_vdisk_by_guid(
                VDiskSetup.create_vdisk(
                    vdisk_name=original_vdisk_name,
                    vpool_name=vpool.name,
                    size=cls.VDISK_SIZE,
                    storagerouter_ip=storagedriver_source.storagerouter.ip))
            vdisks.append(original_vdisk)
            time.sleep(cls.CLONE_SLEEP_AFTER_CREATE)
            ###############
            # Clone vdisk #
            ###############
            cloned_vdisk_name = original_vdisk_name + '-clone-nosnapshot'
            cloned_vdisk = VDiskHelper.get_vdisk_by_guid(
                VDiskSetup.create_clone(
                    vdisk_name=original_vdisk_name,
                    vpool_name=vpool.name,
                    new_vdisk_name=cloned_vdisk_name,
                    storagerouter_ip=storagedriver_destination.storagerouter.ip
                )['vdisk_guid'])
            vdisks.append(cloned_vdisk)
            time.sleep(cls.CLONE_SLEEP_BEFORE_CHECK)
            ######################################
            # clone vdisk from existing snapshot #
            ######################################
            cloned_vdisk_name = original_vdisk_name + '-clone-snapshot'
            snapshot_id = VDiskSetup.create_snapshot(
                vdisk_name=original_vdisk_name,
                vpool_name=vpool.name,
                snapshot_name=cls.PREFIX + 'snapshot')
            cloned_vdisk = VDiskHelper.get_vdisk_by_guid(
                VDiskSetup.create_clone(
                    vdisk_name=original_vdisk_name,
                    vpool_name=vpool.name,
                    new_vdisk_name=cloned_vdisk_name,
                    storagerouter_ip=storagedriver_destination.storagerouter.
                    ip,
                    snapshot_id=snapshot_id)['vdisk_guid'])
            vdisks.append(cloned_vdisk)
        finally:
            VDiskRemover.remove_vdisks_with_structure(vdisks)
        cls.LOGGER.info("Finished validating clone vdisks")
Пример #12
0
    def prepare_vm_disks(self,
                         source_storagedriver,
                         cloud_image_path,
                         cloud_init_loc,
                         vm_name,
                         data_disk_size,
                         edge_user_info=None,
                         logger=LOGGER):
        """
        Will create all necessary vdisks to create the bulk of vms
        :param source_storagedriver: storagedriver to create the disks on
        :param cloud_image_path: path to the cloud image
        :param cloud_init_loc: path to the cloud init script
        :param vm_name: name prefix for the vms
        :param data_disk_size: size of the data disk
        :param edge_user_info: user information for the edge. Optional
        :param logger: logging instance
        :return: 
        """
        logger.info('Starting with preparing vm disk(s)')
        vm_amount = self.amount_of_vms
        if isinstance(edge_user_info, dict):
            required_edge_params = {
                'username': (str, None, False),
                'password': (str, None, False)
            }
            ExtensionsToolbox.verify_required_params(required_edge_params,
                                                     edge_user_info)
        if edge_user_info is None:
            edge_user_info = {}

        protocol = source_storagedriver.cluster_node_config[
            'network_server_uri'].split(':')[0]
        vpool = source_storagedriver.vpool
        client = SSHClient(source_storagedriver.storagerouter, username='******')

        edge_configuration = {
            'ip': source_storagedriver.storage_ip,
            'port': source_storagedriver.ports['edge'],
            'protocol': protocol
        }
        edge_configuration.update(edge_user_info)

        original_boot_disk_name = None  # Cloning purposes
        original_data_disk_name = None  # Cloning purposes

        connection_messages = []
        vm_info = {}
        volume_amount = 0

        for vm_number in xrange(0, vm_amount):
            filled_number = str(vm_number).zfill(3)
            vm_name = '{0}-{1}'.format(vm_name, filled_number)
            create_msg = '{0}_{1}'.format(str(uuid.uuid4()), vm_name)
            boot_vdisk_name = '{0}_vdisk_boot_{1}'.format(
                vm_name, filled_number)
            data_vdisk_name = '{0}_vdisk_data_{1}'.format(
                vm_name, filled_number)
            cd_vdisk_name = '{0}_vdisk_cd_{1}'.format(vm_name, filled_number)
            boot_vdisk_path = '/mnt/{0}/{1}.raw'.format(
                vpool.name, boot_vdisk_name)
            data_vdisk_path = '/mnt/{0}/{1}.raw'.format(
                vpool.name, data_vdisk_name)
            cd_vdisk_path = '/mnt/{0}/{1}.raw'.format(vpool.name,
                                                      cd_vdisk_name)
            if vm_number == 0:
                try:
                    # Create VDISKs
                    self.convert_image(client, cloud_image_path,
                                       boot_vdisk_name, edge_configuration)
                except RuntimeError as ex:
                    logger.error('Could not covert the image. Got {0}'.format(
                        str(ex)))
                    raise
                boot_vdisk = VDiskHelper.get_vdisk_by_name(
                    '{0}.raw'.format(boot_vdisk_name), vpool.name)
                original_boot_disk_name = boot_vdisk_name
                logger.info('Boot VDisk successfully created.')
                try:
                    data_vdisk = VDiskHelper.get_vdisk_by_guid(
                        VDiskSetup.create_vdisk(
                            data_vdisk_name, vpool.name, data_disk_size,
                            source_storagedriver.storage_ip))
                    logger.info('VDisk data_vdisk successfully created!')
                except TimeOutError:
                    logger.error(
                        'The creation of the data vdisk has timed out.')
                    raise
                except RuntimeError as ex:
                    logger.error(
                        'Could not create the data vdisk. Got {0}'.format(
                            str(ex)))
                    raise
                original_data_disk_name = data_vdisk_name
            else:
                # Rely on cloning to speed up the process
                boot_vdisk_info = VDiskSetup.create_clone(
                    vdisk_name=original_boot_disk_name,
                    vpool_name=vpool.name,
                    new_vdisk_name=boot_vdisk_name,
                    storagerouter_ip=source_storagedriver.storage_ip)
                boot_vdisk = VDiskHelper.get_vdisk_by_guid(
                    boot_vdisk_info['vdisk_guid'])
                data_vdisk_info = VDiskSetup.create_clone(
                    vdisk_name=original_data_disk_name,
                    vpool_name=vpool.name,
                    new_vdisk_name=data_vdisk_name,
                    storagerouter_ip=source_storagedriver.storage_ip)
                data_vdisk = VDiskHelper.get_vdisk_by_guid(
                    data_vdisk_info['vdisk_guid'])
            #######################
            # GENERATE CLOUD INIT #
            #######################
            iso_loc = self._generate_cloud_init(
                client=client,
                convert_script_loc=cloud_init_loc,
                create_msg=create_msg)
            self.convert_image(client, iso_loc, cd_vdisk_name,
                               edge_configuration)
            cd_creation_time = time.time()
            cd_vdisk = None
            while cd_vdisk is None:
                if time.time() - cd_creation_time > 60:
                    raise RuntimeError(
                        'Could not fetch the cd vdisk after {}s'.format(
                            time.time() - cd_creation_time))
                try:
                    cd_vdisk = VDiskHelper.get_vdisk_by_name(
                        cd_vdisk_name, vpool.name)
                except VDiskNotFoundError:
                    logger.warning(
                        'Could not fetch the cd vdisk after {0}s.'.format(
                            time.time() - cd_creation_time))
                time.sleep(0.5)

            # Take snapshot to revert back to after every migrate scenario
            data_snapshot_guid = VDiskSetup.create_snapshot(
                '{0}_data'.format(vm_name),
                data_vdisk.devicename,
                vpool.name,
                consistent=False)
            vm_info[vm_name] = {
                'data_snapshot_guid':
                data_snapshot_guid,
                'vdisks': [boot_vdisk, data_vdisk, cd_vdisk],
                'cd_path':
                cd_vdisk_path,
                'disks': [{
                    'mountpoint': boot_vdisk_path
                }, {
                    'mountpoint': data_vdisk_path
                }],
                'networks': [{
                    'network': 'default',
                    'mac': 'RANDOM',
                    'model': 'e1000'
                }],
                'created':
                False,
                'ip':
                '',
                'create_msg':
                create_msg
            }
            connection_messages.append(create_msg)
            volume_amount += len(vm_info[vm_name]['vdisks'])
            logger.info('Prepped everything for VM {0}.'.format(vm_name))

        self.vm_info = vm_info
        self.connection_messages = connection_messages
        self.volume_amount = volume_amount
Пример #13
0
    def _rollback_vdisks(cls,
                         stored_vdisks,
                         vpool,
                         amount_checks=MAX_ROLLBACK_CHECKS,
                         timeout=ROLLBACK_TIMEOUT):
        """
        Rollback the given mapped vdisks

        :param stored_vdisks: dict with stored vdisks, snapshot, location, ...
        :type stored_vdisks: dict
        :param vpool: a valid vpool object
        :type vpool: ovs.model.hybrids.vpool
        :param amount_checks: amount of checks to perform after a vdisk has been rolled back
        :type amount_checks: int
        :param timeout: timeout between checks
        :type timeout: int
        :return: None
        """

        for stored_vdisk in stored_vdisks:
            # fetch vdisk
            vdisk = VDiskHelper.get_vdisk_by_guid(
                vdisk_guid=stored_vdisk['vdisk_guid'])

            # Commencing rollback
            cls.LOGGER.info(
                "Starting rollback on vdisk `{0}` to first snapshot `{1}`".
                format(vdisk.name, stored_vdisk['snapshots'][0]))

            VDiskSetup.rollback_to_snapshot(
                vdisk_name=vdisk.name + '.raw',
                vpool_name=vpool.name,
                snapshot_id=stored_vdisk['snapshots'][0]['snapshot_guid'])

            # Start checking when disk is rollback'ed
            tries = 0
            while tries < amount_checks:
                current_statistics = vdisk.storagedriver_client.info_volume(
                    str(vdisk.volume_id)).stored
                if current_statistics < stored_vdisk['snapshots'][1][
                        'stored_data']:
                    cls.LOGGER.info(
                        "VDisk `{0}` matched the requirements for rollback with {1} < {2}"
                        .format(stored_vdisk['vdisk_guid'], current_statistics,
                                stored_vdisk['snapshots'][1]['stored_data']))
                    break
                else:
                    tries += 1
                    cls.LOGGER.warning(
                        "Try `{0}` when checking stored data on volumedriver for VDisk "
                        "`{1}`, with currently `{2}` but it should be less than `{3}`. "
                        "Now sleeping for `{4}` seconds ...".format(
                            tries, stored_vdisk['vdisk_guid'],
                            current_statistics,
                            stored_vdisk['snapshots'][1]['stored_data'],
                            timeout))
                    time.sleep(timeout)

            # check if amount of tries has exceeded
            if tries == amount_checks:
                error_msg = "VDisk `{0}` should have been rollback'ed but max. amount of checks have exceeded!"\
                            .format(vdisk.name)
                cls.LOGGER.error(error_msg)
                raise RuntimeError(error_msg)
            else:
                cls.LOGGER.info(
                    "Successfully finished rollback'ing on vdisk `{0}`".format(
                        vdisk.name))

                # commencing deleting volumes
                cls.LOGGER.info("Starting to remove VDisk `{0}`".format(
                    vdisk.name))
            VDiskRemover.remove_vdisk(stored_vdisk['vdisk_guid'])
            cls.LOGGER.info("Finished removing VDisk `{0}`".format(vdisk.name))
Пример #14
0
    def _deploy_vdisks(cls,
                       vpool,
                       storagedriver,
                       size=SIZE_VDISK,
                       amount_vdisks=AMOUNT_VDISKS,
                       cloned=False):
        """
        Deploy X amount of vdisks, write some data to it & snapshot
        :param vpool: a valid vpool object
        :type vpool: ovs.model.hybrids.vpool
        :param storagedriver: a valid storagedriver object
        :type storagedriver: ovs.mode.hybrids.storagedriver
        :param size: size of a single vdisk in bytes
        :type size: int
        :return: tuple[0]: stored vdisks, snapshot, location; tuple[1]: base_vdisks_guids that are used for clones
        [{
            'vdisk_guid': u 'b789b23e-1077-4d96-9ec2-a7cc3785686c',
            'snapshots': {
                0: {
                    'snapshot_name': 'integration-tests-rollback0-snapshot0',
                    'snapshot_guid': u 'fbd1c961-7d33-4bd3-8c92-c8a3c52eb74f',
                    'stored_data': 52428800
                },
                1: {
                    'snapshot_name': 'integration-tests-rollback0-snapshot1',
                    'snapshot_guid': u '15eb7119-d984-4c84-985c-1fb1cc44a95e',
                    'stored_data': 104857600
                }
            }
        }, {
            'vdisk_guid': u '9c2cd023-d15b-4994-8a62-07edc36d748c',
            'snapshots': {
                0: {
                    'snapshot_name': 'integration-tests-rollback1-snapshot0',
                    'snapshot_guid': u 'c7500fec-cc5a-4593-89dc-fca78dcb2783',
                    'stored_data': 52428800
                },
                1: {
                    'snapshot_name': 'integration-tests-rollback1-snapshot1',
                    'snapshot_guid': u 'e46bd42b-516d-4636-9d15-d9c1a8f489e4',
                    'stored_data': 104857600
                }
            }
        }], ['8858717a-e6d2-11e6-831d-00249b133798', '8c644a82-e6d2-11e6-8efe-00249b133798']
        :rtype: tuple
        """

        cls.LOGGER.info(
            "Starting deploying {0} vdisks with clone status: {1}".format(
                amount_vdisks, cloned))

        client = SSHClient(storagedriver.storagerouter.ip, username='******')
        vdisks = []
        base_vdisks = []
        for vdisk_nr in xrange(amount_vdisks):
            # create a vdisk & collect results
            vdisk_name = cls.VDISK_NAME + str(vdisk_nr)

            vdisk_guid = VDiskSetup.create_vdisk(
                vdisk_name=vdisk_name + '.raw',
                vpool_name=vpool.name,
                size=size,
                storagerouter_ip=storagedriver.storagerouter.ip)
            # clone
            if cloned:
                clone_vdisk_name = vdisk_name + '_clone'
                cls.LOGGER.info(
                    "Creating clone from vdisk `{0}` with new name `{1}`".
                    format(vdisk_name, clone_vdisk_name))
                base_vdisks.append(str(vdisk_guid))
                cls.LOGGER.info(
                    "Stored old base vdisk guid in list: {0}".format(
                        vdisk_guid))
                vdisk_guid = VDiskSetup.create_clone(
                    vdisk_name=vdisk_name + '.raw',
                    vpool_name=vpool.name,
                    new_vdisk_name=clone_vdisk_name,
                    storagerouter_ip=storagedriver.storagerouter.ip
                )['vdisk_guid']
                vdisk_name = clone_vdisk_name

            vdisk = VDiskHelper.get_vdisk_by_guid(vdisk_guid)
            results = {'vdisk_guid': vdisk_guid, 'snapshots': {}}
            cls.LOGGER.info(
                "Finished deploying vdisk `{0}`".format(vdisk_name))

            cls.LOGGER.info(
                "Starting writing & snapshotting vdisk `{0}`".format(
                    vdisk_name))
            for i in xrange(cls.WRITE_AMOUNT_OF_TIMES):
                # write some data
                try:
                    RollbackChecks.LOGGER.info(
                        "Starting FIO on vdisk `{0}`".format(vdisk_name))
                    client.run([
                        "fio", "--name=test",
                        "--filename=/mnt/{0}/{1}.raw".format(
                            vpool.name, vdisk_name), "--ioengine=libaio",
                        "--iodepth=4", "--rw=write", "--bs=4k", "--direct=1",
                        "--size={0}b".format(size)
                    ])
                    RollbackChecks.LOGGER.info(
                        "Finished FIO on vdisk `{0}`".format(vdisk_name))

                except subprocess.CalledProcessError as ex:
                    raise VDiskNotFoundError(
                        "VDisk `/mnt/{0}/{1}.raw` does not seem to be present "
                        "or has problems on storagerouter `{2}`: {3}".format(
                            vpool.name, vdisk_name,
                            storagedriver.storagerouter.ip, str(ex)))
                # create snapshot
                cls.LOGGER.info(
                    "Starting snapshot creation on vdisk `{0}`".format(
                        vdisk_name))
                snapshot_guid = VDiskSetup.create_snapshot(
                    snapshot_name=vdisk_name + '-snapshot{0}'.format(i),
                    vdisk_name=vdisk_name + '.raw',
                    vpool_name=vpool.name,
                    consistent=False,
                    sticky=False)
                # save the current stored_data for comparison
                stored_data = vdisk.storagedriver_client.info_volume(
                    str(vdisk.volume_id)).stored
                cls.LOGGER.info(
                    "Logged `{0}` stored data for VDisk `{1}` in mapper".
                    format(stored_data, vdisk_name))
                # add details to snapshot mapper
                results['snapshots'][i] = {
                    'snapshot_guid': snapshot_guid,
                    'snapshot_name': vdisk_name + '-snapshot{0}'.format(i),
                    'stored_data': stored_data
                }
                cls.LOGGER.info(
                    "Snapshot creation finished on vdisk `{0}`".format(
                        vdisk_name))
            vdisks.append(results)
            cls.LOGGER.info(
                "Finished writing & snapshotting vdisk `{0}`. Results: {1}".
                format(vdisk_name, results))
        return vdisks, base_vdisks
Пример #15
0
    def _execute_test(cls):
        """
        Validate if DTL is configured as desired
        REQUIREMENTS:
        * 1 vPool should be available with 1 storagedriver
        * 1 vPool should be available with 2 or more storagedrivers in 2 separate domains
        OPTIONAL:
        * 1 vPool with 1 storagedriver with disabled DTL
        :return:
        """
        cls.LOGGER.info("Starting to validate the basic DTL")
        ##########################
        # get deployment details #
        ##########################
        vpools = VPoolHelper.get_vpools()
        assert len(vpools) >= 1, "Not enough vPools to test"

        # Get a suitable vpools
        vpool_single_sd = None
        vpool_multi_sd = None
        vpool_dtl_disabled = None
        for vp in VPoolHelper.get_vpools():
            if vp.configuration['dtl_mode'] != VPoolHelper.DtlStatus.DISABLED:
                if len(vp.storagedrivers) == 1 and vpool_single_sd is None:
                    vpool_single_sd = vp
                    cls.LOGGER.info(
                        "vPool `{0}` has been chosen for SINGLE vPool DTL tests"
                        .format(vp.name))
                elif len(vp.storagedrivers) >= 2 and vpool_multi_sd is None:
                    vpool_multi_sd = vp
                    cls.LOGGER.info(
                        "vPool `{0}` has been chosen for MULTI vPool DTL tests"
                        .format(vp.name))
                else:
                    cls.LOGGER.info(
                        "vPool `{0}` is not suited for tests".format(vp.name))
            else:
                cls.LOGGER.info(
                    "vPool `{0}` with DISABLED DTL is available and will be tested!"
                    .format(vp.name))
                vpool_dtl_disabled = vp

        assert vpool_single_sd is not None, "A vPool should be available with 1 storagedriver"
        assert vpool_multi_sd is not None, "A vPool should be available with 2 or more storagedrivers"

        # pick a random storagedriver
        storagedriver_single = vpool_single_sd.storagedrivers[0]
        storagedriver_multi = random.choice(vpool_multi_sd.storagedrivers)
        storagedrivers = [storagedriver_single, storagedriver_multi]

        # check disabled DTL
        storagedriver_disabled_dtl = None
        if vpool_dtl_disabled is not None:
            storagedriver_disabled_dtl = random.choice(
                vpool_dtl_disabled.storagedrivers)
            storagedrivers.append(storagedriver_disabled_dtl)

        # key = amount of storagedrivers or a_s
        # value = list with the vpool & storagedriver to test
        vpools_to_test = {
            1: [{
                "vpool": vpool_single_sd,
                "storagedriver": storagedriver_single
            }],
            2: [{
                "vpool": vpool_multi_sd,
                "storagedriver": storagedriver_multi
            }]
        }

        # check if disabled DTL vpool needs to be added
        if vpool_dtl_disabled is not None:
            a_s = len(vpool_dtl_disabled.storagedrivers)
            v_s = {
                "vpool": vpool_dtl_disabled,
                "storagedriver": storagedriver_disabled_dtl
            }
            if a_s in vpools_to_test:
                vpools_to_test[a_s].append(v_s)
            else:
                vpools_to_test[a_s] = [v_s]

        ##############
        # start test #
        ##############

        for a_s, vpools in vpools_to_test.iteritems():
            start = time.time()
            for vpool in vpools:

                cls.LOGGER.info(
                    "Starting DTL test with vPool {0} and {1} storagedrivers".
                    format(vpool['vpool'].name,
                           len(vpool['vpool'].storagedrivers)))
                vdisk_name = "{0}-{1}-{2}".format(
                    cls.VDISK_NAME, vpool['vpool'].name,
                    str(len(vpool['vpool'].storagedrivers)))
                try:
                    vdisk_guid = VDiskSetup.create_vdisk(
                        vdisk_name=vdisk_name + '.raw',
                        vpool_name=vpool['vpool'].name,
                        size=cls.SIZE_VDISK,
                        storagerouter_ip=vpool['storagedriver'].storagerouter.
                        ip)
                    # Fetch to validate if it was properly created
                    vdisk = VDiskHelper.get_vdisk_by_guid(
                        vdisk_guid=vdisk_guid)
                except TimeOutError:
                    cls.LOGGER.error("Creation of the vDisk has timed out.")
                    raise
                except RuntimeError as ex:
                    cls.LOGGER.info("Creation of vDisk failed: {0}".format(ex))
                    raise
                else:
                    #####################################
                    # check DTL status after deployment #
                    #####################################

                    correct_msg = "vDisk {0} with {1} storagedriver(s) has correct DTL status: ".format(
                        vdisk_name, a_s)
                    if a_s == 1 and vdisk.dtl_status == VDiskHelper.DtlStatus.STANDALONE:
                        cls.LOGGER.info(correct_msg + vdisk.dtl_status)
                    elif a_s >= 2 and vdisk.dtl_status == VDiskHelper.DtlStatus.SYNC:
                        cls.LOGGER.info(correct_msg + vdisk.dtl_status)
                    elif vdisk.dtl_status == VDiskHelper.DtlStatus.DISABLED and vpool[
                            'vpool'].configuration[
                                'dtl_mode'] == VPoolHelper.DtlStatus.DISABLED:
                        cls.LOGGER.info(
                            correct_msg +
                            " Note: vdisk DTL is disabled but vPool DTL is also disabled!"
                        )
                    else:
                        error_msg = "vDisk {0} with {1} storagedriver(s) has WRONG DTL status: {2}".format(
                            vdisk_name, a_s, vdisk.dtl_status)
                        cls.LOGGER.error(error_msg)
                        raise RuntimeError(error_msg)

                    ################################
                    # try to change the DTL config #
                    ################################

                    base_config = {
                        "sco_size": 4,
                        "dtl_mode": VPoolHelper.DtlStatus.SYNC,
                        "write_buffer": 512
                    }
                    if a_s == 1:
                        ########################################################################################
                        # change config to domain with non existing storagedrivers of this vpool (should fail) #
                        ########################################################################################
                        cls.LOGGER.info(
                            "Starting test: change config to domain with non existing storagedrivers "
                            "of this vpool (should fail)")
                        base_config['dtl_target'] = [
                            random.choice([
                                domain_guid for domain_guid in
                                DomainHelper.get_domain_guids()
                                if domain_guid not in vpool['storagedriver'].
                                storagerouter.regular_domains
                            ])
                        ]
                        cls.LOGGER.info("Changing dtl_target to: {0}".format(
                            DomainHelper.get_domain_by_guid(
                                domain_guid=base_config['dtl_target']
                                [0]).name))
                        try:
                            cls.LOGGER.info(base_config)
                            VDiskSetup.set_config_params(
                                vdisk_name=vdisk_name + '.raw',
                                vpool_name=vpool['vpool'].name,
                                config=base_config)
                            error_msg = "Changing config to a domain with non existing storagedrivers should have failed with vdisk: {0}!".format(
                                vdisk_name)
                            cls.LOGGER.error(error_msg)
                            raise Exception(error_msg)
                        except TimeOutError:
                            cls.LOGGER.error(
                                "Changing config to a same domain with only 1 storagedriver has timed out."
                            )
                            raise
                        except RuntimeError:
                            cls.LOGGER.info(
                                "Changing config to a domain with non existing storagedrivers has failed as expected!"
                            )

                        ##############################################################################################
                        # change config to domain where there are other storagedrivers but not of ours (should fail) #
                        ##############################################################################################
                        cls.LOGGER.info(
                            "Starting test: change config to domain where there are other storagedrivers but not of ours (should fail)"
                        )

                        filtered_domains = list(
                            set(DomainHelper.get_domain_guids()) -
                            set(vpool['storagedriver'].storagerouter.
                                regular_domains))
                        base_config['dtl_target'] = [filtered_domains[0]]
                        cls.LOGGER.info(
                            "Current vdisk domain location: {0}".format(
                                DomainHelper.get_domain_by_guid(
                                    domain_guid=vpool['storagedriver'].
                                    storagerouter.regular_domains[0]).name))
                        cls.LOGGER.info("Changing dtl_target to: {0}".format(
                            DomainHelper.get_domain_by_guid(
                                domain_guid=base_config['dtl_target']
                                [0]).name))
                        try:
                            VDiskSetup.set_config_params(
                                vdisk_name=vdisk_name + '.raw',
                                vpool_name=vpool['vpool'].name,
                                config=base_config)
                            error_msg = "Changing config to a same domain with only 1 storagedriver should have failed with vdisk: {0}!".format(
                                vdisk_name)
                            cls.LOGGER.error(error_msg)
                            raise Exception(error_msg)
                        except TimeOutError:
                            cls.LOGGER.error(
                                "Changing config to a domain with non existing storagedrivers has timed out."
                            )
                            raise
                        except RuntimeError:
                            cls.LOGGER.info(
                                "Changing config to a same domain with only 1 storagedriver has failed as expected!"
                            )
                    elif a_s >= 2:
                        #######################################################################
                        # change config to domain with active storagedrivers (should succeed) #
                        #######################################################################
                        cls.LOGGER.info(
                            "Starting test: change config to domain with active storagedrivers (should succeed)"
                        )

                        # change current target domain to other target domain
                        current_vdisk_domains = StoragedriverHelper.get_storagedriver_by_id(
                            storagedriver_id=vdisk.storagedriver_id
                        ).storagerouter.regular_domains
                        cls.LOGGER.info(
                            "Currently the vdisk is living in: {0}".format(
                                current_vdisk_domains))
                        vpool_domains = VPoolHelper.get_domains_by_vpool(
                            vpool_name=vdisk.vpool.name)
                        cls.LOGGER.info(
                            "Currently the vpool {0} is available in: {1}".
                            format(vdisk.vpool.name, vpool_domains))
                        future_domains = list(
                            set(vpool_domains) - set(current_vdisk_domains))
                        cls.LOGGER.info(
                            "DTL will be moved to other domain: {0}".format(
                                future_domains))
                        base_config['dtl_target'] = future_domains

                        # change settings
                        try:
                            VDiskSetup.set_config_params(
                                vdisk_name=vdisk_name + '.raw',
                                vpool_name=vpool['vpool'].name,
                                config=base_config)
                        except TimeOutError:
                            cls.LOGGER.error(
                                "Changing config to a same domain with only 1 storagedriver has timed out."
                            )
                            raise
                        except RuntimeError:
                            cls.LOGGER.error(
                                "Changing config to a same domain with only 1 storagedriver was unsuccesful!"
                            )
                            raise
                        cls.LOGGER.info(
                            "Changing config to a same domain with only 1 storagedriver was successful!"
                        )

                    cls.LOGGER.info("Removing vDisk {0}".format(vdisk.name))
                    VDiskRemover.remove_vdisk(vdisk_guid=vdisk.guid)
                    cls.LOGGER.info("Finished removing vDisk {0}".format(
                        vdisk.name))

            end = time.time()

            # display run time
            cls.LOGGER.info("Run testing the DTL took {0} seconds".format(
                int(end - start)))

        cls.LOGGER.info("Finished to validate the basic DTL")
Пример #16
0
    def test_reroute_fio(cls, fio_bin_path, cluster_info, disk_amount=1, timeout=CIConstants.HA_TIMEOUT, is_ee=False, logger=LOGGER):
        """
        Uses a modified fio to work with the openvstorage protocol
        :param fio_bin_path: path of the fio binary
        :type fio_bin_path: str
        :param cluster_info: information about the cluster, contains all dal objects
        :type cluster_info: dict
        :param disk_amount: amount of disks to test fail over with
        :type disk_amount: int
        :param timeout: timeout in seconds
        :type timeout: int
        :param is_ee: is it the enterprise edition
        :type is_ee: bool
        :param logger: logger instance
        :type logger: ovs.log.log_handler.LogHandler
        :return: None
        :rtype: NoneType
        """
        compute_client = SSHClient(cluster_info['storagerouters']['compute'], username='******')

        destination_std = cluster_info['storagedrivers']['destination']
        source_std = cluster_info['storagedrivers']['source']  # will be downed
        vpool = source_std.vpool

        values_to_check = {
            'source_std': source_std.serialize(),
            'target_std': destination_std.serialize(),
            'vdisks': []
        }
        # Create vdisks
        protocol = source_std.cluster_node_config['network_server_uri'].split(':')[0]
        edge_configuration = {'fio_bin_location': fio_bin_path, 'hostname': source_std.storage_ip,
                              'port': source_std.ports['edge'],
                              'protocol': protocol,
                              'volumenames': []}
        vdisk_info = {}
        failed_configurations = []

        if is_ee is True:
            edge_configuration.update(cls.get_shell_user())

        for index in xrange(0, disk_amount):
            try:
                vdisk_name = '{0}_vdisk{1}'.format(EdgeTester.TEST_NAME, str(index).zfill(4))
                data_vdisk = VDiskHelper.get_vdisk_by_guid(VDiskSetup.create_vdisk(vdisk_name, vpool.name, EdgeTester.AMOUNT_TO_WRITE * 2, source_std.storage_ip))
                vdisk_info[vdisk_name] = data_vdisk
                edge_configuration['volumenames'].append(data_vdisk.devicename.rsplit('.', 1)[0].split('/', 1)[1])
                values_to_check['vdisks'].append(data_vdisk.serialize())
            except RuntimeError as ex:
                logger.error('Could not create the vdisk. Got {0}'.format(str(ex)))
                raise
        configuration = random.choice(cls.DATA_TEST_CASES)
        threads = {'evented': {'io': {'pairs': [], 'r_semaphore': None}}}
        screen_names = []
        adjusted = False
        try:
            io_thread_pairs, monitoring_data, io_r_semaphore = ThreadingHandler.start_io_polling_threads(volume_bundle=vdisk_info)
            threads['evented']['io']['pairs'] = io_thread_pairs
            threads['evented']['io']['r_semaphore'] = io_r_semaphore
            screen_names, output_files = DataWriter.write_data_fio(client=compute_client,
                                                                   fio_configuration={'io_size': cls.AMOUNT_TO_WRITE,
                                                                                      'configuration': configuration},
                                                                   edge_configuration=edge_configuration)
            logger.info('Doing IO for {0}s before bringing down the node.'.format(cls.IO_TIME))
            ThreadingHandler.keep_threads_running(r_semaphore=io_r_semaphore,
                                                  threads=io_thread_pairs,
                                                  shared_resource=monitoring_data,
                                                  duration=cls.IO_TIME)
            # Threads ready for monitoring at this point, they are waiting to resume
            EdgeTester.adjust_for_reroute(source_std.storagerouter, trigger_rerout=True, ip_to_block=compute_client.ip, additional_ports=[edge_configuration['port']])
            adjusted = True
            downed_time = time.time()
            logger.info('Now waiting two refreshrate intervals to avoid caching. In total {}s'.format(EdgeTester.IO_REFRESH_RATE * 2))
            time.sleep(cls.IO_REFRESH_RATE * 2)
            ThreadingHandler.poll_io(r_semaphore=io_r_semaphore,
                                     required_thread_amount=len(io_thread_pairs),
                                     shared_resource=monitoring_data,
                                     downed_time=downed_time,
                                     timeout=timeout,
                                     output_files=output_files,
                                     client=compute_client,
                                     disk_amount=disk_amount)
            EdgeTester._validate_dal(values_to_check)  # Validate
        except Exception as ex:
            logger.error('Got an exception while running configuration {0}. Namely: {1}'.format(configuration, str(ex)))
            failed_configurations.append({'configuration': configuration, 'reason': str(ex)})
        finally:
            if adjusted is True:
                EdgeTester.adjust_for_reroute(source_std.storagerouter, trigger_rerout=False, ip_to_block=compute_client.ip, additional_ports=[edge_configuration['port']])
            for screen_name in screen_names:
                compute_client.run(['screen', '-S', screen_name, '-X', 'quit'])
            for thread_category, thread_collection in threads['evented'].iteritems():
                ThreadHelper.stop_evented_threads(thread_collection['pairs'], thread_collection['r_semaphore'])
            for vdisk in vdisk_info.values():
                VDiskRemover.remove_vdisk(vdisk.guid)
        assert len(failed_configurations) == 0, 'Certain configuration failed: {0}'.format(failed_configurations)
Пример #17
0
    def test_ha_fio(cls,
                    fio_bin_path,
                    cluster_info,
                    is_ee,
                    disk_amount=1,
                    timeout=CIConstants.HA_TIMEOUT,
                    logger=LOGGER):
        """
        Uses a modified fio to work with the openvstorage protocol
        :param fio_bin_path: path of the fio binary
        :type fio_bin_path: str
        :param cluster_info: information about the cluster, contains all dal objects
        :type cluster_info: dict
        :param is_ee: is it an ee version or not
        :type is_ee: bool
        :param disk_amount: amount of disks to test fail over with
        :type disk_amount: int
        :param timeout: timeout in seconds
        :type timeout: int
        :param logger: logging instance
        :return: None
        :rtype: NoneType
        """
        destination_storagedriver = cluster_info['storagedrivers'][
            'destination']
        source_storagedriver = cluster_info['storagedrivers']['source']
        vpool = destination_storagedriver.vpool

        compute_client = SSHClient(cluster_info['storagerouters']['compute'],
                                   username='******')

        vm_to_stop = cls.HYPERVISOR_INFO['vms'][
            source_storagedriver.storage_ip]['name']
        parent_hypervisor = HypervisorFactory().get()
        values_to_check = {
            'source_std': source_storagedriver.serialize(),
            'target_std': destination_storagedriver.serialize(),
            'vdisks': []
        }
        # Create vdisks
        protocol = source_storagedriver.cluster_node_config[
            'network_server_uri'].split(':')[0]
        edge_configuration = {
            'fio_bin_location': fio_bin_path,
            'hostname': source_storagedriver.storage_ip,
            'port': source_storagedriver.ports['edge'],
            'protocol': protocol,
            'volumenames': []
        }
        if is_ee is True:
            edge_configuration.update(cls.get_shell_user())

        vdisk_info = {}
        failed_configurations = []

        for index in xrange(0, disk_amount):
            try:
                vdisk_name = '{0}_vdisk{1}'.format(cls.TEST_NAME,
                                                   str(index).zfill(3))
                data_vdisk = VDiskHelper.get_vdisk_by_guid(
                    VDiskSetup.create_vdisk(vdisk_name, vpool.name,
                                            cls.AMOUNT_TO_WRITE,
                                            source_storagedriver.storage_ip))
                vdisk_info[vdisk_name] = data_vdisk
                edge_configuration['volumenames'].append(
                    data_vdisk.devicename.rsplit('.', 1)[0].split('/', 1)[1])
                values_to_check['vdisks'].append(data_vdisk.serialize())
            except TimeOutError:
                logger.error('Creating the vdisk has timed out.')
                raise
            except RuntimeError as ex:
                logger.error('Could not create the vdisk. Got {0}'.format(
                    str(ex)))
                raise
        configuration = random.choice(cls.DATA_TEST_CASES)
        threads = {'evented': {'io': {'pairs': [], 'r_semaphore': None}}}
        vm_downed = False
        screen_names = []
        try:
            logger.info(
                'Starting threads.'
            )  # Separate because creating vdisks takes a while, while creating the threads does not

            io_thread_pairs, monitoring_data, io_r_semaphore = ThreadingHandler.start_io_polling_threads(
                volume_bundle=vdisk_info)
            threads['evented']['io']['pairs'] = io_thread_pairs
            threads['evented']['io']['r_semaphore'] = io_r_semaphore
            screen_names, output_files = DataWriter.write_data_fio(
                client=compute_client,
                fio_configuration={
                    'io_size': cls.AMOUNT_TO_WRITE,
                    'configuration': configuration
                },
                edge_configuration=edge_configuration)
            logger.info(
                'Doing IO for {0}s before bringing down the node.'.format(
                    cls.IO_TIME))
            ThreadingHandler.keep_threads_running(
                r_semaphore=io_r_semaphore,
                threads=io_thread_pairs,
                shared_resource=monitoring_data,
                duration=cls.IO_TIME)
            # Threads ready for monitoring at this point
            #########################
            # Bringing original owner of the volume down
            #########################
            try:
                logger.info('Stopping {0}.'.format(vm_to_stop))
                VMHandler.stop_vm(hypervisor=parent_hypervisor,
                                  vmid=vm_to_stop)
                downed_time = time.time()
                vm_downed = True
            except Exception as ex:
                logger.error('Failed to stop. Got {0}'.format(str(ex)))
                raise
            time.sleep(cls.IO_REFRESH_RATE * 2)
            # Start IO polling to verify nothing went down
            ThreadingHandler.poll_io(
                r_semaphore=io_r_semaphore,
                required_thread_amount=len(io_thread_pairs),
                shared_resource=monitoring_data,
                downed_time=downed_time,
                timeout=timeout,
                output_files=output_files,
                client=compute_client,
                disk_amount=disk_amount)
            cls._validate(values_to_check, monitoring_data)
        except Exception as ex:
            failed_configurations.append({
                'configuration': configuration,
                'reason': str(ex)
            })
        finally:
            for thread_category, thread_collection in threads[
                    'evented'].iteritems():
                ThreadHelper.stop_evented_threads(
                    thread_collection['pairs'],
                    thread_collection['r_semaphore'])
            if vm_downed is True:
                VMHandler.start_vm(parent_hypervisor, vm_to_stop)
                SystemHelper.idle_till_ovs_is_up(
                    source_storagedriver.storage_ip, **cls.get_shell_user())
                # @TODO: Remove when https://github.com/openvstorage/integrationtests/issues/540 is fixed
                FwkHandler.restart_all()
            if screen_names:
                for screen_name in screen_names:
                    compute_client.run(
                        ['screen', '-S', screen_name, '-X', 'quit'])
            for vdisk in vdisk_info.values():
                VDiskRemover.remove_vdisk(vdisk.guid)
        assert len(failed_configurations
                   ) == 0, 'Certain configuration failed: {0}'.format(
                       ' '.join(failed_configurations))
Пример #18
0
 def validate_vdisk_clone(cls):
     """
     Validate if vdisk deployment works via various ways
     INFO: 1 vPool should be available on 2 storagerouters
     :return:
     """
     cls.LOGGER.info("Starting to validate template vdisks")
     vpools = VPoolHelper.get_vpools()
     assert len(vpools) >= 1, "Not enough vPools to test"
     try:
         vpool = next(
             (vpool for vpool in vpools if len(vpool.storagedrivers) >= 2))
     except StopIteration:
         assert False, "Not enough Storagedrivers to test"
     # setup base information
     storagedriver_source = vpool.storagedrivers[0]
     vdisks = []
     try:
         # create required vdisk for test
         parent_vdisk_name = '{0}_{1}'.format(cls.PREFIX, str(1).zfill(3))
         parent_vdisk = VDiskHelper.get_vdisk_by_guid(
             VDiskSetup.create_vdisk(
                 vdisk_name=parent_vdisk_name,
                 vpool_name=vpool.name,
                 size=cls.VDISK_SIZE,
                 storagerouter_ip=storagedriver_source.storagerouter.ip))
         vdisks.append(parent_vdisk)
         time.sleep(cls.TEMPLATE_SLEEP_AFTER_CREATE)
         # Create vdisk template  #
         VDiskSetup.set_vdisk_as_template(vdisk_name=parent_vdisk_name,
                                          vpool_name=vpool.name)
         time.sleep(cls.TEMPLATE_SLEEP_AFTER_CREATE)
         clone_vdisk_name = '{0}_from-template'.format(parent_vdisk_name)
         clone_vdisk = VDiskHelper.get_vdisk_by_guid(
             VDiskSetup.create_from_template(
                 vdisk_name=parent_vdisk_name,
                 vpool_name=vpool.name,
                 new_vdisk_name=clone_vdisk_name,
                 storagerouter_ip=storagedriver_source.storagerouter.ip)
             ['vdisk_guid'])
         vdisks.append(clone_vdisk)
         time.sleep(cls.TEMPLATE_SLEEP_BEFORE_DELETE)
         try:
             # try to delete template with clones (should fail) #
             VDiskRemover.remove_vtemplate_by_name(
                 vdisk_name=parent_vdisk_name, vpool_name=vpool.name)
             error_msg = "Removing vtemplate `{0}` should have failed!"
             cls.LOGGER.error(error_msg)
             raise RuntimeError(error_msg)
         except HttpException:
             cls.LOGGER.info(
                 "Removing vtemplate `{0}` has failed as expected (because of leftover clones)!"
                 .format(parent_vdisk_name))
     finally:
         while len(vdisks) > 0:
             vdisk = vdisks.pop()
             VDiskRemover.remove_vdisk(vdisk.guid)
     try:
         # template vdisk from clone (should fail) #
         parent_vdisk = VDiskHelper.get_vdisk_by_guid(
             VDiskSetup.create_vdisk(
                 vdisk_name=parent_vdisk_name,
                 vpool_name=vpool.name,
                 size=cls.VDISK_SIZE,
                 storagerouter_ip=storagedriver_source.storagerouter.ip))
         vdisks.append(parent_vdisk)
         # create a clone from the vdisk
         clone_vdisk_name = '{0}_clone'.format(parent_vdisk_name)
         cloned_vdisk = VDiskHelper.get_vdisk_by_guid(
             VDiskSetup.create_clone(
                 vdisk_name=parent_vdisk_name,
                 vpool_name=vpool.name,
                 new_vdisk_name=clone_vdisk_name,
                 storagerouter_ip=storagedriver_source.storagerouter.ip)
             ['vdisk_guid'])
         vdisks.append(cloned_vdisk)
         # try to create a vTemplate from a clone
         try:
             VDiskSetup.set_vdisk_as_template(vdisk_name=clone_vdisk_name,
                                              vpool_name=vpool.name)
             error_msg = "Setting vdisk `{0}` as template should have failed!".format(
                 clone_vdisk_name)
             cls.LOGGER.error(error_msg)
             raise RuntimeError(error_msg)
         except RuntimeError:
             cls.LOGGER.info(
                 "Setting vdisk `{0}` as template failed as expected (because vdisk is clone)!"
                 .format(clone_vdisk_name))
     finally:
         parent_vdisks = []
         while len(vdisks) > 0:  # Remove clones first
             vdisk = vdisks.pop()
             if vdisk.parent_vdisk_guid is None:
                 parent_vdisks.append(vdisk)
                 continue
             VDiskRemover.remove_vdisk(vdisk.guid)
         for parent_vdisk in parent_vdisks:
             VDiskRemover.remove_vdisk(parent_vdisk.guid)
     cls.LOGGER.info("Finished to validate template vdisks")
Пример #19
0
 def _execute_test(cls, amount_vdisks=AMOUNT_VDISKS):
     """
     Executes a offline migration
     :param amount_vdisks: amount of vdisks to test
     :type amount_vdisks: int
     :return:
     """
     cls.LOGGER.info("Starting offline migrate test.")
     vpool = None  # Get a suitable vpool
     for vp in VPoolHelper.get_vpools():
         if len(vp.storagedrivers) >= 2:
             vpool = vp
             break
     assert vpool is not None, "Not enough vPools to test. Requires 1 with at least 2 storagedrivers and found 0."
     ##########################
     # Setup base information #
     ##########################
     # Executor storagedriver_1 is current system
     std_1 = random.choice([st for st in vpool.storagedrivers])
     # Get a random other storagedriver to migrate to
     std_2 = random.choice([st for st in vpool.storagedrivers if st != std_1])
     # Cache to validate properties
     values_to_check = {
         'source_std': std_1.serialize(),
         'target_std': std_2.serialize()
     }
     ###############################
     # start deploying & migrating #
     ###############################
     created_vdisks = []
     try:
         for i in xrange(amount_vdisks):
             ################
             # create vdisk #
             ################
             vdisk_name = "{0}_{1}".format(cls.TEST_NAME, i)
             try:
                 vdisk_guid = VDiskSetup.create_vdisk(vdisk_name=vdisk_name + '.raw',
                                                      vpool_name=vpool.name,
                                                      size=cls.AMOUNT_TO_WRITE * 5,
                                                      storagerouter_ip=std_1.storagerouter.ip)
                 vdisk = VDiskHelper.get_vdisk_by_guid(vdisk_guid)  # Fetch to validate if it was properly created
                 created_vdisks.append(vdisk)
                 values_to_check['vdisk'] = vdisk.serialize()
             except TimeOutError:
                 cls.LOGGER.error("Creation of the vdisk has timed out.")
                 raise
             except (RuntimeError, TimeOutError) as ex:
                 cls.LOGGER.info("Creation of vdisk failed: {0}".format(ex))
                 raise
             else:
                 time.sleep(cls.SLEEP_TIME)
                 try:
                     cls.LOGGER.info("Moving vdisk {0} from {1} to {2}".format(vdisk_guid, std_1.storage_ip, std_2.storage_ip))
                     VDiskSetup.move_vdisk(vdisk_guid=vdisk_guid, target_storagerouter_guid=std_2.storagerouter_guid)
                     time.sleep(cls.SLEEP_TIME)
                     cls.LOGGER.info("Validating move...")
                     cls._validate_move(values_to_check)
                 except Exception as ex:
                     cls.LOGGER.exception('Failed during migation: {0}'.format(ex))
                     raise
     finally:
         for vdisk in created_vdisks:
             VDiskRemover.remove_vdisk(vdisk.guid)
     cls.LOGGER.info("Finished offline migrate test.")
Пример #20
0
    def _execute_test(cls):
        """
        Mimics the healthcheck creating and deleting disks with the same name/devicename back to back
        :return: None
        """
        local_sr = SystemHelper.get_local_storagerouter()
        cls.LOGGER.info("Starting creation/deletion test.")
        # Elect vpool
        assert len(
            local_sr.storagedrivers
        ) > 0, 'Node {0} has no storagedriver. Cannot test {1}'.format(
            local_sr.ip, VDiskControllerTester.TEST_NAME)
        random_storagedriver = local_sr.storagedrivers[random.randint(
            0,
            len(local_sr.storagedrivers) - 1)]
        vpool = random_storagedriver.vpool
        disk_size = 1024**3
        disk_name = 'ci_scenario_rapid_create_delete_same_device'
        exceptions = []
        for loop in xrange(0, 100):
            test_passed = False
            try:
                cls.LOGGER.info("Creating new disk.")
                try:
                    VDiskController.create_new(disk_name, disk_size,
                                               random_storagedriver.guid)
                except Exception as ex:
                    cls.LOGGER.error(
                        'Creation failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                    exceptions.append(
                        'Creation failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                    continue
                cls.LOGGER.info("Fetching new disk.")
                try:
                    vdisk = VDiskHelper.get_vdisk_by_name(
                        '{0}.raw'.format(disk_name), vpool.name)
                except Exception as ex:
                    cls.LOGGER.error(
                        'Fetch failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                    exceptions.append(
                        'Fetch failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                    continue
                cls.LOGGER.info("Deleting new disk.")
                try:
                    VDiskController.delete(vdisk_guid=vdisk.guid)
                except Exception as ex:
                    cls.LOGGER.error(
                        'Delete failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                    exceptions.append(
                        'Delete failed. Got {0} in iteration {1}'.format(
                            str(ex), loop))
                test_passed = True
            except Exception as ex:
                cls.LOGGER.error(
                    'Unexpected exception occurred during loop {0}. Got {1}.'.
                    format(loop, str(ex)))
            finally:
                try:
                    cls._cleanup_vdisk(disk_name, vpool.name, not test_passed)
                except Exception as ex:
                    cls.LOGGER.error(
                        "Auto cleanup failed with {0} in iteration {1}.".
                        format(str(ex), loop))
                    exceptions.append(
                        'Auto cleanup failed, got {0} in iteration {1}'.format(
                            str(ex), loop))

        assert len(
            exceptions
        ) == 0, 'Exception occurred during the creation of vdisks with the same devicename. Got {0}'.format(
            ', '.join(exceptions))

        cls.LOGGER.info("Finished create/delete test.")