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.
- cancan_microstack/__init__.py +14 -0
- cancan_microstack/__version__.py +10 -0
- cancan_microstack/assets/__init__.py +6 -0
- cancan_microstack/assets/builds/caddy/Caddyfile +187 -0
- cancan_microstack/assets/builds/caddy/DEPLOYMENT.md +303 -0
- cancan_microstack/assets/builds/caddy/Dockerfile +46 -0
- cancan_microstack/assets/builds/caddy/README.md +343 -0
- cancan_microstack/assets/builds/caddy/geoip/README.md +5 -0
- cancan_microstack/assets/builds/caddy/start.sh +78 -0
- cancan_microstack/assets/builds/caddy/waf/coraza.conf +179 -0
- cancan_microstack/assets/builds/service/Dockerfile +59 -0
- cancan_microstack/assets/builds/service/README.md +13 -0
- cancan_microstack/assets/ddl/create_db.sql +22 -0
- cancan_microstack/assets/ddl/infra/execution_log_tbl.sql +46 -0
- cancan_microstack/assets/ddl/infra/node_instance_tbl.sql +56 -0
- cancan_microstack/assets/ddl/infra/service_action_log_tbl.sql +36 -0
- cancan_microstack/assets/ddl/infra/service_config_tbl.sql +26 -0
- cancan_microstack/assets/ddl/infra/service_info_tbl.sql +45 -0
- cancan_microstack/assets/ddl/infra/service_instance_tbl.sql +54 -0
- cancan_microstack/assets/ddl/infra/service_operation_tbl.sql +47 -0
- cancan_microstack/assets/ddl/infra/workflow_definition_tbl.sql +60 -0
- cancan_microstack/assets/ddl/infra/workflow_definition_version_tbl.sql +35 -0
- cancan_microstack/assets/ddl/infra/workflow_engine_alert_tbl.sql +34 -0
- cancan_microstack/assets/ddl/infra/workflow_run_tbl.sql +52 -0
- cancan_microstack/assets/ddl/ops/admin_user_tbl.sql +34 -0
- cancan_microstack/assets/ddl/ops/caddy_access_log_tbl.sql +91 -0
- cancan_microstack/assets/ddl/ops/caddy_certificate_tbl.sql +59 -0
- cancan_microstack/assets/ddl/ops/caddy_rate_limit_tbl.sql +64 -0
- cancan_microstack/assets/ddl/ops/caddy_route_tbl.sql +63 -0
- cancan_microstack/assets/ddl/ops/caddy_stats_tbl.sql +77 -0
- cancan_microstack/assets/ddl/trigger.sql +21 -0
- cancan_microstack/assets/docker/docker-compose.infra.yml +401 -0
- cancan_microstack/assets/scripts/README.md +195 -0
- cancan_microstack/assets/scripts/docker/build_images.sh +44 -0
- cancan_microstack/assets/scripts/docker/force_rebuild_images.sh +38 -0
- cancan_microstack/assets/scripts/docker/rebuild_all.sh +34 -0
- cancan_microstack/assets/scripts/docker/rebuild_compose.sh +61 -0
- cancan_microstack/assets/scripts/docker/restart.sh +35 -0
- cancan_microstack/assets/scripts/docker/restart_compose.sh +35 -0
- cancan_microstack/assets/scripts/docker/start.sh +78 -0
- cancan_microstack/assets/scripts/docker/start_all.sh +46 -0
- cancan_microstack/assets/scripts/docker/start_compose.sh +66 -0
- cancan_microstack/assets/scripts/docker/stop.sh +67 -0
- cancan_microstack/assets/scripts/docker/stop_all.sh +38 -0
- cancan_microstack/assets/scripts/docker/stop_compose.sh +38 -0
- cancan_microstack/assets/scripts/podman/build_images_podman.sh +59 -0
- cancan_microstack/assets/scripts/podman/cleanup_podman.sh +25 -0
- cancan_microstack/assets/scripts/podman/force_rebuild_images_podman.sh +56 -0
- cancan_microstack/assets/scripts/podman/rebuild_all_podman.sh +37 -0
- cancan_microstack/assets/scripts/podman/rebuild_compose_podman.sh +60 -0
- cancan_microstack/assets/scripts/podman/restart_compose_podman.sh +73 -0
- cancan_microstack/assets/scripts/podman/start_all_podman.sh +66 -0
- cancan_microstack/assets/scripts/podman/start_compose_podman.sh +80 -0
- cancan_microstack/assets/scripts/podman/start_podman.sh +91 -0
- cancan_microstack/assets/scripts/podman/stop.sh +73 -0
- cancan_microstack/assets/scripts/podman/stop_all_podman.sh +34 -0
- cancan_microstack/assets/scripts/podman/stop_compose_podman.sh +58 -0
- cancan_microstack/assets/scripts/start_controllersrv.sh +9 -0
- cancan_microstack/assets/scripts/utils/check_all_db_tables.sh +104 -0
- cancan_microstack/assets/scripts/utils/check_env.sh +177 -0
- cancan_microstack/assets/scripts/utils/check_service_management_deployment.sh +225 -0
- cancan_microstack/assets/scripts/utils/deploy_service_management.sh +176 -0
- cancan_microstack/assets/scripts/utils/force_reload_infrasrv.sh +52 -0
- cancan_microstack/assets/scripts/utils/monitor_service_management.sh +187 -0
- cancan_microstack/assets/scripts/utils/reset_postgres_volume.sh +68 -0
- cancan_microstack/assets/scripts/utils/test_async_operations.sh +141 -0
- cancan_microstack/assets/scripts/utils/verify_real_operations.sh +76 -0
- cancan_microstack/assets/service/Dockerfile +65 -0
- cancan_microstack/assets/www/adminops/assets/AppEmpty.vue_vue_type_script_setup_true_lang-BOKUurnM.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConfigManage-DKV5YOUz.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConfigManage-Y5bhy7wG.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ConsoleManage-8ljYvCW2.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ConsoleManage-BWpyqbuQ.css +1 -0
- cancan_microstack/assets/www/adminops/assets/DashboardNew-B9Nf1OPl.js +1 -0
- cancan_microstack/assets/www/adminops/assets/DashboardNew-DYWZKQ1V.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LogSearch-CA0Jhe78.js +1 -0
- cancan_microstack/assets/www/adminops/assets/LogSearch-CCZfTNPF.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LoginView-BId3kP3M.css +1 -0
- cancan_microstack/assets/www/adminops/assets/LoginView-BQZTV_Qy.js +1 -0
- cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-BdEYwqFq.js +1 -0
- cancan_microstack/assets/www/adminops/assets/OperationProgressDialog-D-pASR8G.css +1 -0
- cancan_microstack/assets/www/adminops/assets/PageContainer-Byss-yUC.js +1 -0
- cancan_microstack/assets/www/adminops/assets/PageContainer-C3nSZwM7.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RateLimitManage-BDI8jLpC.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RateLimitManage-DJY4NiF-.js +1 -0
- cancan_microstack/assets/www/adminops/assets/RouteManage-DaUQ4QLw.css +1 -0
- cancan_microstack/assets/www/adminops/assets/RouteManage-w9XCU0UA.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceCard-BFzHe6Tw.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceCard-BJUhWnA-.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceDetail-Cw24WuKp.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceDetail-Yum47zdB.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceList-C7ryvbhE.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceList-Cgd01fUx.css +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceLogs-COpG9H0h.js +1 -0
- cancan_microstack/assets/www/adminops/assets/ServiceLogs-H_Alq0cf.css +1 -0
- cancan_microstack/assets/www/adminops/assets/StatsOverview-D0TwMQkA.js +39 -0
- cancan_microstack/assets/www/adminops/assets/StatsOverview-lqAN6pqM.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpBindView-CWlAmzFt.js +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpBindView-HoQC1lhx.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpVerifyView-BHN1VtX1.css +1 -0
- cancan_microstack/assets/www/adminops/assets/TotpVerifyView-D3w_lZk8.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowCenter-DU_mpIA0.css +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowCenter-i50rZyxN.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-CnHokPL9.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowDesigner-DaZaZpLd.css +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowRuns-B09hK48c.js +1 -0
- cancan_microstack/assets/www/adminops/assets/WorkflowRuns-wGutKIIU.css +1 -0
- cancan_microstack/assets/www/adminops/assets/caddy-nnCKf8fG.js +1 -0
- cancan_microstack/assets/www/adminops/assets/format-Cuzxgna9.js +1 -0
- cancan_microstack/assets/www/adminops/assets/index-CiFlm8oc.js +64 -0
- cancan_microstack/assets/www/adminops/assets/index-UW0T1Dkc.css +1 -0
- cancan_microstack/assets/www/adminops/assets/service-BYlgGPs_.js +1 -0
- cancan_microstack/assets/www/adminops/assets/service-operation-6GzLw2Z1.js +1 -0
- cancan_microstack/assets/www/adminops/assets/style-CcIXnQ5y.css +1 -0
- cancan_microstack/assets/www/adminops/assets/style-lRnStdGu.js +39 -0
- cancan_microstack/assets/www/adminops/assets/useDebounce-BRlqfXqf.js +1 -0
- cancan_microstack/assets/www/adminops/assets/workflow-CUXs39Ac.js +1 -0
- cancan_microstack/assets/www/adminops/index.html +16 -0
- cancan_microstack/assets/www/adminops/vite.svg +1 -0
- cancan_microstack/cli/__init__.py +14 -0
- cancan_microstack/cli/__main__.py +9 -0
- cancan_microstack/cli/main.py +552 -0
- cancan_microstack/cmd/__init__.py +54 -0
- cancan_microstack/cmd/cancan/__init__.py +12 -0
- cancan_microstack/cmd/cancan/run.py +395 -0
- cancan_microstack/cmd/controllersrv/__init__.py +0 -0
- cancan_microstack/cmd/controllersrv/run.py +131 -0
- cancan_microstack/cmd/infrasrv/__init__.py +5 -0
- cancan_microstack/cmd/infrasrv/run.py +100 -0
- cancan_microstack/cmd/opsbffsrv/__init__.py +5 -0
- cancan_microstack/cmd/opsbffsrv/run.py +96 -0
- cancan_microstack/core/__init__.py +5 -0
- cancan_microstack/core/assets.py +123 -0
- cancan_microstack/core/compose_builder.py +102 -0
- cancan_microstack/core/doctor.py +152 -0
- cancan_microstack/core/microstack.py +71 -0
- cancan_microstack/core/runner.py +56 -0
- cancan_microstack/core/stack_manager.py +186 -0
- cancan_microstack/public/__init__.py +7 -0
- cancan_microstack/public/api/__init__.py +1 -0
- cancan_microstack/public/api/controllersrv_client.py +277 -0
- cancan_microstack/public/api/infrasrv_client.py +404 -0
- cancan_microstack/public/const/__init__.py +1 -0
- cancan_microstack/public/const/action_consts.py +18 -0
- cancan_microstack/public/const/app_consts.py +42 -0
- cancan_microstack/public/const/caddy_consts.py +22 -0
- cancan_microstack/public/const/controllersrv_consts.py +163 -0
- cancan_microstack/public/const/docker_consts.py +15 -0
- cancan_microstack/public/const/error.py +56 -0
- cancan_microstack/public/const/health_consts.py +52 -0
- cancan_microstack/public/const/hook_enums.py +56 -0
- cancan_microstack/public/const/logging_enums.py +13 -0
- cancan_microstack/public/const/metrics_enums.py +36 -0
- cancan_microstack/public/const/monitor_enums.py +26 -0
- cancan_microstack/public/const/operation_consts.py +53 -0
- cancan_microstack/public/const/opsbffsrv_error.py +92 -0
- cancan_microstack/public/const/overrides_consts.py +13 -0
- cancan_microstack/public/const/redis.py +17 -0
- cancan_microstack/public/const/service_consts.py +15 -0
- cancan_microstack/public/const/workflow_consts.py +65 -0
- cancan_microstack/public/error.py +41 -0
- cancan_microstack/public/logging/__init__.py +0 -0
- cancan_microstack/public/logging/initializer.py +109 -0
- cancan_microstack/public/logging/mq_handler.py +279 -0
- cancan_microstack/public/schemas/__init__.py +1 -0
- cancan_microstack/public/schemas/caddy/__init__.py +381 -0
- cancan_microstack/public/schemas/caddy/analysis.py +90 -0
- cancan_microstack/public/schemas/caddy/route.py +18 -0
- cancan_microstack/public/schemas/common.py +79 -0
- cancan_microstack/public/schemas/controllersrv/__init__.py +3 -0
- cancan_microstack/public/schemas/controllersrv/async_requests.py +30 -0
- cancan_microstack/public/schemas/controllersrv/compose_models.py +47 -0
- cancan_microstack/public/schemas/controllersrv/const.py +24 -0
- cancan_microstack/public/schemas/controllersrv/docker_models.py +45 -0
- cancan_microstack/public/schemas/controllersrv/docker_responses.py +104 -0
- cancan_microstack/public/schemas/controllersrv/requests.py +54 -0
- cancan_microstack/public/schemas/controllersrv/responses.py +124 -0
- cancan_microstack/public/schemas/controllersrv/task_models.py +102 -0
- cancan_microstack/public/schemas/controllersrv/validation.py +23 -0
- cancan_microstack/public/schemas/hook_metrics.py +124 -0
- cancan_microstack/public/schemas/hooks.py +39 -0
- cancan_microstack/public/schemas/infra/__init__.py +0 -0
- cancan_microstack/public/schemas/infra/cleanup.py +25 -0
- cancan_microstack/public/schemas/infra/container.py +74 -0
- cancan_microstack/public/schemas/infra/enums.py +135 -0
- cancan_microstack/public/schemas/infra/health_check.py +42 -0
- cancan_microstack/public/schemas/infra/hook_log.py +42 -0
- cancan_microstack/public/schemas/infra/operation.py +90 -0
- cancan_microstack/public/schemas/infra/overview.py +25 -0
- cancan_microstack/public/schemas/infra/push.py +33 -0
- cancan_microstack/public/schemas/infra/service_action_log.py +47 -0
- cancan_microstack/public/schemas/infra/service_config.py +10 -0
- cancan_microstack/public/schemas/infra/service_info.py +69 -0
- cancan_microstack/public/schemas/infra/service_instance.py +93 -0
- cancan_microstack/public/schemas/infra/service_management.py +152 -0
- cancan_microstack/public/schemas/infra/service_operation.py +79 -0
- cancan_microstack/public/schemas/infra/service_registry.py +158 -0
- cancan_microstack/public/schemas/infra/status_types.py +19 -0
- cancan_microstack/public/schemas/infra/workflow.py +566 -0
- cancan_microstack/public/schemas/logging/__init__.py +1 -0
- cancan_microstack/public/schemas/logging/log_event.py +121 -0
- cancan_microstack/public/schemas/opsbffsrv/__init__.py +1 -0
- cancan_microstack/public/schemas/opsbffsrv/async_ops.py +17 -0
- cancan_microstack/public/schemas/opsbffsrv/db_admin.py +147 -0
- cancan_microstack/public/schemas/opsbffsrv/db_init.py +48 -0
- cancan_microstack/public/schemas/opsbffsrv/service_config.py +89 -0
- cancan_microstack/public/schemas/opsbffsrv/service_logs.py +54 -0
- cancan_microstack/public/schemas/service_operation.py +24 -0
- cancan_microstack/public/schemas/service_registry.py +40 -0
- cancan_microstack/public/types/__init__.py +7 -0
- cancan_microstack/public/web/__init__.py +0 -0
- cancan_microstack/public/web/config_value.py +105 -0
- cancan_microstack/public/web/server.py +385 -0
- cancan_microstack/py.typed +0 -0
- cancan_microstack/runtime/__init__.py +0 -0
- cancan_microstack/runtime/compose_cmd.py +228 -0
- cancan_microstack/runtime/host_daemon.py +318 -0
- cancan_microstack/runtime/overrides.py +103 -0
- cancan_microstack/runtime/resources.py +25 -0
- cancan_microstack/runtime/workspace.py +94 -0
- cancan_microstack/services/__init__.py +0 -0
- cancan_microstack/services/controllersrv/__init__.py +8 -0
- cancan_microstack/services/controllersrv/application/__init__.py +0 -0
- cancan_microstack/services/controllersrv/application/docker_compose_app.py +427 -0
- cancan_microstack/services/controllersrv/conf/__init__.py +0 -0
- cancan_microstack/services/controllersrv/conf/config.py +76 -0
- cancan_microstack/services/controllersrv/conf/settings.py +54 -0
- cancan_microstack/services/controllersrv/domain/__init__.py +0 -0
- cancan_microstack/services/controllersrv/domain/docker_compose/__init__.py +0 -0
- cancan_microstack/services/controllersrv/domain/docker_compose/docker_compose_domain.py +278 -0
- cancan_microstack/services/controllersrv/domain/service_validator.py +327 -0
- cancan_microstack/services/controllersrv/domain/task/__init__.py +17 -0
- cancan_microstack/services/controllersrv/domain/task/task_queue.py +286 -0
- cancan_microstack/services/controllersrv/domain/task/task_worker.py +495 -0
- cancan_microstack/services/controllersrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/controllersrv/interface/api/docker_control_api.py +470 -0
- cancan_microstack/services/controllersrv/router.py +132 -0
- cancan_microstack/services/infrasrv/__init__.py +4 -0
- cancan_microstack/services/infrasrv/application/__init__.py +0 -0
- cancan_microstack/services/infrasrv/application/health_check_app.py +24 -0
- cancan_microstack/services/infrasrv/application/logging/__init__.py +1 -0
- cancan_microstack/services/infrasrv/application/logging/log_ingestion_service.py +183 -0
- cancan_microstack/services/infrasrv/application/service_config.py +22 -0
- cancan_microstack/services/infrasrv/application/service_logs_app.py +53 -0
- cancan_microstack/services/infrasrv/application/service_management_app.py +689 -0
- cancan_microstack/services/infrasrv/application/service_operation_tracker.py +251 -0
- cancan_microstack/services/infrasrv/application/service_registry.py +53 -0
- cancan_microstack/services/infrasrv/application/workflow/__init__.py +0 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_app.py +991 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_queue.py +302 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_tasks.py +46 -0
- cancan_microstack/services/infrasrv/application/workflow/workflow_worker_runtime.py +122 -0
- cancan_microstack/services/infrasrv/conf/__init__.py +0 -0
- cancan_microstack/services/infrasrv/conf/config.py +98 -0
- cancan_microstack/services/infrasrv/domain/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/health_check/__init__.py +3 -0
- cancan_microstack/services/infrasrv/domain/health_check/health_check_domain.py +576 -0
- cancan_microstack/services/infrasrv/domain/hooks/__init__.py +19 -0
- cancan_microstack/services/infrasrv/domain/hooks/builtin_hooks.py +308 -0
- cancan_microstack/services/infrasrv/domain/hooks/hook_registry.py +43 -0
- cancan_microstack/services/infrasrv/domain/hooks/hooks_log_utils.py +275 -0
- cancan_microstack/services/infrasrv/domain/hooks/init.py +17 -0
- cancan_microstack/services/infrasrv/domain/hooks/metrics.py +205 -0
- cancan_microstack/services/infrasrv/domain/hooks/pre_registration_hooks.py +490 -0
- cancan_microstack/services/infrasrv/domain/registry/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/registry/service_registry.py +509 -0
- cancan_microstack/services/infrasrv/domain/service_config/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/service_config/service_config.py +50 -0
- cancan_microstack/services/infrasrv/domain/service_logs/__init__.py +0 -0
- cancan_microstack/services/infrasrv/domain/service_logs/service_logs_domain.py +51 -0
- cancan_microstack/services/infrasrv/domain/workflow/__init__.py +4 -0
- cancan_microstack/services/infrasrv/domain/workflow/engine.py +159 -0
- cancan_microstack/services/infrasrv/domain/workflow/node_handlers.py +509 -0
- cancan_microstack/services/infrasrv/domain/workflow/workflow_domain.py +164 -0
- cancan_microstack/services/infrasrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/api/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/api/controllersrv_api.py +165 -0
- cancan_microstack/services/infrasrv/infrastructure/cache/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/cache/service_registry_cache.py +174 -0
- cancan_microstack/services/infrasrv/infrastructure/db/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/execution_log_tbl.py +53 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/node_instance_tbl.py +55 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_config_tbl.py +30 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_info_tbl.py +59 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_instance_tbl.py +88 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/service_operation_tbl.py +73 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_tbl.py +55 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_definition_version_tbl.py +43 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_engine_alert_tbl.py +57 -0
- cancan_microstack/services/infrasrv/infrastructure/db/model/workflow_run_tbl.py +56 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/__init__.py +0 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_action_log_op.py +239 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config.py +80 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_config_manager.py +198 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_info_op.py +297 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_instance_op.py +688 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_operation_op.py +387 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/service_registry.py +124 -0
- cancan_microstack/services/infrasrv/infrastructure/db/operate/workflow_op.py +804 -0
- cancan_microstack/services/infrasrv/infrastructure/ddl_manager.py +31 -0
- cancan_microstack/services/infrasrv/infrastructure/mongo/__init__.py +1 -0
- cancan_microstack/services/infrasrv/infrastructure/mongo/log_repository.py +129 -0
- cancan_microstack/services/infrasrv/interface/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/api/health_check_api.py +29 -0
- cancan_microstack/services/infrasrv/interface/api/hooks.py +284 -0
- cancan_microstack/services/infrasrv/interface/api/internal.py +49 -0
- cancan_microstack/services/infrasrv/interface/api/internal_instance_api.py +265 -0
- cancan_microstack/services/infrasrv/interface/api/internal_operation_api.py +206 -0
- cancan_microstack/services/infrasrv/interface/api/service_config.py +50 -0
- cancan_microstack/services/infrasrv/interface/api/service_logs_api.py +49 -0
- cancan_microstack/services/infrasrv/interface/api/service_management_api.py +113 -0
- cancan_microstack/services/infrasrv/interface/api/service_registry.py +117 -0
- cancan_microstack/services/infrasrv/interface/api/workflow_api.py +303 -0
- cancan_microstack/services/infrasrv/interface/schedule/__init__.py +0 -0
- cancan_microstack/services/infrasrv/interface/schedule/cleanup.py +13 -0
- cancan_microstack/services/infrasrv/interface/schedule/health_check.py +27 -0
- cancan_microstack/services/infrasrv/interface/schedule/log_cleanup.py +26 -0
- cancan_microstack/services/infrasrv/interface/schedule/operation_tracker.py +25 -0
- cancan_microstack/services/infrasrv/interface/schedule/scheduler.py +39 -0
- cancan_microstack/services/infrasrv/interface/schedule/workflow_scheduler.py +115 -0
- cancan_microstack/services/infrasrv/router.py +341 -0
- cancan_microstack/services/opsbffsrv/__init__.py +4 -0
- cancan_microstack/services/opsbffsrv/application/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/application/async_operation_app.py +150 -0
- cancan_microstack/services/opsbffsrv/application/auth_app.py +285 -0
- cancan_microstack/services/opsbffsrv/application/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/application/caddy/access_log_analysis_app.py +344 -0
- cancan_microstack/services/opsbffsrv/application/caddy/access_log_ingestion_service.py +169 -0
- cancan_microstack/services/opsbffsrv/application/caddy/certificate_management_app.py +355 -0
- cancan_microstack/services/opsbffsrv/application/caddy/rate_limit_management_app.py +496 -0
- cancan_microstack/services/opsbffsrv/application/caddy/route_management_app.py +401 -0
- cancan_microstack/services/opsbffsrv/application/caddy/stats_aggregation_app.py +364 -0
- cancan_microstack/services/opsbffsrv/application/db_admin_app.py +103 -0
- cancan_microstack/services/opsbffsrv/application/db_init_app.py +283 -0
- cancan_microstack/services/opsbffsrv/application/logging/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/application/logging/log_query_app.py +28 -0
- cancan_microstack/services/opsbffsrv/application/service_config.py +158 -0
- cancan_microstack/services/opsbffsrv/application/service_logs_app.py +74 -0
- cancan_microstack/services/opsbffsrv/application/service_registry.py +36 -0
- cancan_microstack/services/opsbffsrv/application/workflow_ops_app.py +730 -0
- cancan_microstack/services/opsbffsrv/conf/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/conf/config.py +224 -0
- cancan_microstack/services/opsbffsrv/domain/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/auth/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/auth/admin_init.py +38 -0
- cancan_microstack/services/opsbffsrv/domain/auth/auth_domain.py +108 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/access_log_analysis.py +358 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/certificate_management.py +325 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/default_routes.py +53 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/rate_limit_management.py +308 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/route_management.py +279 -0
- cancan_microstack/services/opsbffsrv/domain/caddy/stats_aggregation.py +654 -0
- cancan_microstack/services/opsbffsrv/domain/db_admin/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/db_admin/db_admin_domain.py +118 -0
- cancan_microstack/services/opsbffsrv/domain/db_init/__init__.py +3 -0
- cancan_microstack/services/opsbffsrv/domain/db_init/db_init_domain.py +358 -0
- cancan_microstack/services/opsbffsrv/domain/logging/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/domain/logging/log_query_domain.py +99 -0
- cancan_microstack/services/opsbffsrv/domain/service_config/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/service_config/service_config.py +81 -0
- cancan_microstack/services/opsbffsrv/domain/service_registry/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/domain/service_registry/service_registry.py +292 -0
- cancan_microstack/services/opsbffsrv/infrastructure/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/api/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/api/infrasrv_api.py +242 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/captcha_service.py +67 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/password_service.py +12 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/redis_store.py +131 -0
- cancan_microstack/services/opsbffsrv/infrastructure/auth/totp_service.py +59 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/access_log_parser.py +307 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/admin_api_client.py +678 -0
- cancan_microstack/services/opsbffsrv/infrastructure/caddy/ip_geo_locator.py +176 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/admin_user_tbl.py +33 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_access_log_tbl.py +90 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_certificate_tbl.py +65 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_rate_limit_tbl.py +69 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_route_tbl.py +66 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/caddy_stats_tbl.py +78 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_action_log_tbl.py +44 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_config_tbl.py +30 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_info_tbl.py +51 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/model/service_instance_tbl.py +68 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/admin_user_operate.py +59 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_access_log.py +531 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_certificate.py +451 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_rate_limit.py +360 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_route.py +271 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/caddy_stats.py +343 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_action_log_op.py +57 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_config.py +86 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_info_op.py +79 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_instance.py +58 -0
- cancan_microstack/services/opsbffsrv/infrastructure/db/operate/service_registry.py +138 -0
- cancan_microstack/services/opsbffsrv/infrastructure/ddl_manager.py +31 -0
- cancan_microstack/services/opsbffsrv/infrastructure/mongo/__init__.py +1 -0
- cancan_microstack/services/opsbffsrv/infrastructure/mongo/log_query_repository.py +87 -0
- cancan_microstack/services/opsbffsrv/interface/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/api/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/api/async_operation_api.py +137 -0
- cancan_microstack/services/opsbffsrv/interface/api/auth_api.py +113 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/__init__.py +3 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/access_log_api.py +174 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/certificate_api.py +235 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/rate_limit_api.py +302 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/route_api.py +250 -0
- cancan_microstack/services/opsbffsrv/interface/api/caddy/stats_api.py +243 -0
- cancan_microstack/services/opsbffsrv/interface/api/db_admin_api.py +62 -0
- cancan_microstack/services/opsbffsrv/interface/api/db_init_api.py +109 -0
- cancan_microstack/services/opsbffsrv/interface/api/instance_management_api.py +165 -0
- cancan_microstack/services/opsbffsrv/interface/api/log_query_api.py +41 -0
- cancan_microstack/services/opsbffsrv/interface/api/mongo_express_proxy_api.py +181 -0
- cancan_microstack/services/opsbffsrv/interface/api/pgweb_proxy_api.py +154 -0
- cancan_microstack/services/opsbffsrv/interface/api/rabbitmq_mgmt_proxy_api.py +518 -0
- cancan_microstack/services/opsbffsrv/interface/api/redis_commander_proxy_api.py +133 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_config.py +146 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_logs_api.py +81 -0
- cancan_microstack/services/opsbffsrv/interface/api/service_registry.py +66 -0
- cancan_microstack/services/opsbffsrv/interface/api/workflow_ops_api.py +413 -0
- cancan_microstack/services/opsbffsrv/interface/middleware/__init__.py +0 -0
- cancan_microstack/services/opsbffsrv/interface/middleware/auth_middleware.py +52 -0
- cancan_microstack/services/opsbffsrv/router.py +901 -0
- cancan_microstack/utils/__init__.py +1 -0
- cancan_microstack/utils/container_env.py +218 -0
- cancan_microstack-0.0.1.dist-info/METADATA +155 -0
- cancan_microstack-0.0.1.dist-info/RECORD +440 -0
- cancan_microstack-0.0.1.dist-info/WHEEL +5 -0
- cancan_microstack-0.0.1.dist-info/entry_points.txt +2 -0
- cancan_microstack-0.0.1.dist-info/licenses/LICENSE +21 -0
- cancan_microstack-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Docker Compose 管理领域层(重构版 - 使用 UnifiedExecutor)
|
|
3
|
+
|
|
4
|
+
职责:
|
|
5
|
+
1. 使用 UnifiedExecutor 进行容器操作
|
|
6
|
+
2. API 操作:用于查询容器、镜像、网络等(快速、结构化)
|
|
7
|
+
3. Compose 操作:用于服务编排(启动、停止、扩缩容等)
|
|
8
|
+
4. 不包含业务验证逻辑
|
|
9
|
+
"""
|
|
10
|
+
import asyncio
|
|
11
|
+
from typing import (
|
|
12
|
+
List,
|
|
13
|
+
Optional,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from linglong_web.utils import logger
|
|
17
|
+
from cancan_microstack.public.error import HTTPException
|
|
18
|
+
from cancan_microstack.public.const.controllersrv_consts import ControllersrvErrorCode
|
|
19
|
+
from cancan_microstack.public.schemas.controllersrv.docker_models import (
|
|
20
|
+
ContainerHealthDetail,
|
|
21
|
+
ContainerState,
|
|
22
|
+
HealthCheck,
|
|
23
|
+
)
|
|
24
|
+
from cancan_microstack.public.const.docker_consts import (
|
|
25
|
+
DockerLabel,
|
|
26
|
+
DockerInspectKey,
|
|
27
|
+
)
|
|
28
|
+
from dragonfly_container.core import UnifiedExecutor
|
|
29
|
+
from cancan_microstack.public.schemas.controllersrv.compose_models import (
|
|
30
|
+
CommandResult,
|
|
31
|
+
ServiceListResult,
|
|
32
|
+
ContainerHealthResult,
|
|
33
|
+
ComposeStatusResult,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DockerComposeDomain:
|
|
38
|
+
"""
|
|
39
|
+
Docker Compose 领域层(直接使用 Dragonfly Container UnifiedExecutor)
|
|
40
|
+
|
|
41
|
+
直接使用 UnifiedExecutor 进行容器管理和服务编排
|
|
42
|
+
- API 操作:用于查询和单容器控制(基于 SDK)
|
|
43
|
+
- Compose 操作:用于多服务编排(基于 CLI)
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self, executor: UnifiedExecutor):
|
|
47
|
+
"""
|
|
48
|
+
初始化领域层
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
executor: Dragonfly Container UnifiedExecutor 实例
|
|
52
|
+
"""
|
|
53
|
+
self.executor = executor
|
|
54
|
+
logger.info(
|
|
55
|
+
f"DockerComposeDomain initialized with UnifiedExecutor: "
|
|
56
|
+
f"engine={executor.api.engine_type}"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
async def execute_command(
|
|
60
|
+
self,
|
|
61
|
+
cmd: List[str],
|
|
62
|
+
timeout: int,
|
|
63
|
+
operation_name: str
|
|
64
|
+
) -> CommandResult:
|
|
65
|
+
"""
|
|
66
|
+
执行命令
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
cmd: 命令列表
|
|
70
|
+
timeout: 超时时间(秒)
|
|
71
|
+
operation_name: 操作名称(用于日志)
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
执行结果对象
|
|
75
|
+
"""
|
|
76
|
+
logger.info(f"[{operation_name}] Executing: {' '.join(cmd)}")
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
process = await asyncio.create_subprocess_exec(
|
|
80
|
+
*cmd,
|
|
81
|
+
stdout=asyncio.subprocess.PIPE,
|
|
82
|
+
stderr=asyncio.subprocess.PIPE
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
stdout, stderr = await asyncio.wait_for(
|
|
87
|
+
process.communicate(),
|
|
88
|
+
timeout=timeout
|
|
89
|
+
)
|
|
90
|
+
except asyncio.TimeoutError:
|
|
91
|
+
process.kill()
|
|
92
|
+
await process.wait()
|
|
93
|
+
raise Exception(f"Command timeout after {timeout}s")
|
|
94
|
+
|
|
95
|
+
success = process.returncode == 0
|
|
96
|
+
output = stdout.decode('utf-8', errors='ignore').strip()
|
|
97
|
+
error = stderr.decode('utf-8', errors='ignore').strip()
|
|
98
|
+
|
|
99
|
+
if success:
|
|
100
|
+
logger.info(f"[{operation_name}] Command succeeded")
|
|
101
|
+
else:
|
|
102
|
+
logger.error(
|
|
103
|
+
f"[{operation_name}] Command failed with code {process.returncode}: {error}"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return CommandResult(
|
|
107
|
+
success=success,
|
|
108
|
+
output=output,
|
|
109
|
+
error=error,
|
|
110
|
+
returncode=process.returncode,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error(f"[{operation_name}] Command execution error: {e}", exc_info=True)
|
|
115
|
+
return CommandResult(
|
|
116
|
+
success=False,
|
|
117
|
+
output="",
|
|
118
|
+
error=str(e),
|
|
119
|
+
returncode=-1,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
async def check_compose_running(self) -> bool:
|
|
123
|
+
"""
|
|
124
|
+
检查 Docker Compose 是否正在运行(使用 API)
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
True 表示有容器在运行
|
|
128
|
+
"""
|
|
129
|
+
try:
|
|
130
|
+
# 使用 API 查询当前项目的容器
|
|
131
|
+
containers = await self.executor.list_containers()
|
|
132
|
+
|
|
133
|
+
if containers:
|
|
134
|
+
logger.info(f"Docker Compose is running: {len(containers)} containers found")
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
logger.info("Docker Compose is not running: no containers found")
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
except Exception as e:
|
|
141
|
+
logger.error(f"Failed to check compose status: {e}", exc_info=True)
|
|
142
|
+
return False
|
|
143
|
+
|
|
144
|
+
async def get_service_status(self, service_names: Optional[List[str]] = None) -> ServiceListResult:
|
|
145
|
+
"""
|
|
146
|
+
获取服务状态(使用 API)
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
service_names: 服务名称列表,None 表示获取所有服务状态
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
服务状态结果对象
|
|
153
|
+
"""
|
|
154
|
+
# 使用 API 查询容器
|
|
155
|
+
containers = await self.executor.list_containers(all=True)
|
|
156
|
+
|
|
157
|
+
# 如果指定了服务名称,则过滤
|
|
158
|
+
if service_names:
|
|
159
|
+
# 过滤出指定服务的容器
|
|
160
|
+
# 容器名称格式通常是 project_service_1
|
|
161
|
+
filtered_containers = []
|
|
162
|
+
for container in containers:
|
|
163
|
+
# 检查标签中的 com.docker.compose.service
|
|
164
|
+
service = container.labels.get(DockerLabel.SERVICE, "")
|
|
165
|
+
if service in service_names:
|
|
166
|
+
filtered_containers.append(container)
|
|
167
|
+
containers = filtered_containers
|
|
168
|
+
|
|
169
|
+
# 构建服务列表(格式化输出,类似 docker-compose ps)
|
|
170
|
+
services = []
|
|
171
|
+
for container in containers:
|
|
172
|
+
service_name = container.labels.get(DockerLabel.SERVICE, "unknown")
|
|
173
|
+
services.append(
|
|
174
|
+
f"{container.name}\t{service_name}\t{container.status}\t{container.image}"
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
return ServiceListResult(
|
|
178
|
+
success=True,
|
|
179
|
+
services=services
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
async def list_services(self) -> ServiceListResult:
|
|
183
|
+
"""
|
|
184
|
+
列出所有服务(使用 API 从容器标签中提取)
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
服务列表结果对象
|
|
188
|
+
"""
|
|
189
|
+
# 使用 API 查询所有容器(包括已停止的)
|
|
190
|
+
containers = await self.executor.list_containers(all=True)
|
|
191
|
+
|
|
192
|
+
# 从容器标签中提取唯一的服务名称
|
|
193
|
+
services = set()
|
|
194
|
+
for container in containers:
|
|
195
|
+
service_name = container.labels.get(DockerLabel.SERVICE, "")
|
|
196
|
+
if service_name:
|
|
197
|
+
services.add(service_name)
|
|
198
|
+
|
|
199
|
+
return ServiceListResult(
|
|
200
|
+
success=True,
|
|
201
|
+
services=sorted(list(services))
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
async def get_container_health(self, service_name: str) -> ContainerHealthResult:
|
|
205
|
+
"""
|
|
206
|
+
获取容器健康状态(使用 API)
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
service_name: 服务名称
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
容器健康状态结果对象
|
|
213
|
+
"""
|
|
214
|
+
# 使用 API 查询所有容器
|
|
215
|
+
all_containers = await self.executor.list_containers(all=True)
|
|
216
|
+
|
|
217
|
+
# 过滤出指定服务的容器
|
|
218
|
+
service_containers = []
|
|
219
|
+
for container in all_containers:
|
|
220
|
+
if container.labels.get(DockerLabel.SERVICE) == service_name:
|
|
221
|
+
service_containers.append(container)
|
|
222
|
+
|
|
223
|
+
if not service_containers:
|
|
224
|
+
raise HTTPException(
|
|
225
|
+
error_code=ControllersrvErrorCode.SERVICE_NOT_FOUND,
|
|
226
|
+
msg=f"No containers found for service: {service_name}"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# 获取每个容器的详细信息
|
|
230
|
+
containers = []
|
|
231
|
+
for container in service_containers:
|
|
232
|
+
try:
|
|
233
|
+
# 使用 API 获取详细信息
|
|
234
|
+
detail = await self.executor.inspect_container(container.id)
|
|
235
|
+
state_data = detail.get(DockerInspectKey.STATE, {})
|
|
236
|
+
health_data = state_data.get(DockerInspectKey.HEALTH, {})
|
|
237
|
+
|
|
238
|
+
containers.append(
|
|
239
|
+
ContainerHealthDetail(
|
|
240
|
+
id=container.id,
|
|
241
|
+
name=container.name,
|
|
242
|
+
state=ContainerState.model_validate(state_data) if state_data else None,
|
|
243
|
+
health=HealthCheck.model_validate(health_data) if health_data else None,
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
except Exception as e:
|
|
247
|
+
logger.error(f"Failed to inspect container {container.id}: {e}")
|
|
248
|
+
# 使用基础信息作为备用
|
|
249
|
+
containers.append(
|
|
250
|
+
ContainerHealthDetail(
|
|
251
|
+
id=container.id,
|
|
252
|
+
name=container.name,
|
|
253
|
+
state=None,
|
|
254
|
+
health=None,
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
return ContainerHealthResult(success=True, containers=containers)
|
|
259
|
+
|
|
260
|
+
async def get_compose_status(self) -> ComposeStatusResult:
|
|
261
|
+
"""
|
|
262
|
+
获取 Docker Compose 整体状态(使用 API)
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Docker Compose 状态结果对象
|
|
266
|
+
"""
|
|
267
|
+
is_running = await self.check_compose_running()
|
|
268
|
+
services_info = await self.list_services()
|
|
269
|
+
status_info = await self.get_service_status()
|
|
270
|
+
|
|
271
|
+
return ComposeStatusResult(
|
|
272
|
+
is_running=is_running,
|
|
273
|
+
project_name=self.executor.project_name,
|
|
274
|
+
compose_file=self.executor.compose.compose_file,
|
|
275
|
+
engine_type=str(self.executor.api.engine_type),
|
|
276
|
+
available_services=services_info.services,
|
|
277
|
+
running_services=status_info.services,
|
|
278
|
+
)
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""
|
|
2
|
+
服务验证模块
|
|
3
|
+
|
|
4
|
+
负责验证服务名称是否合法、是否可操作
|
|
5
|
+
"""
|
|
6
|
+
import yaml
|
|
7
|
+
from typing import (
|
|
8
|
+
List,
|
|
9
|
+
Set,
|
|
10
|
+
Optional,
|
|
11
|
+
Dict,
|
|
12
|
+
Any,
|
|
13
|
+
)
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from linglong_web.utils import logger
|
|
16
|
+
from cancan_microstack.public.const.controllersrv_consts import (
|
|
17
|
+
ServiceCategory,
|
|
18
|
+
INFRASTRUCTURE_SERVICES,
|
|
19
|
+
FRAMEWORK_SERVICES,
|
|
20
|
+
ValidationResultKey,
|
|
21
|
+
)
|
|
22
|
+
from dragonfly_container.core import UnifiedExecutor
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ServiceValidator:
|
|
26
|
+
"""
|
|
27
|
+
服务验证器
|
|
28
|
+
|
|
29
|
+
职责:
|
|
30
|
+
1. 从 docker-compose.yml 读取所有服务定义
|
|
31
|
+
2. 区分基础设施服务、框架服务、业务服务
|
|
32
|
+
3. 验证服务名称是否合法、是否可操作
|
|
33
|
+
|
|
34
|
+
使用 Dragonfly Container 的 UnifiedExecutor 来获取服务信息
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, compose_file: str, executor: Optional[UnifiedExecutor] = None):
|
|
38
|
+
"""
|
|
39
|
+
初始化验证器
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
compose_file: docker-compose.yml 文件路径
|
|
43
|
+
executor: Dragonfly Container UnifiedExecutor 实例(可选,用于获取动态服务信息)
|
|
44
|
+
"""
|
|
45
|
+
self.compose_file = compose_file
|
|
46
|
+
self.executor = executor
|
|
47
|
+
self._all_services: Set[str] = set()
|
|
48
|
+
self._operable_services: Set[str] = set()
|
|
49
|
+
self._service_category_map: Dict[str, ServiceCategory] = {}
|
|
50
|
+
|
|
51
|
+
# 加载服务定义
|
|
52
|
+
self._load_services()
|
|
53
|
+
|
|
54
|
+
def _load_services(self):
|
|
55
|
+
"""
|
|
56
|
+
从 docker-compose.yml 加载服务定义
|
|
57
|
+
|
|
58
|
+
使用 Dragonfly Container 的 UnifiedExecutor 获取配置(如果可用),
|
|
59
|
+
否则直接解析 YAML 文件
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
compose_path = Path(self.compose_file)
|
|
63
|
+
if not compose_path.exists():
|
|
64
|
+
logger.error(f"Docker Compose file not found: {self.compose_file}")
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
# 优先使用 executor 获取配置(如果可用)
|
|
68
|
+
if self.executor:
|
|
69
|
+
services = self._get_services_from_executor()
|
|
70
|
+
else:
|
|
71
|
+
services = None
|
|
72
|
+
|
|
73
|
+
# 如果 executor 不可用或获取失败,回退到直接读取 YAML
|
|
74
|
+
if not services:
|
|
75
|
+
logger.info("Using direct YAML parse to get services")
|
|
76
|
+
services = self._get_services_from_yaml()
|
|
77
|
+
|
|
78
|
+
self._all_services = set(services.keys())
|
|
79
|
+
|
|
80
|
+
# 分类服务
|
|
81
|
+
for service_name in self._all_services:
|
|
82
|
+
category = self._categorize_service(service_name)
|
|
83
|
+
self._service_category_map[service_name] = category
|
|
84
|
+
|
|
85
|
+
# 只有业务服务可操作
|
|
86
|
+
if category == ServiceCategory.BUSINESS:
|
|
87
|
+
self._operable_services.add(service_name)
|
|
88
|
+
|
|
89
|
+
logger.info(
|
|
90
|
+
f"Loaded services from compose file: "
|
|
91
|
+
f"total={len(self._all_services)}, "
|
|
92
|
+
f"operable={len(self._operable_services)}"
|
|
93
|
+
)
|
|
94
|
+
logger.info(f"Operable services: {sorted(self._operable_services)}")
|
|
95
|
+
|
|
96
|
+
except Exception as e:
|
|
97
|
+
logger.error(f"Failed to load services from compose file: {e}", exc_info=True)
|
|
98
|
+
|
|
99
|
+
def _get_services_from_executor(self) -> Dict[str, Any]:
|
|
100
|
+
"""
|
|
101
|
+
使用 Dragonfly Container UnifiedExecutor 获取服务列表
|
|
102
|
+
|
|
103
|
+
使用 executor 的 build_config_command 方法构建命令,然后执行
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
服务字典,失败返回空字典
|
|
107
|
+
"""
|
|
108
|
+
import subprocess
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
if not self.executor:
|
|
112
|
+
return {}
|
|
113
|
+
|
|
114
|
+
# 使用 executor 构建 config 命令
|
|
115
|
+
cmd = self.executor.compose.build_config_command()
|
|
116
|
+
logger.debug(f"Getting services using executor: {' '.join(cmd)}")
|
|
117
|
+
|
|
118
|
+
compose_path = Path(self.compose_file)
|
|
119
|
+
work_dir = compose_path.parent
|
|
120
|
+
|
|
121
|
+
result = subprocess.run(
|
|
122
|
+
cmd,
|
|
123
|
+
cwd=work_dir,
|
|
124
|
+
capture_output=True,
|
|
125
|
+
text=True,
|
|
126
|
+
timeout=10
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
if result.returncode != 0:
|
|
130
|
+
logger.warning(f"Compose config command failed: {result.stderr}")
|
|
131
|
+
return {}
|
|
132
|
+
|
|
133
|
+
# 解析输出的 YAML
|
|
134
|
+
config_data = yaml.safe_load(result.stdout)
|
|
135
|
+
services = config_data.get('services', {})
|
|
136
|
+
logger.debug(f"Got {len(services)} services from executor")
|
|
137
|
+
return services
|
|
138
|
+
|
|
139
|
+
except subprocess.TimeoutExpired:
|
|
140
|
+
logger.warning("Compose config command timeout")
|
|
141
|
+
return {}
|
|
142
|
+
except Exception as e:
|
|
143
|
+
logger.debug(f"Failed to get services from executor: {e}")
|
|
144
|
+
return {}
|
|
145
|
+
|
|
146
|
+
def _get_services_from_yaml(self) -> Dict[str, Any]:
|
|
147
|
+
"""
|
|
148
|
+
直接从 YAML 文件读取服务(回退方案)
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
服务字典
|
|
152
|
+
"""
|
|
153
|
+
with open(self.compose_file, 'r', encoding='utf-8') as f:
|
|
154
|
+
compose_data = yaml.safe_load(f)
|
|
155
|
+
|
|
156
|
+
return compose_data.get('services', {})
|
|
157
|
+
|
|
158
|
+
def _categorize_service(self, service_name: str) -> ServiceCategory:
|
|
159
|
+
"""
|
|
160
|
+
对服务进行分类
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
service_name: 服务名称
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
服务分类
|
|
167
|
+
"""
|
|
168
|
+
# 标准化服务名称(去掉 .service 后缀)
|
|
169
|
+
base_name = service_name.replace('.service', '')
|
|
170
|
+
full_name = f"{base_name}.service"
|
|
171
|
+
|
|
172
|
+
# 检查是否是基础设施服务
|
|
173
|
+
if base_name in INFRASTRUCTURE_SERVICES or full_name in INFRASTRUCTURE_SERVICES:
|
|
174
|
+
return ServiceCategory.INFRASTRUCTURE
|
|
175
|
+
|
|
176
|
+
# 检查是否是框架服务
|
|
177
|
+
if base_name in FRAMEWORK_SERVICES or full_name in FRAMEWORK_SERVICES:
|
|
178
|
+
return ServiceCategory.FRAMEWORK
|
|
179
|
+
|
|
180
|
+
# 其他都是业务服务
|
|
181
|
+
return ServiceCategory.BUSINESS
|
|
182
|
+
|
|
183
|
+
def is_valid_service(self, service_name: str) -> bool:
|
|
184
|
+
"""
|
|
185
|
+
检查服务名称是否在 docker-compose.yml 中定义
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
service_name: 服务名称
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
是否有效
|
|
192
|
+
"""
|
|
193
|
+
# 标准化服务名称
|
|
194
|
+
base_name = service_name.replace('.service', '')
|
|
195
|
+
full_name = f"{base_name}.service"
|
|
196
|
+
|
|
197
|
+
return service_name in self._all_services or \
|
|
198
|
+
base_name in self._all_services or \
|
|
199
|
+
full_name in self._all_services
|
|
200
|
+
|
|
201
|
+
def is_operable_service(self, service_name: str) -> bool:
|
|
202
|
+
"""
|
|
203
|
+
检查服务是否可操作(仅业务服务可操作)
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
service_name: 服务名称
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
是否可操作
|
|
210
|
+
"""
|
|
211
|
+
# 标准化服务名称
|
|
212
|
+
base_name = service_name.replace('.service', '')
|
|
213
|
+
full_name = f"{base_name}.service"
|
|
214
|
+
|
|
215
|
+
return service_name in self._operable_services or \
|
|
216
|
+
base_name in self._operable_services or \
|
|
217
|
+
full_name in self._operable_services
|
|
218
|
+
|
|
219
|
+
def get_service_category(self, service_name: str) -> Optional[ServiceCategory]:
|
|
220
|
+
"""
|
|
221
|
+
获取服务分类
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
service_name: 服务名称
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
服务分类,不存在返回 None
|
|
228
|
+
"""
|
|
229
|
+
# 标准化服务名称
|
|
230
|
+
base_name = service_name.replace('.service', '')
|
|
231
|
+
full_name = f"{base_name}.service"
|
|
232
|
+
|
|
233
|
+
return self._service_category_map.get(service_name) or \
|
|
234
|
+
self._service_category_map.get(base_name) or \
|
|
235
|
+
self._service_category_map.get(full_name)
|
|
236
|
+
|
|
237
|
+
def validate_service_names(self, service_names: List[str]) -> Dict[str, Any]:
|
|
238
|
+
"""
|
|
239
|
+
批量验证服务名称
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
service_names: 服务名称列表
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
验证结果字典:
|
|
246
|
+
{
|
|
247
|
+
"valid": bool,
|
|
248
|
+
"invalid_services": [],
|
|
249
|
+
"non_operable_services": [],
|
|
250
|
+
"valid_services": []
|
|
251
|
+
}
|
|
252
|
+
"""
|
|
253
|
+
invalid_services = []
|
|
254
|
+
non_operable_services = []
|
|
255
|
+
valid_services = []
|
|
256
|
+
|
|
257
|
+
for service_name in service_names:
|
|
258
|
+
# 检查是否存在
|
|
259
|
+
if not self.is_valid_service(service_name):
|
|
260
|
+
invalid_services.append(service_name)
|
|
261
|
+
continue
|
|
262
|
+
|
|
263
|
+
# 检查是否可操作
|
|
264
|
+
if not self.is_operable_service(service_name):
|
|
265
|
+
non_operable_services.append(service_name)
|
|
266
|
+
continue
|
|
267
|
+
|
|
268
|
+
valid_services.append(service_name)
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
ValidationResultKey.VALID: len(invalid_services) == 0 and len(non_operable_services) == 0,
|
|
272
|
+
ValidationResultKey.INVALID_SERVICES: invalid_services,
|
|
273
|
+
ValidationResultKey.NON_OPERABLE_SERVICES: non_operable_services,
|
|
274
|
+
ValidationResultKey.VALID_SERVICES: valid_services,
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
def get_all_services(self) -> List[str]:
|
|
278
|
+
"""获取所有服务列表"""
|
|
279
|
+
return sorted(self._all_services)
|
|
280
|
+
|
|
281
|
+
def get_operable_services(self) -> List[str]:
|
|
282
|
+
"""获取所有可操作的服务列表"""
|
|
283
|
+
return sorted(self._operable_services)
|
|
284
|
+
|
|
285
|
+
def get_services_by_category(self, category: ServiceCategory) -> List[str]:
|
|
286
|
+
"""
|
|
287
|
+
按分类获取服务列表
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
category: 服务分类
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
服务名称列表
|
|
294
|
+
"""
|
|
295
|
+
return sorted([
|
|
296
|
+
name for name, cat in self._service_category_map.items()
|
|
297
|
+
if cat == category
|
|
298
|
+
])
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
# 全局验证器实例
|
|
302
|
+
_global_validator: Optional[ServiceValidator] = None
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def get_service_validator() -> Optional[ServiceValidator]:
|
|
306
|
+
"""获取全局服务验证器实例"""
|
|
307
|
+
return _global_validator
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def init_service_validator(compose_file: str, executor: Optional[UnifiedExecutor] = None):
|
|
311
|
+
"""
|
|
312
|
+
初始化全局服务验证器
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
compose_file: docker-compose.yml 文件路径
|
|
316
|
+
executor: Dragonfly Container UnifiedExecutor 实例(可选)
|
|
317
|
+
"""
|
|
318
|
+
global _global_validator
|
|
319
|
+
_global_validator = ServiceValidator(compose_file, executor)
|
|
320
|
+
logger.info("Global service validator initialized")
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def reset_service_validator():
|
|
324
|
+
"""重置全局服务验证器(主要用于测试)"""
|
|
325
|
+
global _global_validator
|
|
326
|
+
_global_validator = None
|
|
327
|
+
logger.info("Global service validator reset")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
任务管理模块
|
|
3
|
+
|
|
4
|
+
提供任务队列和 Worker 功能
|
|
5
|
+
"""
|
|
6
|
+
from cancan_microstack.services.controllersrv.domain.task.task_queue import (
|
|
7
|
+
Task,
|
|
8
|
+
TaskQueue,
|
|
9
|
+
get_task_queue,
|
|
10
|
+
reset_task_queue,
|
|
11
|
+
)
|
|
12
|
+
from cancan_microstack.services.controllersrv.domain.task.task_worker import (
|
|
13
|
+
TaskWorker,
|
|
14
|
+
get_task_worker,
|
|
15
|
+
set_task_worker,
|
|
16
|
+
reset_task_worker,
|
|
17
|
+
)
|