cancan-microstack 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. cancan_microstack/__init__.py +14 -0
  2. cancan_microstack/__version__.py +10 -0
  3. cancan_microstack/assets/__init__.py +6 -0
  4. cancan_microstack/assets/builds/caddy/Caddyfile +187 -0
  5. cancan_microstack/assets/builds/caddy/DEPLOYMENT.md +303 -0
  6. cancan_microstack/assets/builds/caddy/Dockerfile +46 -0
  7. cancan_microstack/assets/builds/caddy/README.md +343 -0
  8. cancan_microstack/assets/builds/caddy/geoip/README.md +5 -0
  9. cancan_microstack/assets/builds/caddy/start.sh +78 -0
  10. cancan_microstack/assets/builds/caddy/waf/coraza.conf +179 -0
  11. cancan_microstack/assets/builds/service/Dockerfile +59 -0
  12. cancan_microstack/assets/builds/service/README.md +13 -0
  13. cancan_microstack/assets/ddl/create_db.sql +22 -0
  14. cancan_microstack/assets/ddl/infra/execution_log_tbl.sql +46 -0
  15. cancan_microstack/assets/ddl/infra/node_instance_tbl.sql +56 -0
  16. cancan_microstack/assets/ddl/infra/service_action_log_tbl.sql +36 -0
  17. cancan_microstack/assets/ddl/infra/service_config_tbl.sql +26 -0
  18. cancan_microstack/assets/ddl/infra/service_info_tbl.sql +45 -0
  19. cancan_microstack/assets/ddl/infra/service_instance_tbl.sql +54 -0
  20. cancan_microstack/assets/ddl/infra/service_operation_tbl.sql +47 -0
  21. cancan_microstack/assets/ddl/infra/workflow_definition_tbl.sql +60 -0
  22. cancan_microstack/assets/ddl/infra/workflow_definition_version_tbl.sql +35 -0
  23. cancan_microstack/assets/ddl/infra/workflow_engine_alert_tbl.sql +34 -0
  24. cancan_microstack/assets/ddl/infra/workflow_run_tbl.sql +52 -0
  25. cancan_microstack/assets/ddl/ops/admin_user_tbl.sql +34 -0
  26. cancan_microstack/assets/ddl/ops/caddy_access_log_tbl.sql +91 -0
  27. cancan_microstack/assets/ddl/ops/caddy_certificate_tbl.sql +59 -0
  28. cancan_microstack/assets/ddl/ops/caddy_rate_limit_tbl.sql +64 -0
  29. cancan_microstack/assets/ddl/ops/caddy_route_tbl.sql +63 -0
  30. cancan_microstack/assets/ddl/ops/caddy_stats_tbl.sql +77 -0
  31. cancan_microstack/assets/ddl/trigger.sql +21 -0
  32. cancan_microstack/assets/docker/docker-compose.infra.yml +401 -0
  33. cancan_microstack/assets/scripts/README.md +195 -0
  34. cancan_microstack/assets/scripts/docker/build_images.sh +44 -0
  35. cancan_microstack/assets/scripts/docker/force_rebuild_images.sh +38 -0
  36. cancan_microstack/assets/scripts/docker/rebuild_all.sh +34 -0
  37. cancan_microstack/assets/scripts/docker/rebuild_compose.sh +61 -0
  38. cancan_microstack/assets/scripts/docker/restart.sh +35 -0
  39. cancan_microstack/assets/scripts/docker/restart_compose.sh +35 -0
  40. cancan_microstack/assets/scripts/docker/start.sh +78 -0
  41. cancan_microstack/assets/scripts/docker/start_all.sh +46 -0
  42. cancan_microstack/assets/scripts/docker/start_compose.sh +66 -0
  43. cancan_microstack/assets/scripts/docker/stop.sh +67 -0
  44. cancan_microstack/assets/scripts/docker/stop_all.sh +38 -0
  45. cancan_microstack/assets/scripts/docker/stop_compose.sh +38 -0
  46. cancan_microstack/assets/scripts/podman/build_images_podman.sh +59 -0
  47. cancan_microstack/assets/scripts/podman/cleanup_podman.sh +25 -0
  48. cancan_microstack/assets/scripts/podman/force_rebuild_images_podman.sh +56 -0
  49. cancan_microstack/assets/scripts/podman/rebuild_all_podman.sh +37 -0
  50. cancan_microstack/assets/scripts/podman/rebuild_compose_podman.sh +60 -0
  51. cancan_microstack/assets/scripts/podman/restart_compose_podman.sh +73 -0
  52. cancan_microstack/assets/scripts/podman/start_all_podman.sh +66 -0
  53. cancan_microstack/assets/scripts/podman/start_compose_podman.sh +80 -0
  54. cancan_microstack/assets/scripts/podman/start_podman.sh +91 -0
  55. cancan_microstack/assets/scripts/podman/stop.sh +73 -0
  56. cancan_microstack/assets/scripts/podman/stop_all_podman.sh +34 -0
  57. cancan_microstack/assets/scripts/podman/stop_compose_podman.sh +58 -0
  58. cancan_microstack/assets/scripts/start_controllersrv.sh +9 -0
  59. cancan_microstack/assets/scripts/utils/check_all_db_tables.sh +104 -0
  60. cancan_microstack/assets/scripts/utils/check_env.sh +177 -0
  61. cancan_microstack/assets/scripts/utils/check_service_management_deployment.sh +225 -0
  62. cancan_microstack/assets/scripts/utils/deploy_service_management.sh +176 -0
  63. cancan_microstack/assets/scripts/utils/force_reload_infrasrv.sh +52 -0
  64. cancan_microstack/assets/scripts/utils/monitor_service_management.sh +187 -0
  65. cancan_microstack/assets/scripts/utils/reset_postgres_volume.sh +68 -0
  66. cancan_microstack/assets/scripts/utils/test_async_operations.sh +141 -0
  67. cancan_microstack/assets/scripts/utils/verify_real_operations.sh +76 -0
  68. cancan_microstack/assets/service/Dockerfile +65 -0
  69. cancan_microstack/assets/www/adminops/assets/AppEmpty.vue_vue_type_script_setup_true_lang-BOKUurnM.js +1 -0
  70. cancan_microstack/assets/www/adminops/assets/ConfigManage-DKV5YOUz.js +1 -0
  71. cancan_microstack/assets/www/adminops/assets/ConfigManage-Y5bhy7wG.css +1 -0
  72. cancan_microstack/assets/www/adminops/assets/ConsoleManage-8ljYvCW2.js +1 -0
  73. cancan_microstack/assets/www/adminops/assets/ConsoleManage-BWpyqbuQ.css +1 -0
  74. cancan_microstack/assets/www/adminops/assets/DashboardNew-B9Nf1OPl.js +1 -0
  75. cancan_microstack/assets/www/adminops/assets/DashboardNew-DYWZKQ1V.css +1 -0
  76. cancan_microstack/assets/www/adminops/assets/LogSearch-CA0Jhe78.js +1 -0
  77. cancan_microstack/assets/www/adminops/assets/LogSearch-CCZfTNPF.css +1 -0
  78. cancan_microstack/assets/www/adminops/assets/LoginView-BId3kP3M.css +1 -0
  79. cancan_microstack/assets/www/adminops/assets/LoginView-BQZTV_Qy.js +1 -0
  80. cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-BdEYwqFq.js +1 -0
  81. cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-D-pASR8G.css +1 -0
  82. cancan_microstack/assets/www/adminops/assets/PageContainer-Byss-yUC.js +1 -0
  83. cancan_microstack/assets/www/adminops/assets/PageContainer-C3nSZwM7.css +1 -0
  84. cancan_microstack/assets/www/adminops/assets/RateLimitManage-BDI8jLpC.css +1 -0
  85. cancan_microstack/assets/www/adminops/assets/RateLimitManage-DJY4NiF-.js +1 -0
  86. cancan_microstack/assets/www/adminops/assets/RouteManage-DaUQ4QLw.css +1 -0
  87. cancan_microstack/assets/www/adminops/assets/RouteManage-w9XCU0UA.js +1 -0
  88. cancan_microstack/assets/www/adminops/assets/ServiceCard-BFzHe6Tw.css +1 -0
  89. cancan_microstack/assets/www/adminops/assets/ServiceCard-BJUhWnA-.js +1 -0
  90. cancan_microstack/assets/www/adminops/assets/ServiceDetail-Cw24WuKp.js +1 -0
  91. cancan_microstack/assets/www/adminops/assets/ServiceDetail-Yum47zdB.css +1 -0
  92. cancan_microstack/assets/www/adminops/assets/ServiceList-C7ryvbhE.js +1 -0
  93. cancan_microstack/assets/www/adminops/assets/ServiceList-Cgd01fUx.css +1 -0
  94. cancan_microstack/assets/www/adminops/assets/ServiceLogs-COpG9H0h.js +1 -0
  95. cancan_microstack/assets/www/adminops/assets/ServiceLogs-H_Alq0cf.css +1 -0
  96. cancan_microstack/assets/www/adminops/assets/StatsOverview-D0TwMQkA.js +39 -0
  97. cancan_microstack/assets/www/adminops/assets/StatsOverview-lqAN6pqM.css +1 -0
  98. cancan_microstack/assets/www/adminops/assets/TotpBindView-CWlAmzFt.js +1 -0
  99. cancan_microstack/assets/www/adminops/assets/TotpBindView-HoQC1lhx.css +1 -0
  100. cancan_microstack/assets/www/adminops/assets/TotpVerifyView-BHN1VtX1.css +1 -0
  101. cancan_microstack/assets/www/adminops/assets/TotpVerifyView-D3w_lZk8.js +1 -0
  102. cancan_microstack/assets/www/adminops/assets/WorkflowCenter-DU_mpIA0.css +1 -0
  103. cancan_microstack/assets/www/adminops/assets/WorkflowCenter-i50rZyxN.js +1 -0
  104. cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-CnHokPL9.js +1 -0
  105. cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-DaZaZpLd.css +1 -0
  106. cancan_microstack/assets/www/adminops/assets/WorkflowRuns-B09hK48c.js +1 -0
  107. cancan_microstack/assets/www/adminops/assets/WorkflowRuns-wGutKIIU.css +1 -0
  108. cancan_microstack/assets/www/adminops/assets/caddy-nnCKf8fG.js +1 -0
  109. cancan_microstack/assets/www/adminops/assets/format-Cuzxgna9.js +1 -0
  110. cancan_microstack/assets/www/adminops/assets/index-CiFlm8oc.js +64 -0
  111. cancan_microstack/assets/www/adminops/assets/index-UW0T1Dkc.css +1 -0
  112. cancan_microstack/assets/www/adminops/assets/service-BYlgGPs_.js +1 -0
  113. cancan_microstack/assets/www/adminops/assets/service-operation-6GzLw2Z1.js +1 -0
  114. cancan_microstack/assets/www/adminops/assets/style-CcIXnQ5y.css +1 -0
  115. cancan_microstack/assets/www/adminops/assets/style-lRnStdGu.js +39 -0
  116. cancan_microstack/assets/www/adminops/assets/useDebounce-BRlqfXqf.js +1 -0
  117. cancan_microstack/assets/www/adminops/assets/workflow-CUXs39Ac.js +1 -0
  118. cancan_microstack/assets/www/adminops/index.html +16 -0
  119. cancan_microstack/assets/www/adminops/vite.svg +1 -0
  120. cancan_microstack/cli/__init__.py +14 -0
  121. cancan_microstack/cli/__main__.py +9 -0
  122. cancan_microstack/cli/main.py +552 -0
  123. cancan_microstack/cmd/__init__.py +54 -0
  124. cancan_microstack/cmd/cancan/__init__.py +12 -0
  125. cancan_microstack/cmd/cancan/run.py +395 -0
  126. cancan_microstack/cmd/controllersrv/__init__.py +0 -0
  127. cancan_microstack/cmd/controllersrv/run.py +131 -0
  128. cancan_microstack/cmd/infrasrv/__init__.py +5 -0
  129. cancan_microstack/cmd/infrasrv/run.py +100 -0
  130. cancan_microstack/cmd/opsbffsrv/__init__.py +5 -0
  131. cancan_microstack/cmd/opsbffsrv/run.py +96 -0
  132. cancan_microstack/core/__init__.py +5 -0
  133. cancan_microstack/core/assets.py +123 -0
  134. cancan_microstack/core/compose_builder.py +102 -0
  135. cancan_microstack/core/doctor.py +152 -0
  136. cancan_microstack/core/microstack.py +71 -0
  137. cancan_microstack/core/runner.py +56 -0
  138. cancan_microstack/core/stack_manager.py +186 -0
  139. cancan_microstack/public/__init__.py +7 -0
  140. cancan_microstack/public/api/__init__.py +1 -0
  141. cancan_microstack/public/api/controllersrv_client.py +277 -0
  142. cancan_microstack/public/api/infrasrv_client.py +404 -0
  143. cancan_microstack/public/const/__init__.py +1 -0
  144. cancan_microstack/public/const/action_consts.py +18 -0
  145. cancan_microstack/public/const/app_consts.py +42 -0
  146. cancan_microstack/public/const/caddy_consts.py +22 -0
  147. cancan_microstack/public/const/controllersrv_consts.py +163 -0
  148. cancan_microstack/public/const/docker_consts.py +15 -0
  149. cancan_microstack/public/const/error.py +56 -0
  150. cancan_microstack/public/const/health_consts.py +52 -0
  151. cancan_microstack/public/const/hook_enums.py +56 -0
  152. cancan_microstack/public/const/logging_enums.py +13 -0
  153. cancan_microstack/public/const/metrics_enums.py +36 -0
  154. cancan_microstack/public/const/monitor_enums.py +26 -0
  155. cancan_microstack/public/const/operation_consts.py +53 -0
  156. cancan_microstack/public/const/opsbffsrv_error.py +92 -0
  157. cancan_microstack/public/const/overrides_consts.py +13 -0
  158. cancan_microstack/public/const/redis.py +17 -0
  159. cancan_microstack/public/const/service_consts.py +15 -0
  160. cancan_microstack/public/const/workflow_consts.py +65 -0
  161. cancan_microstack/public/error.py +41 -0
  162. cancan_microstack/public/logging/__init__.py +0 -0
  163. cancan_microstack/public/logging/initializer.py +109 -0
  164. cancan_microstack/public/logging/mq_handler.py +279 -0
  165. cancan_microstack/public/schemas/__init__.py +1 -0
  166. cancan_microstack/public/schemas/caddy/__init__.py +381 -0
  167. cancan_microstack/public/schemas/caddy/analysis.py +90 -0
  168. cancan_microstack/public/schemas/caddy/route.py +18 -0
  169. cancan_microstack/public/schemas/common.py +79 -0
  170. cancan_microstack/public/schemas/controllersrv/__init__.py +3 -0
  171. cancan_microstack/public/schemas/controllersrv/async_requests.py +30 -0
  172. cancan_microstack/public/schemas/controllersrv/compose_models.py +47 -0
  173. cancan_microstack/public/schemas/controllersrv/const.py +24 -0
  174. cancan_microstack/public/schemas/controllersrv/docker_models.py +45 -0
  175. cancan_microstack/public/schemas/controllersrv/docker_responses.py +104 -0
  176. cancan_microstack/public/schemas/controllersrv/requests.py +54 -0
  177. cancan_microstack/public/schemas/controllersrv/responses.py +124 -0
  178. cancan_microstack/public/schemas/controllersrv/task_models.py +102 -0
  179. cancan_microstack/public/schemas/controllersrv/validation.py +23 -0
  180. cancan_microstack/public/schemas/hook_metrics.py +124 -0
  181. cancan_microstack/public/schemas/hooks.py +39 -0
  182. cancan_microstack/public/schemas/infra/__init__.py +0 -0
  183. cancan_microstack/public/schemas/infra/cleanup.py +25 -0
  184. cancan_microstack/public/schemas/infra/container.py +74 -0
  185. cancan_microstack/public/schemas/infra/enums.py +135 -0
  186. cancan_microstack/public/schemas/infra/health_check.py +42 -0
  187. cancan_microstack/public/schemas/infra/hook_log.py +42 -0
  188. cancan_microstack/public/schemas/infra/operation.py +90 -0
  189. cancan_microstack/public/schemas/infra/overview.py +25 -0
  190. cancan_microstack/public/schemas/infra/push.py +33 -0
  191. cancan_microstack/public/schemas/infra/service_action_log.py +47 -0
  192. cancan_microstack/public/schemas/infra/service_config.py +10 -0
  193. cancan_microstack/public/schemas/infra/service_info.py +69 -0
  194. cancan_microstack/public/schemas/infra/service_instance.py +93 -0
  195. cancan_microstack/public/schemas/infra/service_management.py +152 -0
  196. cancan_microstack/public/schemas/infra/service_operation.py +79 -0
  197. cancan_microstack/public/schemas/infra/service_registry.py +158 -0
  198. cancan_microstack/public/schemas/infra/status_types.py +19 -0
  199. cancan_microstack/public/schemas/infra/workflow.py +566 -0
  200. cancan_microstack/public/schemas/logging/__init__.py +1 -0
  201. cancan_microstack/public/schemas/logging/log_event.py +121 -0
  202. cancan_microstack/public/schemas/opsbffsrv/__init__.py +1 -0
  203. cancan_microstack/public/schemas/opsbffsrv/async_ops.py +17 -0
  204. cancan_microstack/public/schemas/opsbffsrv/db_admin.py +147 -0
  205. cancan_microstack/public/schemas/opsbffsrv/db_init.py +48 -0
  206. cancan_microstack/public/schemas/opsbffsrv/service_config.py +89 -0
  207. cancan_microstack/public/schemas/opsbffsrv/service_logs.py +54 -0
  208. cancan_microstack/public/schemas/service_operation.py +24 -0
  209. cancan_microstack/public/schemas/service_registry.py +40 -0
  210. cancan_microstack/public/types/__init__.py +7 -0
  211. cancan_microstack/public/web/__init__.py +0 -0
  212. cancan_microstack/public/web/config_value.py +105 -0
  213. cancan_microstack/public/web/server.py +385 -0
  214. cancan_microstack/py.typed +0 -0
  215. cancan_microstack/runtime/__init__.py +0 -0
  216. cancan_microstack/runtime/compose_cmd.py +228 -0
  217. cancan_microstack/runtime/host_daemon.py +318 -0
  218. cancan_microstack/runtime/overrides.py +103 -0
  219. cancan_microstack/runtime/resources.py +25 -0
  220. cancan_microstack/runtime/workspace.py +94 -0
  221. cancan_microstack/services/__init__.py +0 -0
  222. cancan_microstack/services/controllersrv/__init__.py +8 -0
  223. cancan_microstack/services/controllersrv/application/__init__.py +0 -0
  224. cancan_microstack/services/controllersrv/application/docker_compose_app.py +427 -0
  225. cancan_microstack/services/controllersrv/conf/__init__.py +0 -0
  226. cancan_microstack/services/controllersrv/conf/config.py +76 -0
  227. cancan_microstack/services/controllersrv/conf/settings.py +54 -0
  228. cancan_microstack/services/controllersrv/domain/__init__.py +0 -0
  229. cancan_microstack/services/controllersrv/domain/docker_compose/__init__.py +0 -0
  230. cancan_microstack/services/controllersrv/domain/docker_compose/docker_compose_domain.py +278 -0
  231. cancan_microstack/services/controllersrv/domain/service_validator.py +327 -0
  232. cancan_microstack/services/controllersrv/domain/task/__init__.py +17 -0
  233. cancan_microstack/services/controllersrv/domain/task/task_queue.py +286 -0
  234. cancan_microstack/services/controllersrv/domain/task/task_worker.py +495 -0
  235. cancan_microstack/services/controllersrv/infrastructure/__init__.py +0 -0
  236. cancan_microstack/services/controllersrv/interface/__init__.py +0 -0
  237. cancan_microstack/services/controllersrv/interface/api/__init__.py +0 -0
  238. cancan_microstack/services/controllersrv/interface/api/docker_control_api.py +470 -0
  239. cancan_microstack/services/controllersrv/router.py +132 -0
  240. cancan_microstack/services/infrasrv/__init__.py +4 -0
  241. cancan_microstack/services/infrasrv/application/__init__.py +0 -0
  242. cancan_microstack/services/infrasrv/application/health_check_app.py +24 -0
  243. cancan_microstack/services/infrasrv/application/logging/__init__.py +1 -0
  244. cancan_microstack/services/infrasrv/application/logging/log_ingestion_service.py +183 -0
  245. cancan_microstack/services/infrasrv/application/service_config.py +22 -0
  246. cancan_microstack/services/infrasrv/application/service_logs_app.py +53 -0
  247. cancan_microstack/services/infrasrv/application/service_management_app.py +689 -0
  248. cancan_microstack/services/infrasrv/application/service_operation_tracker.py +251 -0
  249. cancan_microstack/services/infrasrv/application/service_registry.py +53 -0
  250. cancan_microstack/services/infrasrv/application/workflow/__init__.py +0 -0
  251. cancan_microstack/services/infrasrv/application/workflow/workflow_app.py +991 -0
  252. cancan_microstack/services/infrasrv/application/workflow/workflow_queue.py +302 -0
  253. cancan_microstack/services/infrasrv/application/workflow/workflow_tasks.py +46 -0
  254. cancan_microstack/services/infrasrv/application/workflow/workflow_worker_runtime.py +122 -0
  255. cancan_microstack/services/infrasrv/conf/__init__.py +0 -0
  256. cancan_microstack/services/infrasrv/conf/config.py +98 -0
  257. cancan_microstack/services/infrasrv/domain/__init__.py +0 -0
  258. cancan_microstack/services/infrasrv/domain/health_check/__init__.py +3 -0
  259. cancan_microstack/services/infrasrv/domain/health_check/health_check_domain.py +576 -0
  260. cancan_microstack/services/infrasrv/domain/hooks/__init__.py +19 -0
  261. cancan_microstack/services/infrasrv/domain/hooks/builtin_hooks.py +308 -0
  262. cancan_microstack/services/infrasrv/domain/hooks/hook_registry.py +43 -0
  263. cancan_microstack/services/infrasrv/domain/hooks/hooks_log_utils.py +275 -0
  264. cancan_microstack/services/infrasrv/domain/hooks/init.py +17 -0
  265. cancan_microstack/services/infrasrv/domain/hooks/metrics.py +205 -0
  266. cancan_microstack/services/infrasrv/domain/hooks/pre_registration_hooks.py +490 -0
  267. cancan_microstack/services/infrasrv/domain/registry/__init__.py +0 -0
  268. cancan_microstack/services/infrasrv/domain/registry/service_registry.py +509 -0
  269. cancan_microstack/services/infrasrv/domain/service_config/__init__.py +0 -0
  270. cancan_microstack/services/infrasrv/domain/service_config/service_config.py +50 -0
  271. cancan_microstack/services/infrasrv/domain/service_logs/__init__.py +0 -0
  272. cancan_microstack/services/infrasrv/domain/service_logs/service_logs_domain.py +51 -0
  273. cancan_microstack/services/infrasrv/domain/workflow/__init__.py +4 -0
  274. cancan_microstack/services/infrasrv/domain/workflow/engine.py +159 -0
  275. cancan_microstack/services/infrasrv/domain/workflow/node_handlers.py +509 -0
  276. cancan_microstack/services/infrasrv/domain/workflow/workflow_domain.py +164 -0
  277. cancan_microstack/services/infrasrv/infrastructure/__init__.py +0 -0
  278. cancan_microstack/services/infrasrv/infrastructure/api/__init__.py +0 -0
  279. cancan_microstack/services/infrasrv/infrastructure/api/controllersrv_api.py +165 -0
  280. cancan_microstack/services/infrasrv/infrastructure/cache/__init__.py +0 -0
  281. cancan_microstack/services/infrasrv/infrastructure/cache/service_registry_cache.py +174 -0
  282. cancan_microstack/services/infrasrv/infrastructure/db/__init__.py +0 -0
  283. cancan_microstack/services/infrasrv/infrastructure/db/model/__init__.py +0 -0
  284. cancan_microstack/services/infrasrv/infrastructure/db/model/execution_log_tbl.py +53 -0
  285. cancan_microstack/services/infrasrv/infrastructure/db/model/node_instance_tbl.py +55 -0
  286. cancan_microstack/services/infrasrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
  287. cancan_microstack/services/infrasrv/infrastructure/db/model/service_config_tbl.py +30 -0
  288. cancan_microstack/services/infrasrv/infrastructure/db/model/service_info_tbl.py +59 -0
  289. cancan_microstack/services/infrasrv/infrastructure/db/model/service_instance_tbl.py +88 -0
  290. cancan_microstack/services/infrasrv/infrastructure/db/model/service_operation_tbl.py +73 -0
  291. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_tbl.py +55 -0
  292. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_version_tbl.py +43 -0
  293. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_engine_alert_tbl.py +57 -0
  294. cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_run_tbl.py +56 -0
  295. cancan_microstack/services/infrasrv/infrastructure/db/operate/__init__.py +0 -0
  296. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_action_log_op.py +239 -0
  297. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config.py +80 -0
  298. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config_manager.py +198 -0
  299. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_info_op.py +297 -0
  300. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_instance_op.py +688 -0
  301. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_operation_op.py +387 -0
  302. cancan_microstack/services/infrasrv/infrastructure/db/operate/service_registry.py +124 -0
  303. cancan_microstack/services/infrasrv/infrastructure/db/operate/workflow_op.py +804 -0
  304. cancan_microstack/services/infrasrv/infrastructure/ddl_manager.py +31 -0
  305. cancan_microstack/services/infrasrv/infrastructure/mongo/__init__.py +1 -0
  306. cancan_microstack/services/infrasrv/infrastructure/mongo/log_repository.py +129 -0
  307. cancan_microstack/services/infrasrv/interface/__init__.py +0 -0
  308. cancan_microstack/services/infrasrv/interface/api/__init__.py +0 -0
  309. cancan_microstack/services/infrasrv/interface/api/health_check_api.py +29 -0
  310. cancan_microstack/services/infrasrv/interface/api/hooks.py +284 -0
  311. cancan_microstack/services/infrasrv/interface/api/internal.py +49 -0
  312. cancan_microstack/services/infrasrv/interface/api/internal_instance_api.py +265 -0
  313. cancan_microstack/services/infrasrv/interface/api/internal_operation_api.py +206 -0
  314. cancan_microstack/services/infrasrv/interface/api/service_config.py +50 -0
  315. cancan_microstack/services/infrasrv/interface/api/service_logs_api.py +49 -0
  316. cancan_microstack/services/infrasrv/interface/api/service_management_api.py +113 -0
  317. cancan_microstack/services/infrasrv/interface/api/service_registry.py +117 -0
  318. cancan_microstack/services/infrasrv/interface/api/workflow_api.py +303 -0
  319. cancan_microstack/services/infrasrv/interface/schedule/__init__.py +0 -0
  320. cancan_microstack/services/infrasrv/interface/schedule/cleanup.py +13 -0
  321. cancan_microstack/services/infrasrv/interface/schedule/health_check.py +27 -0
  322. cancan_microstack/services/infrasrv/interface/schedule/log_cleanup.py +26 -0
  323. cancan_microstack/services/infrasrv/interface/schedule/operation_tracker.py +25 -0
  324. cancan_microstack/services/infrasrv/interface/schedule/scheduler.py +39 -0
  325. cancan_microstack/services/infrasrv/interface/schedule/workflow_scheduler.py +115 -0
  326. cancan_microstack/services/infrasrv/router.py +341 -0
  327. cancan_microstack/services/opsbffsrv/__init__.py +4 -0
  328. cancan_microstack/services/opsbffsrv/application/__init__.py +0 -0
  329. cancan_microstack/services/opsbffsrv/application/async_operation_app.py +150 -0
  330. cancan_microstack/services/opsbffsrv/application/auth_app.py +285 -0
  331. cancan_microstack/services/opsbffsrv/application/caddy/__init__.py +0 -0
  332. cancan_microstack/services/opsbffsrv/application/caddy/access_log_analysis_app.py +344 -0
  333. cancan_microstack/services/opsbffsrv/application/caddy/access_log_ingestion_service.py +169 -0
  334. cancan_microstack/services/opsbffsrv/application/caddy/certificate_management_app.py +355 -0
  335. cancan_microstack/services/opsbffsrv/application/caddy/rate_limit_management_app.py +496 -0
  336. cancan_microstack/services/opsbffsrv/application/caddy/route_management_app.py +401 -0
  337. cancan_microstack/services/opsbffsrv/application/caddy/stats_aggregation_app.py +364 -0
  338. cancan_microstack/services/opsbffsrv/application/db_admin_app.py +103 -0
  339. cancan_microstack/services/opsbffsrv/application/db_init_app.py +283 -0
  340. cancan_microstack/services/opsbffsrv/application/logging/__init__.py +1 -0
  341. cancan_microstack/services/opsbffsrv/application/logging/log_query_app.py +28 -0
  342. cancan_microstack/services/opsbffsrv/application/service_config.py +158 -0
  343. cancan_microstack/services/opsbffsrv/application/service_logs_app.py +74 -0
  344. cancan_microstack/services/opsbffsrv/application/service_registry.py +36 -0
  345. cancan_microstack/services/opsbffsrv/application/workflow_ops_app.py +730 -0
  346. cancan_microstack/services/opsbffsrv/conf/__init__.py +0 -0
  347. cancan_microstack/services/opsbffsrv/conf/config.py +224 -0
  348. cancan_microstack/services/opsbffsrv/domain/__init__.py +0 -0
  349. cancan_microstack/services/opsbffsrv/domain/auth/__init__.py +0 -0
  350. cancan_microstack/services/opsbffsrv/domain/auth/admin_init.py +38 -0
  351. cancan_microstack/services/opsbffsrv/domain/auth/auth_domain.py +108 -0
  352. cancan_microstack/services/opsbffsrv/domain/caddy/__init__.py +0 -0
  353. cancan_microstack/services/opsbffsrv/domain/caddy/access_log_analysis.py +358 -0
  354. cancan_microstack/services/opsbffsrv/domain/caddy/certificate_management.py +325 -0
  355. cancan_microstack/services/opsbffsrv/domain/caddy/default_routes.py +53 -0
  356. cancan_microstack/services/opsbffsrv/domain/caddy/rate_limit_management.py +308 -0
  357. cancan_microstack/services/opsbffsrv/domain/caddy/route_management.py +279 -0
  358. cancan_microstack/services/opsbffsrv/domain/caddy/stats_aggregation.py +654 -0
  359. cancan_microstack/services/opsbffsrv/domain/db_admin/__init__.py +0 -0
  360. cancan_microstack/services/opsbffsrv/domain/db_admin/db_admin_domain.py +118 -0
  361. cancan_microstack/services/opsbffsrv/domain/db_init/__init__.py +3 -0
  362. cancan_microstack/services/opsbffsrv/domain/db_init/db_init_domain.py +358 -0
  363. cancan_microstack/services/opsbffsrv/domain/logging/__init__.py +1 -0
  364. cancan_microstack/services/opsbffsrv/domain/logging/log_query_domain.py +99 -0
  365. cancan_microstack/services/opsbffsrv/domain/service_config/__init__.py +0 -0
  366. cancan_microstack/services/opsbffsrv/domain/service_config/service_config.py +81 -0
  367. cancan_microstack/services/opsbffsrv/domain/service_registry/__init__.py +0 -0
  368. cancan_microstack/services/opsbffsrv/domain/service_registry/service_registry.py +292 -0
  369. cancan_microstack/services/opsbffsrv/infrastructure/__init__.py +0 -0
  370. cancan_microstack/services/opsbffsrv/infrastructure/api/__init__.py +0 -0
  371. cancan_microstack/services/opsbffsrv/infrastructure/api/infrasrv_api.py +242 -0
  372. cancan_microstack/services/opsbffsrv/infrastructure/auth/__init__.py +0 -0
  373. cancan_microstack/services/opsbffsrv/infrastructure/auth/captcha_service.py +67 -0
  374. cancan_microstack/services/opsbffsrv/infrastructure/auth/password_service.py +12 -0
  375. cancan_microstack/services/opsbffsrv/infrastructure/auth/redis_store.py +131 -0
  376. cancan_microstack/services/opsbffsrv/infrastructure/auth/totp_service.py +59 -0
  377. cancan_microstack/services/opsbffsrv/infrastructure/caddy/__init__.py +0 -0
  378. cancan_microstack/services/opsbffsrv/infrastructure/caddy/access_log_parser.py +307 -0
  379. cancan_microstack/services/opsbffsrv/infrastructure/caddy/admin_api_client.py +678 -0
  380. cancan_microstack/services/opsbffsrv/infrastructure/caddy/ip_geo_locator.py +176 -0
  381. cancan_microstack/services/opsbffsrv/infrastructure/db/__init__.py +0 -0
  382. cancan_microstack/services/opsbffsrv/infrastructure/db/model/__init__.py +0 -0
  383. cancan_microstack/services/opsbffsrv/infrastructure/db/model/admin_user_tbl.py +33 -0
  384. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_access_log_tbl.py +90 -0
  385. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_certificate_tbl.py +65 -0
  386. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_rate_limit_tbl.py +69 -0
  387. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_route_tbl.py +66 -0
  388. cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_stats_tbl.py +78 -0
  389. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
  390. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_config_tbl.py +30 -0
  391. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_info_tbl.py +51 -0
  392. cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_instance_tbl.py +68 -0
  393. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/__init__.py +0 -0
  394. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/admin_user_operate.py +59 -0
  395. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_access_log.py +531 -0
  396. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_certificate.py +451 -0
  397. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_rate_limit.py +360 -0
  398. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_route.py +271 -0
  399. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_stats.py +343 -0
  400. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_action_log_op.py +57 -0
  401. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_config.py +86 -0
  402. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_info_op.py +79 -0
  403. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_instance.py +58 -0
  404. cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_registry.py +138 -0
  405. cancan_microstack/services/opsbffsrv/infrastructure/ddl_manager.py +31 -0
  406. cancan_microstack/services/opsbffsrv/infrastructure/mongo/__init__.py +1 -0
  407. cancan_microstack/services/opsbffsrv/infrastructure/mongo/log_query_repository.py +87 -0
  408. cancan_microstack/services/opsbffsrv/interface/__init__.py +0 -0
  409. cancan_microstack/services/opsbffsrv/interface/api/__init__.py +0 -0
  410. cancan_microstack/services/opsbffsrv/interface/api/async_operation_api.py +137 -0
  411. cancan_microstack/services/opsbffsrv/interface/api/auth_api.py +113 -0
  412. cancan_microstack/services/opsbffsrv/interface/api/caddy/__init__.py +3 -0
  413. cancan_microstack/services/opsbffsrv/interface/api/caddy/access_log_api.py +174 -0
  414. cancan_microstack/services/opsbffsrv/interface/api/caddy/certificate_api.py +235 -0
  415. cancan_microstack/services/opsbffsrv/interface/api/caddy/rate_limit_api.py +302 -0
  416. cancan_microstack/services/opsbffsrv/interface/api/caddy/route_api.py +250 -0
  417. cancan_microstack/services/opsbffsrv/interface/api/caddy/stats_api.py +243 -0
  418. cancan_microstack/services/opsbffsrv/interface/api/db_admin_api.py +62 -0
  419. cancan_microstack/services/opsbffsrv/interface/api/db_init_api.py +109 -0
  420. cancan_microstack/services/opsbffsrv/interface/api/instance_management_api.py +165 -0
  421. cancan_microstack/services/opsbffsrv/interface/api/log_query_api.py +41 -0
  422. cancan_microstack/services/opsbffsrv/interface/api/mongo_express_proxy_api.py +181 -0
  423. cancan_microstack/services/opsbffsrv/interface/api/pgweb_proxy_api.py +154 -0
  424. cancan_microstack/services/opsbffsrv/interface/api/rabbitmq_mgmt_proxy_api.py +518 -0
  425. cancan_microstack/services/opsbffsrv/interface/api/redis_commander_proxy_api.py +133 -0
  426. cancan_microstack/services/opsbffsrv/interface/api/service_config.py +146 -0
  427. cancan_microstack/services/opsbffsrv/interface/api/service_logs_api.py +81 -0
  428. cancan_microstack/services/opsbffsrv/interface/api/service_registry.py +66 -0
  429. cancan_microstack/services/opsbffsrv/interface/api/workflow_ops_api.py +413 -0
  430. cancan_microstack/services/opsbffsrv/interface/middleware/__init__.py +0 -0
  431. cancan_microstack/services/opsbffsrv/interface/middleware/auth_middleware.py +52 -0
  432. cancan_microstack/services/opsbffsrv/router.py +901 -0
  433. cancan_microstack/utils/__init__.py +1 -0
  434. cancan_microstack/utils/container_env.py +218 -0
  435. cancan_microstack-0.0.1.dist-info/METADATA +155 -0
  436. cancan_microstack-0.0.1.dist-info/RECORD +440 -0
  437. cancan_microstack-0.0.1.dist-info/WHEEL +5 -0
  438. cancan_microstack-0.0.1.dist-info/entry_points.txt +2 -0
  439. cancan_microstack-0.0.1.dist-info/licenses/LICENSE +21 -0
  440. cancan_microstack-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,302 @@
