cluster_service.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import os
  2. from lib.compose.object import Service, ServiceDataVolume, ServicePort
  3. from lib.compose import SERVICE_RESTART_ON_FAILURE
  4. from lib.compose.object import DependOn
  5. from lib.compose import options
  6. def COMPOSE_SERVICE_INIT_VERSION():
  7. version = os.environ.get("COMPOSE_SERVICE_INIT_VERSION", None)
  8. if version:
  9. return version
  10. return os.environ.get('VERSION', 'v3.11.9')
  11. class ClusterService(Service):
  12. def __init__(self, name, version,
  13. image_name='',
  14. repo='${CLOUDPODS_REPO:-registry.cn-beijing.aliyuncs.com/yunionio}'):
  15. if image_name == '':
  16. image_name = name
  17. self.image = f'{repo}/{image_name}:{version}'
  18. super(ClusterService, self).__init__(name, self.image)
  19. class ComposeServiceInitService(ClusterService):
  20. STEP_INIT = "init"
  21. STEP_POST_INIT = "post-init"
  22. def __init__(self,
  23. component_name,
  24. step,
  25. db_svc=None,
  26. keystone_svc=None,
  27. depend_svc=None,
  28. product_version="CMP"):
  29. super().__init__(f"{component_name}-{step}", COMPOSE_SERVICE_INIT_VERSION(), image_name='compose-service-init')
  30. if not step:
  31. raise Exception("step is required")
  32. pv = os.getenv("PRODUCT_VERSION", product_version)
  33. self.component_name = component_name
  34. self.db_svc = db_svc
  35. config_dir = ClusterCommonService.YUNION_ETC_PATH
  36. vol = ServiceDataVolume(config_dir)
  37. cmd = [
  38. "/opt/yunion/bin/compose-service-init",
  39. "--config-dir=/",
  40. f"--component={self.component_name}",
  41. f"--step={step}",
  42. f"--product-version={pv}",
  43. ]
  44. if self.db_svc:
  45. cmd = cmd + [
  46. f"--mysql-host={self.db_svc.get_name()}",
  47. f"--mysql-port={self.db_svc.get_port()}",
  48. "--mysql-user=root",
  49. f"--mysql-password={self.db_svc.get_password()}",
  50. ]
  51. self.set_command(*cmd)
  52. self.add_volume(vol)
  53. if options.has_public_ip():
  54. self.add_environment({
  55. "PUBLIC_IP": "$PUBLIC_IP",
  56. })
  57. if self.db_svc:
  58. self.depend_on_health(db_svc)
  59. if keystone_svc:
  60. self.depend_on_completed(keystone_svc.get_post_init_service())
  61. if depend_svc:
  62. if isinstance(depend_svc, ClusterCommonService):
  63. post_init_svc = depend_svc.get_post_init_service()
  64. if post_init_svc:
  65. self.depend_on_completed(post_init_svc)
  66. class ClusterCommonService(ClusterService):
  67. YUNION_BIN_PATH = "/opt/yunion/bin/"
  68. YUNION_ETC_PATH = "/etc/yunion/"
  69. YUNION_CLOUD_PATH = "/opt/cloud"
  70. YUNION_CLOUD_WORKSPACE_PATH = "/opt/cloud/workspace"
  71. YUNION_GLANCE_DATA_PATH = f'{YUNION_CLOUD_WORKSPACE_PATH}/data/glance'
  72. YUNION_RUN_ONECLOUD_PATH = "/var/run/onecloud"
  73. YUNION_RUN_VMWARE_PATH = "/var/run/vmware"
  74. YUNION_CERTS_PATH = YUNION_ETC_PATH + "pki/"
  75. STEP_INIT = ComposeServiceInitService.STEP_INIT
  76. STEP_POST_INIT = ComposeServiceInitService.STEP_POST_INIT
  77. def __init__(self, name, version,
  78. db_svc=None,
  79. disable_auto_sync_table=False,
  80. keystone_svc=None,
  81. depend_svc=None,
  82. port=-1,
  83. image_name="",
  84. repo="${CLOUDPODS_REPO:-registry.cn-beijing.aliyuncs.com/yunionio}"):
  85. super().__init__(name, version, image_name=image_name, repo=repo)
  86. self.db_svc = db_svc
  87. self.disable_auto_sync_table = disable_auto_sync_table
  88. self.keystone_svc = keystone_svc
  89. self.depend_svc = depend_svc
  90. self.port = port
  91. self.init_svc = self._get_init_service()
  92. if self.init_svc:
  93. self.depend_on(self.init_svc, condition=DependOn.CONDITION_COMPLETED_SUCCESSFULLY)
  94. self.post_init_svc = self._get_post_init_service()
  95. if self.db_svc:
  96. self.depend_on(self.db_svc)
  97. self.set_command(*self.get_command())
  98. self.add_volume(ServiceDataVolume(self.YUNION_CERTS_PATH, readonly=True))
  99. if self.get_config_path():
  100. self.add_volume(ServiceDataVolume(self.get_config_path(), readonly=True))
  101. if self.port >= 0:
  102. self.set_healthcheck(f"netstat -tln | grep -c {self.port}")
  103. self.set_restart_on_failure()
  104. def get_ports(self):
  105. if self.port >= 0:
  106. if options.has_public_ip() and not self.is_host_network():
  107. self.add_port(ServicePort(self.port, self.port, 'tcp'))
  108. return super().get_ports()
  109. def get_command(self):
  110. cmd = [
  111. self.get_bin_path(),
  112. "--config",
  113. self.get_config_path(),
  114. ]
  115. if self.db_svc and not self.disable_auto_sync_table:
  116. cmd.append("--auto-sync-table")
  117. return cmd
  118. def get_bin_path(self):
  119. return self.YUNION_BIN_PATH + self.get_name()
  120. def get_config_path(self):
  121. return self.YUNION_ETC_PATH + self.get_name() + ".conf"
  122. def get_component_name(self):
  123. return self.get_name()
  124. def _get_init_service(self):
  125. init_svc = ComposeServiceInitService(
  126. self.get_component_name(),
  127. self.STEP_INIT,
  128. self.db_svc,
  129. keystone_svc=self.keystone_svc,
  130. depend_svc=self.depend_svc)
  131. return init_svc
  132. def get_init_service(self):
  133. return self.init_svc
  134. def _get_post_init_service(self):
  135. post_init_svc = ComposeServiceInitService(self.get_component_name(),
  136. self.STEP_POST_INIT,
  137. self.db_svc)
  138. post_init_svc.set_restart(SERVICE_RESTART_ON_FAILURE)
  139. post_init_svc.depend_on(self, DependOn.CONDITION_SERVICE_HEALTHY)
  140. return post_init_svc
  141. def get_post_init_service(self):
  142. return self.post_init_svc