def create_vdisks_for_mds_service(amount, start_id, mds_service=None, storagedriver=None): """ Generates vdisks and appends them to a given mds_service """ if (mds_service is None and storagedriver is None) or (mds_service is not None and storagedriver is not None): raise RuntimeError( 'Either `mds_service` or `storagedriver` should be passed') vdisks = {} storagedriver_id = None vpool = None mds_services = [] if mds_service is not None: mds_services.append(mds_service) for sd in mds_service.vpool.storagedrivers: if sd.storagerouter_guid == mds_service.service.storagerouter_guid: storagedriver_id = sd.storagedriver_id vpool = sd.vpool if storagedriver_id is None: raise RuntimeError( 'The given MDSService is located on a node without StorageDriver' ) else: storagedriver_id = storagedriver.storagedriver_id vpool = storagedriver.vpool srclient = StorageRouterClient(vpool.guid, None) for i in xrange(start_id, start_id + amount): devicename = 'vdisk_{0}'.format(i) mds_backend_config = DalHelper.generate_mds_metadata_backend_config( mds_services) volume_id = srclient.create_volume(devicename, mds_backend_config, 0, str(storagedriver_id)) if len(mds_services) == 1: MDSClient.set_catchup(mds_services[0], volume_id, 50) vdisk = VDisk() vdisk.name = str(i) vdisk.devicename = devicename vdisk.volume_id = volume_id vdisk.vpool = vpool vdisk.size = 0 vdisk.save() vdisk.reload_client('storagedriver') if mds_service is not None: junction = MDSServiceVDisk() junction.vdisk = vdisk junction.mds_service = mds_service junction.is_master = True junction.save() vdisks[i] = vdisk return vdisks
def load(vpool, excluded_storagedrivers=None): """ Initializes the wrapper for a given vpool :param vpool: vPool for which the StorageRouterClient needs to be loaded :type vpool: vPool :param excluded_storagedrivers: A list of storagedrivers that cannot be used as a client :type excluded_storagedrivers: list or None """ if excluded_storagedrivers is None: excluded_storagedrivers = [] key = vpool.identifier if key not in client_vpool_cache: cluster_contacts = [] for storagedriver in vpool.storagedrivers[:3]: if storagedriver not in excluded_storagedrivers: cluster_contacts.append( ClusterContact(str(storagedriver.cluster_ip), storagedriver.ports['xmlrpc'])) client = StorageRouterClient(str(vpool.guid), cluster_contacts) client_vpool_cache[key] = client return client_vpool_cache[key]
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 = DalHelper.build_dal_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 = DalHelper.generate_mds_metadata_backend_config( [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')
def build_dal_structure(structure, previous_structure=None): """ Builds a model structure Example: structure = DalHelper.build_service_structure( {'vpools': [1], 'domains': [], 'storagerouters': [1], 'storagedrivers': [(1, 1, 1)], # (<id>, <vpool_id>, <storagerouter_id>) 'mds_services': [(1, 1)], # (<id>, <storagedriver_id>) 'storagerouter_domains': []} # (<id>, <storagerouter_id>, <domain_id>) ) """ Configuration.set(key=Configuration.EDITION_KEY, value=PackageFactory.EDITION_ENTERPRISE) if previous_structure is None: previous_structure = {} vdisks = previous_structure.get('vdisks', {}) vpools = previous_structure.get('vpools', {}) domains = previous_structure.get('domains', {}) services = previous_structure.get('services', {}) mds_services = previous_structure.get('mds_services', {}) storagerouters = previous_structure.get('storagerouters', {}) storagedrivers = previous_structure.get('storagedrivers', {}) storagerouter_domains = previous_structure.get('storagerouter_domains', {}) service_types = {} for service_type_name in ServiceType.SERVICE_TYPES.values(): service_type = ServiceTypeList.get_by_name(service_type_name) if service_type is None: service_type = ServiceType() service_type.name = service_type_name service_type.save() service_types[service_type_name] = service_type srclients = {} for domain_id in structure.get('domains', []): if domain_id not in domains: domain = Domain() domain.name = 'domain_{0}'.format(domain_id) domain.save() domains[domain_id] = domain for vpool_id in structure.get('vpools', []): if vpool_id not in vpools: vpool = VPool() vpool.name = str(vpool_id) vpool.status = 'RUNNING' vpool.metadata = {'backend': {}, 'caching_info': {}} vpool.metadata_store_bits = 5 vpool.save() vpools[vpool_id] = vpool else: vpool = vpools[vpool_id] srclients[vpool_id] = StorageRouterClient(vpool.guid, None) Configuration.set( '/ovs/vpools/{0}/mds_config|mds_tlogs'.format(vpool.guid), 100) Configuration.set( '/ovs/vpools/{0}/mds_config|mds_safety'.format(vpool.guid), 2) Configuration.set( '/ovs/vpools/{0}/mds_config|mds_maxload'.format(vpool.guid), 75) Configuration.set( '/ovs/vpools/{0}/proxies/scrub/generic_scrub'.format( vpool.guid), json.dumps({}, indent=4), raw=True) for sr_id in structure.get('storagerouters', []): if sr_id not in storagerouters: storagerouter = StorageRouter() storagerouter.name = str(sr_id) storagerouter.ip = '10.0.0.{0}'.format(sr_id) storagerouter.rdma_capable = False storagerouter.node_type = 'MASTER' storagerouter.machine_id = str(sr_id) storagerouter.save() storagerouters[sr_id] = storagerouter disk = Disk() disk.storagerouter = storagerouter disk.state = 'OK' disk.name = '/dev/uda' disk.size = 1 * 1024**4 disk.is_ssd = True disk.aliases = ['/dev/uda'] disk.save() partition = DiskPartition() partition.offset = 0 partition.size = disk.size partition.aliases = ['/dev/uda-1'] partition.state = 'OK' partition.mountpoint = '/tmp/unittest/sr_{0}/disk_1/partition_1'.format( sr_id) partition.disk = disk partition.roles = [ DiskPartition.ROLES.DB, DiskPartition.ROLES.SCRUB ] partition.save() else: storagerouter = storagerouters[sr_id] # noinspection PyProtectedMember System._machine_id[storagerouter.ip] = str(sr_id) mds_start = 10000 + 100 * (sr_id - 1) mds_end = 10000 + 100 * sr_id - 1 arakoon_start = 20000 + 100 * (sr_id - 1) storagedriver_start = 30000 + 100 * (sr_id - 1) storagedriver_end = 30000 + 100 * sr_id - 1 Configuration.initialize_host( host_id=sr_id, port_info={ 'mds': [mds_start, mds_end], 'arakoon': arakoon_start, 'storagedriver': [storagedriver_start, storagedriver_end] }) for sd_id, vpool_id, sr_id in structure.get('storagedrivers', ()): if sd_id not in storagedrivers: storagedriver = StorageDriver() storagedriver.vpool = vpools[vpool_id] storagedriver.storagerouter = storagerouters[sr_id] storagedriver.name = str(sd_id) storagedriver.mountpoint = '/' storagedriver.cluster_ip = storagerouters[sr_id].ip storagedriver.storage_ip = '10.0.1.{0}'.format(sr_id) storagedriver.storagedriver_id = str(sd_id) storagedriver.ports = { 'management': 1, 'xmlrpc': 2, 'dtl': 3, 'edge': 4 } storagedriver.save() storagedrivers[sd_id] = storagedriver DalHelper.set_vpool_storage_driver_configuration( vpool=vpools[vpool_id], storagedriver=storagedriver) for mds_id, sd_id in structure.get('mds_services', ()): if mds_id not in mds_services: sd = storagedrivers[sd_id] s_id = '{0}-{1}'.format(sd.storagerouter.name, mds_id) service = Service() service.name = s_id service.storagerouter = sd.storagerouter service.ports = [mds_id] service.type = service_types['MetadataServer'] service.save() services[s_id] = service mds_service = MDSService() mds_service.service = service mds_service.number = 0 mds_service.capacity = 10 mds_service.vpool = sd.vpool mds_service.save() mds_services[mds_id] = mds_service StorageDriverController.add_storagedriverpartition( sd, { 'size': None, 'role': DiskPartition.ROLES.DB, 'sub_role': StorageDriverPartition.SUBROLE.MDS, 'partition': sd.storagerouter.disks[0].partitions[0], 'mds_service': mds_service }) for vdisk_id, storage_driver_id, vpool_id, mds_id in structure.get( 'vdisks', ()): if vdisk_id not in vdisks: vpool = vpools[vpool_id] devicename = 'vdisk_{0}'.format(vdisk_id) mds_backend_config = DalHelper.generate_mds_metadata_backend_config( [] if mds_id is None else [mds_services[mds_id]]) volume_id = srclients[vpool_id].create_volume( devicename, mds_backend_config, 0, str(storage_driver_id)) vdisk = VDisk() vdisk.name = str(vdisk_id) vdisk.devicename = devicename vdisk.volume_id = volume_id vdisk.vpool = vpool vdisk.size = 0 vdisk.save() vdisk.reload_client('storagedriver') vdisks[vdisk_id] = vdisk for srd_id, sr_id, domain_id, backup in structure.get( 'storagerouter_domains', ()): if srd_id not in storagerouter_domains: sr_domain = StorageRouterDomain() sr_domain.backup = backup sr_domain.domain = domains[domain_id] sr_domain.storagerouter = storagerouters[sr_id] sr_domain.save() storagerouter_domains[srd_id] = sr_domain return { 'vdisks': vdisks, 'vpools': vpools, 'domains': domains, 'services': services, 'mds_services': mds_services, 'service_types': service_types, 'storagerouters': storagerouters, 'storagedrivers': storagedrivers, 'storagerouter_domains': storagerouter_domains }
def build_service_structure(structure, previous_structure=None): """ Builds an MDS service structure Example: structure = Helper.build_service_structure( {'vpools': [1], 'domains': [], 'storagerouters': [1], 'storagedrivers': [(1, 1, 1)], # (<id>, <vpool_id>, <storagerouter_id>) 'mds_services': [(1, 1)], # (<id>, <storagedriver_id>) 'storagerouter_domains': []} # (<id>, <storagerouter_id>, <domain_id>) ) """ if previous_structure is None: previous_structure = {} vdisks = previous_structure.get('vdisks', {}) vpools = previous_structure.get('vpools', {}) domains = previous_structure.get('domains', {}) services = previous_structure.get('services', {}) mds_services = previous_structure.get('mds_services', {}) storagerouters = previous_structure.get('storagerouters', {}) storagedrivers = previous_structure.get('storagedrivers', {}) storagerouter_domains = previous_structure.get('storagerouter_domains', {}) service_type = ServiceTypeList.get_by_name('MetadataServer') if service_type is None: service_type = ServiceType() service_type.name = 'MetadataServer' service_type.save() srclients = {} for domain_id in structure.get('domains', []): if domain_id not in domains: domain = Domain() domain.name = 'domain_{0}'.format(domain_id) domain.save() domains[domain_id] = domain for vpool_id in structure.get('vpools', []): if vpool_id not in vpools: vpool = VPool() vpool.name = str(vpool_id) vpool.status = 'RUNNING' vpool.save() vpools[vpool_id] = vpool else: vpool = vpools[vpool_id] srclients[vpool_id] = StorageRouterClient(vpool.guid, None) for sr_id in structure.get('storagerouters', []): if sr_id not in storagerouters: storagerouter = StorageRouter() storagerouter.name = str(sr_id) storagerouter.ip = '10.0.0.{0}'.format(sr_id) storagerouter.rdma_capable = False storagerouter.node_type = 'MASTER' storagerouter.machine_id = str(sr_id) storagerouter.save() storagerouters[sr_id] = storagerouter disk = Disk() disk.storagerouter = storagerouter disk.state = 'OK' disk.name = '/dev/uda' disk.size = 1 * 1024**4 disk.is_ssd = True disk.aliases = ['/dev/uda'] disk.save() partition = DiskPartition() partition.offset = 0 partition.size = disk.size partition.aliases = ['/dev/uda-1'] partition.state = 'OK' partition.mountpoint = '/tmp/unittest/sr_{0}/disk_1/partition_1'.format( sr_id) partition.disk = disk partition.roles = [ DiskPartition.ROLES.DB, DiskPartition.ROLES.SCRUB ] partition.save() for sd_id, vpool_id, sr_id in structure.get('storagedrivers', ()): if sd_id not in storagedrivers: storagedriver = StorageDriver() storagedriver.vpool = vpools[vpool_id] storagedriver.storagerouter = storagerouters[sr_id] storagedriver.name = str(sd_id) storagedriver.mountpoint = '/' storagedriver.cluster_ip = storagerouters[sr_id].ip storagedriver.storage_ip = '10.0.1.{0}'.format(sr_id) storagedriver.storagedriver_id = str(sd_id) storagedriver.ports = { 'management': 1, 'xmlrpc': 2, 'dtl': 3, 'edge': 4 } storagedriver.save() storagedrivers[sd_id] = storagedriver Helper._set_vpool_storage_driver_configuration( vpool=vpools[vpool_id], storagedriver=storagedriver) for mds_id, sd_id in structure.get('mds_services', ()): if mds_id not in mds_services: sd = storagedrivers[sd_id] s_id = '{0}-{1}'.format(sd.storagerouter.name, mds_id) service = Service() service.name = s_id service.storagerouter = sd.storagerouter service.ports = [mds_id] service.type = service_type service.save() services[s_id] = service mds_service = MDSService() mds_service.service = service mds_service.number = 0 mds_service.capacity = 10 mds_service.vpool = sd.vpool mds_service.save() mds_services[mds_id] = mds_service StorageDriverController.add_storagedriverpartition( sd, { 'size': None, 'role': DiskPartition.ROLES.DB, 'sub_role': StorageDriverPartition.SUBROLE.MDS, 'partition': sd.storagerouter.disks[0].partitions[0], 'mds_service': mds_service }) for vdisk_id, storage_driver_id, vpool_id, mds_id in structure.get( 'vdisks', ()): if vdisk_id not in vdisks: vpool = vpools[vpool_id] devicename = 'vdisk_{0}'.format(vdisk_id) mds_backend_config = Helper._generate_mdsmetadatabackendconfig( [] if mds_id is None else [mds_services[mds_id]]) volume_id = srclients[vpool_id].create_volume( devicename, mds_backend_config, 0, str(storage_driver_id)) vdisk = VDisk() vdisk.name = str(vdisk_id) vdisk.devicename = devicename vdisk.volume_id = volume_id vdisk.vpool = vpool vdisk.size = 0 vdisk.save() vdisk.reload_client('storagedriver') vdisks[vdisk_id] = vdisk for srd_id, sr_id, domain_id, backup in structure.get( 'storagerouter_domains', ()): if srd_id not in storagerouter_domains: sr_domain = StorageRouterDomain() sr_domain.backup = backup sr_domain.domain = domains[domain_id] sr_domain.storagerouter = storagerouters[sr_id] sr_domain.save() storagerouter_domains[srd_id] = sr_domain return { 'vdisks': vdisks, 'vpools': vpools, 'domains': domains, 'services': services, 'service_type': service_type, 'mds_services': mds_services, 'storagerouters': storagerouters, 'storagedrivers': storagedrivers, 'storagerouter_domains': storagerouter_domains }
def test_reusing_devicename(self): """ Validates whether the framework can handle out of sync processed events when a vDisk with the same devicename is created and removed over and over """ 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>) ) vpool = structure['vpools'][1] storagedriver = structure['storagedrivers'][1] mds_service = structure['mds_services'][1] # noinspection PyArgumentList backend_config = MDSMetaDataBackendConfig([ MDSNodeConfig(address=str(mds_service.service.storagerouter.ip), port=mds_service.service.ports[0]) ]) devicename = '/test.raw' size = 1024**3 srclient = StorageRouterClient(vpool.guid, None) # A normal flow would be: # * create volume, resize event, # * delete volume, delete event, # * create volume, resize event, # * delete volume, delete event # Let's test the normal flow first_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) VDiskController.resize_from_voldrv(first_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 1) srclient.unlink(devicename) VDiskController.delete_from_voldrv(first_volume_id) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 0) second_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) VDiskController.resize_from_voldrv(second_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 1) srclient.unlink(devicename) VDiskController.delete_from_voldrv(second_volume_id) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 0) # Out of sync - scenario 1 first_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) VDiskController.resize_from_voldrv(first_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 1) srclient.unlink(devicename) second_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) VDiskController.resize_from_voldrv(second_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 2) VDiskController.delete_from_voldrv(first_volume_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 1) srclient.unlink(devicename) VDiskController.delete_from_voldrv(second_volume_id) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 0) # Out of sync - scenario 2 first_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 0) srclient.unlink(devicename) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 0) second_volume_id = srclient.create_volume( devicename, backend_config, size, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 0) VDiskController.resize_from_voldrv(first_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 0) VDiskController.resize_from_voldrv(second_volume_id, size, devicename, storagedriver.storagedriver_id) self.assertEqual(len(srclient.list_volumes()), 1) self.assertEqual(len(vpool.vdisks), 1) srclient.unlink(devicename) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 1) VDiskController.delete_from_voldrv(first_volume_id) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 1) VDiskController.delete_from_voldrv(second_volume_id) self.assertEqual(len(srclient.list_volumes()), 0) self.assertEqual(len(vpool.vdisks), 0)
def test_sync(self): """ Validates whether the sync works as expected """ 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>) ) vpool = structure['vpools'][1] storagedriver = structure['storagedrivers'][1] mds_service = structure['mds_services'][1] # noinspection PyArgumentList backend_config = MDSMetaDataBackendConfig([ MDSNodeConfig(address=str(mds_service.service.storagerouter.ip), port=mds_service.service.ports[0]) ]) srclient = StorageRouterClient(vpool.guid, None) VDiskController.create_new('one', 1024**3, storagedriver.guid) VDiskController.create_new('two', 1024**3, storagedriver.guid) vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 2) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 2) volume_id = srclient.create_volume('/three.raw', backend_config, 1024**3, storagedriver.storagedriver_id) vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 2) self.assertEqual(len(srclient.list_volumes()), 3) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 3) self.assertEqual(len(srclient.list_volumes()), 3) vdisk = VDiskList.get_vdisk_by_volume_id(volume_id) self.assertEqual(vdisk.devicename, '/three.raw') vdisk = VDisk() vdisk.volume_id = 'foo' vdisk.name = 'foo' vdisk.devicename = 'foo.raw' vdisk.size = 1024**3 vdisk.vpool = vpool vdisk.save() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 4) self.assertEqual(len(srclient.list_volumes()), 3) VDiskController.sync_with_reality() vdisks = VDiskList.get_vdisks() self.assertEqual(len(vdisks), 3) self.assertEqual(len(srclient.list_volumes()), 3) with self.assertRaises(ObjectNotFoundException): vdisk.save()