Exemplo n.º 1
0
    def delete_replica_disks(self, ctxt, replica_id):
        replica = self._get_replica(ctxt, replica_id)
        self._check_replica_running_executions(ctxt, replica)

        execution = models.TasksExecution()
        execution.id = str(uuid.uuid4())
        execution.status = constants.EXECUTION_STATUS_RUNNING
        execution.action = replica

        has_tasks = False
        for instance in replica.instances:
            if (instance in replica.info
                    and "volumes_info" in replica.info[instance]):
                self._create_task(instance,
                                  constants.TASK_TYPE_DELETE_REPLICA_DISKS,
                                  execution)
                has_tasks = True

        if not has_tasks:
            raise exception.InvalidReplicaState(
                "This replica does not have volumes information for any "
                "instance. Ensure that the replica has been executed "
                "successfully priorly")

        db_api.add_replica_tasks_execution(ctxt, execution)
        LOG.info("Replica tasks execution created: %s", execution.id)

        self._begin_tasks(ctxt, execution, replica.info)
        return self.get_replica_tasks_execution(ctxt, replica_id, execution.id)
Exemplo n.º 2
0
 def _check_running_replica_migrations(ctxt, replica_id):
     migrations = db_api.get_replica_migrations(ctxt, replica_id)
     if [
             m.id for m in migrations
             if m.executions[0].status == constants.EXECUTION_STATUS_RUNNING
     ]:
         raise exception.InvalidReplicaState(
             "This replica is currently being migrated")
Exemplo n.º 3
0
 def cancel_replica_tasks_execution(self, ctxt, replica_id, execution_id,
                                    force):
     execution = self._get_replica_tasks_execution(ctxt, replica_id,
                                                   execution_id)
     if execution.status != constants.EXECUTION_STATUS_RUNNING:
         raise exception.InvalidReplicaState(
             "The replica tasks execution is not running")
     self._cancel_tasks_execution(ctxt, execution, force)
Exemplo n.º 4
0
    def _check_valid_replica_tasks_execution(replica, force=False):
        sorted_executions = sorted(replica.executions,
                                   key=lambda e: e.number,
                                   reverse=True)

        if (force and sorted_executions[0].status !=
                constants.EXECUTION_STATUS_COMPLETED):
            raise exception.InvalidReplicaState(
                "The last replica tasks execution was not successful. "
                "Perform a forced migration if you wish to perform a "
                "migration without a successful last replica execution")
        elif not [
                e for e in sorted_executions
                if e.status == constants.EXECUTION_STATUS_COMPLETED
        ]:
            raise exception.InvalidReplicaState(
                "A replica must have been executed succesfully in order "
                "to be migrated")
Exemplo n.º 5
0
    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)