1
+ """Workflow task dispatch helpers for Celery.
2
+
3
+ 提供封装后的 Celery 调度工具,避免业务层到处硬编码 task 名称。
4
+ This module centralizes Celery helper functions so higher layers can enqueue work
5
+ without importing Celery primitives directly.
6
+ """
7
+ import asyncio
8
+ import threading
9
+ import time
10
+ from dataclasses import dataclass
11
+ from typing import (
12
+ Awaitable,
13
+ Callable,
14
+ Dict,
15
+ Optional,
16
+ Tuple,
17
+ )
18
+
19
+ from linglong_web.utils import logger
20
+
21
+ from cancan_microstack.public.const.workflow_consts import WorkflowTask
22
+ from linglong_web import LinglongConfig
23
+ from linglong_web import Rmanager
24
+
25
+ _WORKER_STATUS = {
26
+ "checked_at": 0.0,
27
+ "has_worker": False,
28
+ }
29
+ _WORKER_STATUS_LOCK = threading.Lock()
30
+
31
+
32
+ def _missing_inline_orchestrator(run_id: str, node_id: str, loop_index: int) -> Awaitable[None]:
33
+ """当未注册 orchestrator 时,给出明确错误。
34
+ Raise a clear error when inline orchestrator hasn't been registered.
35
+ """
36
+
37
+ async def _raise() -> None:
38
+ raise RuntimeError(
39
+ "Workflow inline orchestrator is not registered. "
40
+ "Ensure workflow_app registers it via register_inline_orchestrator()."
41
+ )
42
+
43
+ return _raise()
44
+
45
+
46
+ _INLINE_ORCHESTRATOR: Callable[[str, str, int], Awaitable[None]] = _missing_inline_orchestrator
47
+ _INLINE_ORCHESTRATOR_LOCK = threading.Lock()
48
+
49
+
50
+ def register_inline_orchestrator(func: Callable[[str, str, int], Awaitable[None]]) -> None:
51
+ """注册工作流节点内联执行 orchestrator。
52
+ Register workflow node inline orchestrator.
53
+
54
+ Note:
55
+ This avoids a circular import between workflow_app and workflow_queue.
56
+ """
57
+
58
+ if not callable(func):
59
+ raise TypeError("Inline orchestrator must be callable")
60
+
61
+ global _INLINE_ORCHESTRATOR
62
+ with _INLINE_ORCHESTRATOR_LOCK:
63
+ _INLINE_ORCHESTRATOR = func
64
+
65
+
66
+ def _get_inline_orchestrator() -> Callable[[str, str, int], Awaitable[None]]:
67
+ with _INLINE_ORCHESTRATOR_LOCK:
68
+ return _INLINE_ORCHESTRATOR
69
+
70
+
71
+ def _to_positive_int(value, default: int) -> int:
72
+ """将配置值转换为正整数 / Ensure config-driven integers stay positive."""
73
+
74
+ try:
75
+ candidate = int(value)
76
+ except (TypeError, ValueError):
77
+ return default
78
+ return candidate if candidate > 0 else default
79
+
80
+
81
+ @dataclass(slots=True)
82
+ class _InlineJob:
83
+ """表示一次内联执行任务 / Represents a single inline execution request."""
84
+
85
+ run_id: str
86
+ node_id: str
87
+ loop_index: int
88
+
89
+
90
+ class _InlineFallbackExecutor:
91
+ """受限并发的内联执行器,防止 Celery 降级时无限制堆积。
92
+ Bounded-concurrency inline executor that prevents unbounded fan-out when Celery is unavailable.
93
+ """
94
+
95
+ def __init__(self, *, max_concurrency: int, queue_limit: int) -> None:
96
+ self._max_concurrency = max_concurrency
97
+ self._queue_limit = queue_limit
98
+ self._queues: Dict[int, asyncio.Queue[_InlineJob]] = {}
99
+
100
+ async def _run_job(self, job: _InlineJob) -> None:
101
+ orchestrator = _get_inline_orchestrator()
102
+ await orchestrator(job.run_id, job.node_id, job.loop_index)
103
+
104
+ async def _worker(self, queue: asyncio.Queue[_InlineJob], worker_idx: int) -> None:
105
+ """后台 worker,串行消费队列任务 / Background worker that drains inline queue with bounded concurrency."""
106
+
107
+ while True:
108
+ job = await queue.get()
109
+ try:
110
+ await self._run_job(job)
111
+ except Exception as exc: # noqa: BLE001 - inline fallback必须兜底 / inline fallback must never crash the orchestrator
112
+ logger.error(
113
+ "Inline workflow worker %s failed for run=%s node=%s: %s",
114
+ worker_idx,
115
+ job.run_id,
116
+ job.node_id,
117
+ exc,
118
+ exc_info=True,
119
+ )
120
+ finally:
121
+ queue.task_done()
122
+
123
+ async def _enqueue_with_backpressure(self, queue: asyncio.Queue[_InlineJob], job: _InlineJob) -> None:
124
+ """等待队列空位,避免一次性放入过多任务 / Wait for free slot instead of flooding the loop."""
125
+
126
+ await queue.put(job)
127
+
128
+ def _ensure_queue(self, loop: asyncio.AbstractEventLoop) -> asyncio.Queue[_InlineJob]:
129
+ """按事件循环初始化队列和 worker / Ensure queue + workers exist for the active loop."""
130
+
131
+ loop_id = id(loop)
132
+ queue = self._queues.get(loop_id)
133
+ if queue:
134
+ return queue
135
+
136
+ queue = asyncio.Queue(maxsize=self._queue_limit)
137
+ self._queues[loop_id] = queue
138
+
139
+ for idx in range(self._max_concurrency):
140
+ loop.create_task(
141
+ self._worker(queue, idx + 1),
142
+ name=f"workflow-inline-worker-{idx + 1}",
143
+ )
144
+
145
+ return queue
146
+
147
+ def submit(self, run_id: str, node_id: str, loop_index: int) -> None:
148
+ """投递内联执行任务,自动施加并发限流。
149
+ Submit inline execution with bounded concurrency to keep fallback predictable.
150
+ """
151
+
152
+ job = _InlineJob(run_id=run_id, node_id=node_id, loop_index=loop_index)
153
+ try:
154
+ loop = asyncio.get_running_loop()
155
+ except RuntimeError:
156
+ logger.warning(
157
+ "No running event loop detected while executing workflow node inline; creating a temporary loop",
158
+ )
159
+ asyncio.run(self._run_job(job))
160
+ return
161
+
162
+ queue = self._ensure_queue(loop)
163
+
164
+ try:
165
+ queue.put_nowait(job)
166
+ except asyncio.QueueFull:
167
+ logger.warning(
168
+ "Inline workflow queue saturated (size=%s limit=%s); applying async backpressure",
169
+ queue.qsize(),
170
+ self._queue_limit,
171
+ )
172
+ loop.create_task(self._enqueue_with_backpressure(queue, job))
173
+
174
+ async def wait_for_idle(self, loop: asyncio.AbstractEventLoop | None = None) -> None:
175
+ """等待队列清空(测试辅助) / Wait for inline queue to drain (useful for tests)."""
176
+
177
+ target_loop = loop or asyncio.get_running_loop()
178
+ queue = self._queues.get(id(target_loop))
179
+ if not queue:
180
+ return
181
+ await queue.join()
182
+
183
+
184
+ _INLINE_EXECUTOR: Optional[_InlineFallbackExecutor] = None
185
+ _INLINE_EXECUTOR_CONFIG: Optional[Tuple[int, int]] = None
186
+ _INLINE_EXECUTOR_OVERRIDE: Optional[_InlineFallbackExecutor] = None
187
+ _INLINE_EXECUTOR_LOCK = threading.Lock()
188
+
189
+
190
+ def _read_inline_executor_config() -> Tuple[int, int]:
191
+ """读取并规范化内联执行器配置 / Read + normalize inline executor config."""
192
+
193
+ max_concurrency = _to_positive_int(LinglongConfig.WORKFLOW_INLINE_MAX_CONCURRENCY, 4)
194
+ queue_limit_hint = max(max_concurrency * 4, 1024)
195
+ queue_limit = _to_positive_int(LinglongConfig.WORKFLOW_INLINE_QUEUE_LIMIT, queue_limit_hint)
196
+ queue_limit = max(queue_limit, max_concurrency)
197
+ return max_concurrency, queue_limit
198
+
199
+
200
+ def _get_inline_executor() -> _InlineFallbackExecutor:
201
+ """根据当前 Config 获取内联执行器,支持热更新。
202
+ Resolve inline executor lazily so Config updates take effect without process restarts.
203
+ """
204
+
205
+ override = _INLINE_EXECUTOR_OVERRIDE
206
+ if override is not None:
207
+ return override
208
+
209
+ global _INLINE_EXECUTOR, _INLINE_EXECUTOR_CONFIG
210
+ with _INLINE_EXECUTOR_LOCK:
211
+ desired = _read_inline_executor_config()
212
+ if _INLINE_EXECUTOR and _INLINE_EXECUTOR_CONFIG == desired:
213
+ return _INLINE_EXECUTOR
214
+
215
+ max_concurrency, queue_limit = desired
216
+ logger.info(
217
+ "Rebuilding inline executor due to config change: concurrency=%s queue_limit=%s",
218
+ max_concurrency,
219
+ queue_limit,
220
+ )
221
+ _INLINE_EXECUTOR = _InlineFallbackExecutor(
222
+ max_concurrency=max_concurrency,
223
+ queue_limit=queue_limit,
224
+ )
225
+ _INLINE_EXECUTOR_CONFIG = desired
226
+ return _INLINE_EXECUTOR
227
+
228
+
229
+ async def wait_for_inline_queue_idle() -> None:
230
+ """等待内联队列清空(测试辅助) / Wait for inline queue to drain (test helper)."""
231
+
232
+ executor = _get_inline_executor()
233
+ await executor.wait_for_idle()
234
+
235
+
236
+ def _celery_has_workers(celery_app, cache_ttl: float = 15.0) -> bool:
237
+ """检测 Celery worker 是否在线,避免任务无限排队。
238
+ Check if at least one Celery worker is alive so we can decide whether to enqueue or run inline."""
239
+
240
+ now = time.monotonic()
241
+ with _WORKER_STATUS_LOCK:
242
+ checked_at = _WORKER_STATUS["checked_at"]
243
+ cached_result = _WORKER_STATUS["has_worker"]
244
+
245
+ if now - checked_at < cache_ttl:
246
+ return cached_result
247
+
248
+ try:
249
+ responses = celery_app.control.ping(timeout=1.0) or []
250
+ has_worker = len(responses) > 0
251
+ except Exception as exc: # noqa: BLE001
252
+ logger.warning("Failed to ping Celery workers: %s", exc)
253
+ has_worker = False
254
+
255
+ with _WORKER_STATUS_LOCK:
256
+ _WORKER_STATUS["checked_at"] = now
257
+ _WORKER_STATUS["has_worker"] = has_worker
258
+ return has_worker
259
+
260
+
261
+ def _execute_inline_node(run_id: str, node_id: str, loop_index: int) -> None:
262
+ """直接在当前进程执行节点,但通过队列控制瞬时并发。
263
+ Execute node orchestrator inline while honoring bounded inline concurrency.
264
+ """
265
+
266
+ executor = _get_inline_executor()
267
+ executor.submit(run_id, node_id, loop_index)
268
+
269
+
270
+ def enqueue_node_execution(run_id: str, node_id: str, loop_index: int) -> None:
271
+ """将节点执行请求投递到 Celery 队列 / Send a node execution request to Celery."""
272
+
273
+ celery_app = Rmanager.CeleryApp
274
+ if not celery_app:
275
+ logger.warning(
276
+ "Celery is not initialized, executing workflow node inline: run=%s node=%s",
277
+ run_id,
278
+ node_id,
279
+ )
280
+ _execute_inline_node(run_id, node_id, loop_index)
281
+ return
282
+
283
+ if not _celery_has_workers(celery_app):
284
+ logger.warning(
285
+ "Celery has no active workers, executing workflow node inline: run=%s node=%s",
286
+ run_id,
287
+ node_id,
288
+ )
289
+ _execute_inline_node(run_id, node_id, loop_index)
290
+ return
291
+
292
+ try:
293
+ celery_app.send_task(WorkflowTask.EXECUTE_NODE, args=(run_id, node_id, loop_index))
294
+ except Exception as exc: # noqa: BLE001 - we need to capture all Celery backend issues
295
+ logger.error(
296
+ "Failed to enqueue workflow node via Celery (run=%s node=%s). Falling back to inline execution. Error: %s",
297
+ run_id,
298
+ node_id,
299
+ exc,
300
+ exc_info=True,
301
+ )
302
+ _execute_inline_node(run_id, node_id, loop_index)
@@ -0,0 +1,46 @@
1
+ """Workflow Celery task registration helpers.
2
+
3
+ 按照项目规范集中注册 Celery 任务,便于在 cmd/infrasrv/run.py 中一眼看出
4
+ 服务暴露了哪些任务;同时也避免循环导入。
5
+ This module centralizes Celery task declarations so run.py can register them
6
+ explicitly, making task discovery and testing easier.
7
+ """
8
+ import asyncio
9
+ import threading
10
+
11
+ from celery import Celery
12
+
13
+ from linglong_web import Rmanager
14
+ from cancan_microstack.public.const.workflow_consts import WorkflowTask
15
+ from cancan_microstack.services.infrasrv.application.workflow.workflow_app import workflow_app
16
+ from cancan_microstack.services.infrasrv.interface.schedule.workflow_scheduler import scan_and_trigger_workflows
17
+
18
+ _TASKS_REGISTERED = False
19
+ _REGISTER_LOCK = threading.Lock()
20
+
21
+
22
+ def register_workflow_tasks() -> None:
23
+ """注册工作流相关的 Celery 任务 / Register workflow Celery tasks only once."""
24
+ global _TASKS_REGISTERED
25
+ if _TASKS_REGISTERED:
26
+ return
27
+
28
+ # 双重检查锁,避免并发调用重复注册任务
29
+ # Double-checked locking to keep concurrent registrations idempotent
30
+ with _REGISTER_LOCK:
31
+ if _TASKS_REGISTERED:
32
+ return
33
+
34
+ celery_app: Celery = Rmanager.CeleryApp
35
+
36
+ @celery_app.task(name=WorkflowTask.EXECUTE_NODE, bind=True, max_retries=3, acks_late=True)
37
+ def execute_node_task(self, run_id: str, node_id: str, loop_index: int = 1):
38
+ """调用执行协调器 / Run the async node orchestrator inside Celery."""
39
+ asyncio.run(workflow_app._execute_node_orchestrator(run_id, node_id, loop_index))
40
+
41
+ @celery_app.task(name=WorkflowTask.SCAN_SCHEDULED, bind=True, autoretry_for=(Exception,), retry_backoff=True)
42
+ def scan_scheduled_task(self):
43
+ """周期扫描数据库查找待执行的工作流 / Periodically scan DB for due workflows."""
44
+ asyncio.run(scan_and_trigger_workflows())
45
+
46
+ _TASKS_REGISTERED = True
@@ -0,0 +1,122 @@
1
+ """Embedded Celery worker runtime for infrasrv workflow tasks.
2
+
3
+ 在单实例 infrasrv 内启动/停止 Celery worker,避免额外容器或进程。
4
+ The worker runs inside a dedicated daemon thread so the service can keep a
5
+ single deployment unit while still benefiting from Celery's queue semantics.
6
+ """
7
+ import os
8
+ import threading
9
+ from typing import Optional
10
+
11
+ from celery import Celery
12
+
13
+ from linglong_web import LinglongConfig
14
+ from linglong_web import Rmanager
15
+ from linglong_web.utils import logger
16
+
17
+ _worker_thread: Optional[threading.Thread] = None
18
+ _worker_hostname: Optional[str] = None
19
+ _worker_shutdown_lock = threading.Lock()
20
+
21
+
22
+ def _build_worker_hostname() -> str:
23
+ suffix = LinglongConfig.CELERY_WORKER_HOSTNAME_SUFFIX
24
+ base = (
25
+ os.environ.get("SERVICE_WORKER_HOSTNAME")
26
+ or os.environ.get("HOSTNAME")
27
+ or "infrasrv"
28
+ )
29
+ base = base.replace("/", "").split(".")[0]
30
+ suffix = suffix.lstrip(".@") or "inline"
31
+ return f"{base}@{suffix}"
32
+
33
+
34
+ def _build_worker_argv(hostname: str) -> list[str]:
35
+ log_level = LinglongConfig.CELERY_WORKER_LOG_LEVEL
36
+ concurrency = LinglongConfig.CELERY_WORKER_CONCURRENCY
37
+ pool = LinglongConfig.CELERY_WORKER_POOL
38
+ enable_beat = LinglongConfig.CELERY_WORKER_ENABLE_BEAT
39
+
40
+ argv = [
41
+ "worker",
42
+ f"--hostname={hostname}",
43
+ f"--loglevel={log_level}",
44
+ "--concurrency",
45
+ str(concurrency),
46
+ ]
47
+
48
+ if pool:
49
+ argv.extend(["--pool", str(pool)])
50
+
51
+ if enable_beat:
52
+ argv.append("--beat")
53
+
54
+ return argv
55
+
56
+
57
+ def start_inline_worker() -> None:
58
+ """启动内嵌 Celery worker / Start embedded Celery worker."""
59
+
60
+ if not LinglongConfig.CELERY_WORKER_AUTOSTART:
61
+ logger.info("Embedded Celery worker autostart disabled via config")
62
+ return
63
+
64
+ app: Celery | None = Rmanager.CeleryApp
65
+ if not app:
66
+ logger.warning("Celery is not initialized; embedded worker skipped")
67
+ return
68
+
69
+ global _worker_thread, _worker_hostname
70
+ with _worker_shutdown_lock:
71
+ if _worker_thread and _worker_thread.is_alive():
72
+ logger.info("Embedded Celery worker already running: hostname=%s", _worker_hostname)
73
+ return
74
+
75
+ hostname = _build_worker_hostname()
76
+ argv = _build_worker_argv(hostname)
77
+
78
+ def _run_worker():
79
+ logger.info(
80
+ "Starting embedded Celery worker hostname=%s argv=%s",
81
+ hostname,
82
+ " ".join(argv),
83
+ )
84
+ try:
85
+ app.worker_main(argv=argv)
86
+ except SystemExit as exc:
87
+ logger.info("Embedded Celery worker exited: %s", exc)
88
+ except Exception as exc: # noqa: BLE001
89
+ logger.error("Embedded Celery worker crashed: %s", exc, exc_info=True)
90
+ finally:
91
+ logger.info("Embedded Celery worker stopped")
92
+
93
+ worker_thread = threading.Thread(target=_run_worker, name="embedded-celery-worker", daemon=True)
94
+ worker_thread.start()
95
+ _worker_thread = worker_thread
96
+ _worker_hostname = hostname
97
+
98
+
99
+ def stop_inline_worker(timeout: float = 30.0) -> None:
100
+ """停止内嵌 Celery worker / Stop embedded Celery worker."""
101
+
102
+ global _worker_thread
103
+ with _worker_shutdown_lock:
104
+ thread = _worker_thread
105
+ if not thread or not thread.is_alive():
106
+ _worker_thread = None
107
+ return
108
+
109
+ app: Celery | None = Rmanager.CeleryApp
110
+ if app and _worker_hostname:
111
+ try:
112
+ logger.info("Sending shutdown signal to embedded Celery worker: %s", _worker_hostname)
113
+ app.control.shutdown(destination=[_worker_hostname])
114
+ except Exception as exc: # noqa: BLE001
115
+ logger.warning("Failed to send shutdown command to worker: %s", exc)
116
+
117
+ thread.join(timeout=timeout)
118
+ if thread.is_alive():
119
+ logger.warning("Embedded Celery worker did not stop within %.1fs", timeout)
120
+ else:
121
+ logger.info("Embedded Celery worker terminated cleanly")
122
+ _worker_thread = None
File without changes
@@ -0,0 +1,98 @@
1
+ import logging
2
+ import os
3
+
4
+ from linglong_web import LinglongConfigBase
5
+ from cancan_microstack.public.const.workflow_consts import WorkflowTask
6
+
7
+ from cancan_microstack.runtime.resources import resolve_workspace_or_asset
8
+ from cancan_microstack.runtime.workspace import configure_workspace, ensure_server_log_dir
9
+
10
+ _WORKSPACE_ROOT = str(configure_workspace())
11
+ ensure_server_log_dir()
12
+
13
+
14
+ class _BaseConfig(LinglongConfigBase):
15
+ """基础配置"""
16
+ DEBUG = False
17
+
18
+ # 项目根目录(动态获取)
19
+ _PROJECT_ROOT = _WORKSPACE_ROOT
20
+
21
+ INFRASRV_HOST = "http://infrasrv.service:8080"
22
+ CONTROLLERSRV_HOST = os.getenv("CONTROLLERSRV_HOST", "http://host.containers.internal:22100")
23
+
24
+ SKIP_SERVICE_REGISTRY = True
25
+
26
+ # DDL 自管理配置
27
+ ENABLE_DDL_AUTO_INIT = True # 启动时自动创建 infra 表
28
+ # DDL 脚本路径使用项目根目录
29
+ # - In Pod: /app/ddl/infra (Dockerfile COPY)
30
+ # - Out Pod: {project_root}/ddl/infra
31
+ DDL_SCRIPT_PATH = str(resolve_workspace_or_asset("ddl/infra", "ddl/infra"))
32
+
33
+ # 数据库配置
34
+ PGSQL_DB = "infra" # infrasrv 使用 infra 数据库
35
+
36
+ # PostgreSQL 连接池配置(兼顾并发与连接上限)
37
+ # PostgreSQL pool settings (balance concurrency and connection cap)
38
+ # 说明:infrasrv 需要同时处理操作轮询、健康检查、日志写入和服务管理写操作。
39
+ # Note: infrasrv handles operation polling, health checks, log ingestion, and management writes concurrently.
40
+ PGSQL_POOL_SIZE = 5
41
+ PGSQL_MAX_OVERFLOW = 5
42
+
43
+ # 服务注册清理配置 / Service registry cleanup settings
44
+ INSTANCE_HEARTBEAT_TIMEOUT_SECONDS = 90 # 僵尸实例的超时阈值(秒) / Stale instance threshold (seconds)
45
+
46
+ # 业务日志消费配置 / Business log ingestion settings
47
+ LOG_PIPELINE_CONSUMER_ENABLED = True
48
+ RABBITMQ_LOG_CONNECTION_NAME = "infrasrv-log-consumer"
49
+
50
+ # RabbitMQ 连接配置(日志消费 + 工作流 broker)
51
+ # RabbitMQ connection settings (log consumer + workflow broker)
52
+ RABBITMQ_HOST = os.getenv("RABBITMQ_HOST", "rabbitmq.internal")
53
+ RABBITMQ_PORT = int(os.getenv("RABBITMQ_PORT", "5672"))
54
+ RABBITMQ_VHOST = os.getenv("RABBITMQ_VHOST", "/")
55
+ RABBITMQ_USERNAME = os.getenv("RABBITMQ_USERNAME", "admin")
56
+ RABBITMQ_PASSWORD = os.getenv("RABBITMQ_PASSWORD", "admin123")
57
+
58
+ # MongoDB 配置(日志存储) / MongoDB settings for log storage
59
+ # 注意:默认使用 root 用户认证数据库 admin
60
+ # Note: default uses root user with authSource=admin
61
+ MONGODB_URI = os.getenv(
62
+ "MONGODB_URI",
63
+ "mongodb://admin:admin123@mongo.internal:27017/admin?authSource=admin",
64
+ )
65
+ MONGODB_DB = "infra_logging"
66
+ MONGODB_COLLECTION = "service_logs"
67
+
68
+ # Celery 调度配置(基于 RabbitMQ + Redis)
69
+ # Celery scheduling settings (broker via RabbitMQ, backend via Redis)
70
+ ENABLE_WORKFLOW_CELERY = True
71
+ CELERY_APP_NAME = "infrasrv_workflow"
72
+ CELERY_RESULT_BACKEND_DB = 5
73
+ CELERY_TIMEZONE = "Asia/Shanghai"
74
+ CELERY_ENABLE_UTC = True
75
+ CELERY_BEAT_SCHEDULE = {
76
+ "scan-workflow-triggers": {
77
+ "task": WorkflowTask.SCAN_SCHEDULED,
78
+ "schedule": 5.0,
79
+ }
80
+ }
81
+
82
+ # 日志配置 - 使用项目根目录
83
+ # - In Pod: /app/server_log_data/{}.log (volume 挂载到宿主机)
84
+ # - Out Pod: {project_root}/server_log_data/{}.log
85
+ LOGGING_ENABLE_FILE_HANDLER = True
86
+ LOGGING_FILE_ADDR_FORMAT = os.path.join(_PROJECT_ROOT, "server_log_data", "{}.log")
87
+
88
+
89
+ class _ProductionConfig(_BaseConfig):
90
+ """生产环境配置"""
91
+ ENV_MODE = "prod"
92
+ DEBUG = False
93
+ LOGGING_LEVEL = logging.INFO
94
+
95
+
96
+ service_conf_dict = {
97
+ 'prod': _ProductionConfig,
98
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ """
2
+ 健康检查领域层模块
3
+ """