def unclaim_disks(alba_backend): """ Un-claim disks :param alba_backend: ALBA backend :return: None """ # @TODO: Allow the unclaim of disks go sequentially or parallel (parallel should be default) alba_backend.invalidate_dynamics(['local_stack']) for disks in alba_backend.local_stack.values(): for disk_id, disk in disks.iteritems(): if disk['status'] in ['uninitialized']: continue asd_node = GeneralAlba.get_node_by_id(disk['node_id']) for osd_id in disk['asds'].keys(): current_safety = AlbaController.calculate_safety(alba_backend.guid, [osd_id]) data = {'asd_id': osd_id, 'safety': current_safety} GeneralAlba.logger.info(GeneralAlba.api.execute_post_action('alba/nodes', asd_node.guid, 'reset_asd', data, wait=True)) data = {'disk': '/dev/disk/by-id/' + disk_id} GeneralAlba.logger.info(GeneralAlba.api.execute_post_action('alba/nodes', asd_node.guid, 'remove_disk', data, wait=True))
def remove_asd(node_guid, asd_id, expected_safety): """ Removes an ASD :param node_guid: Guid of the node to remove an ASD from :type node_guid: str :param asd_id: ID of the ASD to remove :type asd_id: str :param expected_safety: Expected safety after having removed the ASD :type expected_safety: dict or None :return: Aliases of the disk on which the ASD was removed :rtype: list """ node = AlbaNode(node_guid) AlbaNodeController._logger.debug('Removing ASD {0} at node {1}'.format(asd_id, node.ip)) model_osd = None for disk in node.disks: for asd in disk.osds: if asd.osd_id == asd_id: model_osd = asd break if model_osd is not None: break if model_osd is not None: alba_backend = model_osd.alba_backend else: alba_backend = None asds = {} try: asds = node.client.get_asds() except (requests.ConnectionError, requests.Timeout, InvalidCredentialsError): AlbaNodeController._logger.warning('Could not connect to node {0} to validate ASD'.format(node.guid)) partition_alias = None for alias, asd_ids in asds.iteritems(): if asd_id in asd_ids: partition_alias = alias break if alba_backend is not None: if expected_safety is None: AlbaNodeController._logger.warning('Skipping safety check for ASD {0} on backend {1} - this is dangerous'.format(asd_id, alba_backend.guid)) else: final_safety = AlbaController.calculate_safety(alba_backend_guid=alba_backend.guid, removal_osd_ids=[asd_id]) safety_lost = final_safety['lost'] safety_crit = final_safety['critical'] if (safety_crit != 0 or safety_lost != 0) and (safety_crit != expected_safety['critical'] or safety_lost != expected_safety['lost']): raise RuntimeError('Cannot remove ASD {0} as the current safety is not as expected ({1} vs {2})'.format(asd_id, final_safety, expected_safety)) AlbaNodeController._logger.debug('Safety OK for ASD {0} on backend {1}'.format(asd_id, alba_backend.guid)) AlbaNodeController._logger.debug('Purging ASD {0} on backend {1}'.format(asd_id, alba_backend.guid)) AlbaController.remove_units(alba_backend_guid=alba_backend.guid, osd_ids=[asd_id]) else: AlbaNodeController._logger.warning('Could not match ASD {0} to any backend. Cannot purge'.format(asd_id)) disk_data = None if partition_alias is not None: AlbaNodeController._logger.debug('Removing ASD {0} from disk {1}'.format(asd_id, partition_alias)) for device_info in node.client.get_disks().itervalues(): if partition_alias in device_info['partition_aliases']: disk_data = device_info result = node.client.delete_asd(disk_id=device_info['aliases'][0].split('/')[-1], asd_id=asd_id) if result['_success'] is False: raise RuntimeError('Error removing ASD: {0}'.format(result['_error'])) if disk_data == {}: raise RuntimeError('Failed to find disk for partition with alias {0}'.format(partition_alias)) else: AlbaNodeController._logger.warning('Could not remove ASD from remote node (node down)'.format(asd_id)) if Configuration.exists(AlbaNodeController.ASD_CONFIG.format(asd_id), raw=True): Configuration.delete(AlbaNodeController.ASD_CONFIG_DIR.format(asd_id), raw=True) if model_osd is not None: model_osd.delete() if alba_backend is not None: alba_backend.invalidate_dynamics() alba_backend.backend.invalidate_dynamics() if node.storagerouter is not None: DiskController.sync_with_reality(storagerouter_guid=node.storagerouter_guid) return [] if disk_data is None else disk_data.get('aliases', [])
def remove_osd(node_guid, osd_id, expected_safety): """ Removes an OSD :param node_guid: Guid of the node to remove an OSD from :type node_guid: str :param osd_id: ID of the OSD to remove :type osd_id: str :param expected_safety: Expected safety after having removed the OSD :type expected_safety: dict or None :return: Aliases of the disk on which the OSD was removed :rtype: list """ # Retrieve corresponding OSD in model node = AlbaNode(node_guid) AlbaNodeController._logger.debug('Removing OSD {0} at node {1}'.format( osd_id, node.ip)) osd = AlbaOSDList.get_by_osd_id(osd_id) alba_backend = osd.alba_backend if expected_safety is None: AlbaNodeController._logger.warning( 'Skipping safety check for OSD {0} on backend {1} - this is dangerous' .format(osd_id, alba_backend.guid)) else: final_safety = AlbaController.calculate_safety( alba_backend_guid=alba_backend.guid, removal_osd_ids=[osd_id]) safety_lost = final_safety['lost'] safety_crit = final_safety['critical'] if (safety_crit != 0 or safety_lost != 0) and ( safety_crit != expected_safety['critical'] or safety_lost != expected_safety['lost']): raise RuntimeError( 'Cannot remove OSD {0} as the current safety is not as expected ({1} vs {2})' .format(osd_id, final_safety, expected_safety)) AlbaNodeController._logger.debug( 'Safety OK for OSD {0} on backend {1}'.format( osd_id, alba_backend.guid)) AlbaNodeController._logger.debug( 'Purging OSD {0} on backend {1}'.format(osd_id, alba_backend.guid)) AlbaController.remove_units(alba_backend_guid=alba_backend.guid, osd_ids=[osd_id]) # Delete the OSD result = node.client.delete_osd(slot_id=osd.slot_id, osd_id=osd_id) if result['_success'] is False: raise RuntimeError('Error removing OSD: {0}'.format( result['_error'])) # Clean configuration management and model - Well, just try it at least if Configuration.exists(ASD_CONFIG.format(osd_id), raw=True): Configuration.delete(ASD_CONFIG_DIR.format(osd_id), raw=True) osd.delete() node.invalidate_dynamics() if alba_backend is not None: alba_backend.invalidate_dynamics() alba_backend.backend.invalidate_dynamics() if node.storagerouter is not None: try: DiskController.sync_with_reality( storagerouter_guid=node.storagerouter_guid) except UnableToConnectException: AlbaNodeController._logger.warning( 'Skipping disk sync since StorageRouter {0} is offline'. format(node.storagerouter.name)) return [osd.slot_id]