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,54 @@
|
|
|
1
|
+
"""Cancan microstack service entrypoints under cmd/.
|
|
2
|
+
|
|
3
|
+
该目录用于放置 cancan_microstack 内置服务启动入口(controllersrv/infrasrv/opsbffsrv)。
|
|
4
|
+
This directory hosts builtin service entrypoints (controllersrv/infrasrv/opsbffsrv).
|
|
5
|
+
|
|
6
|
+
⚠️ 注意 / Note:
|
|
7
|
+
Python 标准库也有一个名为 `cmd` 的模块,pytest/pdb 会依赖其中的 `Cmd`。
|
|
8
|
+
当开发者在源码目录下运行(例如直接在 cancan_microstack 仓库根目录执行 pytest)时,
|
|
9
|
+
同名目录 `cmd/` 会遮蔽标准库模块,导致 pytest 在启动阶段崩溃。
|
|
10
|
+
|
|
11
|
+
为保证:
|
|
12
|
+
- 仍保留 `cancan_microstack.cmd.*` 入口结构 / keep entrypoints importable
|
|
13
|
+
- 同时 `import cmd; cmd.Cmd` 仍指向标准库实现 / keep stdlib cmd symbols available
|
|
14
|
+
|
|
15
|
+
这里做一个轻量桥接:从标准库路径加载 `cmd.py` 并暴露必要符号。
|
|
16
|
+
"""
|
|
17
|
+
import importlib.util
|
|
18
|
+
import sysconfig
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from types import ModuleType
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _load_stdlib_cmd_module() -> ModuleType:
|
|
24
|
+
"""加载标准库 cmd 模块(避免被当前包遮蔽)。
|
|
25
|
+
Load stdlib cmd module without being shadowed by this package.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
stdlib_dir = sysconfig.get_path("stdlib")
|
|
29
|
+
if not stdlib_dir:
|
|
30
|
+
raise RuntimeError("Unable to locate stdlib path / 无法定位标准库路径")
|
|
31
|
+
|
|
32
|
+
cmd_py_path = Path(stdlib_dir) / "cmd.py"
|
|
33
|
+
if not cmd_py_path.exists():
|
|
34
|
+
raise RuntimeError(f"Stdlib cmd.py not found at: {cmd_py_path}")
|
|
35
|
+
|
|
36
|
+
spec = importlib.util.spec_from_file_location("_stdlib_cmd", cmd_py_path)
|
|
37
|
+
if spec is None or spec.loader is None:
|
|
38
|
+
raise RuntimeError("Unable to load stdlib cmd spec / 无法加载标准库 cmd 模块 spec")
|
|
39
|
+
|
|
40
|
+
module = importlib.util.module_from_spec(spec)
|
|
41
|
+
spec.loader.exec_module(module)
|
|
42
|
+
return module
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
_stdlib_cmd = _load_stdlib_cmd_module()
|
|
46
|
+
|
|
47
|
+
# Expose stdlib symbols used by pdb/pytest.
|
|
48
|
+
# 暴露 pdb/pytest 依赖的标准库符号。
|
|
49
|
+
Cmd = _stdlib_cmd.Cmd # type: ignore[attr-defined]
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
"Cmd",
|
|
53
|
+
]
|
|
54
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""cancan CLI module (library-owned).
|
|
2
|
+
|
|
3
|
+
说明 / Notes:
|
|
4
|
+
- 该目录属于 cancan_microstack(libs),用于提供宿主机侧的 CLI 能力。
|
|
5
|
+
This folder belongs to cancan_microstack (libs) and provides host-side CLI utilities.
|
|
6
|
+
|
|
7
|
+
- 使用方仓库(consumer repo)不应长期保存框架 CLI 代码;应通过安装 libs 包或
|
|
8
|
+
使用 `python -m cancan_microstack.cmd.cancan.run` 调用。
|
|
9
|
+
Consumer repos should not permanently carry framework CLI code; use the installed package
|
|
10
|
+
or `python -m cancan_microstack.cmd.cancan.run`.
|
|
11
|
+
"""
|
|
12
|
+
__all__ = []
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
"""cancan CLI entrypoint (library-owned).
|
|
2
|
+
|
|
3
|
+
目标 / Goal:
|
|
4
|
+
- controllersrv 在宿主机运行:提供 start/stop/status
|
|
5
|
+
controllersrv runs on host: start/stop/status
|
|
6
|
+
- 集群通过 {engine} compose 启动/关闭:提供 cluster up/down
|
|
7
|
+
cluster via {engine} compose: cluster up/down
|
|
8
|
+
- adminops 前端构建为静态 SPA 并发布到使用方工作区的 Caddy 静态目录
|
|
9
|
+
Build adminops frontend into static assets and publish to consumer workspace's Caddy static dir
|
|
10
|
+
|
|
11
|
+
重要说明 / Important Notes:
|
|
12
|
+
- 该 CLI 属于 libs(cancan_microstack),使用方仓库不应长期保存框架脚本。
|
|
13
|
+
This CLI belongs to libs (cancan_microstack); consumer repos should not keep framework scripts.
|
|
14
|
+
- 所有路径均通过动态计算,禁止硬编码绝对路径。
|
|
15
|
+
All paths are resolved dynamically; do NOT hardcode absolute paths.
|
|
16
|
+
"""
|
|
17
|
+
import argparse
|
|
18
|
+
import os
|
|
19
|
+
import shutil
|
|
20
|
+
import signal
|
|
21
|
+
import subprocess
|
|
22
|
+
import sys
|
|
23
|
+
import time
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Optional
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _find_repo_root(start: Path) -> Path:
|
|
29
|
+
"""尝试从 start 向上查找使用方仓库根目录 / Try to locate consumer repo root.
|
|
30
|
+
|
|
31
|
+
查找标记 / Markers:
|
|
32
|
+
- compose.cancan.yml
|
|
33
|
+
- docker-compose.yml
|
|
34
|
+
- pyproject.toml
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
start = start.resolve()
|
|
38
|
+
candidates = [start, *start.parents]
|
|
39
|
+
|
|
40
|
+
for base in candidates:
|
|
41
|
+
if (base / "compose.cancan.yml").exists():
|
|
42
|
+
return base
|
|
43
|
+
if (base / "docker-compose.yml").exists():
|
|
44
|
+
return base
|
|
45
|
+
if (base / "pyproject.toml").exists():
|
|
46
|
+
return base
|
|
47
|
+
|
|
48
|
+
return start
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _runtime_dir(repo_root: Path) -> Path:
|
|
52
|
+
"""运行时目录 / Runtime dir."""
|
|
53
|
+
|
|
54
|
+
runtime_dir = repo_root / ".runtime"
|
|
55
|
+
runtime_dir.mkdir(parents=True, exist_ok=True)
|
|
56
|
+
return runtime_dir
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _pid_file(repo_root: Path) -> Path:
|
|
60
|
+
"""controllersrv PID 文件路径 / controllersrv PID file path."""
|
|
61
|
+
|
|
62
|
+
return _runtime_dir(repo_root) / "controllersrv.pid"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _log_file(repo_root: Path) -> Path:
|
|
66
|
+
"""controllersrv 日志文件路径 / controllersrv log file path."""
|
|
67
|
+
|
|
68
|
+
return _runtime_dir(repo_root) / "controllersrv.log"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _is_process_alive(pid: int) -> bool:
|
|
72
|
+
"""判断进程是否存在 / Check whether a process exists."""
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
os.kill(pid, 0)
|
|
76
|
+
except ProcessLookupError:
|
|
77
|
+
return False
|
|
78
|
+
except PermissionError:
|
|
79
|
+
return True
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _read_pid(repo_root: Path) -> Optional[int]:
|
|
84
|
+
"""读取 PID / Read PID."""
|
|
85
|
+
|
|
86
|
+
pid_path = _pid_file(repo_root)
|
|
87
|
+
if not pid_path.exists():
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
pid = int(pid_path.read_text(encoding="utf-8").strip())
|
|
92
|
+
except Exception:
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
return pid
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def controllersrv_status(repo_root: Path) -> int:
|
|
99
|
+
"""打印 controllersrv 状态 / Print controllersrv status."""
|
|
100
|
+
|
|
101
|
+
pid = _read_pid(repo_root)
|
|
102
|
+
if pid is None:
|
|
103
|
+
print("controllersrv: stopped (no pid file)")
|
|
104
|
+
return 1
|
|
105
|
+
|
|
106
|
+
if _is_process_alive(pid):
|
|
107
|
+
print(f"controllersrv: running (pid={pid})")
|
|
108
|
+
return 0
|
|
109
|
+
|
|
110
|
+
print(f"controllersrv: stale pid file (pid={pid})")
|
|
111
|
+
return 2
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def controllersrv_start(repo_root: Path, host: str, port: int) -> int:
|
|
115
|
+
"""启动 controllersrv(后台)/ Start controllersrv in background."""
|
|
116
|
+
|
|
117
|
+
pid = _read_pid(repo_root)
|
|
118
|
+
if pid is not None and _is_process_alive(pid):
|
|
119
|
+
print(f"controllersrv already running (pid={pid})")
|
|
120
|
+
return 0
|
|
121
|
+
|
|
122
|
+
# 清理陈旧 pid 文件 / Remove stale pid file
|
|
123
|
+
try:
|
|
124
|
+
_pid_file(repo_root).unlink(missing_ok=True)
|
|
125
|
+
except Exception:
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
wrapper_script = repo_root / "cmd" / "controllersrv" / "run.py"
|
|
129
|
+
if not wrapper_script.exists():
|
|
130
|
+
print(f"controllersrv wrapper not found: {wrapper_script}")
|
|
131
|
+
print("Hint: in a consumer repo, cmd wrappers are usually generated by cancan build.")
|
|
132
|
+
return 2
|
|
133
|
+
|
|
134
|
+
log_path = _log_file(repo_root)
|
|
135
|
+
log_fp = open(log_path, "a", encoding="utf-8")
|
|
136
|
+
|
|
137
|
+
# 使用当前解释器启动(建议在 venv 下运行本脚本)
|
|
138
|
+
# Start using current interpreter (recommended: run this script under venv)
|
|
139
|
+
cmd = [sys.executable, "-u", str(wrapper_script)]
|
|
140
|
+
|
|
141
|
+
env = os.environ.copy()
|
|
142
|
+
env.setdefault("PYTHONUNBUFFERED", "1")
|
|
143
|
+
|
|
144
|
+
# 控制 host/port 通过环境变量传递。
|
|
145
|
+
# Pass host/port via env.
|
|
146
|
+
env["CONTROLLERSRV_HOST_BIND"] = host
|
|
147
|
+
env["CONTROLLERSRV_PORT_BIND"] = str(port)
|
|
148
|
+
|
|
149
|
+
proc = subprocess.Popen(
|
|
150
|
+
cmd,
|
|
151
|
+
cwd=str(repo_root),
|
|
152
|
+
env=env,
|
|
153
|
+
stdout=log_fp,
|
|
154
|
+
stderr=log_fp,
|
|
155
|
+
start_new_session=True,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
_pid_file(repo_root).write_text(str(proc.pid), encoding="utf-8")
|
|
159
|
+
print(f"controllersrv started (pid={proc.pid}) log={log_path}")
|
|
160
|
+
return 0
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def controllersrv_stop(repo_root: Path, timeout_seconds: int = 10) -> int:
|
|
164
|
+
"""停止 controllersrv / Stop controllersrv."""
|
|
165
|
+
|
|
166
|
+
pid = _read_pid(repo_root)
|
|
167
|
+
if pid is None:
|
|
168
|
+
print("controllersrv already stopped (no pid file)")
|
|
169
|
+
return 0
|
|
170
|
+
|
|
171
|
+
if not _is_process_alive(pid):
|
|
172
|
+
print(f"controllersrv already stopped (pid={pid})")
|
|
173
|
+
try:
|
|
174
|
+
_pid_file(repo_root).unlink(missing_ok=True)
|
|
175
|
+
except Exception:
|
|
176
|
+
pass
|
|
177
|
+
return 0
|
|
178
|
+
|
|
179
|
+
print(f"Stopping controllersrv (pid={pid}) ...")
|
|
180
|
+
try:
|
|
181
|
+
os.kill(pid, signal.SIGTERM)
|
|
182
|
+
except ProcessLookupError:
|
|
183
|
+
_pid_file(repo_root).unlink(missing_ok=True)
|
|
184
|
+
print("controllersrv stopped")
|
|
185
|
+
return 0
|
|
186
|
+
|
|
187
|
+
deadline = time.time() + timeout_seconds
|
|
188
|
+
while time.time() < deadline:
|
|
189
|
+
if not _is_process_alive(pid):
|
|
190
|
+
_pid_file(repo_root).unlink(missing_ok=True)
|
|
191
|
+
print("controllersrv stopped")
|
|
192
|
+
return 0
|
|
193
|
+
time.sleep(0.2)
|
|
194
|
+
|
|
195
|
+
print("controllersrv did not stop in time; sending SIGKILL")
|
|
196
|
+
try:
|
|
197
|
+
os.kill(pid, signal.SIGKILL)
|
|
198
|
+
except ProcessLookupError:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
_pid_file(repo_root).unlink(missing_ok=True)
|
|
202
|
+
return 0
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _run_compose(repo_root: Path, compose_engine: str, compose_file: Path, args: list[str]) -> int:
|
|
206
|
+
"""运行 compose 命令 / Run compose command."""
|
|
207
|
+
|
|
208
|
+
if compose_engine not in {"podman", "docker"}:
|
|
209
|
+
print(f"Unsupported compose engine: {compose_engine}")
|
|
210
|
+
return 2
|
|
211
|
+
|
|
212
|
+
cmd = [compose_engine, "compose", "-f", str(compose_file), *args]
|
|
213
|
+
print("Running:", " ".join(cmd))
|
|
214
|
+
|
|
215
|
+
proc = subprocess.run(cmd, cwd=str(repo_root))
|
|
216
|
+
return int(proc.returncode)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def cluster_up(repo_root: Path, compose_engine: str, compose_file: Path) -> int:
|
|
220
|
+
"""启动集群 / Bring up the cluster."""
|
|
221
|
+
|
|
222
|
+
rc = controllersrv_start(repo_root=repo_root, host="0.0.0.0", port=22100)
|
|
223
|
+
if rc != 0:
|
|
224
|
+
return rc
|
|
225
|
+
|
|
226
|
+
return _run_compose(repo_root, compose_engine, compose_file, ["up", "-d"])
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def cluster_down(repo_root: Path, compose_engine: str, compose_file: Path, keep_controllersrv: bool) -> int:
|
|
230
|
+
"""关闭集群 / Bring down the cluster."""
|
|
231
|
+
|
|
232
|
+
rc = _run_compose(repo_root, compose_engine, compose_file, ["down"])
|
|
233
|
+
if keep_controllersrv:
|
|
234
|
+
return rc
|
|
235
|
+
|
|
236
|
+
stop_rc = controllersrv_stop(repo_root)
|
|
237
|
+
return rc if rc != 0 else stop_rc
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def adminops_build_and_publish(repo_root: Path, admin_root: Path, output_dir: Path) -> int:
|
|
241
|
+
"""Build adminops and publish to output directory.
|
|
242
|
+
|
|
243
|
+
- 构建 adminops 前端工程
|
|
244
|
+
Build the adminops frontend project
|
|
245
|
+
- 拷贝 dist 到使用方工作区的 Caddy 静态目录
|
|
246
|
+
Copy dist into consumer workspace's Caddy static dir
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
if not admin_root.exists():
|
|
250
|
+
print(f"adminops UI source not found: {admin_root}")
|
|
251
|
+
return 2
|
|
252
|
+
|
|
253
|
+
pnpm = shutil.which("pnpm")
|
|
254
|
+
if not pnpm:
|
|
255
|
+
print("pnpm not found in PATH")
|
|
256
|
+
return 2
|
|
257
|
+
|
|
258
|
+
print(f"Building adminops UI at: {admin_root}")
|
|
259
|
+
build_proc = subprocess.run([pnpm, "-C", str(admin_root), "build"], check=False)
|
|
260
|
+
if build_proc.returncode != 0:
|
|
261
|
+
return int(build_proc.returncode)
|
|
262
|
+
|
|
263
|
+
dist_dir = admin_root / "dist"
|
|
264
|
+
if not dist_dir.exists():
|
|
265
|
+
print(f"Build output not found: {dist_dir}")
|
|
266
|
+
return 2
|
|
267
|
+
|
|
268
|
+
output_dir.parent.mkdir(parents=True, exist_ok=True)
|
|
269
|
+
if output_dir.exists():
|
|
270
|
+
shutil.rmtree(output_dir)
|
|
271
|
+
|
|
272
|
+
shutil.copytree(dist_dir, output_dir)
|
|
273
|
+
print(f"Published adminops to: {output_dir}")
|
|
274
|
+
print("Note: output directory is intended to be git-ignored.")
|
|
275
|
+
return 0
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _parse_args(argv: list[str]) -> argparse.Namespace:
|
|
279
|
+
parser = argparse.ArgumentParser(prog="cancan", add_help=True)
|
|
280
|
+
|
|
281
|
+
parser.add_argument(
|
|
282
|
+
"--repo-root",
|
|
283
|
+
default=os.getenv("CANCAN_REPO_ROOT", ""),
|
|
284
|
+
help="consumer repo root / 使用方仓库根目录(默认自动探测)",
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
parser.add_argument(
|
|
288
|
+
"--engine",
|
|
289
|
+
default=os.getenv("CANCAN_COMPOSE_ENGINE", "podman"),
|
|
290
|
+
choices=["podman", "docker"],
|
|
291
|
+
help="compose engine / compose 引擎(默认 podman)",
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
parser.add_argument(
|
|
295
|
+
"--compose-file",
|
|
296
|
+
default=os.getenv("CANCAN_COMPOSE_FILE", ""),
|
|
297
|
+
help="compose file path / compose 文件路径(默认 repo_root/compose.cancan.yml)",
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
301
|
+
|
|
302
|
+
# controllersrv
|
|
303
|
+
controllersrv_parser = subparsers.add_parser("controllersrv", help="controllersrv lifecycle")
|
|
304
|
+
controllersrv_sub = controllersrv_parser.add_subparsers(dest="action", required=True)
|
|
305
|
+
|
|
306
|
+
start_parser = controllersrv_sub.add_parser("start", help="start controllersrv")
|
|
307
|
+
start_parser.add_argument("--host", default="0.0.0.0")
|
|
308
|
+
start_parser.add_argument("--port", type=int, default=22100)
|
|
309
|
+
|
|
310
|
+
stop_parser = controllersrv_sub.add_parser("stop", help="stop controllersrv")
|
|
311
|
+
stop_parser.add_argument("--timeout", type=int, default=10)
|
|
312
|
+
|
|
313
|
+
controllersrv_sub.add_parser("status", help="status controllersrv")
|
|
314
|
+
|
|
315
|
+
# cluster
|
|
316
|
+
cluster_parser = subparsers.add_parser("cluster", help="cluster up/down")
|
|
317
|
+
cluster_sub = cluster_parser.add_subparsers(dest="action", required=True)
|
|
318
|
+
|
|
319
|
+
cluster_sub.add_parser("up", help="compose up -d with controllersrv")
|
|
320
|
+
|
|
321
|
+
down_parser = cluster_sub.add_parser("down", help="compose down and stop controllersrv")
|
|
322
|
+
down_parser.add_argument(
|
|
323
|
+
"--keep-controllersrv",
|
|
324
|
+
action="store_true",
|
|
325
|
+
help="do not stop controllersrv / 不停止 controllersrv",
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
# adminops
|
|
329
|
+
admin_parser = subparsers.add_parser("adminops", help="adminops build/publish")
|
|
330
|
+
admin_sub = admin_parser.add_subparsers(dest="action", required=True)
|
|
331
|
+
|
|
332
|
+
build_parser = admin_sub.add_parser("build", help="build adminops and publish to Caddy dir")
|
|
333
|
+
build_parser.add_argument(
|
|
334
|
+
"--admin-root",
|
|
335
|
+
default=os.getenv("CANCAN_ADMIN_ROOT", ""),
|
|
336
|
+
help="adminops frontend root / 前端工程根目录(默认 repo_root 的同级目录)",
|
|
337
|
+
)
|
|
338
|
+
build_parser.add_argument(
|
|
339
|
+
"--output-dir",
|
|
340
|
+
default=os.getenv("CANCAN_ADMIN_OUTPUT_DIR", ""),
|
|
341
|
+
help="publish output dir / 发布输出目录(默认 repo_root/builds/caddy/www/adminops)",
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
return parser.parse_args(argv)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def main(argv: list[str]) -> int:
|
|
348
|
+
args = _parse_args(argv)
|
|
349
|
+
|
|
350
|
+
if args.repo_root:
|
|
351
|
+
repo_root = Path(args.repo_root).expanduser().absolute()
|
|
352
|
+
else:
|
|
353
|
+
repo_root = _find_repo_root(Path.cwd())
|
|
354
|
+
|
|
355
|
+
compose_file = Path(args.compose_file).expanduser().absolute() if args.compose_file else (repo_root / "compose.cancan.yml")
|
|
356
|
+
|
|
357
|
+
if args.command == "controllersrv":
|
|
358
|
+
if args.action == "start":
|
|
359
|
+
return controllersrv_start(repo_root=repo_root, host=args.host, port=args.port)
|
|
360
|
+
if args.action == "stop":
|
|
361
|
+
return controllersrv_stop(repo_root=repo_root, timeout_seconds=args.timeout)
|
|
362
|
+
if args.action == "status":
|
|
363
|
+
return controllersrv_status(repo_root)
|
|
364
|
+
|
|
365
|
+
if args.command == "cluster":
|
|
366
|
+
if args.action == "up":
|
|
367
|
+
return cluster_up(repo_root=repo_root, compose_engine=args.engine, compose_file=compose_file)
|
|
368
|
+
if args.action == "down":
|
|
369
|
+
return cluster_down(
|
|
370
|
+
repo_root=repo_root,
|
|
371
|
+
compose_engine=args.engine,
|
|
372
|
+
compose_file=compose_file,
|
|
373
|
+
keep_controllersrv=bool(args.keep_controllersrv),
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
if args.command == "adminops":
|
|
377
|
+
if args.action == "build":
|
|
378
|
+
admin_root = (
|
|
379
|
+
Path(args.admin_root).expanduser().absolute()
|
|
380
|
+
if args.admin_root
|
|
381
|
+
else repo_root.parent.absolute()
|
|
382
|
+
)
|
|
383
|
+
output_dir = (
|
|
384
|
+
Path(args.output_dir).expanduser().absolute()
|
|
385
|
+
if args.output_dir
|
|
386
|
+
else (repo_root / "builds" / "caddy" / "www" / "adminops")
|
|
387
|
+
)
|
|
388
|
+
return adminops_build_and_publish(repo_root=repo_root, admin_root=admin_root, output_dir=output_dir)
|
|
389
|
+
|
|
390
|
+
print("Unknown command")
|
|
391
|
+
return 2
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
if __name__ == "__main__":
|
|
395
|
+
raise SystemExit(main(sys.argv[1:]))
|
|
File without changes
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""
|
|
2
|
+
controllersrv 启动脚本
|
|
3
|
+
|
|
4
|
+
这是一个特殊的服务,运行在宿主机上,负责管理 Docker Compose 集群。
|
|
5
|
+
|
|
6
|
+
初始化流程:
|
|
7
|
+
1. 初始化路由
|
|
8
|
+
2. 初始化服务,挂载启动和关闭回调
|
|
9
|
+
3. 启动服务
|
|
10
|
+
|
|
11
|
+
启动回调 (`initialize_controllersrv`):
|
|
12
|
+
1. 初始化服务验证器
|
|
13
|
+
2. 初始化执行器
|
|
14
|
+
3. 初始化并启动 Worker
|
|
15
|
+
|
|
16
|
+
关闭回调 (`shutdown_controllersrv`):
|
|
17
|
+
1. 优雅关闭 Worker
|
|
18
|
+
"""
|
|
19
|
+
import asyncio
|
|
20
|
+
import os
|
|
21
|
+
from typing import Optional
|
|
22
|
+
|
|
23
|
+
from linglong_web.utils import logger
|
|
24
|
+
from linglong_web import ServerRouter
|
|
25
|
+
from linglong_web import LinglongConfig
|
|
26
|
+
from dragonfly_container.core import ExecutorFactory
|
|
27
|
+
from dragonfly_container.models.constants import ContainerEngine
|
|
28
|
+
|
|
29
|
+
from cancan_microstack.public.web.server import AppServer
|
|
30
|
+
|
|
31
|
+
from cancan_microstack.services.controllersrv.router import router_list
|
|
32
|
+
from cancan_microstack.services.controllersrv.conf.config import service_conf_dict
|
|
33
|
+
from cancan_microstack.services.controllersrv.domain.task import TaskWorker, set_task_worker
|
|
34
|
+
from cancan_microstack.services.controllersrv.domain.service_validator import init_service_validator
|
|
35
|
+
|
|
36
|
+
worker_instance: Optional[TaskWorker] = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def initialize_controllersrv():
|
|
40
|
+
"""
|
|
41
|
+
controllersrv 的启动回调函数(直接使用 Dragonfly Container UnifiedExecutor)
|
|
42
|
+
"""
|
|
43
|
+
global worker_instance
|
|
44
|
+
logger.info("=" * 60)
|
|
45
|
+
logger.info("Starting controllersrv initialization")
|
|
46
|
+
logger.info("=" * 60)
|
|
47
|
+
|
|
48
|
+
# 1. 创建 UnifiedExecutor(自动检测 Docker 或 Podman)
|
|
49
|
+
# Create UnifiedExecutor (auto-detect Docker or Podman)
|
|
50
|
+
logger.info("Step 1: Creating Dragonfly Container UnifiedExecutor...")
|
|
51
|
+
compose_file = LinglongConfig.DOCKER_COMPOSE_FILE
|
|
52
|
+
project_name = LinglongConfig.DOCKER_COMPOSE_PROJECT_NAME
|
|
53
|
+
# engine 选择:默认 Docker-first auto-detect 可能在 macOS 上导致慢启动(Docker 未运行时会卡住)。
|
|
54
|
+
# Engine selection: Docker-first auto-detect may cause slow startup on macOS when Docker isn't running.
|
|
55
|
+
engine_env = (os.environ.get("CANCAN_CONTAINER_ENGINE") or "").strip().lower()
|
|
56
|
+
engine: ContainerEngine | None = None
|
|
57
|
+
if engine_env in {"podman"}:
|
|
58
|
+
engine = ContainerEngine.PODMAN
|
|
59
|
+
elif engine_env in {"docker"}:
|
|
60
|
+
engine = ContainerEngine.DOCKER
|
|
61
|
+
|
|
62
|
+
executor = ExecutorFactory.create_unified_executor(
|
|
63
|
+
compose_file=compose_file,
|
|
64
|
+
project_name=project_name,
|
|
65
|
+
engine=engine,
|
|
66
|
+
)
|
|
67
|
+
logger.info(
|
|
68
|
+
f"UnifiedExecutor created: "
|
|
69
|
+
f"engine={executor.api.engine_type}, "
|
|
70
|
+
f"compose_file={compose_file}, "
|
|
71
|
+
f"project={project_name}"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# 2. 初始化服务验证器(传入 executor 以便使用其 API)
|
|
75
|
+
# Initialize service validator (pass executor to use its API)
|
|
76
|
+
logger.info("Step 2: Initializing service validator...")
|
|
77
|
+
init_service_validator(compose_file, executor)
|
|
78
|
+
logger.info(f"Service validator initialized with compose file: {compose_file}")
|
|
79
|
+
|
|
80
|
+
# 3. 初始化并启动 Worker(直接使用 UnifiedExecutor)
|
|
81
|
+
logger.info("Step 3: Starting task worker...")
|
|
82
|
+
worker = TaskWorker(executor)
|
|
83
|
+
worker_instance = worker
|
|
84
|
+
set_task_worker(worker)
|
|
85
|
+
await worker.start()
|
|
86
|
+
logger.info("Task worker started")
|
|
87
|
+
|
|
88
|
+
logger.info("=" * 60)
|
|
89
|
+
logger.info("controllersrv initialization completed")
|
|
90
|
+
logger.info("=" * 60)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
async def shutdown_controllersrv():
|
|
94
|
+
"""
|
|
95
|
+
controllersrv 的关闭回调函数
|
|
96
|
+
"""
|
|
97
|
+
if worker_instance:
|
|
98
|
+
logger.info("Shutting down task worker...")
|
|
99
|
+
await worker_instance.stop()
|
|
100
|
+
logger.info("Task worker stopped")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async def main(host='0.0.0.0', port=22100):
|
|
104
|
+
"""
|
|
105
|
+
启动 controllersrv 服务
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
host: 监听地址,默认 0.0.0.0(允许容器访问)
|
|
109
|
+
port: 监听端口,默认 22100
|
|
110
|
+
"""
|
|
111
|
+
# 1. 初始化路由
|
|
112
|
+
router_factory = ServerRouter()
|
|
113
|
+
router_factory.initialize(router_list)
|
|
114
|
+
|
|
115
|
+
# 2. 初始化服务器
|
|
116
|
+
app = AppServer()
|
|
117
|
+
await app.initialize(
|
|
118
|
+
service_name="controllersrv",
|
|
119
|
+
router=router_factory.get_router(),
|
|
120
|
+
config_dict=service_conf_dict,
|
|
121
|
+
scheduler_group=None, # controllersrv 不需要定时任务
|
|
122
|
+
on_startup=[initialize_controllersrv],
|
|
123
|
+
on_shutdown=[shutdown_controllersrv],
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# 3. 启动 Web 服务
|
|
127
|
+
await app.start(host=host, port=port)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
asyncio.run(main())
|