Просмотр исходного кода

Make conductor immediately release minion machines after their respective tasks are completed.

Nashwan Azhari 5 лет назад
Родитель
Сommit
2c2a10df81

+ 39 - 0
coriolis/conductor/rpc/server.py

@@ -2936,6 +2936,45 @@ class ConductorServerEndpoint(object):
                 ctxt, task_info['osmorphing_minion_machine_id'],
                 updated_values)
 
+        elif task_type == constants.TASK_TYPE_RELEASE_SOURCE_MINION:
+
+            LOG.debug(
+                "Releasing source minion '%s' following the completion of "
+                "task with ID '%s' (type '%s')",
+                task_info['source_minion_machine_id'],
+                task.id, task_type)
+            self._minion_manager_client.deallocate_minion_machine(
+                ctxt, task_info['source_minion_machine_id'])
+
+        elif task_type == constants.TASK_TYPE_RELEASE_DESTINATION_MINION:
+
+            if task_info['target_minion_machine_id'] != task_info.get(
+                    "osmorphing_minion_machine_id"):
+                LOG.debug(
+                    "Releasing destination minion '%s' following the "
+                    "completion of task with ID '%s' (type '%s')",
+                    task_info['target_minion_machine_id'],
+                    task.id, task_type)
+                self._minion_manager_client.deallocate_minion_machine(
+                    ctxt, task_info['target_minion_machine_id'])
+            else:
+                LOG.debug(
+                    "NOT releasing destination minion with ID '%s' following "
+                    "the completion of task with ID '%s' (type '%s') as it "
+                    "also to be used as the OSMorphing minion.",
+                    task_info['target_minion_machine_id'],
+                    task.id, task_type)
+
+        elif task_type == constants.TASK_TYPE_RELEASE_OSMORPHING_MINION:
+
+            LOG.debug(
+                "Releasing OSMorphing minion '%s' following the completion of "
+                "task with ID '%s' (type '%s')",
+                task_info['osmorphing_minion_machine_id'],
+                task.id, task_type)
+            self._minion_manager_client.deallocate_minion_machine(
+                ctxt, task_info['osmorphing_minion_machine_id'])
+
         else:
             LOG.debug(
                 "No post-task actions required for task '%s' of type '%s'",

+ 4 - 2
coriolis/db/api.py

@@ -1217,7 +1217,8 @@ def update_minion_machine(context, minion_machine_id, updated_values):
 
 @enginefacade.writer
 def set_minion_machines_allocation_statuses(
-        context, minion_machine_ids, action_id, allocation_status):
+        context, minion_machine_ids, action_id, allocation_status,
+        refresh_allocation_time=True):
     machines = get_minion_machines(context)
     existing_machine_id_mappings = {
         machine.id: machine for machine in machines}
@@ -1237,7 +1238,8 @@ def set_minion_machines_allocation_statuses(
                 machine.id, machine.status, allocation_status,
                 machine.allocated_action, action_id))
         machine.allocated_action = action_id
-        machine.allocated_at = timeutils.utcnow()
+        if refresh_allocation_time:
+            machine.allocated_at = timeutils.utcnow()
         machine.status = allocation_status
 
 

+ 5 - 0
coriolis/minion_manager/rpc/client.py

@@ -71,6 +71,11 @@ class MinionManagerClient(object):
             include_transfer_minions=include_transfer_minions,
             include_osmorphing_minions=include_osmorphing_minions)
 
+    def deallocate_minion_machine(self, ctxt, minion_machine_id):
+         return self._client.cast(
+            ctxt, 'deallocate_minion_machine',
+            minion_machine_id=minion_machine_id)
+
     def deallocate_minion_machines_for_action(self, ctxt, action_id):
         return self._client.cast(
             ctxt, 'deallocate_minion_machines_for_action', action_id=action_id)

+ 42 - 2
coriolis/minion_manager/rpc/server.py

