osmorphing_tasks.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # Copyright 2016 Cloudbase Solutions Srl
  2. # All Rights Reserved.
  3. from oslo_log import log as logging
  4. from coriolis import constants
  5. from coriolis import exception
  6. from coriolis.osmorphing import manager as osmorphing_manager
  7. from coriolis.providers import factory as providers_factory
  8. from coriolis import schemas
  9. from coriolis.tasks import base
  10. LOG = logging.getLogger(__name__)
  11. class OSMorphingTask(base.TaskRunner):
  12. @classmethod
  13. def get_required_platform(cls):
  14. return constants.TASK_PLATFORM_DESTINATION
  15. @classmethod
  16. def get_required_task_info_properties(cls):
  17. return [
  18. "osmorphing_info", "osmorphing_connection_info",
  19. "user_scripts"]
  20. @classmethod
  21. def get_returned_task_info_properties(cls):
  22. return []
  23. @classmethod
  24. def get_required_provider_types(cls):
  25. return {
  26. constants.PROVIDER_PLATFORM_SOURCE: [
  27. constants.PROVIDER_TYPE_TRANSFER_EXPORT],
  28. constants.PROVIDER_PLATFORM_DESTINATION: [
  29. constants.PROVIDER_TYPE_TRANSFER_IMPORT],
  30. }
  31. def _run(self, ctxt, instance, origin, destination, task_info,
  32. event_handler):
  33. origin_provider = providers_factory.get_provider(
  34. origin["type"], constants.PROVIDER_TYPE_TRANSFER_EXPORT,
  35. event_handler)
  36. destination_provider = providers_factory.get_provider(
  37. destination["type"], constants.PROVIDER_TYPE_TRANSFER_IMPORT,
  38. event_handler)
  39. osmorphing_connection_info = base.unmarshal_migr_conn_info(
  40. task_info['osmorphing_connection_info'])
  41. osmorphing_info = task_info.get('osmorphing_info', {})
  42. user_scripts = task_info.get("user_scripts")
  43. instance_scripts = None
  44. if user_scripts:
  45. instance_scripts = user_scripts.get("instances", {}).get(instance)
  46. if not instance_scripts:
  47. os_type = osmorphing_info.get("os_type")
  48. if os_type:
  49. instance_scripts = user_scripts.get(
  50. "global", {}).get(os_type)
  51. if isinstance(instance_scripts, str):
  52. # Legacy record, convert to extended format.
  53. instance_scripts = [
  54. {
  55. "phase": constants.PHASE_OSMORPHING_POST_OS_MOUNT,
  56. "payload": instance_scripts,
  57. }
  58. ]
  59. osmorphing_manager.morph_image(
  60. origin_provider,
  61. destination_provider,
  62. osmorphing_connection_info,
  63. osmorphing_info,
  64. instance_scripts,
  65. event_handler)
  66. return {}
  67. class DeployOSMorphingResourcesTask(base.TaskRunner):
  68. @classmethod
  69. def get_required_platform(cls):
  70. return constants.TASK_PLATFORM_DESTINATION
  71. @classmethod
  72. def get_required_task_info_properties(cls):
  73. return ["target_environment", "instance_deployment_info"]
  74. @classmethod
  75. def get_returned_task_info_properties(cls):
  76. return [
  77. "os_morphing_resources", "osmorphing_info",
  78. "osmorphing_connection_info"]
  79. @classmethod
  80. def get_required_provider_types(cls):
  81. return {
  82. constants.PROVIDER_PLATFORM_DESTINATION: [
  83. constants.PROVIDER_TYPE_OS_MORPHING]
  84. }
  85. def _run(self, ctxt, instance, origin, destination, task_info,
  86. event_handler):
  87. provider = providers_factory.get_provider(
  88. destination["type"], constants.PROVIDER_TYPE_OS_MORPHING,
  89. event_handler)
  90. connection_info = base.get_connection_info(ctxt, destination)
  91. target_environment = task_info["target_environment"]
  92. instance_deployment_info = task_info["instance_deployment_info"]
  93. import_info = provider.deploy_os_morphing_resources(
  94. ctxt, connection_info, target_environment,
  95. instance_deployment_info)
  96. schemas.validate_value(
  97. import_info, schemas.CORIOLIS_OS_MORPHING_RESOURCES_SCHEMA,
  98. # NOTE: we avoid raising so that the cleanup task
  99. # can [try] to deal with the temporary resources.
  100. raise_on_error=False)
  101. os_morphing_resources = import_info.get('os_morphing_resources')
  102. if not os_morphing_resources:
  103. raise exception.InvalidTaskResult(
  104. "Target provider for '%s' did NOT return any "
  105. "'os_morphing_resources'." % (
  106. destination["type"]))
  107. osmorphing_connection_info = import_info.get(
  108. 'osmorphing_connection_info')
  109. if not osmorphing_connection_info:
  110. raise exception.InvalidTaskResult(
  111. "Target provider '%s' did NOT return any "
  112. "'osmorphing_connection_info'." % (
  113. destination["type"]))
  114. osmorphing_connection_info = base.marshal_migr_conn_info(
  115. osmorphing_connection_info)
  116. os_morphing_info = import_info.get("osmorphing_info", {})
  117. if not os_morphing_info:
  118. LOG.warn(
  119. "Target provider for '%s' did NOT return any "
  120. "'osmorphing_info'. Defaulting to %s",
  121. destination["type"], os_morphing_info)
  122. return {
  123. "os_morphing_resources": os_morphing_resources,
  124. "osmorphing_connection_info": osmorphing_connection_info,
  125. "osmorphing_info": os_morphing_info}
  126. class DeleteOSMorphingResourcesTask(base.TaskRunner):
  127. @classmethod
  128. def get_required_platform(cls):
  129. return constants.TASK_PLATFORM_DESTINATION
  130. @classmethod
  131. def get_required_task_info_properties(cls):
  132. return ["target_environment", "os_morphing_resources"]
  133. @classmethod
  134. def get_returned_task_info_properties(cls):
  135. return ["os_morphing_resources", "osmorphing_connection_info"]
  136. @classmethod
  137. def get_required_provider_types(cls):
  138. return {
  139. constants.PROVIDER_PLATFORM_DESTINATION: [
  140. constants.PROVIDER_TYPE_OS_MORPHING]
  141. }
  142. def _run(self, ctxt, instance, origin, destination, task_info,
  143. event_handler):
  144. provider = providers_factory.get_provider(
  145. destination["type"], constants.PROVIDER_TYPE_OS_MORPHING,
  146. event_handler)
  147. connection_info = base.get_connection_info(ctxt, destination)
  148. os_morphing_resources = task_info.get("os_morphing_resources")
  149. target_environment = task_info["target_environment"]
  150. provider.delete_os_morphing_resources(
  151. ctxt, connection_info, target_environment, os_morphing_resources)
  152. return {
  153. "os_morphing_resources": None,
  154. "osmorphing_connection_info": None}