Переглянути джерело

Avoid loading Executions on Replica listing operations.

Nashwan Azhari 5 роки тому
батько
коміт
9cc1b9345c

+ 16 - 8
coriolis/conductor/rpc/server.py

@@ -687,9 +687,15 @@ class ConductorServerEndpoint(object):
                     raise
                     raise
                 newly_started_tasks.append(task.id)
                 newly_started_tasks.append(task.id)
 
 
-        # NOTE: this should never happen if _check_execution_tasks_sanity
-        # was called before this method:
-        if not newly_started_tasks:
+        if newly_started_tasks:
+            LOG.info(
+                "Started the following tasks for Execution '%s': %s",
+                execution.id, newly_started_tasks)
+            self._set_tasks_execution_status(
+                ctxt, execution.id, constants.TASK_STATUS_RUNNING)
+        else:
+            # NOTE: this should never happen if _check_execution_tasks_sanity
+            # was called before this method:
             raise exception.InvalidActionTasksExecutionState(
             raise exception.InvalidActionTasksExecutionState(
                 "No tasks were started at the beginning of execution '%s'" % (
                 "No tasks were started at the beginning of execution '%s'" % (
                     execution.id))
                     execution.id))
@@ -834,8 +840,8 @@ class ConductorServerEndpoint(object):
         self._check_replica_running_executions(ctxt, replica)
         self._check_replica_running_executions(ctxt, replica)
         execution = models.TasksExecution()
         execution = models.TasksExecution()
         execution.id = str(uuid.uuid4())
         execution.id = str(uuid.uuid4())
-        execution.status = constants.EXECUTION_STATUS_RUNNING
         execution.action = replica
         execution.action = replica
+        execution.status = constants.EXECUTION_STATUS_UNEXECUTED
         execution.type = constants.EXECUTION_TYPE_REPLICA_EXECUTION
         execution.type = constants.EXECUTION_TYPE_REPLICA_EXECUTION
 
 
         # TODO(aznashwan): have these passed separately to the relevant
         # TODO(aznashwan): have these passed separately to the relevant
@@ -1011,7 +1017,7 @@ class ConductorServerEndpoint(object):
 
 
         execution = models.TasksExecution()
         execution = models.TasksExecution()
         execution.id = str(uuid.uuid4())
         execution.id = str(uuid.uuid4())
-        execution.status = constants.EXECUTION_STATUS_RUNNING
+        execution.status = constants.EXECUTION_STATUS_UNEXECUTED
         execution.action = replica
         execution.action = replica
         execution.type = constants.EXECUTION_TYPE_REPLICA_DISKS_DELETE
         execution.type = constants.EXECUTION_TYPE_REPLICA_DISKS_DELETE
 
 
@@ -1082,6 +1088,7 @@ class ConductorServerEndpoint(object):
         replica.destination_endpoint_id = destination_endpoint_id
         replica.destination_endpoint_id = destination_endpoint_id
         replica.destination_environment = destination_environment
         replica.destination_environment = destination_environment
         replica.source_environment = source_environment
         replica.source_environment = source_environment
