Răsfoiți Sursa

Adds cancel action

Alessandro Pilotti 10 ani în urmă
părinte
comite
95ab5b7022

+ 25 - 0
coriolis/api/v1/migration_actions.py

@@ -0,0 +1,25 @@
+from webob import exc
+
+from coriolis.api import wsgi as api_wsgi
+from coriolis import exception
+from coriolis.migrations import api
+
+
+class MigrationActionsController(api_wsgi.Controller):
+    def __init__(self):
+        self._migration_api = api.API()
+        super(MigrationActionsController, self).__init__()
+
+    @api_wsgi.action('cancel')
+    def _cancel(self, req, id, body):
+        try:
+            self._migration_api.cancel(req.environ['coriolis.context'], id)
+            raise exc.HTTPNoContent()
+        except exception.NotFound as ex:
+            raise exc.HTTPNotFound(explanation=ex.msg)
+        except exception.InvalidParameterValue as ex:
+            raise exc.HTTPNotFound(explanation=ex.msg)
+
+
+def create_resource():
+    return api_wsgi.Resource(MigrationActionsController())

+ 6 - 3
coriolis/api/v1/migrations.py

@@ -8,7 +8,7 @@ from coriolis.migrations import api
 from coriolis.providers import factory
 
 
-class MigrationController(object):
+class MigrationController(api_wsgi.Controller):
     def __init__(self):
         self._migration_api = api.API()
         super(MigrationController, self).__init__()
@@ -59,8 +59,11 @@ class MigrationController(object):
             req.environ['coriolis.context'], origin, destination, instances))
 
     def delete(self, req, id):
-        self._migration_api.delete(req.environ['coriolis.context'], id)
-        raise exc.HTTPNoContent()
+        try:
+            self._migration_api.delete(req.environ['coriolis.context'], id)
+            raise exc.HTTPNoContent()
+        except exception.NotFound as ex:
+            raise exc.HTTPNotFound(explanation=ex.msg)
 
 
 def create_resource():

+ 10 - 0
coriolis/api/v1/router.py

@@ -2,6 +2,7 @@ from oslo_log import log as logging
 
 from coriolis import api
 from coriolis.api.v1 import migrations
+from coriolis.api.v1 import migration_actions
 
 LOG = logging.getLogger(__name__)
 
@@ -25,3 +26,12 @@ class APIRouter(api.APIRouter):
                         controller=self.resources['migrations'],
                         collection={'detail': 'GET'},
                         member={'action': 'POST'})
+
+        migration_actions_resource = migration_actions.create_resource()
+        self.resources['migration_actions'] = migration_actions_resource
+        migration_path = '/{project_id}/migrations/{id}'
+        mapper.connect('migration_actions',
+                       migration_path + '/actions',
+                       controller=self.resources['migration_actions'],
+                       action='action',
+                       conditions={'method': 'POST'})

+ 2 - 2
coriolis/conductor/rpc/client.py

@@ -26,9 +26,9 @@ class ConductorClient(object):
         self._client.call(
             ctxt, 'delete_migration', migration_id=migration_id)
 
-    def stop_instances_migration(self, ctxt, migration_id):
+    def cancel_migration(self, ctxt, migration_id):
         self._client.call(
-            ctxt, 'stop_instances_migration', migration_id=migration_id)
+            ctxt, 'cancel_migration', migration_id=migration_id)
 
     def set_task_host(self, ctxt, task_id, host, process_id):
         self._client.call(

+ 6 - 2
coriolis/conductor/rpc/server.py

@@ -76,11 +76,15 @@ class ConductorServerEndpoint(object):
                     "Cannot delete a running migration")
         db_api.delete_migration(ctxt, migration_id)
 
-    def stop_instances_migration(self, ctxt, migration_id):
+    def cancel_migration(self, ctxt, migration_id):
         migration = self._get_migration(ctxt, migration_id)
