def get_existing_exports(self): """ Result of descovering - dict of dicts in the form: { 'devicename': '5ce99e968d67ded2', 'guid': UUID('600144f0-0001-8aa6-91a2-19f911e39d8f'), 'has_errors': False, 'luns': { 'pserver123': '26'}, 'read_only': False, 'volume': '/dev/storage/0001-8aa6-91a2-19f911e39d8f'} Keys of the upper dict are the SCST devicenames. """ self.existing_exports = {} first = True pb_lv_pattern = (r'^' + os.sep + os.path.join('dev', self.storage_vg) + os.sep + r'((?:[0-9a-f]{4}-){3}[0-9a-f]{12})$') if self.verbose > 2: log.debug("Search pattern for ProfiBricks volumes: %r", pb_lv_pattern) pb_lv = re.compile(pb_lv_pattern) pattern = os.path.join(SCST_DEV_DIR, '*') log.debug("Searching for SCST devices in %r ...", pattern) dev_dirs = glob.glob(pattern) for dev_dir in dev_dirs: vl = 4 if first: vl = 2 filename_file = os.path.join(dev_dir, 'filename') handler_link = os.path.join(dev_dir, 'handler') has_errors = False read_only = False if not os.path.exists(filename_file): continue if not os.path.exists(handler_link): continue self.count['exported_devs'] += 1 exported_dir = os.path.join(dev_dir, 'exported') luns = {} if os.path.isdir(exported_dir): exports = glob.glob(os.path.join(exported_dir, '*')) nr_exports = 0 for export_link in exports: nr_exports += 1 link_target = os.readlink(export_link) if os.path.isabs(link_target): lun_dir = os.path.realpath(export_link) else: lun_dir = os.path.realpath(os.path.relpath(link_target, os.path.dirname(export_link))) ini_group = os.path.basename(os.path.dirname(os.path.dirname(lun_dir))) lun_nr = os.path.basename(lun_dir) luns[ini_group] = {'id': lun_nr, 'checked': False} self.count['exported_luns'] += 1 # if nr_exports > 1: # vl = 2 devname = os.path.basename(dev_dir) export_filename = self.get_scst_export_filename(filename_file) if not export_filename: log.info("No devicename found for export %r.", devname) self.count['error'] += 1 continue match = pb_lv.search(export_filename) if not match: if self.verbose > 2: log.debug("Export %r for device %r is not a regular ProfitBricks volume.", devname, export_filename) self.count['alien'] += 1 continue short_guid = match.group(1) if short_guid == DUMMY_LV and devname == DUMMY_CRC: if self.verbose > 1: log.debug("Found the exported notorious dummy device.") self.count['dummy'] += 1 continue guid = '600144f0-' + short_guid digest = crc64_digest(guid) if not digest == devname: log.info(("Found mismatch between volume name %r and SCST " "device name %r (should be %r)."), export_filename, devname, digest) self.count['error'] += 1 continue fc_ph_id_expected = guid.replace('-', '') fc_ph_id_current = self.get_fc_ph_id(dev_dir) if fc_ph_id_expected != fc_ph_id_current: log.info("Export %r for device %r has wrong fc_ph_id %r.", devname, export_filename, fc_ph_id_current) has_errors = True read_only = self.get_read_only(dev_dir) if read_only is None: has_errors = True export = { 'devicename': devname, 'volume': export_filename, 'guid': uuid.UUID(guid), 'read_only': read_only, 'has_errors': has_errors, 'luns': luns, 'checked': False, } self.existing_exports[devname] = export if has_errors: self.count['error'] += 1 if self.verbose > 2: log.debug("Found export %r.", devname) if self.verbose > vl: log.debug("Got existing export:\n%s", pp(export)) if first: first = False
def get_api_storage_exports(self): self.storage_exports = [] api_volumes = {} key_replicated = 'replicated' key_replicas = 'replicas' key_storage_server = 'storage_server' key_guid = 'guid' key_uuid = 'uuid' key_pstorage_name = 'pstorage_name' key_vstorage_uuid = 'vstorage_uuid' key_pserver_name = 'pserver_name' if sys.version_info[0] <= 2: key_replicated = key_replicated.decode('utf-8') key_replicas = key_replicas.decode('utf-8') key_storage_server = key_storage_server.decode('utf-8') key_guid = key_guid.decode('utf-8') key_uuid = key_uuid.decode('utf-8') key_pstorage_name = key_pstorage_name.decode('utf-8') key_vstorage_uuid = key_vstorage_uuid.decode('utf-8') key_pserver_name = key_pserver_name.decode('utf-8') log.debug("Retrieving storage volumes from API ...") storages = None try: storages = self.api.vstorages(pstorage=self.hostname, contract_infos=False) except RestApiError as e: self.die(str(e)) except Exception as e: self.die("%s: %s" % (e.__class__.__name__, e)) first = True for stor in storages: """ { 'cloned_from': None, 'cluster': 'de-ka-cluster-01', 'contract': 31721232, 'creation_date': '2014-05-21T04:10:38.399', 'modification_date': '2014-05-21T04:15:35.620', 'name': 'DWDCStorage_EMEA_D_Mirror', 'os_type': None, 'physical_server': 'pserver117', 'region': 'europe', 'replicas': [ { 'guid': '600144f0-0001-dc9b-0121-e09d11e3920c', 'storage_server': 'storage201', 'virtual_state': 'AVAILABLE'}, { 'guid': '600144f0-0001-dc98-6910-e09d11e3920c', 'storage_server': 'storage103', 'virtual_state': 'AVAILABLE'}], 'size': 716800, 'uuid': 'e7abbe07-3d3e-4468-9af4-1bfe8af418dc', 'virtual_network': '61ba3819-d719-4986-b59d-c6178a32aabe'} """ vl = 4 if first: vl = 2 if self.verbose > vl: log.debug("Got Storage volume from API:\n%s", pp(stor)) replicated = True if key_replicated in stor: replicated = stor[key_replicated] vol_uuid = uuid.UUID(stor[key_uuid]) guid = None for replica in stor[key_replicas]: hn = replica[key_storage_server] if sys.version_info[0] <= 2: hn = hn.encode('utf-8') if hn == self.hostname: guid = uuid.UUID(replica[key_guid]) break if not guid: log.debug("No valid GUID found for storage volume:\n%s", pp(stor)) continue vol = { 'guid': guid, 'replicated': replicated, } api_volumes[vol_uuid] = vol if self.verbose > vl: log.debug("Transformed Storage volume %r:\n%s", vol_uuid, pp(vol)) if first: first = False log.debug("Retrieving storage mappings from API ...") maps = None try: maps = self.api.vstorage_maps(pstorage=self.hostname) except RestApiError as e: self.die(str(e)) except Exception as e: self.die("%s: %s" % (e.__class__.__name__, e)) first = True for mapping in maps: """ { 'boot_order': 1, 'creation_date': '2014-05-23T08:42:32.770', 'dc_name': 'BKK Pfalz', 'modification_date': '2014-05-23T08:42:32.770', 'mount_state': 'AVAILABLE', 'mount_type': 'VIRTIO', 'mount_uuid': '8b30c7e8-f9fb-41b3-8b1d-723e1c41ee99', 'network_uuid': '485abc1d-ec56-81d0-24cc-621cde8f34dc', 'order_nr': 1, 'pserver_name': 'pserver220', 'pserver_uuid': '48385147-3600-0030-48FF-003048FF26B2', 'pstorage_name': 'storage201', 'pstorage_uuid': '49434D53-0200-9071-2500-71902500F26D', 'size_mb': 102400, 'vm_name': 'replacement', 'vm_uuid': '001f75f0-fa36-40cc-a628-060d2ecdccc1', 'vstorage_guid': None, 'vstorage_name': 'BKK Storage 2', 'vstorage_uuid': '64f9dd3a-6db9-4405-a023-a0d32203c2aa'} """ if mapping[key_pstorage_name] != self.hostname: continue pserver = mapping[key_pserver_name] if pserver is None: continue if pserver not in self.valid_pservers: log.debug("Storage export to %r not considered.", pserver) continue vl = 4 if first: vl = 2 if self.verbose > vl: log.debug("Got Storage mapping from API:\n%s", pp(mapping)) vol_uuid = uuid.UUID(mapping[key_vstorage_uuid]) if vol_uuid not in api_volumes: log.error("No volume for mapping of %r found.", vol_uuid) continue guid = api_volumes[vol_uuid]['guid'] scst_devname = crc64_digest(str(guid)) if sys.version_info[0] <= 2: pserver = pserver.encode('utf-8') m = { 'uuid': vol_uuid, 'guid': guid, 'scst_devname': scst_devname, 'replicated': api_volumes[vol_uuid]['replicated'], 'pserver': pserver, 'checked': False, } self.storage_exports.append(m) if self.verbose > vl: log.debug("Transformed storage mapping:\n%s", pp(m)) if first: first = False log.debug("Finished retrieving storage mappings from API, found %d mappings.", len(self.storage_exports))
def get_api_image_exports(self): self.image_exports = [] api_volumes = {} key_replicated = 'replicate' key_replicas = 'replicas' key_storage_server = 'storage_server' key_guid = 'guid' key_uuid = 'uuid' key_pstorage_name = 'pstorage_name' key_vstorage_uuid = 'vstorage_uuid' key_image_uuid = 'image_uuid' key_pserver_name = 'pserver_name' if sys.version_info[0] <= 2: key_replicated = key_replicated.decode('utf-8') key_replicas = key_replicas.decode('utf-8') key_storage_server = key_storage_server.decode('utf-8') key_guid = key_guid.decode('utf-8') key_uuid = key_uuid.decode('utf-8') key_pstorage_name = key_pstorage_name.decode('utf-8') key_vstorage_uuid = key_vstorage_uuid.decode('utf-8') key_image_uuid = key_image_uuid.decode('utf-8') key_pserver_name = key_pserver_name.decode('utf-8') log.debug("Retrieving image volumes from API ...") images = None try: images = self.api.vimages(pstorage=self.hostname) except RestApiError as e: self.die(str(e)) except Exception as e: self.die("%s: %s" % (e.__class__.__name__, e)) first = True for img in images: """ { 'absolute_path': 'ftp://*****:*****@imageserver/3111/iso-images/XYZ.iso', 'contract': 31720930, 'creation_date': '2014-02-06T14:55:19.333', 'image_type': 'CDROM', 'modification_date': '2014-02-06T14:55:19.333', 'replicas': [ { 'guid': '600144f0-0001-d843-4c30-8f3e11e3ae16', 'storage_server': 'storage108', 'virtual_state': 'AVAILABLE'}, { 'guid': '600144f0-0001-d843-4c31-8f3e11e3ae16', 'storage_server': 'storage203', 'virtual_state': 'AVAILABLE'}], 'replicate': True, 'size': 272, 'uuid': 'b24d6e86-8f3e-11e3-b7e8-52540066fee9', 'virtual_state': 'AVAILABLE'} """ vl = 4 if first: vl = 2 if self.verbose > vl: log.debug("Got Image volume from API:\n%s", pp(img)) replicated = bool(img[key_replicated]) vol_uuid = uuid.UUID(img[key_uuid]) guid = None for replica in img[key_replicas]: hn = replica[key_storage_server] if sys.version_info[0] <= 2: hn = hn.encode('utf-8') if hn == self.hostname: guid = uuid.UUID(replica[key_guid]) break if not guid: log.debug("No valid GUID found for image volume:\n%s", pp(img)) continue vol = { 'guid': guid, 'replicated': replicated, } api_volumes[vol_uuid] = vol if self.verbose > vl: log.debug("Transformed Image volume %r:\n%s", vol_uuid, pp(vol)) if first: first = False log.debug("Retrieving image mappings from API ...") maps = None try: maps = self.api.vimage_maps(pstorage=self.hostname) except RestApiError as e: self.die(str(e)) except Exception as e: self.die("%s: %s" % (e.__class__.__name__, e)) first = True for mapping in maps: """ { 'boot_order': 1, 'creation_date': '2014-03-03T09:23:35.748', 'dc_name': 'ldcb.tjasys.net', 'image_guid': '600144f0-0001-7e84-f65a-a2b511e3ad7d', 'image_legalentity': 12508, 'image_name': 'GSP1RMCPRXFREO_DE_DVD.ISO', 'image_size': 3271557120, 'image_type': 'CDROM', 'image_uuid': 'ada919ce-a284-11e3-b5f6-52540066fee9', 'modification_date': '2014-03-03T09:45:16.915', 'mount_state': 'DEALLOCATED', 'mount_type': 'IDE', 'mount_uuid': '0b778d45-b5ac-4be8-bd89-3b4de4e13491', 'network_uuid': '8ca30b27-9300-9b8e-dc84-f0349a0498de', 'order_nr': 1, 'pserver_name': None, 'pserver_uuid': None, 'pstorage_name': 'storage108', 'pstorage_uuid': '00000000-0000-0000-0000-002590A93640', 'replicated': True, 'size_mb': 3120, 'vm_name': 'Win7Test', 'vm_uuid': 'c1b53ee7-66a7-4dc9-8240-e50432438582'} """ if mapping[key_pstorage_name] != self.hostname: continue pserver = mapping[key_pserver_name] if pserver is None: continue if pserver not in self.valid_pservers: log.debug("Image export to %r not considered.", pserver) continue vl = 4 if first: vl = 2 if self.verbose > vl: log.debug("Got Image mapping from API:\n%s", pp(mapping)) if first: first = False vol_uuid = uuid.UUID(mapping[key_image_uuid]) if vol_uuid not in api_volumes: log.error("No volume for mapping of %r found.", vol_uuid) continue guid = api_volumes[vol_uuid]['guid'] scst_devname = crc64_digest(str(guid)) if sys.version_info[0] <= 2: pserver = pserver.encode('utf-8') m = { 'uuid': vol_uuid, 'guid': guid, 'scst_devname': scst_devname, 'replicated': api_volumes[vol_uuid]['replicated'], 'pserver': pserver, 'checked': False, } self.image_exports.append(m) if self.verbose > vl: log.debug("Transformed storage mapping:\n%s", pp(m)) log.debug("Finished retrieving image mappings from API, found %d mappings.", len(self.image_exports))
def _run(self): """The underlaying startpoint of the application.""" for token in self.args.tokens: digest = crc64_digest(token) print(digest)