+        replica.last_execution_status = constants.EXECUTION_STATUS_UNEXECUTED
         replica.instances = instances
         replica.instances = instances
         replica.executions = []
         replica.executions = []
         replica.info = {instance: {
         replica.info = {instance: {
@@ -1202,7 +1209,7 @@ class ConductorServerEndpoint(object):
 
 
         execution = models.TasksExecution()
         execution = models.TasksExecution()
         migration.executions = [execution]
         migration.executions = [execution]
-        execution.status = constants.EXECUTION_STATUS_RUNNING
+        execution.status = constants.EXECUTION_STATUS_UNEXECUTED
         execution.number = 1
         execution.number = 1
         execution.type = constants.EXECUTION_TYPE_REPLICA_DEPLOY
         execution.type = constants.EXECUTION_TYPE_REPLICA_DEPLOY
 
 
@@ -1347,8 +1354,9 @@ class ConductorServerEndpoint(object):
         migration.source_environment = source_environment
         migration.source_environment = source_environment
         migration.network_map = network_map
         migration.network_map = network_map
         migration.storage_mappings = storage_mappings
         migration.storage_mappings = storage_mappings
+        migration.last_execution_status = constants.EXECUTION_STATUS_UNEXECUTED
         execution = models.TasksExecution()
         execution = models.TasksExecution()
-        execution.status = constants.EXECUTION_STATUS_RUNNING
+        execution.status = constants.EXECUTION_STATUS_UNEXECUTED
         execution.number = 1
         execution.number = 1
         execution.type = constants.EXECUTION_TYPE_MIGRATION
         execution.type = constants.EXECUTION_TYPE_MIGRATION
         migration.executions = [execution]
         migration.executions = [execution]
@@ -2679,7 +2687,7 @@ class ConductorServerEndpoint(object):
         self._check_valid_replica_tasks_execution(replica, force=True)
         self._check_valid_replica_tasks_execution(replica, force=True)
         execution = models.TasksExecution()
         execution = models.TasksExecution()
         execution.id = str(uuid.uuid4())
         execution.id = str(uuid.uuid4())
-        execution.status = constants.EXECUTION_STATUS_RUNNING
+        execution.status = constants.EXECUTION_STATUS_UNEXECUTED
         execution.action = replica
         execution.action = replica
         execution.type = constants.EXECUTION_TYPE_REPLICA_UPDATE
         execution.type = constants.EXECUTION_TYPE_REPLICA_UPDATE
 
 

+ 1 - 0
coriolis/constants.py

@@ -3,6 +3,7 @@
 
 
 DEFAULT_CORIOLIS_REGION_NAME = "Default Region"
 DEFAULT_CORIOLIS_REGION_NAME = "Default Region"
 
 
+EXECUTION_STATUS_UNEXECUTED = "UNEXECUTED"
 EXECUTION_STATUS_RUNNING = "RUNNING"
 EXECUTION_STATUS_RUNNING = "RUNNING"
 EXECUTION_STATUS_COMPLETED = "COMPLETED"
 EXECUTION_STATUS_COMPLETED = "COMPLETED"
 EXECUTION_STATUS_ERROR = "ERROR"
 EXECUTION_STATUS_ERROR = "ERROR"

+ 20 - 3
coriolis/db/api.py

@@ -420,7 +420,11 @@ def get_replicas(context,
             models.Replica.project_id == context.tenant)
             models.Replica.project_id == context.tenant)
     db_result = q.all()
     db_result = q.all()
     if to_dict:
     if to_dict:
-        return [i.to_dict(include_info=include_info) for i in db_result]
+        return [
+            i.to_dict(
+                include_info=include_info,
+                include_executions=include_tasks_executions)
+            for i in db_result]
     return db_result
     return db_result
 
 
 
 
@@ -502,7 +506,9 @@ def get_migrations(context, include_tasks=False,
         args["project_id"] = context.tenant
         args["project_id"] = context.tenant
     result = q.filter_by(**args).all()
     result = q.filter_by(**args).all()
     if to_dict:
     if to_dict:
-        return [i.to_dict(include_info=include_info) for i in result]
+        return [i.to_dict(
+            include_info=include_info,
+            include_tasks=include_tasks) for i in result]
     return result
     return result
 
 
 
 
@@ -550,7 +556,8 @@ def delete_migration(context, migration_id):
 
 
 
 
 @enginefacade.writer
 @enginefacade.writer
-def set_execution_status(context, execution_id, status):
+def set_execution_status(
+        context, execution_id, status, update_action_status=True):
     execution = _soft_delete_aware_query(
     execution = _soft_delete_aware_query(
         context, models.TasksExecution).join(
         context, models.TasksExecution).join(
             models.TasksExecution.action)
             models.TasksExecution.action)
@@ -564,6 +571,9 @@ def set_execution_status(context, execution_id, status):
             "Tasks execution not found: %s" % execution_id)
             "Tasks execution not found: %s" % execution_id)
 
 
     execution.status = status
     execution.status = status
+    if update_action_status:
+        set_action_last_execution_status(
+            context, execution.action_id, status)
 
 
 
 
 @enginefacade.reader
 @enginefacade.reader
@@ -581,6 +591,13 @@ def get_action(context, action_id):
     return action
     return action
 
 
 
 
+@enginefacade.writer
+def set_action_last_execution_status(
+        context, action_id, last_execution_status):
+    action = get_action(context, action_id)
+    action.last_execution_status = last_execution_status
+
+
 @enginefacade.writer
 @enginefacade.writer
 def update_transfer_action_info_for_instance(
 def update_transfer_action_info_for_instance(
         context, action_id, instance, new_instance_info):
         context, action_id, instance, new_instance_info):

+ 18 - 0
coriolis/db/sqlalchemy/migrate_repo/versions/015_adds_action_last_execution_status.py

@@ -0,0 +1,18 @@
+# Copyright 2020 Cloudbase Solutions Srl
+# All Rights Reserved.
+
+import sqlalchemy
+
+
+def upgrade(migrate_engine):
+    meta = sqlalchemy.MetaData()
+    meta.bind = migrate_engine
+
+    # add 'last_execution_status' column to 'base_transfer_action':
+    base_transfer_action = sqlalchemy.Table(
+        'base_transfer_action', meta, autoload=True)
+
+    last_execution_status = sqlalchemy.Column(
+        "last_execution_status", sqlalchemy.String(255),
+        default=lambda: "UNEXECUTED", nullable=False)
+    base_transfer_action.create_column(last_execution_status)

+ 13 - 7
coriolis/db/sqlalchemy/models.py

@@ -180,6 +180,9 @@ class BaseTransferAction(BASE, models.TimestampMixin, models.ModelBase,
                                   "base_id==TasksExecution.action_id, "
                                   "base_id==TasksExecution.action_id, "
                                   "TasksExecution.deleted=='0')")
                                   "TasksExecution.deleted=='0')")
     instances = sqlalchemy.Column(types.List, nullable=False)
     instances = sqlalchemy.Column(types.List, nullable=False)
+    last_execution_status = sqlalchemy.Column(
+        sqlalchemy.String(255), nullable=False,
+        default=lambda: constants.EXECUTION_STATUS_UNEXECUTED)
     reservation_id = sqlalchemy.Column(sqlalchemy.String(36), nullable=True)
     reservation_id = sqlalchemy.Column(sqlalchemy.String(36), nullable=True)
     info = sqlalchemy.Column(types.Bson, nullable=False)
     info = sqlalchemy.Column(types.Bson, nullable=False)
     notes = sqlalchemy.Column(sqlalchemy.Text, nullable=True)
     notes = sqlalchemy.Column(sqlalchemy.Text, nullable=True)
@@ -199,7 +202,7 @@ class BaseTransferAction(BASE, models.TimestampMixin, models.ModelBase,
         'polymorphic_on': type,
         'polymorphic_on': type,
     }
     }
 
 
