فهرست منبع

Split BaseReplicaUpdateableProvider class

Split the `BaseReplicaUpdateableProvider` class into separate
classes for source and destination clouds.

This fixes a bug when providers were not being properly loaded,
and the wrong `check_update_environment_params` was called.
Ionut Balutoiu 6 سال پیش
والد
کامیت
d30f6c451e
5فایلهای تغییر یافته به همراه56 افزوده شده و 24 حذف شده
  1. 6 1
      coriolis/conductor/rpc/server.py
  2. 2 1
      coriolis/constants.py
  3. 33 11
      coriolis/providers/base.py
  4. 4 2
      coriolis/providers/factory.py
  5. 11 9
      coriolis/tasks/replica_tasks.py

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

@@ -1137,13 +1137,18 @@ class ConductorServerEndpoint(object):
             inst_info_copy = copy.deepcopy(replica.info[instance])
             inst_info_copy = copy.deepcopy(replica.info[instance])
             inst_info_copy.update(properties)
             inst_info_copy.update(properties)
             replica.info[instance] = inst_info_copy
             replica.info[instance] = inst_info_copy
+            get_instance_info_task = self._create_task(
+                instance, constants.TASK_TYPE_GET_INSTANCE_INFO,
+                execution)
             update_source_replica_task = self._create_task(
             update_source_replica_task = self._create_task(
                 instance, constants.TASK_TYPE_UPDATE_SOURCE_REPLICA,
                 instance, constants.TASK_TYPE_UPDATE_SOURCE_REPLICA,
                 execution)
                 execution)
             self._create_task(
             self._create_task(
                 instance, constants.TASK_TYPE_UPDATE_DESTINATION_REPLICA,
                 instance, constants.TASK_TYPE_UPDATE_DESTINATION_REPLICA,
                 execution,
                 execution,
-                depends_on=[update_source_replica_task.id])
+                depends_on=[
+                    get_instance_info_task.id,
+                    update_source_replica_task.id])
         LOG.debug(
         LOG.debug(
             "Replica '%s' info post-replica-update: %s",
             "Replica '%s' info post-replica-update: %s",
             replica_id, replica.info)
             replica_id, replica.info)

+ 2 - 1
coriolis/constants.py

@@ -73,8 +73,9 @@ PROVIDER_TYPE_VALIDATE_REPLICA_EXPORT = 4096
 PROVIDER_TYPE_VALIDATE_MIGRATION_IMPORT = 8192
 PROVIDER_TYPE_VALIDATE_MIGRATION_IMPORT = 8192
 PROVIDER_TYPE_VALIDATE_REPLICA_IMPORT = 16384
 PROVIDER_TYPE_VALIDATE_REPLICA_IMPORT = 16384
 PROVIDER_TYPE_ENDPOINT_STORAGE = 32768
 PROVIDER_TYPE_ENDPOINT_STORAGE = 32768
-PROVIDER_TYPE_REPLICA_UPDATE = 65536
+PROVIDER_TYPE_SOURCE_REPLICA_UPDATE = 65536
 PROVIDER_TYPE_SOURCE_ENDPOINT_OPTIONS = 131072
 PROVIDER_TYPE_SOURCE_ENDPOINT_OPTIONS = 131072
+PROVIDER_TYPE_DESTINATION_REPLICA_UPDATE = 262144
 
 
 DISK_FORMAT_VMDK = 'vmdk'
 DISK_FORMAT_VMDK = 'vmdk'
 DISK_FORMAT_RAW = 'raw'
 DISK_FORMAT_RAW = 'raw'

+ 33 - 11
coriolis/providers/base.py

@@ -454,25 +454,47 @@ class BaseEndpointStorageProvider(object, with_metaclass(abc.ABCMeta)):
         pass
         pass
 
 
 
 
-class BaseReplicaUpdateableProvider(object, with_metaclass(abc.ABCMeta)):
-    """ Class for replica providers (export and import) which offer the
-    functionality of updating the parameters for a replica.
+class BaseUpdateSourceReplicaProvider(object, with_metaclass(abc.ABCMeta)):
+    """ Class for replica export providers which offer the functionality
+    of updating the parameters for a replica.
     """
     """
     @abc.abstractmethod
     @abc.abstractmethod
-    def check_update_environment_params(
-            self, ctxt, connection_info, export_info, volumes_info, old_params,
-            new_params):
+    def check_update_source_environment_params(
+            self, ctxt, connection_info, instance_name, volumes_info,
+            old_params, new_params):
         """ Checks that any existing replica resources for the VM given by its
         """ Checks that any existing replica resources for the VM given by its
         `export_info` which were replicated using the `old_params` is
         `export_info` which were replicated using the `old_params` is
-        compatible with the `new_params`. Depending on whether it's an Import
-        or Export provider, the `old_params` and `new_params` refer to either
-        the `destination_environment` or `source_environment` replica fields.
+        compatible with the `new_params`. The `old_params` and `new_params`
+        refer to either the `source_environment` replica fields.
         This method should raise and error given incompatible `new_params` and
         This method should raise and error given incompatible `new_params` and
-        also perform the necessary update procedures if they are compatible
+        also perform the necessary update procedures if they are compatible.
 
 
         return on success: updated `volumes_info`
         return on success: updated `volumes_info`
 
 
