def _create_migration(self, ctxt, migration_ref): """ Migration setps: Step - 1: Get resource object, R Step - 2: Get the source cloud, S Step - 3: Get the destination cloud, D Step - 4: Check if D is destination Step - 5: Check if S support R migration Step - 6: Check if D support R migration Step - 7: Load source driver, source_driver Step - 8: Load destination driver, dest_driver Step - 9: Call R's migration method """ utils.migration_status_update(migration_ref, 'INITIATING', 'validating') try: # NOTE(Step - 1): Get resource object, R resource = objects.Resource.get_by_id(ctxt, migration_ref.resource_id) # NOTE(Step - 2): Get the source cloud, S source = objects.Cloud.get_by_id(ctxt, resource.cloud_id) # NOTE(Step - 3): Get the destination cloud, D dest = objects.Cloud.get_by_id(ctxt, migration_ref.destination_cloud_id) except exception.GutsException as error: LOG.exception(error.message) utils.migration_status_update(migration_ref, 'FAILED', '-', error.message) raise exception.MigrationFailed(messaage=error.message) except Exception as error: LOG.exception(error.message) utils.migration_status_update(migration_ref, 'FAILED', '-', error.message) raise exception.MigrationFailed(message=error.message) LOG.info(_LI('Starting %(r_name)s migration from %(s_name)s cloud ' 'to %(d_name)s cloud.') % {'r_name': resource.name, 's_name': source.name, 'd_name': dest.name}) # NOTE(Step - 4): Verify D supports R migration if dest.type != "destination": msg = (_('Cloud %(cloud_name)s is not a destination Cloud.'), {'cloud_name': dest.name}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 5): Check if S support R migration if resource.type not in ast.literal_eval(source.capabilities): msg = (_('%(resource_type)s resource migration not supported by ' 'the source cloud %(cloud_name)s.'), {'resource_type': resource.type, 'cloud_name': source.name}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 6): Check if D support R migration if resource.type not in ast.literal_eval(dest.capabilities): msg = (_('%(resource_type)s resource migration not supported by ' 'the destination cloud %(cloud_name)s.'), {'resource_type': resource.type, 'cloud_name': dest.name}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 7): Load source driver, source_driver try: source_driver = importutils.import_object(source.driver, cloud=source) except Exception: msg = (_('Failed to load source driver: %s') % source.driver) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 8): Load destination driver, dest_driver try: dest_driver = importutils.import_object(dest.driver, cloud=dest) except Exception: msg = (_('Failed to load destination driver: %s') % dest.driver) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 9): Call migration method try: self._migrate_resource(migration_ref, resource, source_driver, dest_driver) except AttributeError: msg = (_('Method %(name)s not implemented in the manager:') % {'name': method_name}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) except exception.OpenStackException as error: msg = (_('Failed fetch resource %(r_name)s properties from ' '%(s_name)s cloud: %(err)s') % {'r_name': resource.name, 's_name': source.name, 'err': error}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg)
def _migrate_resource(self, migration_ref, resource_ref, source_driver, dest_driver): """ Steps to migrate users Step - 1: Check if user still exist on source cloud, get properties, if exists Step - 2: Get the required params list from destination cloud, to create user Step - 3: Asign source user properties to the destination params Step - 4: Send assigned properties to destination to create user """ utils.migration_status_update(migration_ref, 'INPROGRESS', 'fetching from source') # NOTE(Step - 1): Check if user still exist on source cloud, get # properties, if exists source_resource_id = resource_ref.id_at_source try: meth = getattr(source_driver, 'get_%s' % resource_ref.type) if resource_ref.type in ['instance', 'image', 'volume']: con_dir = create_con_dir(migration_ref.id) source_resource_properties = meth(source_resource_id, con_dir) else: source_resource_properties = meth(source_resource_id) except Exception as error: msg = (_('Failed to fetch resource %(resource_id)s properties from source ' 'cloud. Reason: %(reason)s') % {'resource_id': source_resource_id, 'reason': error.message}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) # NOTE(Step - 2): Get the required params list from destination cloud, # to create user try: meth = getattr(dest_driver, 'get_%s_params' % resource_ref.type) required_params = meth() except Exception as error: msg = (_('Failed to fetch required resource properties from destination ' 'cloud. Reason: %s') % error.message) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) resource_params = {} # NOTE(Step - 3): Asign source user properties to the destination params utils.migration_status_update(migration_ref, event='creating at destination') for param in required_params['from_source'].keys(): from_source = source_resource_properties.get(param) from_user = migration_ref.properties.get(param) val = from_user or from_source if val: required_params['from_source'][param] = val for param in required_params['from_user'].keys(): val = migration_ref.properties.get(param) if val: required_params['from_user'][param] = val # NOTE(Step - 4): Send assigned properties to destination to create resource resource_params = required_params['from_source'].copy() resource_params.update(required_params['from_user']) try: meth = getattr(dest_driver, 'create_%s' % resource_ref.type) meth(resource_params) except Exception as error: msg = (_('Failed to create resource at the destination with ' 'params: %(param)s. Reason: %(err)s') % {'param': resource_params, 'err': error}) LOG.exception(msg) utils.migration_status_update(migration_ref, 'FAILED', '-', msg) raise exception.MigrationFailed(message=msg) utils.migration_status_update(migration_ref, 'SUCCESS', '-')
def create_migration(self, ctxt, migration_ref): try: self._create_migration(ctxt, migration_ref) except Exception as error: msg = (_('%s') % error) utils.migration_status_update(migration_ref, 'FAILED', '-', msg)