-    def to_dict(self, include_info=True):
+    def to_dict(self, include_info=True, include_executions=True):
         result = {
         result = {
             "base_id": self.base_id,
             "base_id": self.base_id,
             "user_id": self.user_id,
             "user_id": self.user_id,
@@ -216,13 +219,15 @@ class BaseTransferAction(BASE, models.TimestampMixin, models.ModelBase,
             "network_map": self.network_map,
             "network_map": self.network_map,
             "storage_mappings": self.storage_mappings,
             "storage_mappings": self.storage_mappings,
             "source_environment": self.source_environment,
             "source_environment": self.source_environment,
+            "last_execution_status": self.last_execution_status,
             "created_at": self.created_at,
             "created_at": self.created_at,
             "updated_at": self.updated_at,
             "updated_at": self.updated_at,
             "deleted_at": self.deleted_at,
             "deleted_at": self.deleted_at,
             "deleted": self.deleted,
             "deleted": self.deleted,
         }
         }
-        for ex in self.executions:
-            result["executions"].append(ex.to_dict())
+        if include_executions:
+            for ex in self.executions:
+                result["executions"].append(ex.to_dict())
         if include_info:
         if include_info:
             result["info"] = self.info
             result["info"] = self.info
         return result
         return result
@@ -240,9 +245,10 @@ class Replica(BaseTransferAction):
         'polymorphic_identity': 'replica',
         'polymorphic_identity': 'replica',
     }
     }
 
 
-    def to_dict(self, include_info=True):
+    def to_dict(self, include_info=True, include_executions=True):
         base = super(Replica, self).to_dict(
         base = super(Replica, self).to_dict(
-            include_info=include_info)
+            include_info=include_info,
+            include_executions=include_executions)
         base.update({"id": self.id})
         base.update({"id": self.id})
         return base
         return base
 
 
@@ -268,9 +274,9 @@ class Migration(BaseTransferAction):
         'polymorphic_identity': 'migration',
         'polymorphic_identity': 'migration',
     }
     }
 
 
-    def to_dict(self, include_info=True):
+    def to_dict(self, include_info=True, include_tasks=True):
         base = super(Migration, self).to_dict(
         base = super(Migration, self).to_dict(
-            include_info=include_info)
+            include_info=include_info, include_executions=include_tasks)
         base.update({
         base.update({
             "id": self.id,
             "id": self.id,
             "replica_id": self.replica_id,
             "replica_id": self.replica_id,