+        if migration.status != constants.MIGRATION_STATUS_RUNNING:
+            raise exception.InvalidParameterValue(
+                "The migration is not running: %s" % migration_id)
+
         for task in migration.tasks:
             if task.status == constants.TASK_STATUS_RUNNING:
-                self._rpc_worker_client.stop_task(
+                self._rpc_worker_client.cancel_task(
                     ctxt, task.host, task.process_id)
 
     def set_task_host(self, ctxt, task_id, host, process_id):

+ 2 - 2
coriolis/migrations/api.py

@@ -12,8 +12,8 @@ class API(object):
     def delete(self, ctxt, migration_id):
         self._rpc_client.delete_migration(ctxt, migration_id)
 
-    def stop(self, ctxt, migration_id):
-        self._rpc_client.stop_instances_migration(ctxt, migration_id)
+    def cancel(self, ctxt, migration_id):
+        self._rpc_client.cancel_migration(ctxt, migration_id)
 
     def get_migrations(self, ctxt):
         return self._rpc_client.get_migrations(ctxt)

+ 12 - 6
coriolis/rpc.py

@@ -2,6 +2,7 @@ from oslo_config import cfg
 import oslo_messaging as messaging
 
 from coriolis import context
+import coriolis.exception
 
 rpc_opts = [
     cfg.StrOpt('messaging_transport_url',
@@ -12,6 +13,10 @@ rpc_opts = [
 CONF = cfg.CONF
 CONF.register_opts(rpc_opts)
 
+ALLOWED_EXMODS = [
+    coriolis.exception.__name__,
+]
+
 
 class RequestContextSerializer(messaging.Serializer):
 
@@ -35,17 +40,18 @@ class RequestContextSerializer(messaging.Serializer):
         return context.RequestContext.from_dict(ctxt)
 
 
+def _get_transport():
+    return messaging.get_transport(cfg.CONF, CONF.messaging_transport_url,
+                                   allowed_remote_exmods=ALLOWED_EXMODS)
+
+
 def get_client(target, serializer=None):
-    transport = messaging.get_transport(cfg.CONF, CONF.messaging_transport_url)
     serializer = RequestContextSerializer(serializer)
-
-    return messaging.RPCClient(transport, target, serializer=serializer)
+    return messaging.RPCClient(_get_transport(), target, serializer=serializer)
 
 
 def get_server(target, endpoints, serializer=None):
-    transport = messaging.get_transport(cfg.CONF, CONF.messaging_transport_url)
     serializer = RequestContextSerializer(serializer)
-
-    return messaging.get_rpc_server(transport, target, endpoints,
+    return messaging.get_rpc_server(_get_transport(), target, endpoints,
                                     executor='eventlet',
                                     serializer=serializer)

+ 2 - 2
coriolis/worker/rpc/client.py

@@ -18,10 +18,10 @@ class WorkerClient(object):
             origin=origin, destination=destination, instance=instance,
             task_info=task_info)
 
-    def stop_task(self, ctxt, server, process_id):
+    def cancel_task(self, ctxt, server, process_id):
         # Needs to be executed on the same server
         cctxt = self._client.prepare(server=server)
-        cctxt.call(ctxt, 'stop_task', process_id=process_id)
+        cctxt.call(ctxt, 'cancel_task', process_id=process_id)
 
     def update_migration_status(self, ctxt, task_id, status):
         self._client.call(ctxt, "update_migration_status", status=status)

+ 2 - 2
coriolis/worker/rpc/server.py

@@ -71,7 +71,7 @@ class WorkerServerEndpoint(object):
                         # Ignore exception
                         LOG.exception(ex)
 
-    def stop_task(self, ctxt, process_id):
+    def cancel_task(self, ctxt, process_id):
         try:
             p = psutil.Process(process_id)
             p.kill()
@@ -91,7 +91,7 @@ class WorkerServerEndpoint(object):
         p.join()
 
         if mp_q.empty():
-            raise exception.CoriolisException("Task process terminated")
+            raise exception.CoriolisException("Task canceled")
         result = mp_q.get(False)
 
         if isinstance(result, str):