@@ -518,7 +518,8 @@ class MinionManagerServerEndpoint(object):
                 allocated_osmorphing_machine_ids))
             db_api.set_minion_machines_allocation_statuses(
                 ctxt, all_machine_ids, action['id'],
-                constants.MINION_MACHINE_STATUS_ALLOCATED)
+                constants.MINION_MACHINE_STATUS_ALLOCATED,
+                refresh_allocation_time=True)
 
         # filter out redundancies:
         instance_machine_allocations = {
@@ -535,6 +536,44 @@ class MinionManagerServerEndpoint(object):
                 for (instance, allocation) in instance_machine_allocations.items()})
         return instance_machine_allocations
 
+    def deallocate_minion_machine(self, ctxt, minion_machine_id):
+
+        minion_machine = db_api.get_minion_machine(
+            ctxt, minion_machine_id)
+        if not minion_machine:
+            LOG.warn(
+                "Could not find minion machine with ID '%s' for deallocation. "
+                "Presuming it was deleted and returning early",
+                minion_machine_id)
+            return
+
+        machine_allocated_status = constants.MINION_MACHINE_STATUS_ALLOCATED
+        with lockutils.lock(
+                constants.MINION_POOL_LOCK_NAME_FORMAT % (
+                    minion_machine.pool_id),
+                external=True):
+
+            if minion_machine.status != machine_allocated_status or (
+                    not minion_machine.allocated_action):
+                LOG.warn(
+                    "Minion machine '%s' was either in an improper status (%s)"
+                    ", or did not have an associated action ('%s') for "
+                    "deallocation request. Marking as available anyway.",
+                    minion_machine.id, minion_machine.status,
+                    minion_machine.allocated_action)
+            LOG.debug(
+                "Attempting to deallocate all minion pool machine '%s' "
+                "(currently allocated to action '%s' with status '%s')",
+                minion_machine.id, minion_machine.allocated_action,
+                minion_machine.status)
+            db_api.update_minion_machine(
+                ctxt, minion_machine.id, {
+                    "status": constants.MINION_MACHINE_STATUS_AVAILABLE,
+                    "allocated_action": None})
+            LOG.debug(
+                "Successfully deallocated minion machine with '%s'.",
+                minion_machine.id)
+
     def deallocate_minion_machines_for_action(self, ctxt, action_id):
 
         allocated_minion_machines = db_api.get_minion_machines(
@@ -569,7 +608,8 @@ class MinionManagerServerEndpoint(object):
                 "action '%s': %s", action_id, machine_ids)
             db_api.set_minion_machines_allocation_statuses(
                 ctxt, machine_ids, None,
-                constants.MINION_MACHINE_STATUS_AVAILABLE)
+                constants.MINION_MACHINE_STATUS_AVAILABLE,
+                refresh_allocation_time=False)
             LOG.debug(
                 "Successfully released all minion machines associated "
                 "with action with base_id '%s'.", action_id)

+ 0 - 5
coriolis/tasks/minion_pool_tasks.py

@@ -14,18 +14,13 @@ LOG = logging.getLogger(__name__)
 
 
 SOURCE_MINION_TASK_INFO_FIELD_MAPPINGS = {
-    # NOTE: these redundancies are in place so as to have the
-    # 'Release*' task classes clear these fields after they run:
-    "source_minion_machine_id": "source_minion_machine_id",
     "source_minion_provider_properties": "source_resources",
     "source_minion_connection_info": "source_resources_connection_info"}
 TARGET_MINION_TASK_INFO_FIELD_MAPPINGS = {
-    "target_minion_machine_id": "target_minion_machine_id",
     "target_minion_provider_properties": "target_resources",
     "target_minion_backup_writer_connection_info": (
         "target_resources_connection_info")}
 OSMOPRHING_MINION_TASK_INFO_FIELD_MAPPINGS = {
-    "osmorphing_minion_machine_id": "osmorphing_minion_machine_id",
     "osmorphing_minion_provider_properties": "os_morphing_resources",
     "osmorphing_minion_connection_info": "osmorphing_connection_info"}