iamt 1.1.27__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.
- iamt/__init__.py +67 -0
- iamt/__main__.py +5 -0
- iamt/client_config/client_config.py +354 -0
- iamt/completers/customCompleter.py +143 -0
- iamt/composes/5425CICD/gitea/.rdm.md +4 -0
- iamt/composes/5425CICD/gitea/docker-compose.yml +52 -0
- iamt/composes/5425CICD/gitlab/.rdm.md +20 -0
- iamt/composes/5425CICD/gitlab/config/ssl/.gitkeep +0 -0
- iamt/composes/5425CICD/gitlab/docker-compose.yml +32 -0
- iamt/composes/5425CICD/gitlabDocs/.rdm.md +3 -0
- iamt/composes/5425CICD/gitlabRunner/.rdm.md +5 -0
- iamt/composes/5425CICD/sonarQube/.rdm.md +14 -0
- iamt/composes/5425CICD/sonarQube/docker-compose.yml +46 -0
- iamt/composes/5425CICD/sonarQube/docker-compose3.yml +41 -0
- iamt/composes/5425CICD/sonarQube/docker-compose4.yml +33 -0
- iamt/composes/5425CICD/sonarQube/sonarqube_conf/.gitkeep +0 -0
- iamt/composes/5425CICD/sonarQube/sonarqube_data/.gitkeep +0 -0
- iamt/composes/5425CICD/sonarQube/sonarqube_extensions/.gitkeep +0 -0
- iamt/composes/5425CICD/sonarQube/sonarqube_logs/.gitkeep +0 -0
- iamt/composes/5425CICD/sonarQube/sonarqube_temp/.gitkeep +0 -0
- iamt/composes/5435PROMPT/.rdm.md +11 -0
- iamt/composes/5435PROMPT/langfuse/.env +276 -0
- iamt/composes/5435PROMPT/langfuse/.rdm.md +3 -0
- iamt/composes/5435PROMPT/langfuse/docker-compose.yml +166 -0
- iamt/composes/5435PROMPT/prompt-optimizer/.rdm.md +3 -0
- iamt/composes/5465BASE/alpine/.rdm.md +6 -0
- iamt/composes/5465BASE/mysql/.rdm.md +40 -0
- iamt/composes/5465BASE/mysql/conf/my.cnf +52 -0
- iamt/composes/5465BASE/mysql/docker-compose.yml +31 -0
- iamt/composes/5465BASE/mysql/init/01-init.sql +14 -0
- iamt/composes/5465BASE/nginx/.rdm.md +16 -0
- iamt/composes/5465BASE/nginx/docker-compose.yml +29 -0
- iamt/composes/5465BASE/nginx/html/index.html +11 -0
- iamt/composes/5465BASE/nginx/nginx/conf.d/default.conf +22 -0
- iamt/composes/5465BASE/nginx/nginx/nginx.conf +35 -0
- iamt/composes/5465BASE/node/.rdm.md +0 -0
- iamt/composes/5465BASE/node/docker-compose.yml +0 -0
- iamt/composes/5465BASE/php/.rdm.md +0 -0
- iamt/composes/5465BASE/php/docker-compose.yml +0 -0
- iamt/composes/5465BASE/redis/.env +11 -0
- iamt/composes/5465BASE/redis/.rdm.md +7 -0
- iamt/composes/5465BASE/redis/config/redis.conf +57 -0
- iamt/composes/5465BASE/redis/docker-compose.yml +35 -0
- iamt/composes/5475TTS/GPTsovits/.rdm.md +4 -0
- iamt/composes/5475TTS/GPTsovits/docker-compose.yml +34 -0
- iamt/composes/5475TTS/indexTTS/.rdm.md +3 -0
- iamt/composes/5485MCP/.rdm.md +5 -0
- iamt/composes/5485MCP/mcpGateway/.rdm.md +2 -0
- iamt/composes/5485MCP/mcpGateway/docker-compose.yml +0 -0
- iamt/composes/5485MCP/mcpProxy/.rdm.md +2 -0
- iamt/composes/5485MCP/mcpProxy/config.json +53 -0
- iamt/composes/5485MCP/mcpProxy/docker-compose.yml +34 -0
- iamt/composes/5485MCP/superGateway/.env +2 -0
- iamt/composes/5485MCP/superGateway/.rdm.md +17 -0
- iamt/composes/5485MCP/superGateway/docker-compose.yml +21 -0
- iamt/composes/5495LLM/ollama_nvidia/.rdm.md +21 -0
- iamt/composes/5495LLM/ollama_nvidia/docker-compose.yml +24 -0
- iamt/composes/5555RAG/QAnything/.rdm.md +5 -0
- iamt/composes/5555RAG/bisheng/.rdm.md +4 -0
- iamt/composes/5555RAG/devdocs/.rdm.md +4 -0
- iamt/composes/5555RAG/devdocs/docker-compose.yml +81 -0
- iamt/composes/5555RAG/kotaemon/.rdm.md +3 -0
- iamt/composes/5555RAG/kotaemon/docker-compose.yml +3 -0
- iamt/composes/5555RAG/llama_index/.rdm.md +3 -0
- iamt/composes/5555RAG/ragflow/.rdm.md +4 -0
- iamt/composes/5555RAG/ragflow/docker-compose.yml +0 -0
- iamt/composes/5556LLMAPI/litellm/.env +29 -0
- iamt/composes/5556LLMAPI/litellm/.rdm.md +17 -0
- iamt/composes/5556LLMAPI/litellm/config.yaml +211 -0
- iamt/composes/5556LLMAPI/litellm/docker-compose.yml +68 -0
- iamt/composes/5556LLMAPI/litellm/prometheus.yml +9 -0
- iamt/composes/5556LLMAPI/newapi/.env +7 -0
- iamt/composes/5556LLMAPI/newapi/docker-compose.yml +54 -0
- iamt/composes/5556LLMAPI/newapi_sqlite/.env +3 -0
- iamt/composes/5556LLMAPI/newapi_sqlite/.rdm.md +15 -0
- iamt/composes/5556LLMAPI/newapi_sqlite/docker-compose.yml +15 -0
- iamt/composes/5556LLMAPI/oneapi/.env +5 -0
- iamt/composes/5556LLMAPI/oneapi/docker-compose.yml +51 -0
- iamt/composes/5556LLMAPI/oneapi_postgresql/docker-compose.yml +51 -0
- iamt/composes/5556LLMAPI/oneapi_sqlite/.rdm.md +10 -0
- iamt/composes/5556LLMAPI/oneapi_sqlite/docker-compose.yml +15 -0
- iamt/composes/5557AICLIENT/chatgpt-web-midjourney-proxy/.rdm.md +4 -0
- iamt/composes/5557AICLIENT/librechat/.env +511 -0
- iamt/composes/5557AICLIENT/librechat/.env.example +509 -0
- iamt/composes/5557AICLIENT/librechat/README.md +10 -0
- iamt/composes/5557AICLIENT/librechat/docker-compose.override.yml +21 -0
- iamt/composes/5557AICLIENT/librechat/docker-compose.yml +70 -0
- iamt/composes/5557AICLIENT/librechat/librechat.yaml +19 -0
- iamt/composes/5557AICLIENT/librechat/litellm-config.yml +21 -0
- iamt/composes/5557AICLIENT/librechat_oneapi/.env +535 -0
- iamt/composes/5557AICLIENT/librechat_oneapi/.rdm.md +19 -0
- iamt/composes/5557AICLIENT/librechat_oneapi/docker-compose.override.yml +14 -0
- iamt/composes/5557AICLIENT/librechat_oneapi/docker-compose.yml +72 -0
- iamt/composes/5557AICLIENT/librechat_oneapi/librechat.yaml +42 -0
- iamt/composes/5557AICLIENT/nextChat/.rdm.md +13 -0
- iamt/composes/5557AICLIENT/nextChat/docker-compose.yml +2 -0
- iamt/composes/5557AICLIENT/openwebui/.env +15 -0
- iamt/composes/5557AICLIENT/openwebui/.rdm.md +6 -0
- iamt/composes/5557AICLIENT/openwebui/docker-compose.yml +33 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/.env +193 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/.rdm.md +15 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/README.md +71 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/atlas.hcl +12 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250703095335_initial.sql +90 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250703115304_update.sql +2 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250704040445_update.sql +2 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250708075302_update.sql +10 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250710100212_update.sql +38 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250711034533_update.sql +8 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/20250717125913_update.sql +12 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/migrations/atlas.sum +8 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/atlas/opencoze_latest_schema.hcl +4057 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/model_template_qwen.yaml +106 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark.yaml +133 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-lite.yaml +108 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-pro-256k.yaml +108 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-pro-32k.yaml +108 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-thinking-pro.yaml +131 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-thinking-vision-pro.yaml +132 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-vision-lite.yaml +131 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-1.5-vision-pro.yaml +132 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-seed-1.6-flash.yaml +132 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-seed-1.6-thinking.yaml +132 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_doubao-seed-1.6.yaml +132 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_volc_deepseek-r1.yaml +108 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ark_volc_deepseek-v3.yaml +108 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_basic.yaml +201 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_claude.yaml +90 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_deepseek.yaml +107 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_gemini.yaml +139 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_ollama.yaml +84 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_openai.yaml +171 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/model/template/model_template_qwen.yaml +106 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/common/oauth_schema.json +42 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/bocha_search.yaml +179 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/chestnut_sign.yaml +50 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/gaode_map.yaml +754 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/image_compression.yaml +58 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_authentication_authorization.yaml +56 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_base.yaml +1172 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_calendar.yaml +479 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_docx.yaml +552 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_message.yaml +499 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_sheet.yaml +795 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_task.yaml +409 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/lark_wiki.yaml +95 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/library_search.yaml +73 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/maker_smart_design.yaml +82 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/plugin_meta.yaml +913 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/sky_eye_check.yaml +431 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/sohu_hot_news.yaml +69 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/wolfram_alpha.yaml +100 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/plugin/pluginproduct/worth_buying.yaml +77 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/prompt/messages_to_query_template_jinja2.json +10 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/backend/conf/prompt/nl2sql_template_jinja2.json +10 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/docker-compose.yml +549 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/proxy/go.mod +3 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/proxy/proxy.go +100 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/elasticsearch/analysis-smartcn.zip +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/elasticsearch/elasticsearch.yml +14 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/elasticsearch/es_index_schema/coze_resource.index-template.json +74 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/elasticsearch/es_index_schema/project_draft.index-template.json +79 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/elasticsearch/setup_es.sh +142 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/etcd/etcd.conf.yml +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/.mc/config.json +1 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/claude_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/connector-api.jpg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/connector-chat-sdk.jpg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/connector-coze.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/deepseek_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_agent_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_app_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_database_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_dataset_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_prompt_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/default_workflow_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/doubao_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/gemini_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/image_kn_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/ollama.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/openai_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/plugin_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/qwen_v2.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_10coz_folder.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_11coz_trans_switch.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_12coz_location.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_13coz_link.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_14coz_clock.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_1coz_ai.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_2icon_ai_writing.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_3coz_imageflow.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_4icon_aisearch.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_5icon_summary.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_6icon_digest.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_7icon_video.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_8icon_audio.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/shortcut_9coz_variables.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/table_kn_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/team_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/template_7416518827749425204.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/template_7418535986059067392.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/text_kn_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/default_icon/user_default_icon.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_ai_ppt.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_bocha_search.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_chat_ppt.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_chestnut_sign.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_constellation.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_gaode_map.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_image_compression.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_authentication_authorization.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_base.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_calendar.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_docx.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_message.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_sheet.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_task.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_lark_wiki.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_library_search.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_liepin.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_maker_smart_design.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_sky_eye_check.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_sohu_hot_news.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_wolfram_alpha.png +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/minio/official_plugin_icon/plugin_worth_buying.jpeg +0 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/mysql/schema.sql +836 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/mysql/sql_init.sql +666 -0
- iamt/composes/5558AIWORKFLOW/coze_studio/volumes/rocketmq/broker.conf +28 -0
- iamt/composes/5558AIWORKFLOW/dify/.env +1090 -0
- iamt/composes/5558AIWORKFLOW/dify/.rdm.md +11 -0
- iamt/composes/5558AIWORKFLOW/dify/certbot/README.md +76 -0
- iamt/composes/5558AIWORKFLOW/dify/certbot/docker-entrypoint.sh +30 -0
- iamt/composes/5558AIWORKFLOW/dify/certbot/update-cert.template.txt +19 -0
- iamt/composes/5558AIWORKFLOW/dify/couchbase-server/Dockerfile +4 -0
- iamt/composes/5558AIWORKFLOW/dify/couchbase-server/init-cbserver.sh +44 -0
- iamt/composes/5558AIWORKFLOW/dify/docker-compose.yml +1174 -0
- iamt/composes/5558AIWORKFLOW/dify/elasticsearch/docker-entrypoint.sh +25 -0
- iamt/composes/5558AIWORKFLOW/dify/image.png +0 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/conf.d/default.conf.template +48 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/docker-entrypoint.sh +42 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/https.conf.template +9 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/nginx.conf.template +34 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/proxy.conf.template +11 -0
- iamt/composes/5558AIWORKFLOW/dify/nginx/ssl/.gitkeep +0 -0
- iamt/composes/5558AIWORKFLOW/dify/pgvector/docker-entrypoint.sh +24 -0
- iamt/composes/5558AIWORKFLOW/dify/ssrf_proxy/docker-entrypoint.sh +42 -0
- iamt/composes/5558AIWORKFLOW/dify/ssrf_proxy/squid.conf.template +56 -0
- iamt/composes/5558AIWORKFLOW/dify/startupscripts/init.sh +13 -0
- iamt/composes/5558AIWORKFLOW/dify/startupscripts/init_user.script +10 -0
- iamt/composes/5558AIWORKFLOW/dify/tidb/config/pd.toml +4 -0
- iamt/composes/5558AIWORKFLOW/dify/tidb/config/tiflash-learner.toml +13 -0
- iamt/composes/5558AIWORKFLOW/dify/tidb/config/tiflash.toml +19 -0
- iamt/composes/5558AIWORKFLOW/dify/tidb/docker-compose.yaml +62 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/myscale/config/users.d/custom_users_config.xml +17 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/oceanbase/init.d/vec_memory.sql +1 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/opensearch/opensearch_dashboards.yml +222 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/sandbox/conf/config.yaml +14 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/sandbox/conf/config.yaml.example +35 -0
- iamt/composes/5558AIWORKFLOW/dify/volumes/sandbox/dependencies/python-requirements.txt +0 -0
- iamt/composes/5558AIWORKFLOW/fastgpt/.rdm.md +14 -0
- iamt/composes/5558AIWORKFLOW/fastgpt/docker-compose-pgvector.yml +177 -0
- iamt/composes/5558AIWORKFLOW/langflow/.rdm.md +9 -0
- iamt/composes/5558AIWORKFLOW/langflow/docker-compose.yml +30 -0
- iamt/composes/5558AIWORKFLOW/n8n/.env +6 -0
- iamt/composes/5558AIWORKFLOW/n8n/.rdm.md +24 -0
- iamt/composes/5558AIWORKFLOW/n8n/docker-compose.yml +52 -0
- iamt/composes/5558AIWORKFLOW/n8n/init-data.sh +13 -0
- iamt/composes/5558AIWORKFLOW/n8n/n8n_storage/.gitkeep +0 -0
- iamt/composes/5559MJAPI/midjourney-proxy/.rdm.md +10 -0
- iamt/composes/5559MJAPI/midjourney-proxy/docker-compose.yml +0 -0
- iamt/composes/5559MJAPI/midjourney-proxy2/.rdm.md +5 -0
- iamt/composes/5559MJAPI/midjourney-proxy2/docker-compose.yml +21 -0
- iamt/composes/5655PROXY/3xui/.rdm.md +12 -0
- iamt/composes/5655PROXY/3xui/docker-compose.yml +15 -0
- iamt/composes/5655PROXY/hui/.rdm.md +6 -0
- iamt/composes/5655PROXY/hui/docker-compose.yml +18 -0
- iamt/composes/5655PROXY/mihomo/.rdm.config.md +17 -0
- iamt/composes/5655PROXY/mihomo/.rdm.md +40 -0
- iamt/composes/5655PROXY/mihomo/clash_meta_config/config.yaml +584 -0
- iamt/composes/5655PROXY/mihomo/clash_meta_config/geoip.metadb +0 -0
- iamt/composes/5655PROXY/mihomo/clash_meta_config/sub1.yaml +7 -0
- iamt/composes/5655PROXY/mihomo/clash_meta_config/sub2.yaml +56 -0
- iamt/composes/5655PROXY/mihomo/docker-compose.yml +33 -0
- iamt/composes/5655PROXY/nginx/.rdm +2 -0
- iamt/composes/5655PROXY/nginx/docker-compose.yml +21 -0
- iamt/composes/5655PROXY/sub-web/.rdm.md +9 -0
- iamt/composes/5655PROXY/sub2clash/.rdm.md +3 -0
- iamt/composes/5655PROXY/sub2clash/docker-compose.yml +21 -0
- iamt/composes/5655PROXY/subconverter/.rdm.md +4 -0
- iamt/composes/5655PROXY/v2ray/.rdm.md +3 -0
- iamt/composes/5655PROXY/v2raya/.rdm.md +33 -0
- iamt/composes/5655PROXY/v2raya/docker-compose.yml +19 -0
- iamt/composes/5655PROXY/xui/.rdm.md +3 -0
- iamt/composes/5755COMFYUI/akegarasu_lora-scripts/.rdm.md +18 -0
- iamt/composes/5755COMFYUI/akegarasu_lora-scripts/Dockerfile-for-Mainland-China +42 -0
- iamt/composes/5755COMFYUI/akegarasu_lora-scripts/docker-compose.yml +39 -0
- iamt/composes/5755COMFYUI/comfyui_boot/.rdm.md +29 -0
- iamt/composes/5755COMFYUI/comfyui_boot/docker-compose.yml +0 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu121/.env +1 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu121/.rdm.md +20 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu121/docker-compose.yml +45 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu121/storage/.gitkeep +0 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu124-cn/.rdm.md +22 -0
- iamt/composes/5755COMFYUI/comfyui_boot_cu124-cn/docker-compose.yml +31 -0
- iamt/composes/5755COMFYUI/comfyui_boot_minimal/.rdm.md +26 -0
- iamt/composes/5755COMFYUI/comfyui_boot_minimal/docker-compose.yml +0 -0
- iamt/composes/5755COMFYUI/comfyui_boot_slim/.env +0 -0
- iamt/composes/5755COMFYUI/comfyui_boot_slim/.rdm.md +23 -0
- iamt/composes/5755COMFYUI/comfyui_boot_slim/docker-compose.yml +24 -0
- iamt/composes/5755COMFYUI/swarmui/.rdm.md +5 -0
- iamt/composes/5755COMFYUI/swarmui/docker-compose.yml +38 -0
- iamt/composes/5855MEDIA/any-listen/.rdm.md +7 -0
- iamt/composes/5855MEDIA/any-listen/data/config.cjs +20 -0
- iamt/composes/5855MEDIA/any-listen/docker-compose.yml +10 -0
- iamt/composes/5855MEDIA/blackcandy/.rdm.md +1 -0
- iamt/composes/5855MEDIA/koel/.rdm.md +17 -0
- iamt/composes/5855MEDIA/koel/docker-compose.yml +41 -0
- iamt/composes/5855MEDIA/navidrome/.rdm.md +15 -0
- iamt/composes/5855MEDIA/navidrome/docker-compose.yml +15 -0
- iamt/composes/5955BACKUP/gobackup/.rdm.md +9 -0
- iamt/composes/5955BACKUP/gobackup/docker-compose.yml +19 -0
- iamt/composes/5955BACKUP/gobackup/gobackup/gobackup.yml +5 -0
- iamt/composes/5955BACKUP/rclone/.rdm.md +6 -0
- iamt/composes/5955BACKUP/rclone/docker-compose.yml +0 -0
- iamt/composes/5965SYNC/verysync/.rdm.md +16 -0
- iamt/composes/5965SYNC/verysync/docker-compose.yml +22 -0
- iamt/composes/6055DATABASE/adminer/.rdm.md +13 -0
- iamt/composes/6055DATABASE/cloudbeaver/.rdm.md +10 -0
- iamt/composes/6055DATABASE/mongodb/.env +7 -0
- iamt/composes/6055DATABASE/mongodb/.rdm.md +8 -0
- iamt/composes/6055DATABASE/mongodb/docker-compose.yml +24 -0
- iamt/composes/6055DATABASE/mongodbExpress/.env +10 -0
- iamt/composes/6055DATABASE/mongodbExpress/.rdm.md +14 -0
- iamt/composes/6055DATABASE/mongodbExpress/docker-compose.yml +24 -0
- iamt/composes/6055DATABASE/mysql/.env +0 -0
- iamt/composes/6055DATABASE/mysql/.rdm.md +0 -0
- iamt/composes/6055DATABASE/mysql/docker-compose.yml +26 -0
- iamt/composes/6055DATABASE/mysql/my.cnf +107 -0
- iamt/composes/6155AUTH/authentik/.env +10 -0
- iamt/composes/6155AUTH/authentik/.rdm.md +7 -0
- iamt/composes/6155AUTH/authentik/docker-compose.yml +90 -0
- iamt/composes/6155AUTH/casdoor/conf/app.conf +30 -0
- iamt/composes/6155AUTH/casdoor/docker-compose.yml +20 -0
- iamt/composes/6255Monitor/dcgm_exporter/.rdm.md +5 -0
- iamt/composes/6255Monitor/dcgm_exporter/docker-compose.yml +34 -0
- iamt/composes/6255Monitor/grafana/.env +5 -0
- iamt/composes/6255Monitor/grafana/.rdm.md +0 -0
- iamt/composes/6255Monitor/grafana/docker-compose.yml +22 -0
- iamt/composes/6255Monitor/node_exporter/.env +1 -0
- iamt/composes/6255Monitor/node_exporter/docker-compose.yml +19 -0
- iamt/composes/6255Monitor/prometheus/.env +6 -0
- iamt/composes/6255Monitor/prometheus/.rdm.md +8 -0
- iamt/composes/6255Monitor/prometheus/conf/prometheus.yml +39 -0
- iamt/composes/6255Monitor/prometheus/docker-compose.yml +28 -0
- iamt/composes/6255Monitor/prometheus/prometheus/.gitkeep +0 -0
- iamt/composes/6355SSL/certbot/.rdm.md +4 -0
- iamt/composes/6355SSL/certd/.rdm.md +4 -0
- iamt/composes/6355SSL/certimate/.rdm.md +23 -0
- iamt/composes/6355SSL/certimate/docker-compose.yml +17 -0
- iamt/composes/6455Storage/fileBrowser/.env +5 -0
- iamt/composes/6455Storage/fileBrowser/.rdm.md +17 -0
- iamt/composes/6455Storage/fileBrowser/docker-compose.yml +14 -0
- iamt/composes/6455Storage/fileBrowser/filebrowser.db +0 -0
- iamt/composes/6455Storage/fileBrowser/settings.json +8 -0
- iamt/composes/6455Storage/kskypro/.env +3 -0
- iamt/composes/6455Storage/kskypro/.rdm.md +30 -0
- iamt/composes/6455Storage/kskypro/buildimg/000-default.conf.template +45 -0
- iamt/composes/6455Storage/kskypro/buildimg/Dockerfile +97 -0
- iamt/composes/6455Storage/kskypro/buildimg/LICENSE +661 -0
- iamt/composes/6455Storage/kskypro/buildimg/entrypoint.sh +29 -0
- iamt/composes/6455Storage/kskypro/buildimg/ports.conf.template +2 -0
- iamt/composes/6455Storage/kskypro/buildimg/ssl/certs/ssl-cert-snakeoil.pem +21 -0
- iamt/composes/6455Storage/kskypro/buildimg/ssl/private/ssl-cert-snakeoil.key +28 -0
- iamt/composes/6455Storage/kskypro/docker-compose.yml +43 -0
- iamt/composes/6455Storage/kskypro/env.conf +43 -0
- iamt/composes/6455Storage/kskypro/mysql/conf/.gitkeep +0 -0
- iamt/composes/6455Storage/kskypro/mysql/data/.gitkeep +0 -0
- iamt/composes/6455Storage/kskypro/mysql/log/.gitkeep +0 -0
- iamt/composes/6455Storage/lskypro/.rdm.md +15 -0
- iamt/composes/6455Storage/lskypro/Dockerfile +12 -0
- iamt/composes/6455Storage/lskypro/docker-compose.yml +51 -0
- iamt/composes/6455Storage/minio/.rdm.md +1 -0
- iamt/composes/6455Storage/minio/docker-compose.yml +31 -0
- iamt/composes/6455Storage/nextcloud/.rdm.md +0 -0
- iamt/composes/6455Storage/nextcloud/docker-compose.yml +25 -0
- iamt/composes/6455Storage/seafile/.env +46 -0
- iamt/composes/6455Storage/seafile/.rdm.md +31 -0
- iamt/composes/6455Storage/seafile/caddy.yml +26 -0
- iamt/composes/6455Storage/seafile/seadoc.yml +39 -0
- iamt/composes/6455Storage/seafile/seafile-server.yml +79 -0
- iamt/composes/6555DNS/ddnsgo/.env +8 -0
- iamt/composes/6555DNS/ddnsgo/.rdm.md +7 -0
- iamt/composes/6555DNS/ddnsgo/docker-compose.yml +17 -0
- iamt/composes/6555DNS/lucky/.rdm.md +4 -0
- iamt/composes/6555DNS/lucky/docker-compose.yml +14 -0
- iamt/composes/6655CONTAINER/harbor/.rdm.md +1 -0
- iamt/composes/6755SHOP/dujiaoka/.rdm.md +10 -0
- iamt/composes/6755SHOP/dujiaoka/docker-compose.yml +37 -0
- iamt/composes/6755SHOP/dujiaoka/env.conf +46 -0
- iamt/composes/6755SHOP/dujiaoka/storage/.gitkeep +0 -0
- iamt/composes/6755SHOP/dujiaoka/uploads/.gitkeep +0 -0
- iamt/composes/6755SHOP/dujiaoka2/.rdm.md +3 -0
- iamt/composes/8888Others/apitable/docker-compose.yml +233 -0
- iamt/composes/8888Others/changeDetect/README +18 -0
- iamt/composes/8888Others/changeDetect/docker-compose.yml +44 -0
- iamt/composes/8888Others/codeServer/.rdm.md +7 -0
- iamt/composes/8888Others/codeServer/docker-compose.yml +39 -0
- iamt/composes/8888Others/douyin_tiktok_download_api/.rdm.md +19 -0
- iamt/composes/8888Others/douyin_tiktok_download_api/config.yaml +32 -0
- iamt/composes/8888Others/douyin_tiktok_download_api/docker-compose.yml +17 -0
- iamt/composes/8888Others/kasmweb_chrome/.rdm.md +19 -0
- iamt/composes/8888Others/kasmweb_chrome/docker-compose.yml +17 -0
- iamt/composes/8888Others/meilisearch/.env +10 -0
- iamt/composes/8888Others/meilisearch/config/config.toml +132 -0
- iamt/composes/8888Others/meilisearch/docker-compose.yml +34 -0
- iamt/composes/8888Others/memcached/.env +8 -0
- iamt/composes/8888Others/memcached/docker-compose.yml +20 -0
- iamt/composes/8888Others/minio/docker-compose.yml +20 -0
- iamt/composes/8888Others/minio/minio +9 -0
- iamt/composes/8888Others/neko/README.md +11 -0
- iamt/composes/8888Others/neko/docker-compose.yml +16 -0
- iamt/composes/8888Others/ocrmypdf/README.md +14 -0
- iamt/composes/8888Others/outline/docker-compose.yml +76 -0
- iamt/composes/8888Others/outline/docker.env +164 -0
- iamt/composes/8888Others/outline/redis.conf +0 -0
- iamt/composes/8888Others/pandas_ai/.rdm.md +5 -0
- iamt/composes/8888Others/pandas_ai/docker-compose.yml +49 -0
- iamt/composes/8888Others/rancher/.rdm.md +4 -0
- iamt/composes/8888Others/rustdesk/.env +10 -0
- iamt/composes/8888Others/rustdesk/docker-compose.yml +29 -0
- iamt/composes/8888Others/ttrss/docker-compose.yml +74 -0
- iamt/composes/8888Others/vultrCLI/.rdm.md +9 -0
- iamt/composes/8888Others/wewerss/docker-compose.yml +44 -0
- iamt/dcd/dcd.py +337 -0
- iamt/decorators/singleton.py +224 -0
- iamt/modules/_utils/_utils.py +1 -0
- iamt/modules/_utils/arch.py +22 -0
- iamt/modules/_utils/cleanup_network_config.py +68 -0
- iamt/modules/_utils/github.py +123 -0
- iamt/modules/_utils/setup_apt_sources.py +94 -0
- iamt/modules/_utils/steps.py +26 -0
- iamt/modules/claudecode/claudecode.py +0 -0
- iamt/modules/dcdtask/dcdtask.py +164 -0
- iamt/modules/docker/docker.py +370 -0
- iamt/modules/docker/roles/role.py +54 -0
- iamt/modules/docker/templates/daemon/daemon_multi_mirrors.json +21 -0
- iamt/modules/docker/templates/gpgkey/debian_gpgkey +62 -0
- iamt/modules/docker/templates/gpgkey/ubuntu_gpgkey +62 -0
- iamt/modules/github/ghcli.py +197 -0
- iamt/modules/nvm/nvm.py +183 -0
- iamt/modules/nvm/roles/role.py +24 -0
- iamt/modules/runlinetask/runlinetask.py +22 -0
- iamt/modules/ubuntud/antigravity.py +191 -0
- iamt/modules/ubuntud/chrome.py +111 -0
- iamt/modules/ubuntud/fcitx5.py +0 -0
- iamt/modules/ubuntud/ibus.py +53 -0
- iamt/modules/ubuntud/kiro.py +41 -0
- iamt/modules/ubuntud/rime_ice.py +173 -0
- iamt/modules/ubuntud/roles/role.py +28 -0
- iamt/modules/ubuntud/templates/ibus/ibus_rime.custom.yaml +3 -0
- iamt/modules/ubuntud/v2ray-core.py +238 -0
- iamt/modules/ubuntud/v2rayN.py +127 -0
- iamt/modules/ubuntud/vscode.py +162 -0
- iamt/modules/uv/roles/role.py +56 -0
- iamt/modules/uv/templates/uv.toml +5 -0
- iamt/modules/uv/uv.py +315 -0
- iamt/modules/vagrant/templates/Vagrantfile +25 -0
- iamt/modules/vagrant/vagrant.py +91 -0
- iamt/modules/vboxinit/base_box_init.py +142 -0
- iamt/modules/vboxinit/roles/role.py +15 -0
- iamt/role/role.py +134 -0
- iamt/run_file/run_file.py +121 -0
- iamt/run_line/commands.py +70 -0
- iamt/run_line/run_line.py +78 -0
- iamt/task/task.py +108 -0
- iamt/utils/__init__.py +6 -0
- iamt/utils/config_saver.py +90 -0
- iamt/utils/task_tracker.py +136 -0
- iamt-1.1.27.dist-info/METADATA +19 -0
- iamt-1.1.27.dist-info/RECORD +482 -0
- iamt-1.1.27.dist-info/WHEEL +4 -0
- iamt-1.1.27.dist-info/entry_points.txt +5 -0
iamt/dcd/dcd.py
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"""DCD 模块 - Docker Compose 部署管理
|
|
2
|
+
|
|
3
|
+
提供以下命令:
|
|
4
|
+
- iamt dcd ls: 列出所有可用的 docker compose 模块
|
|
5
|
+
- iamt dcd x: 交互式部署 docker compose 模块到远程服务器
|
|
6
|
+
- iamt dcd file: 从配置文件执行部署任务
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import TypedDict
|
|
11
|
+
|
|
12
|
+
import questionary
|
|
13
|
+
import yaml
|
|
14
|
+
from prompt_toolkit import prompt
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
from rich.table import Table
|
|
17
|
+
|
|
18
|
+
from ..completers.customCompleter import CustomCompleter, CustomValidator
|
|
19
|
+
from ..utils.config_saver import TaskCall, save_task_config, get_hostname_from_iamt_config
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# region 常量配置
|
|
23
|
+
|
|
24
|
+
COMPOSES_DIR = Path(__file__).parent.parent / "composes"
|
|
25
|
+
DCD_CONFIG_SUFFIX = ".dcd.yaml"
|
|
26
|
+
|
|
27
|
+
# endregion
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# region 类型定义
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ComposeModule(TypedDict):
|
|
34
|
+
"""Docker Compose 模块信息"""
|
|
35
|
+
name: str # 模块名称
|
|
36
|
+
category: str # 所属分类
|
|
37
|
+
path: Path # 模块路径
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DCDConfig(TypedDict):
|
|
41
|
+
"""DCD 配置文件结构"""
|
|
42
|
+
hostname: str
|
|
43
|
+
tasks: list[TaskCall]
|
|
44
|
+
|
|
45
|
+
# endregion
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class DCD:
|
|
49
|
+
"""Docker Compose 部署管理类"""
|
|
50
|
+
|
|
51
|
+
def __init__(self):
|
|
52
|
+
self._console = Console()
|
|
53
|
+
|
|
54
|
+
# region iamt dcd ls - 列出所有 compose 模块
|
|
55
|
+
|
|
56
|
+
def ls(self) -> None:
|
|
57
|
+
"""列出所有可用的 docker compose 模块"""
|
|
58
|
+
modules = self._scan_compose_modules()
|
|
59
|
+
if not modules:
|
|
60
|
+
self._console.print("[yellow]未找到任何 docker compose 模块[/yellow]")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
table = Table(title="Docker Compose 模块列表", show_lines=False)
|
|
64
|
+
table.add_column("分类", style="cyan")
|
|
65
|
+
table.add_column("模块名", style="green")
|
|
66
|
+
table.add_column("路径", style="dim")
|
|
67
|
+
|
|
68
|
+
for module in modules:
|
|
69
|
+
table.add_row(module["category"], module["name"], str(module["path"].relative_to(COMPOSES_DIR)))
|
|
70
|
+
|
|
71
|
+
self._console.print(table)
|
|
72
|
+
self._console.print(f"\n[dim]共 {len(modules)} 个模块[/dim]")
|
|
73
|
+
|
|
74
|
+
def _scan_compose_modules(self) -> list[ComposeModule]:
|
|
75
|
+
"""扫描 composes 目录下所有包含 docker-compose.yml 的模块
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
包含所有找到的 compose 模块信息的列表
|
|
79
|
+
"""
|
|
80
|
+
modules: list[ComposeModule] = []
|
|
81
|
+
if not COMPOSES_DIR.exists():
|
|
82
|
+
return modules
|
|
83
|
+
|
|
84
|
+
for category_dir in sorted(COMPOSES_DIR.iterdir()):
|
|
85
|
+
if not category_dir.is_dir() or category_dir.name.startswith("."):
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
for module_dir in sorted(category_dir.iterdir()):
|
|
89
|
+
if not module_dir.is_dir():
|
|
90
|
+
continue
|
|
91
|
+
|
|
92
|
+
compose_file = module_dir / "docker-compose.yml"
|
|
93
|
+
if compose_file.exists():
|
|
94
|
+
modules.append({
|
|
95
|
+
"name": module_dir.name,
|
|
96
|
+
"category": category_dir.name,
|
|
97
|
+
"path": module_dir,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
return modules
|
|
101
|
+
|
|
102
|
+
# endregion
|
|
103
|
+
|
|
104
|
+
# region iamt dcd x - 交互式部署
|
|
105
|
+
|
|
106
|
+
def x(self, force: bool = False, start: bool = False) -> None:
|
|
107
|
+
"""交互式部署 docker compose 模块到远程服务器
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
force: 强制执行,若远程目录已存在且有 compose 项目运行,会先停止并删除
|
|
111
|
+
start: 部署完成后是否立即启动项目
|
|
112
|
+
"""
|
|
113
|
+
from ..client_config.client_config import ClientConfig
|
|
114
|
+
|
|
115
|
+
# region 选择 compose 模块
|
|
116
|
+
modules = self._scan_compose_modules()
|
|
117
|
+
if not modules:
|
|
118
|
+
self._console.print("[red]未找到任何 docker compose 模块[/red]")
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
module_choices = {f"{m['category']}/{m['name']}": f"{m['category']}/{m['name']}" for m in modules}
|
|
122
|
+
completer = CustomCompleter(module_choices)
|
|
123
|
+
validator = CustomValidator(completer, "无效的模块,请从补全列表中选择。")
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
selected = prompt(
|
|
127
|
+
"请选择要部署的 docker compose 模块: ",
|
|
128
|
+
completer=completer,
|
|
129
|
+
validator=validator,
|
|
130
|
+
)
|
|
131
|
+
except (KeyboardInterrupt, EOFError):
|
|
132
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
if not selected:
|
|
136
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
selected_module = modules[list(module_choices.keys()).index(selected)]
|
|
140
|
+
# endregion
|
|
141
|
+
|
|
142
|
+
# region 获取远程部署目录
|
|
143
|
+
default_remote_dir = f"/opt/docker/{selected_module['name']}"
|
|
144
|
+
remote_dir = questionary.text(
|
|
145
|
+
"请输入远程部署目录:",
|
|
146
|
+
default=default_remote_dir,
|
|
147
|
+
).ask()
|
|
148
|
+
|
|
149
|
+
if remote_dir is None:
|
|
150
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
151
|
+
return
|
|
152
|
+
# endregion
|
|
153
|
+
|
|
154
|
+
# region 确认并执行部署
|
|
155
|
+
config = ClientConfig()
|
|
156
|
+
conn = config.connect()
|
|
157
|
+
if conn is None:
|
|
158
|
+
self._console.print("[red]无法连接到服务器[/red]")
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
host_info = f"{conn.user}@{conn.host}:{conn.port}"
|
|
162
|
+
mode_hints = []
|
|
163
|
+
if force:
|
|
164
|
+
mode_hints.append("强制模式")
|
|
165
|
+
if start:
|
|
166
|
+
mode_hints.append("部署后启动")
|
|
167
|
+
mode_hint = f" [{', '.join(mode_hints)}]" if mode_hints else ""
|
|
168
|
+
confirm = questionary.confirm(
|
|
169
|
+
f"确认部署 {selected} 到 {host_info}:{remote_dir}?{mode_hint}",
|
|
170
|
+
default=True,
|
|
171
|
+
).ask()
|
|
172
|
+
|
|
173
|
+
if not confirm:
|
|
174
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
175
|
+
return
|
|
176
|
+
# endregion
|
|
177
|
+
|
|
178
|
+
# region 执行部署任务
|
|
179
|
+
from ..modules.dcdtask.dcdtask import compose_up, deploy_compose_module
|
|
180
|
+
|
|
181
|
+
# 记录执行的 task 调用
|
|
182
|
+
executed_tasks: list[TaskCall] = []
|
|
183
|
+
|
|
184
|
+
deploy_args = {
|
|
185
|
+
"local_path": str(selected_module["path"]),
|
|
186
|
+
"remote_dir": remote_dir,
|
|
187
|
+
"force": force,
|
|
188
|
+
}
|
|
189
|
+
success, msg = deploy_compose_module(conn, **deploy_args)
|
|
190
|
+
executed_tasks.append({"task": "dcdtask.deploy_compose_module", "args": deploy_args})
|
|
191
|
+
|
|
192
|
+
if not success:
|
|
193
|
+
self._console.print(f"[red]部署失败: {msg}[/red]")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
if start:
|
|
197
|
+
up_args = {"remote_dir": remote_dir}
|
|
198
|
+
compose_up(conn, **up_args)
|
|
199
|
+
executed_tasks.append({"task": "dcdtask.compose_up", "args": up_args})
|
|
200
|
+
# endregion
|
|
201
|
+
|
|
202
|
+
# region 保存配置文件
|
|
203
|
+
save_config = questionary.confirm(
|
|
204
|
+
"是否保存部署配置到当前目录?",
|
|
205
|
+
default=True,
|
|
206
|
+
).ask()
|
|
207
|
+
|
|
208
|
+
if save_config:
|
|
209
|
+
config_name = Path(remote_dir).name
|
|
210
|
+
save_task_config(
|
|
211
|
+
hostname=get_hostname_from_iamt_config(),
|
|
212
|
+
tasks=executed_tasks,
|
|
213
|
+
config_name=config_name,
|
|
214
|
+
suffix=DCD_CONFIG_SUFFIX,
|
|
215
|
+
)
|
|
216
|
+
# endregion
|
|
217
|
+
|
|
218
|
+
# endregion
|
|
219
|
+
|
|
220
|
+
# region iamt dcd file - 从配置文件部署
|
|
221
|
+
|
|
222
|
+
def file(self) -> None:
|
|
223
|
+
"""从当前目录的配置文件执行部署任务
|
|
224
|
+
|
|
225
|
+
扫描当前目录下的 .dcd.yaml 配置文件,读取其中的主机和任务信息,
|
|
226
|
+
连接到目标服务器并按顺序执行配置的部署任务。
|
|
227
|
+
"""
|
|
228
|
+
from ..client_config.client_config import ClientConfig
|
|
229
|
+
|
|
230
|
+
# region 扫描配置文件
|
|
231
|
+
dcd_config_files = list(Path.cwd().glob(f"*{DCD_CONFIG_SUFFIX}"))
|
|
232
|
+
if not dcd_config_files:
|
|
233
|
+
self._console.print(f"[yellow]当前目录未找到 {DCD_CONFIG_SUFFIX} 配置文件[/yellow]")
|
|
234
|
+
return
|
|
235
|
+
# endregion
|
|
236
|
+
|
|
237
|
+
# region 选择配置文件
|
|
238
|
+
if len(dcd_config_files) == 1:
|
|
239
|
+
selected_file = dcd_config_files[0]
|
|
240
|
+
else:
|
|
241
|
+
file_choices = [f.name for f in dcd_config_files]
|
|
242
|
+
selected_name = questionary.select(
|
|
243
|
+
"请选择配置文件:",
|
|
244
|
+
choices=file_choices,
|
|
245
|
+
).ask()
|
|
246
|
+
|
|
247
|
+
if selected_name is None:
|
|
248
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
249
|
+
return
|
|
250
|
+
|
|
251
|
+
selected_file = Path.cwd() / selected_name
|
|
252
|
+
# endregion
|
|
253
|
+
|
|
254
|
+
# region 读取配置
|
|
255
|
+
try:
|
|
256
|
+
config_data: DCDConfig = yaml.safe_load(selected_file.read_text(encoding="utf-8"))
|
|
257
|
+
except Exception as e:
|
|
258
|
+
self._console.print(f"[red]读取配置文件失败: {e}[/red]")
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
hostname = config_data.get("hostname", "")
|
|
262
|
+
tasks = config_data.get("tasks", [])
|
|
263
|
+
|
|
264
|
+
if not hostname:
|
|
265
|
+
self._console.print("[red]配置文件缺少 hostname[/red]")
|
|
266
|
+
return
|
|
267
|
+
if not tasks:
|
|
268
|
+
self._console.print("[red]配置文件缺少 tasks[/red]")
|
|
269
|
+
return
|
|
270
|
+
# endregion
|
|
271
|
+
|
|
272
|
+
# region 验证 hostname 并创建连接
|
|
273
|
+
client_config = ClientConfig()
|
|
274
|
+
if not client_config.config_file.exists():
|
|
275
|
+
self._console.print("[red]未找到 iamt.yaml 配置文件[/red]")
|
|
276
|
+
return
|
|
277
|
+
|
|
278
|
+
iamt_config = yaml.safe_load(client_config.config_file.read_text(encoding="utf-8"))
|
|
279
|
+
hosts = iamt_config.get("hosts", {})
|
|
280
|
+
if hostname not in hosts:
|
|
281
|
+
self._console.print(f"[red]iamt.yaml 中未找到主机: {hostname}[/red]")
|
|
282
|
+
return
|
|
283
|
+
|
|
284
|
+
conn = client_config.connect(hostname)
|
|
285
|
+
if conn is None:
|
|
286
|
+
self._console.print("[red]无法连接到服务器[/red]")
|
|
287
|
+
return
|
|
288
|
+
# endregion
|
|
289
|
+
|
|
290
|
+
# region 显示配置信息并确认
|
|
291
|
+
self._console.print(f"[cyan]配置文件: {selected_file.name}[/cyan]")
|
|
292
|
+
self._console.print(f"[cyan]目标主机: {hostname}[/cyan]")
|
|
293
|
+
self._console.print("[cyan]待执行任务:[/cyan]")
|
|
294
|
+
for t in tasks:
|
|
295
|
+
self._console.print(f" - {t['task']}: {t['args']}")
|
|
296
|
+
|
|
297
|
+
confirm = questionary.confirm("确认执行部署?", default=True).ask()
|
|
298
|
+
if not confirm:
|
|
299
|
+
self._console.print("[yellow]已取消[/yellow]")
|
|
300
|
+
return
|
|
301
|
+
# endregion
|
|
302
|
+
|
|
303
|
+
# region 执行 tasks
|
|
304
|
+
from ..modules.dcdtask import dcdtask as dcdtask_module
|
|
305
|
+
|
|
306
|
+
for task_call in tasks:
|
|
307
|
+
task_name = task_call["task"]
|
|
308
|
+
task_args = task_call["args"].copy()
|
|
309
|
+
|
|
310
|
+
# 解析 task 名称 (格式: module.function)
|
|
311
|
+
parts = task_name.split(".")
|
|
312
|
+
if len(parts) != 2:
|
|
313
|
+
self._console.print(f"[red]无效的 task 名称: {task_name}[/red]")
|
|
314
|
+
continue
|
|
315
|
+
|
|
316
|
+
module_name, func_name = parts
|
|
317
|
+
|
|
318
|
+
# 获取 task 函数
|
|
319
|
+
try:
|
|
320
|
+
task_func = getattr(dcdtask_module, func_name, None)
|
|
321
|
+
if task_func is None:
|
|
322
|
+
self._console.print(f"[red]未找到 task 函数: {task_name}[/red]")
|
|
323
|
+
continue
|
|
324
|
+
except Exception as e:
|
|
325
|
+
self._console.print(f"[red]加载 task 失败: {task_name}, {e}[/red]")
|
|
326
|
+
continue
|
|
327
|
+
|
|
328
|
+
# 执行 task
|
|
329
|
+
self._console.print(f"[cyan]执行: {task_name}[/cyan]")
|
|
330
|
+
try:
|
|
331
|
+
task_func(conn, **task_args)
|
|
332
|
+
except Exception as e:
|
|
333
|
+
self._console.print(f"[red]执行失败: {e}[/red]")
|
|
334
|
+
return
|
|
335
|
+
# endregion
|
|
336
|
+
|
|
337
|
+
# endregion
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""
|
|
2
|
+
单例模式装饰器实现
|
|
3
|
+
提供线程安全的单例模式装饰器,确保类只能创建一个实例。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import threading
|
|
7
|
+
from functools import wraps
|
|
8
|
+
from typing import Dict, Type, Any, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Singleton:
|
|
12
|
+
"""
|
|
13
|
+
单例模式装饰器类
|
|
14
|
+
使用@Singleton装饰器方式实现单例模式,线程安全。
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
@Singleton
|
|
18
|
+
class ConfigManager:
|
|
19
|
+
def __init__(self):
|
|
20
|
+
if hasattr(self, '_initialized'):
|
|
21
|
+
return
|
|
22
|
+
self._initialized = True
|
|
23
|
+
self.config = {}
|
|
24
|
+
|
|
25
|
+
# 使用
|
|
26
|
+
config1 = ConfigManager()
|
|
27
|
+
config2 = ConfigManager()
|
|
28
|
+
assert config1 is config2 # True
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, cls: Type):
|
|
32
|
+
"""
|
|
33
|
+
初始化单例装饰器
|
|
34
|
+
Args:
|
|
35
|
+
cls: 要应用单例模式的类
|
|
36
|
+
"""
|
|
37
|
+
self._cls = cls
|
|
38
|
+
self._instance: Optional[Any] = None
|
|
39
|
+
self._lock = threading.Lock()
|
|
40
|
+
|
|
41
|
+
# 保持原类的属性
|
|
42
|
+
self.__name__ = cls.__name__
|
|
43
|
+
self.__doc__ = cls.__doc__
|
|
44
|
+
self.__module__ = cls.__module__
|
|
45
|
+
self.__qualname__ = cls.__qualname__
|
|
46
|
+
|
|
47
|
+
def __call__(self, *args, **kwargs):
|
|
48
|
+
"""
|
|
49
|
+
实现单例逻辑的调用方法
|
|
50
|
+
使用双重检查锁定确保线程安全
|
|
51
|
+
"""
|
|
52
|
+
if self._instance is None:
|
|
53
|
+
with self._lock:
|
|
54
|
+
if self._instance is None:
|
|
55
|
+
self._instance = self._cls(*args, **kwargs)
|
|
56
|
+
return self._instance
|
|
57
|
+
|
|
58
|
+
def reset_instance(self):
|
|
59
|
+
"""重置单例实例(主要用于测试)"""
|
|
60
|
+
with self._lock:
|
|
61
|
+
self._instance = None
|
|
62
|
+
|
|
63
|
+
def get_instance_count(self):
|
|
64
|
+
"""获取实例数量"""
|
|
65
|
+
return 1 if self._instance is not None else 0
|
|
66
|
+
|
|
67
|
+
def get_original_class(self):
|
|
68
|
+
"""获取原始类"""
|
|
69
|
+
return self._cls
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def instance(self):
|
|
73
|
+
"""获取当前实例(如果存在)"""
|
|
74
|
+
return self._instance
|
|
75
|
+
|
|
76
|
+
# 一旦一个类被 Sginleton 装饰 这个类就会变成一个Singleton实例
|
|
77
|
+
# 被装饰类初始化的时候 其实会嗲用 Singleton的 call 方法 直接从Singleton实例当中返回 被装饰类的实例
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class SingletonMeta(type):
|
|
84
|
+
"""
|
|
85
|
+
线程安全的单例元类实现
|
|
86
|
+
|
|
87
|
+
使用方式:
|
|
88
|
+
class MyClass(metaclass=SingletonMeta):
|
|
89
|
+
def __init__(self):
|
|
90
|
+
self.value = "singleton"
|
|
91
|
+
|
|
92
|
+
特点:
|
|
93
|
+
- 线程安全的双重检查锁定
|
|
94
|
+
- 支持继承
|
|
95
|
+
- 支持多重继承
|
|
96
|
+
- 每个类维护独立的单例实例
|
|
97
|
+
|
|
98
|
+
Example:
|
|
99
|
+
class DatabaseManager(metaclass=SingletonMeta):
|
|
100
|
+
def __init__(self):
|
|
101
|
+
self.connections = {}
|
|
102
|
+
|
|
103
|
+
class CacheService(DatabaseManager): # 继承也是单例
|
|
104
|
+
def __init__(self):
|
|
105
|
+
super().__init__()
|
|
106
|
+
self.cache = {}
|
|
107
|
+
|
|
108
|
+
# 使用
|
|
109
|
+
db1 = DatabaseManager()
|
|
110
|
+
db2 = DatabaseManager()
|
|
111
|
+
assert db1 is db2 # True
|
|
112
|
+
|
|
113
|
+
cache1 = CacheService()
|
|
114
|
+
cache2 = CacheService()
|
|
115
|
+
assert cache1 is cache2 # True
|
|
116
|
+
assert cache1 is not db1 # True (不同类有不同实例)
|
|
117
|
+
"""
|
|
118
|
+
_instances: Dict[Type, Any] = {}
|
|
119
|
+
_lock: threading.Lock = threading.Lock()
|
|
120
|
+
|
|
121
|
+
def __call__(cls, *args, **kwargs):
|
|
122
|
+
if cls not in cls._instances:
|
|
123
|
+
with cls._lock:
|
|
124
|
+
# 双重检查锁定模式
|
|
125
|
+
if cls not in cls._instances:
|
|
126
|
+
instance = super().__call__(*args, **kwargs)
|
|
127
|
+
cls._instances[cls] = instance
|
|
128
|
+
return cls._instances[cls]
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def reset_all_instances(mcs):
|
|
132
|
+
"""重置所有单例实例(主要用于测试)"""
|
|
133
|
+
with mcs._lock:
|
|
134
|
+
mcs._instances.clear()
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def get_instance_info(mcs):
|
|
138
|
+
"""获取所有单例实例信息"""
|
|
139
|
+
return {cls.__name__: id(instance) for cls, instance in mcs._instances.items()}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def singleton(cls: Type) -> Type:
|
|
143
|
+
"""
|
|
144
|
+
单例模式装饰器
|
|
145
|
+
使用装饰器方式实现单例模式,线程安全。
|
|
146
|
+
Args:
|
|
147
|
+
cls: 要应用单例模式的类
|
|
148
|
+
Returns:
|
|
149
|
+
应用了单例模式的类
|
|
150
|
+
"""
|
|
151
|
+
instances: Dict[Type, Any] = {}
|
|
152
|
+
lock = threading.Lock()
|
|
153
|
+
|
|
154
|
+
@wraps(cls)
|
|
155
|
+
def get_instance(*args, **kwargs):
|
|
156
|
+
if cls not in instances:
|
|
157
|
+
with lock:
|
|
158
|
+
if cls not in instances:
|
|
159
|
+
instances[cls] = cls(*args, **kwargs)
|
|
160
|
+
return instances[cls]
|
|
161
|
+
|
|
162
|
+
return get_instance
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def thread_safe_singleton(cls: Type) -> Type:
|
|
166
|
+
"""
|
|
167
|
+
线程安全的单例装饰器(增强版)
|
|
168
|
+
提供更强的线程安全保证和实例管理功能。
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
cls: 要应用单例模式的类
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
应用了单例模式的类
|
|
175
|
+
"""
|
|
176
|
+
instances: Dict[Type, Any] = {}
|
|
177
|
+
locks: Dict[Type, threading.Lock] = {}
|
|
178
|
+
main_lock = threading.Lock()
|
|
179
|
+
|
|
180
|
+
def get_instance(*args, **kwargs):
|
|
181
|
+
if cls not in instances:
|
|
182
|
+
# 为每个类创建独立的锁
|
|
183
|
+
if cls not in locks:
|
|
184
|
+
with main_lock:
|
|
185
|
+
if cls not in locks:
|
|
186
|
+
locks[cls] = threading.Lock()
|
|
187
|
+
|
|
188
|
+
with locks[cls]:
|
|
189
|
+
if cls not in instances:
|
|
190
|
+
instances[cls] = cls(*args, **kwargs)
|
|
191
|
+
return instances[cls]
|
|
192
|
+
|
|
193
|
+
# 保持原类的属性
|
|
194
|
+
get_instance.__name__ = cls.__name__
|
|
195
|
+
get_instance.__doc__ = cls.__doc__
|
|
196
|
+
get_instance.__module__ = cls.__module__
|
|
197
|
+
get_instance.__qualname__ = cls.__qualname__
|
|
198
|
+
|
|
199
|
+
# 添加实用方法
|
|
200
|
+
def reset_instance():
|
|
201
|
+
"""重置单例实例(主要用于测试)"""
|
|
202
|
+
if cls in instances:
|
|
203
|
+
with locks.get(cls, threading.Lock()):
|
|
204
|
+
if cls in instances:
|
|
205
|
+
del instances[cls]
|
|
206
|
+
|
|
207
|
+
def get_instance_count():
|
|
208
|
+
"""获取实例数量"""
|
|
209
|
+
return 1 if cls in instances else 0
|
|
210
|
+
|
|
211
|
+
get_instance.reset_instance = reset_instance
|
|
212
|
+
get_instance.get_instance_count = get_instance_count
|
|
213
|
+
get_instance._original_class = cls
|
|
214
|
+
|
|
215
|
+
return get_instance
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# 导出的公共接口
|
|
219
|
+
__all__ = [
|
|
220
|
+
'singleton',
|
|
221
|
+
'Singleton',
|
|
222
|
+
'SingletonMeta',
|
|
223
|
+
'thread_safe_singleton'
|
|
224
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# 此文件内容已移动到 setup_apt_sources.py
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""架构转换工具模块"""
|
|
2
|
+
|
|
3
|
+
# 架构映射表 (uname -m -> dpkg architecture)
|
|
4
|
+
ARCH_MAP = {
|
|
5
|
+
"x86_64": "amd64",
|
|
6
|
+
"aarch64": "arm64",
|
|
7
|
+
"armv7l": "armhf",
|
|
8
|
+
"i686": "i386",
|
|
9
|
+
"i386": "i386",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def normalize_arch(uname_arch: str) -> str:
|
|
14
|
+
"""将 uname -m 输出转换为 dpkg 架构格式
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
uname_arch: uname -m 的输出 (如 x86_64, aarch64)
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
dpkg 架构名称 (如 amd64, arm64)
|
|
21
|
+
"""
|
|
22
|
+
return ARCH_MAP.get(uname_arch, uname_arch)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from fabric import Connection, task
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@task
|
|
5
|
+
def cleanup_network_config(conn: Connection) -> None:
|
|
6
|
+
"""根据系统类型清理静态 IP 配置"""
|
|
7
|
+
distro_id = conn.hostvars.get("distribution", {}).get("id", "").lower()
|
|
8
|
+
|
|
9
|
+
if distro_id == "ubuntu":
|
|
10
|
+
_cleanup_ubuntu_netplan(conn)
|
|
11
|
+
else:
|
|
12
|
+
_cleanup_debian_interfaces(conn)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# region Ubuntu (netplan)
|
|
16
|
+
def _cleanup_ubuntu_netplan(conn: Connection) -> None:
|
|
17
|
+
"""清理 Ubuntu netplan 配置,恢复 DHCP"""
|
|
18
|
+
print(" 检测到 Ubuntu,清理 netplan 配置...")
|
|
19
|
+
|
|
20
|
+
# 查找非默认的 netplan 配置文件
|
|
21
|
+
result = conn.sudo("find /etc/netplan/ -name '*.yaml' -type f 2>/dev/null || true")
|
|
22
|
+
files = [f.strip() for f in result.stdout.strip().split("\n") if f.strip()]
|
|
23
|
+
|
|
24
|
+
# 删除自定义配置文件(保留系统默认的 00-installer-config.yaml 或 01-netcfg.yaml)
|
|
25
|
+
default_files = {"01-network-manager-all.yaml","00-installer-config.yaml", "01-netcfg.yaml", "50-cloud-init.yaml"}
|
|
26
|
+
for f in files:
|
|
27
|
+
filename = f.split("/")[-1]
|
|
28
|
+
if filename not in default_files:
|
|
29
|
+
conn.sudo(f"rm -f {f}")
|
|
30
|
+
print(f" 已删除: {f}")
|
|
31
|
+
|
|
32
|
+
# # 生成默认 DHCP 配置
|
|
33
|
+
# dhcp_config = """
|
|
34
|
+
# network:
|
|
35
|
+
# version: 2
|
|
36
|
+
# ethernets:
|
|
37
|
+
# enp0s8:
|
|
38
|
+
# dhcp4: true
|
|
39
|
+
# """
|
|
40
|
+
# conn.sudo(f"bash -c \"echo '{dhcp_config}' > /etc/netplan/50-dhcp.yaml\"")
|
|
41
|
+
# conn.sudo("chmod 600 /etc/netplan/50-dhcp.yaml")
|
|
42
|
+
# print(" 已创建 DHCP 配置: /etc/netplan/50-dhcp.yaml")
|
|
43
|
+
|
|
44
|
+
# 应用 netplan 配置(执行后网络会变更,连接将断开)
|
|
45
|
+
conn.sudo("netplan apply", warn=True)
|
|
46
|
+
print(" 已应用 netplan 配置,正在断开连接...")
|
|
47
|
+
conn.close()
|
|
48
|
+
# endregion
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# region Debian (interfaces)
|
|
52
|
+
def _cleanup_debian_interfaces(conn: Connection) -> None:
|
|
53
|
+
"""清理 Debian 传统 interfaces 配置"""
|
|
54
|
+
print(" 检测到 Debian,清理 interfaces 配置...")
|
|
55
|
+
|
|
56
|
+
# 查找并删除 interfaces.d 下的配置文件
|
|
57
|
+
result = conn.sudo("find /etc/network/interfaces.d/ -type f 2>/dev/null || true")
|
|
58
|
+
files = [f.strip() for f in result.stdout.strip().split("\n") if f.strip()]
|
|
59
|
+
|
|
60
|
+
for f in files:
|
|
61
|
+
conn.sudo(f"rm -f {f}")
|
|
62
|
+
print(f" 已删除: {f}")
|
|
63
|
+
|
|
64
|
+
# 重启网络服务
|
|
65
|
+
if files:
|
|
66
|
+
conn.sudo("systemctl restart networking", warn=True)
|
|
67
|
+
print(" 已重启网络服务")
|
|
68
|
+
# endregion
|