-        NOTE: if there is no `volumes_info` present due to the replica never
+        NOTE: If there is no `volumes_info` present due to the replica never
+        having been executed or the replica disks having been deleted, this
+        method should simply return the empty `volumes_info` it was given.
+        """
+
+
+class BaseUpdateDestinationReplicaProvider(object, with_metaclass(abc.ABCMeta)):
+    """ Class for replica import providers which offer the functionality
+    of updating the parameters for a replica.
+    """
+    @abc.abstractmethod
+    def check_update_destination_environment_params(
+            self, ctxt, connection_info, export_info, volumes_info,
+            old_params, new_params):
+        """ Checks that any existing replica resources for the VM given by its
+        `export_info` which were replicated using the `old_params` is
+        compatible with the `new_params`. The `old_params` and `new_params`
+        refer to the `destination_environment` replica fields.
+        This method should raise and error given incompatible `new_params` and
+        also perform the necessary update procedures if they are compatible.
+
+        return on success: updated `volumes_info`
+
+        NOTE: If there is no `volumes_info` present due to the replica never
         having been executed or the replica disks having been deleted, this
         having been executed or the replica disks having been deleted, this
         method should simply return the empty `volumes_info` it was given.
         method should simply return the empty `volumes_info` it was given.
         """
         """

+ 4 - 2
coriolis/providers/factory.py

@@ -42,8 +42,10 @@ PROVIDER_TYPE_MAP = {
         base.BaseMigrationImportValidationProvider),
         base.BaseMigrationImportValidationProvider),
     constants.PROVIDER_TYPE_VALIDATE_REPLICA_IMPORT: (
     constants.PROVIDER_TYPE_VALIDATE_REPLICA_IMPORT: (
         base.BaseReplicaImportValidationProvider),
         base.BaseReplicaImportValidationProvider),
-    constants.PROVIDER_TYPE_REPLICA_UPDATE: (
-        base.BaseReplicaUpdateableProvider),
+    constants.PROVIDER_TYPE_SOURCE_REPLICA_UPDATE: (
+        base.BaseUpdateSourceReplicaProvider),
+    constants.PROVIDER_TYPE_DESTINATION_REPLICA_UPDATE: (
+        base.BaseUpdateDestinationReplicaProvider),
     constants.PROVIDER_TYPE_SOURCE_ENDPOINT_OPTIONS: (
     constants.PROVIDER_TYPE_SOURCE_ENDPOINT_OPTIONS: (
         base.BaseEndpointSourceOptionsProvider)
         base.BaseEndpointSourceOptionsProvider)
 }
 }

+ 11 - 9
coriolis/tasks/replica_tasks.py

@@ -439,7 +439,7 @@ class UpdateSourceReplicaTask(base.TaskRunner):
             return task_info
             return task_info
 
 
         source_provider = providers_factory.get_provider(
         source_provider = providers_factory.get_provider(
-            origin["type"], constants.PROVIDER_TYPE_REPLICA_UPDATE,
+            origin["type"], constants.PROVIDER_TYPE_SOURCE_REPLICA_UPDATE,
             event_handler, raise_if_not_found=False)
             event_handler, raise_if_not_found=False)
         if not source_provider:
         if not source_provider:
             raise exception.CoriolisException(
             raise exception.CoriolisException(
@@ -447,7 +447,6 @@ class UpdateSourceReplicaTask(base.TaskRunner):
                 " updating Replicas" % origin["type"])
                 " updating Replicas" % origin["type"])
 
 
         origin_connection_info = base.get_connection_info(ctxt, origin)
         origin_connection_info = base.get_connection_info(ctxt, origin)
-        export_info = task_info.get("export_info", {})
         volumes_info = task_info.get("volumes_info", {})
         volumes_info = task_info.get("volumes_info", {})
 
 
         LOG.info("Checking source provider environment params")
         LOG.info("Checking source provider environment params")
@@ -455,9 +454,10 @@ class UpdateSourceReplicaTask(base.TaskRunner):
         # in the dedicated DB column of the Replica and thus stores
         # in the dedicated DB column of the Replica and thus stores
         # the previous value of it:
         # the previous value of it:
         old_source_env = origin.get('source_environment', {})
         old_source_env = origin.get('source_environment', {})
-        volumes_info = source_provider.check_update_environment_params(
-            ctxt, origin_connection_info, export_info, volumes_info,
-            old_source_env, new_source_env)
+        volumes_info = (
+            source_provider.check_update_source_environment_params(
+                ctxt, origin_connection_info, instance, volumes_info,
+                old_source_env, new_source_env))
 
 
         task_info['volumes_info'] = volumes_info
         task_info['volumes_info'] = volumes_info
 
 
@@ -475,7 +475,8 @@ class UpdateDestinationReplicaTask(base.TaskRunner):
             return task_info
             return task_info
 
 
         destination_provider = providers_factory.get_provider(
         destination_provider = providers_factory.get_provider(
-            destination["type"], constants.PROVIDER_TYPE_REPLICA_UPDATE,
+            destination["type"],
+            constants.PROVIDER_TYPE_DESTINATION_REPLICA_UPDATE,
             event_handler, raise_if_not_found=False)
             event_handler, raise_if_not_found=False)
         if not destination_provider:
         if not destination_provider:
             raise exception.CoriolisException(
             raise exception.CoriolisException(
@@ -492,9 +493,10 @@ class UpdateDestinationReplicaTask(base.TaskRunner):
         # set in the dedicated DB column of the Replica and thus stores
         # set in the dedicated DB column of the Replica and thus stores
         # the previous value of it:
         # the previous value of it:
         old_destination_env = destination.get('target_environment', {})
         old_destination_env = destination.get('target_environment', {})
-        volumes_info = destination_provider.check_update_environment_params(
-            ctxt, destination_connection_info, export_info, volumes_info,
-            old_destination_env, new_destination_env)
+        volumes_info = (
+            destination_provider.check_update_destination_environment_params(
+                ctxt, destination_connection_info, export_info, volumes_info,
+                old_destination_env, new_destination_env))
 
 
         task_info['volumes_info'] = volumes_info
         task_info['volumes_info'] = volumes_info