def migrate_instances(self, ctxt, origin, destination, instances): migration = models.Migration() migration.id = str(uuid.uuid4()) migration.status = constants.MIGRATION_STATUS_RUNNING migration.origin = origin migration.destination = destination for instance in instances: task_export = models.Task() task_export.id = str(uuid.uuid4()) task_export.migration = migration task_export.instance = instance task_export.status = constants.TASK_STATUS_PENDING task_export.task_type = constants.TASK_TYPE_EXPORT_INSTANCE task_import = models.Task() task_import.id = str(uuid.uuid4()) task_import.migration = migration task_import.instance = instance task_import.status = constants.TASK_STATUS_PENDING task_import.task_type = constants.TASK_TYPE_IMPORT_INSTANCE task_import.depends_on = [task_export.id] db_api.add_migration(ctxt, migration) LOG.info("Migration created: %s", migration.id) for task in migration.tasks: if not task.depends_on: self._rpc_worker_client.begin_task( ctxt, server=None, task_id=task.id, task_type=task.task_type, origin=migration.origin, destination=migration.destination, instance=task.instance, task_info=None) return self.get_migration(ctxt, migration.id)
def migrate_instances(self, ctxt, origin_endpoint_id, destination_endpoint_id, source_environment, destination_environment, instances, network_map, storage_mappings, skip_os_morphing=False, notes=None): origin_endpoint = self.get_endpoint(ctxt, origin_endpoint_id) destination_endpoint = self.get_endpoint(ctxt, destination_endpoint_id) self._check_endpoints(ctxt, origin_endpoint, destination_endpoint) destination_provider_types = self._get_provider_types( ctxt, destination_endpoint) migration = models.Migration() migration.id = str(uuid.uuid4()) migration.origin_endpoint = origin_endpoint migration.destination_endpoint = destination_endpoint migration.destination_environment = destination_environment migration.source_environment = source_environment migration.network_map = network_map migration.storage_mappings = storage_mappings execution = models.TasksExecution() execution.status = constants.EXECUTION_STATUS_RUNNING execution.number = 1 migration.executions = [execution] migration.instances = instances migration.info = {} migration.notes = notes for instance in instances: task_validate = self._create_task( instance, constants.TASK_TYPE_VALIDATE_MIGRATION_INPUTS, execution) task_export = self._create_task( instance, constants.TASK_TYPE_EXPORT_INSTANCE, execution, depends_on=[task_validate.id]) if (constants.PROVIDER_TYPE_INSTANCE_FLAVOR in destination_provider_types): get_optimal_flavor_task = self._create_task( instance, constants.TASK_TYPE_GET_OPTIMAL_FLAVOR, execution, depends_on=[task_export.id]) next_task = get_optimal_flavor_task.id else: next_task = task_export.id task_import = self._create_task( instance, constants.TASK_TYPE_IMPORT_INSTANCE, execution, depends_on=[next_task]) task_deploy_disk_copy_resources = self._create_task( instance, constants.TASK_TYPE_DEPLOY_DISK_COPY_RESOURCES, execution, depends_on=[task_import.id]) task_copy_disk = self._create_task( instance, constants.TASK_TYPE_COPY_DISK_DATA, execution, depends_on=[task_deploy_disk_copy_resources.id]) task_delete_disk_copy_resources = self._create_task( instance, constants.TASK_TYPE_DELETE_DISK_COPY_RESOURCES, execution, depends_on=[task_copy_disk.id], on_error=True) if not skip_os_morphing: task_deploy_os_morphing_resources = self._create_task( instance, constants.TASK_TYPE_DEPLOY_OS_MORPHING_RESOURCES, execution, depends_on=[task_delete_disk_copy_resources.id]) task_osmorphing = self._create_task( instance, constants.TASK_TYPE_OS_MORPHING, execution, depends_on=[task_deploy_os_morphing_resources.id]) task_delete_os_morphing_resources = self._create_task( instance, constants.TASK_TYPE_DELETE_OS_MORPHING_RESOURCES, execution, depends_on=[task_osmorphing.id], on_error=True) next_task = task_delete_os_morphing_resources else: next_task = task_delete_disk_copy_resources self._create_task(instance, constants.TASK_TYPE_FINALIZE_IMPORT_INSTANCE, execution, depends_on=[next_task.id]) self._create_task( instance, constants.TASK_TYPE_CLEANUP_FAILED_IMPORT_INSTANCE, execution, on_error=True) db_api.add_migration(ctxt, migration) LOG.info("Migration created: %s", migration.id) self._begin_tasks(ctxt, execution) return self.get_migration(ctxt, migration.id)
def deploy_replica_instances(self, ctxt, replica_id, clone_disks, force, skip_os_morphing=False): replica = self._get_replica(ctxt, replica_id) self._check_replica_running_executions(ctxt, replica) self._check_valid_replica_tasks_execution(replica, force) destination_endpoint = self.get_endpoint( ctxt, replica.destination_endpoint_id) destination_provider_types = self._get_provider_types( ctxt, destination_endpoint) for instance, info in replica.info.items(): if not info.get("volumes_info"): raise exception.InvalidReplicaState( "The replica doesn't contain volumes information for " "instance: %s. If replicated disks are deleted, the " "replica needs to be executed anew before a migration can " "occur" % instance) instances = replica.instances migration = models.Migration() migration.id = str(uuid.uuid4()) migration.origin_endpoint_id = replica.origin_endpoint_id migration.destination_endpoint_id = replica.destination_endpoint_id migration.destination_environment = replica.destination_environment migration.source_environment = replica.source_environment migration.network_map = replica.network_map migration.storage_mappings = replica.storage_mappings migration.instances = instances migration.replica = replica migration.info = replica.info for instance in instances: migration.info[instance]["clone_disks"] = clone_disks execution = models.TasksExecution() migration.executions = [execution] execution.status = constants.EXECUTION_STATUS_RUNNING execution.number = 1 for instance in instances: validate_replica_desployment_inputs_task = self._create_task( instance, constants.TASK_TYPE_VALIDATE_REPLICA_DEPLOYMENT_INPUTS, execution) create_snapshot_task_depends_on = [ validate_replica_desployment_inputs_task.id ] if (constants.PROVIDER_TYPE_INSTANCE_FLAVOR in destination_provider_types): get_optimal_flavor_task = self._create_task( instance, constants.TASK_TYPE_GET_OPTIMAL_FLAVOR, execution, depends_on=[validate_replica_desployment_inputs_task.id]) create_snapshot_task_depends_on.append( get_optimal_flavor_task.id) create_snapshot_task = self._create_task( instance, constants.TASK_TYPE_CREATE_REPLICA_DISK_SNAPSHOTS, execution, depends_on=create_snapshot_task_depends_on) deploy_replica_task = self._create_task( instance, constants.TASK_TYPE_DEPLOY_REPLICA_INSTANCE, execution, [create_snapshot_task.id]) if not skip_os_morphing: task_deploy_os_morphing_resources = self._create_task( instance, constants.TASK_TYPE_DEPLOY_OS_MORPHING_RESOURCES, execution, depends_on=[deploy_replica_task.id]) task_osmorphing = self._create_task( instance, constants.TASK_TYPE_OS_MORPHING, execution, depends_on=[task_deploy_os_morphing_resources.id]) task_delete_os_morphing_resources = self._create_task( instance, constants.TASK_TYPE_DELETE_OS_MORPHING_RESOURCES, execution, depends_on=[task_osmorphing.id], on_error=True) next_task = task_delete_os_morphing_resources else: next_task = deploy_replica_task finalize_deployment_task = self._create_task( instance, constants.TASK_TYPE_FINALIZE_REPLICA_INSTANCE_DEPLOYMENT, execution, depends_on=[next_task.id]) self._create_task( instance, constants.TASK_TYPE_DELETE_REPLICA_DISK_SNAPSHOTS, execution, depends_on=[finalize_deployment_task.id], on_error=clone_disks) cleanup_deployment_task = self._create_task( instance, constants.TASK_TYPE_CLEANUP_FAILED_REPLICA_INSTANCE_DEPLOYMENT, execution, on_error=True) if not clone_disks: self._create_task( instance, constants.TASK_TYPE_RESTORE_REPLICA_DISK_SNAPSHOTS, execution, depends_on=[cleanup_deployment_task.id], on_error=True) db_api.add_migration(ctxt, migration) LOG.info("Migration created: %s", migration.id) self._begin_tasks(ctxt, execution, migration.info) return self.get_migration(ctxt, migration.id)