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/__init__.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import fire
|
|
4
|
+
import yaml
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.columns import Columns
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
|
|
9
|
+
from .client_config.client_config import ClientConfig
|
|
10
|
+
from .dcd.dcd import DCD
|
|
11
|
+
from .task.task import Task
|
|
12
|
+
from .role.role import Role
|
|
13
|
+
from .run_file.run_file import RunFile
|
|
14
|
+
from .run_line.run_line import RunLine
|
|
15
|
+
|
|
16
|
+
class ENTRY:
|
|
17
|
+
|
|
18
|
+
def __init__(self):
|
|
19
|
+
self.dcd = DCD()
|
|
20
|
+
self.task = Task()
|
|
21
|
+
self.role = Role()
|
|
22
|
+
self.runline=RunLine()
|
|
23
|
+
self.rfx = RunFile().x
|
|
24
|
+
self.rler = RunLine().select_and_exec_remote
|
|
25
|
+
self.rlel = RunLine().select_and_exec_local
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _scan_modules(self) -> list[str]:
|
|
29
|
+
"""扫描 modules 目录下的所有模块"""
|
|
30
|
+
modules_path = Path(__file__).parent / "modules"
|
|
31
|
+
return [
|
|
32
|
+
d.name for d in modules_path.iterdir()
|
|
33
|
+
if d.is_dir() and not d.name.startswith("_")
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
def list_modules(self):
|
|
37
|
+
"""列出所有可用模块"""
|
|
38
|
+
console = Console()
|
|
39
|
+
columns = Columns(self._scan_modules(), equal=True, expand=True, column_first=False)
|
|
40
|
+
panel = Panel(columns, title="可用模块", border_style="blue")
|
|
41
|
+
console.print(panel)
|
|
42
|
+
|
|
43
|
+
def list_hostvars(self, hostname: str | None = None):
|
|
44
|
+
"""列出主机变量,可指定 hostname"""
|
|
45
|
+
config = ClientConfig()
|
|
46
|
+
conn = config.connect(hostname)
|
|
47
|
+
if conn is None:
|
|
48
|
+
return
|
|
49
|
+
console = Console()
|
|
50
|
+
console.print(config.hostvars)
|
|
51
|
+
|
|
52
|
+
def test(self, hostname: str | None = None):
|
|
53
|
+
"""测试连接"""
|
|
54
|
+
config = ClientConfig()
|
|
55
|
+
conn = config.connect(hostname)
|
|
56
|
+
if conn:
|
|
57
|
+
print(f"连接成功: {config.hostvars.get('hostname', 'unknown')}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def main() -> None:
|
|
63
|
+
try:
|
|
64
|
+
fire.Fire(ENTRY)
|
|
65
|
+
except KeyboardInterrupt:
|
|
66
|
+
print("\n操作已取消")
|
|
67
|
+
exit(0)
|
iamt/__main__.py
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
|
|
2
|
+
"""
|
|
3
|
+
客户端配置管理模块
|
|
4
|
+
|
|
5
|
+
提供 SSH 连接配置的加载、管理和主机信息收集功能:
|
|
6
|
+
创建 ClientConfig 实例 实例初始化的最后一步 回去寻找iamt配置文件
|
|
7
|
+
如果找到配置文件 则读取配置文件中的所有host信息 同步到 self.hosts
|
|
8
|
+
找到配置文件之后 应当搜索配置文件同级别目录下是否存在 .artifacts 目录如果没有则创建
|
|
9
|
+
|
|
10
|
+
connect 函数 就是链接 管理器
|
|
11
|
+
如果发现 self.hosts 是空的则说明没有找到配置文件/或者配置文件是空配置
|
|
12
|
+
则询问用户服务器信息 得到这个信息就能够 通过 _create_connection_from_info 创建Connection实例
|
|
13
|
+
从配置文件读取信息之后同样需要 使用 _create_connection_from_info 创建 Connection 实例
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from ..decorators.singleton import Singleton
|
|
17
|
+
from fabric import Connection, Config
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from rich.console import Console
|
|
20
|
+
import logging
|
|
21
|
+
import questionary
|
|
22
|
+
import yaml
|
|
23
|
+
|
|
24
|
+
console = Console()
|
|
25
|
+
logging.getLogger("paramiko").setLevel(logging.CRITICAL)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@Singleton
|
|
29
|
+
class ClientConfig():
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def _find_config_file() -> Path:
|
|
33
|
+
"""向上遍历目录查找 iamt.yaml,找不到则返回当前目录下的路径"""
|
|
34
|
+
current = Path.cwd()
|
|
35
|
+
for parent in [current, *current.parents]:
|
|
36
|
+
candidate = parent / "iamt.yaml"
|
|
37
|
+
if candidate.exists():
|
|
38
|
+
return candidate
|
|
39
|
+
return current / "iamt.yaml"
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
self.config_file = self._find_config_file() # 实例化时查找配置文件
|
|
43
|
+
self.hosts: dict[str, dict] = {} # 所有 host 配置
|
|
44
|
+
self.conn: Connection | None = None # 当前连接
|
|
45
|
+
self.hostvars: dict = {} # 当前连接的主机信息
|
|
46
|
+
self._current_host: str | None = None # 当前连接的 host 名称
|
|
47
|
+
|
|
48
|
+
if self.config_file.exists():
|
|
49
|
+
self._load_all_hosts()
|
|
50
|
+
self._ensure_artifacts_dir()
|
|
51
|
+
|
|
52
|
+
# region 配置加载
|
|
53
|
+
def _load_all_hosts(self) -> None:
|
|
54
|
+
"""从配置文件加载所有 host 信息"""
|
|
55
|
+
config_data = yaml.safe_load(self.config_file.read_text(encoding="utf-8"))
|
|
56
|
+
self.hosts = config_data.get("hosts", {})
|
|
57
|
+
|
|
58
|
+
def _ensure_artifacts_dir(self) -> Path:
|
|
59
|
+
"""确保配置文件同级目录下存在 .artifacts 目录,用于临时存放下载的软件安装包"""
|
|
60
|
+
artifacts_dir = self.config_file.parent / ".artifacts"
|
|
61
|
+
artifacts_dir.mkdir(exist_ok=True)
|
|
62
|
+
return artifacts_dir
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def artifacts_dir(self) -> Path:
|
|
66
|
+
"""获取 .artifacts 目录路径,如不存在则创建"""
|
|
67
|
+
return self._ensure_artifacts_dir()
|
|
68
|
+
|
|
69
|
+
def get_host_names(self) -> list[str]:
|
|
70
|
+
"""获取所有可用的 host 名称"""
|
|
71
|
+
return list(self.hosts.keys())
|
|
72
|
+
|
|
73
|
+
def get_host_info(self, hostname: str) -> dict | None:
|
|
74
|
+
"""获取指定 host 的配置信息"""
|
|
75
|
+
return self.hosts.get(hostname)
|
|
76
|
+
# endregion
|
|
77
|
+
|
|
78
|
+
# region 连接管理
|
|
79
|
+
def connect(self, hostname: str | None = None) -> Connection | None:
|
|
80
|
+
"""
|
|
81
|
+
建立到目标服务器的 SSH 连接,并收集主机信息。
|
|
82
|
+
|
|
83
|
+
这是 ClientConfig 的核心方法,负责管理 SSH 连接的生命周期。
|
|
84
|
+
连接成功后会自动调用 _gather_facts() 收集主机信息,并将其挂载到
|
|
85
|
+
conn.hostvars 属性上,供后续 task 函数使用。
|
|
86
|
+
|
|
87
|
+
连接策略:
|
|
88
|
+
1. 复用检查:如果已连接到同一 host,直接返回现有连接(避免重复连接)
|
|
89
|
+
2. 清理旧连接:建立新连接前先断开现有连接
|
|
90
|
+
3. 主机选择:
|
|
91
|
+
- 无配置文件:交互式收集服务器信息并创建连接
|
|
92
|
+
- 有配置文件:根据 hostname 参数或交互选择确定目标主机
|
|
93
|
+
4. 信息收集:连接成功后自动收集 hostvars(类似 Ansible 的 setup 模块)
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
hostname: 目标主机名称(对应 iamt.yaml 中 hosts 下的 key)
|
|
97
|
+
- 指定具体名称:直接连接该主机
|
|
98
|
+
- None 且只有一个主机:自动选择唯一主机
|
|
99
|
+
- None 且有多个主机:弹出交互式选择菜单
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Connection: fabric 的 Connection 对象,包含额外的 hostvars 属性
|
|
103
|
+
None: 连接失败或用户取消时返回
|
|
104
|
+
|
|
105
|
+
Side Effects:
|
|
106
|
+
- 更新 self.conn: 当前活动的 Connection 对象
|
|
107
|
+
- 更新 self.hostvars: 当前主机的收集信息
|
|
108
|
+
- 更新 self._current_host: 当前连接的主机名称
|
|
109
|
+
- 可能创建 iamt.yaml: 当无配置文件时通过交互收集信息
|
|
110
|
+
|
|
111
|
+
Example:
|
|
112
|
+
>>> config = ClientConfig()
|
|
113
|
+
>>> conn = config.connect("my-server") # 连接指定主机
|
|
114
|
+
>>> conn = config.connect() # 交互选择或自动选择
|
|
115
|
+
>>> print(conn.hostvars["distribution"]["name"]) # 访问主机信息
|
|
116
|
+
"""
|
|
117
|
+
# 复用检查:如果已连接到同一 host,直接返回现有连接
|
|
118
|
+
# 这避免了重复建立 SSH 连接的开销
|
|
119
|
+
if hostname and hostname == self._current_host and self.conn:
|
|
120
|
+
return self.conn
|
|
121
|
+
|
|
122
|
+
# 清理旧连接:确保同一时刻只维护一个活动连接
|
|
123
|
+
self.disconnect()
|
|
124
|
+
|
|
125
|
+
# 主机选择与连接建立
|
|
126
|
+
if not self.hosts:
|
|
127
|
+
# 无配置文件场景:交互式收集服务器信息
|
|
128
|
+
# 这通常发生在首次使用或 iamt.yaml 不存在时
|
|
129
|
+
info = self.collect_server_info()
|
|
130
|
+
if info is None or not info.get("host"):
|
|
131
|
+
console.print("[yellow]⚠[/yellow] 未提供服务器地址,退出")
|
|
132
|
+
return None
|
|
133
|
+
self.conn = self._create_connection_from_info(info)
|
|
134
|
+
else:
|
|
135
|
+
# 有配置文件场景:从 hosts 配置中选择目标主机
|
|
136
|
+
hostname = self._resolve_hostname(hostname)
|
|
137
|
+
if hostname is None:
|
|
138
|
+
return None
|
|
139
|
+
host_info = self.hosts[hostname]
|
|
140
|
+
self.conn = self._create_connection_from_info(host_info)
|
|
141
|
+
self._current_host = hostname
|
|
142
|
+
|
|
143
|
+
# 连接失败检查
|
|
144
|
+
if self.conn is None:
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
# 收集主机信息并挂载到 Connection 对象
|
|
148
|
+
# hostvars 类似 Ansible 的 hostvars,包含 OS、内存、网络等信息
|
|
149
|
+
# task 函数可通过 conn.hostvars 访问这些预收集的数据
|
|
150
|
+
self.hostvars = self._gather_facts()
|
|
151
|
+
self.conn.hostvars = self.hostvars
|
|
152
|
+
self.conn.artifacts_dir = self.artifacts_dir
|
|
153
|
+
return self.conn
|
|
154
|
+
|
|
155
|
+
def _resolve_hostname(self, hostname: str | None) -> str | None:
|
|
156
|
+
"""解析 hostname,为 None 时自动选择"""
|
|
157
|
+
if hostname:
|
|
158
|
+
if hostname not in self.hosts:
|
|
159
|
+
console.print(f"[red]✗[/red] 未找到 host: [bold]{hostname}[/bold],可用: {', '.join(self.hosts.keys())}")
|
|
160
|
+
return None
|
|
161
|
+
return hostname
|
|
162
|
+
|
|
163
|
+
# 只有一个 host 时直接使用
|
|
164
|
+
if len(self.hosts) == 1:
|
|
165
|
+
return next(iter(self.hosts))
|
|
166
|
+
|
|
167
|
+
# 多个 host 时交互选择,显示详细信息
|
|
168
|
+
choices = []
|
|
169
|
+
for name, info in self.hosts.items():
|
|
170
|
+
host = info.get("host", "")
|
|
171
|
+
user = info.get("user", "")
|
|
172
|
+
port = info.get("port", "22")
|
|
173
|
+
label = f"{name} ({user}@{host}:{port})"
|
|
174
|
+
choices.append(questionary.Choice(title=label, value=name))
|
|
175
|
+
|
|
176
|
+
selected = questionary.select("请选择要连接的服务器:", choices=choices).ask()
|
|
177
|
+
return selected
|
|
178
|
+
|
|
179
|
+
def disconnect(self) -> None:
|
|
180
|
+
"""断开当前连接"""
|
|
181
|
+
if self.conn:
|
|
182
|
+
try:
|
|
183
|
+
self.conn.close()
|
|
184
|
+
except Exception:
|
|
185
|
+
pass
|
|
186
|
+
self.conn = None
|
|
187
|
+
self.hostvars = {}
|
|
188
|
+
self._current_host = None
|
|
189
|
+
|
|
190
|
+
def _create_connection_from_info(self, host_info: dict) -> Connection | None:
|
|
191
|
+
"""根据 host_info 创建连接"""
|
|
192
|
+
config = Config(overrides={"sudo": {"password": host_info["sudo_password"]}})
|
|
193
|
+
try:
|
|
194
|
+
conn = Connection(
|
|
195
|
+
host=host_info["host"],
|
|
196
|
+
port=int(host_info.get("port", 22)),
|
|
197
|
+
user=host_info["user"],
|
|
198
|
+
connect_kwargs={"password": host_info["password"]},
|
|
199
|
+
config=config,
|
|
200
|
+
)
|
|
201
|
+
conn.open()
|
|
202
|
+
return conn
|
|
203
|
+
except Exception:
|
|
204
|
+
console.print("[red]✗[/red] 连接服务器失败")
|
|
205
|
+
return None
|
|
206
|
+
# endregion
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
# region 用户输入收集
|
|
211
|
+
def collect_server_info(self) -> dict[str, str] | None:
|
|
212
|
+
"""通过交互式问答收集服务器连接信息并写入 iamt.yaml,用户取消时返回 None"""
|
|
213
|
+
hostname = questionary.text("请输入主机名 (用于标识此服务器):").ask()
|
|
214
|
+
if hostname is None:
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
ip = questionary.text("请输入服务器IP地址:").ask()
|
|
218
|
+
if ip is None:
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
port = questionary.text("请输入SSH端口:", default="22").ask()
|
|
222
|
+
if port is None:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
username = questionary.text("请输入用户名:", default="vagrant").ask()
|
|
226
|
+
if username is None:
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
password = questionary.password("请输入密码:", default="vagrant").ask()
|
|
230
|
+
if password is None:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
sudo_password = questionary.password("请输入SUDO密码 (留空则与登录密码相同):").ask()
|
|
234
|
+
if sudo_password is None:
|
|
235
|
+
return None
|
|
236
|
+
|
|
237
|
+
host_entry = {
|
|
238
|
+
"host": ip,
|
|
239
|
+
"port": port,
|
|
240
|
+
"user": username,
|
|
241
|
+
"password": password,
|
|
242
|
+
"sudo_password": sudo_password or password,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
confirm = questionary.confirm(f"是否将配置写入 {self.config_file}?", default=True).ask()
|
|
246
|
+
if confirm is None or not confirm:
|
|
247
|
+
console.print("[yellow]⚠[/yellow] 用户取消写入配置文件")
|
|
248
|
+
return host_entry
|
|
249
|
+
|
|
250
|
+
# 手动格式化为 flow style: hosts:\n hostname: {key: value, ...}
|
|
251
|
+
flow_entry = yaml.dump(host_entry, default_flow_style=True, allow_unicode=True).strip()
|
|
252
|
+
yaml_content = f"hosts:\n {hostname}: {flow_entry}\n"
|
|
253
|
+
self.config_file.write_text(yaml_content, encoding="utf-8")
|
|
254
|
+
return host_entry
|
|
255
|
+
# endregion
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
# region 主机信息收集
|
|
260
|
+
def _gather_facts(self) -> dict:
|
|
261
|
+
"""收集主机基础信息,类似 Ansible setup 模块"""
|
|
262
|
+
facts = {}
|
|
263
|
+
|
|
264
|
+
# 发行版信息
|
|
265
|
+
os_release = self._run_cmd("cat /etc/os-release 2>/dev/null || cat /etc/*-release 2>/dev/null | head -20")
|
|
266
|
+
facts["distribution"] = self._parse_os_release(os_release)
|
|
267
|
+
|
|
268
|
+
# 主机名
|
|
269
|
+
facts["hostname"] = self._run_cmd("hostname").strip()
|
|
270
|
+
facts["fqdn"] = self._run_cmd("hostname -f 2>/dev/null || hostname").strip()
|
|
271
|
+
|
|
272
|
+
# 内核信息
|
|
273
|
+
facts["kernel"] = self._run_cmd("uname -r").strip()
|
|
274
|
+
facts["architecture"] = self._run_cmd("uname -m").strip()
|
|
275
|
+
|
|
276
|
+
# 内存信息 (KB)
|
|
277
|
+
meminfo = self._run_cmd("cat /proc/meminfo")
|
|
278
|
+
facts["memory"] = self._parse_meminfo(meminfo)
|
|
279
|
+
|
|
280
|
+
# CPU 信息
|
|
281
|
+
facts["processor_count"] = int(self._run_cmd("nproc").strip() or "1")
|
|
282
|
+
|
|
283
|
+
# 网络接口
|
|
284
|
+
facts["default_ipv4"] = self._get_default_ipv4()
|
|
285
|
+
|
|
286
|
+
# 用户信息
|
|
287
|
+
facts["user"] = self._run_cmd("whoami").strip()
|
|
288
|
+
facts["user_home"] = self._run_cmd("echo $HOME").strip()
|
|
289
|
+
|
|
290
|
+
return facts
|
|
291
|
+
|
|
292
|
+
def _run_cmd(self, cmd: str) -> str:
|
|
293
|
+
"""执行命令并返回输出,失败时返回空字符串"""
|
|
294
|
+
try:
|
|
295
|
+
result = self.conn.run(cmd, hide=True, warn=True)
|
|
296
|
+
return result.stdout if result.ok else ""
|
|
297
|
+
except Exception:
|
|
298
|
+
return ""
|
|
299
|
+
|
|
300
|
+
def _parse_os_release(self, content: str) -> dict:
|
|
301
|
+
"""解析 /etc/os-release 内容"""
|
|
302
|
+
info = {"name": "", "version": "", "version_id": "", "codename": "", "id": "", "id_like": ""}
|
|
303
|
+
for line in content.splitlines():
|
|
304
|
+
if "=" in line:
|
|
305
|
+
key, _, value = line.partition("=")
|
|
306
|
+
value = value.strip('"\'')
|
|
307
|
+
key_lower = key.lower()
|
|
308
|
+
if key_lower == "name":
|
|
309
|
+
info["name"] = value
|
|
310
|
+
elif key_lower == "version":
|
|
311
|
+
info["version"] = value
|
|
312
|
+
elif key_lower == "version_id":
|
|
313
|
+
info["version_id"] = value
|
|
314
|
+
elif key_lower == "version_codename":
|
|
315
|
+
info["codename"] = value
|
|
316
|
+
elif key_lower == "id":
|
|
317
|
+
info["id"] = value
|
|
318
|
+
elif key_lower == "id_like":
|
|
319
|
+
info["id_like"] = value
|
|
320
|
+
# 如果 id_like 为空,使用 id 作为回退
|
|
321
|
+
if not info["id_like"]:
|
|
322
|
+
info["id_like"] = info["id"]
|
|
323
|
+
return info
|
|
324
|
+
|
|
325
|
+
def _parse_meminfo(self, content: str) -> dict:
|
|
326
|
+
"""解析 /proc/meminfo 内容,返回 MB 单位"""
|
|
327
|
+
mem = {"total_mb": 0, "free_mb": 0, "available_mb": 0}
|
|
328
|
+
for line in content.splitlines():
|
|
329
|
+
parts = line.split()
|
|
330
|
+
if len(parts) >= 2:
|
|
331
|
+
key, value = parts[0].rstrip(":"), parts[1]
|
|
332
|
+
if key == "MemTotal":
|
|
333
|
+
mem["total_mb"] = int(value) // 1024
|
|
334
|
+
elif key == "MemFree":
|
|
335
|
+
mem["free_mb"] = int(value) // 1024
|
|
336
|
+
elif key == "MemAvailable":
|
|
337
|
+
mem["available_mb"] = int(value) // 1024
|
|
338
|
+
return mem
|
|
339
|
+
|
|
340
|
+
def _get_default_ipv4(self) -> dict:
|
|
341
|
+
"""获取默认 IPv4 地址和网关"""
|
|
342
|
+
info = {"address": "", "gateway": "", "interface": ""}
|
|
343
|
+
route = self._run_cmd("ip route get 1.1.1.1 2>/dev/null | head -1")
|
|
344
|
+
if route:
|
|
345
|
+
parts = route.split()
|
|
346
|
+
for i, p in enumerate(parts):
|
|
347
|
+
if p == "src" and i + 1 < len(parts):
|
|
348
|
+
info["address"] = parts[i + 1]
|
|
349
|
+
elif p == "via" and i + 1 < len(parts):
|
|
350
|
+
info["gateway"] = parts[i + 1]
|
|
351
|
+
elif p == "dev" and i + 1 < len(parts):
|
|
352
|
+
info["interface"] = parts[i + 1]
|
|
353
|
+
return info
|
|
354
|
+
# endregion
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
2
|
+
from prompt_toolkit.document import Document
|
|
3
|
+
from prompt_toolkit.validation import Validator, ValidationError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CustomCompleter(Completer):
|
|
7
|
+
"""自定义补全器,支持从外部传入字典数据"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, choices: dict[str, str]):
|
|
10
|
+
"""
|
|
11
|
+
初始化补全器
|
|
12
|
+
:param choices: 补全选项字典,格式为 {key: display_text}
|
|
13
|
+
"""
|
|
14
|
+
self.choices = choices
|
|
15
|
+
self.choice_items = list(choices.items())
|
|
16
|
+
|
|
17
|
+
def get_completions(self, document: Document, complete_event):
|
|
18
|
+
"""实现模糊补全逻辑,按匹配质量排序"""
|
|
19
|
+
text = document.text_before_cursor.lower()
|
|
20
|
+
|
|
21
|
+
# region 收集所有匹配项及其分数
|
|
22
|
+
matches: list[tuple[int, str, str]] = []
|
|
23
|
+
for key, display in self.choice_items:
|
|
24
|
+
key_score = self._fuzzy_match_score(text, key.lower())
|
|
25
|
+
display_score = self._fuzzy_match_score(text, display.lower())
|
|
26
|
+
best_score = max(key_score, display_score)
|
|
27
|
+
if best_score > 0:
|
|
28
|
+
matches.append((best_score, key, display))
|
|
29
|
+
# endregion
|
|
30
|
+
|
|
31
|
+
# region 按分数降序排列后返回补全结果
|
|
32
|
+
matches.sort(key=lambda x: x[0], reverse=True)
|
|
33
|
+
for _, key, display in matches:
|
|
34
|
+
yield Completion(
|
|
35
|
+
key,
|
|
36
|
+
start_position=-len(document.text_before_cursor),
|
|
37
|
+
display=display
|
|
38
|
+
)
|
|
39
|
+
# endregion
|
|
40
|
+
|
|
41
|
+
def _fuzzy_match_score(self, pattern: str, text: str) -> int:
|
|
42
|
+
"""
|
|
43
|
+
模糊匹配并返回匹配分数(寻找最佳匹配)
|
|
44
|
+
分数越高表示匹配质量越好:
|
|
45
|
+
- 0: 不匹配
|
|
46
|
+
- 完全连续匹配优先级最高
|
|
47
|
+
- 其次考虑位置和紧凑度
|
|
48
|
+
"""
|
|
49
|
+
if not pattern:
|
|
50
|
+
return 1
|
|
51
|
+
|
|
52
|
+
# region 寻找所有可能的匹配并选择最佳
|
|
53
|
+
best_score = 0
|
|
54
|
+
|
|
55
|
+
def find_matches(p_idx: int, t_idx: int, positions: list[int]):
|
|
56
|
+
"""递归寻找所有可能的匹配组合"""
|
|
57
|
+
nonlocal best_score
|
|
58
|
+
|
|
59
|
+
if p_idx == len(pattern):
|
|
60
|
+
score = self._calculate_score(positions, len(pattern))
|
|
61
|
+
best_score = max(best_score, score)
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
for i in range(t_idx, len(text)):
|
|
65
|
+
if text[i] == pattern[p_idx]:
|
|
66
|
+
find_matches(p_idx + 1, i + 1, positions + [i])
|
|
67
|
+
|
|
68
|
+
find_matches(0, 0, [])
|
|
69
|
+
# endregion
|
|
70
|
+
|
|
71
|
+
return best_score
|
|
72
|
+
|
|
73
|
+
def _calculate_score(self, match_positions: list[int], pattern_len: int) -> int:
|
|
74
|
+
"""根据匹配位置计算分数"""
|
|
75
|
+
# region 计算连续匹配数
|
|
76
|
+
consecutive_count = 0
|
|
77
|
+
for i in range(1, len(match_positions)):
|
|
78
|
+
if match_positions[i] == match_positions[i - 1] + 1:
|
|
79
|
+
consecutive_count += 1
|
|
80
|
+
# endregion
|
|
81
|
+
|
|
82
|
+
# region 计算分数
|
|
83
|
+
is_fully_consecutive = consecutive_count == pattern_len - 1
|
|
84
|
+
|
|
85
|
+
if is_fully_consecutive:
|
|
86
|
+
score = 1000 - match_positions[0]
|
|
87
|
+
else:
|
|
88
|
+
score = 100
|
|
89
|
+
score += max(0, 50 - match_positions[0] * 2)
|
|
90
|
+
span = match_positions[-1] - match_positions[0] + 1
|
|
91
|
+
score += max(0, 30 - (span - len(match_positions)) * 2)
|
|
92
|
+
score += consecutive_count * 10
|
|
93
|
+
# endregion
|
|
94
|
+
|
|
95
|
+
return score
|
|
96
|
+
|
|
97
|
+
def get_valid_keys(self) -> list[str]:
|
|
98
|
+
"""返回所有有效的 key 列表"""
|
|
99
|
+
return list(self.choices.keys())
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class CustomValidator(Validator):
|
|
103
|
+
"""验证器:确保用户输入的值有效"""
|
|
104
|
+
|
|
105
|
+
def __init__(self, completer: CustomCompleter, error_msg: str = "无效的输入,请从补全列表中选择。"):
|
|
106
|
+
self.completer = completer
|
|
107
|
+
self.valid_keys = completer.get_valid_keys()
|
|
108
|
+
self.error_msg = error_msg
|
|
109
|
+
|
|
110
|
+
def validate(self, document: Document):
|
|
111
|
+
"""验证用户输入是否有效"""
|
|
112
|
+
text = document.text.strip()
|
|
113
|
+
|
|
114
|
+
if text and text not in self.valid_keys:
|
|
115
|
+
raise ValidationError(
|
|
116
|
+
message=self.error_msg,
|
|
117
|
+
cursor_position=len(text)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__ == "__main__":
|
|
123
|
+
# 调试测试
|
|
124
|
+
test_choices = {
|
|
125
|
+
"linux_init.setup_vagrant_user": "linux_init.setup_vagrant_user",
|
|
126
|
+
"linux_init.setup_apt_sources": "linux_init.setup_apt_sources",
|
|
127
|
+
"linux_init.install_kernel_dev_packages": "linux_init.install_kernel_dev_packages",
|
|
128
|
+
"docker.configure_docker_user": "docker.configure_docker_user",
|
|
129
|
+
"docker.uninstall_old_docker": "docker.uninstall_old_docker",
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
completer = CustomCompleter(test_choices)
|
|
133
|
+
pattern = "user"
|
|
134
|
+
|
|
135
|
+
print(f"Pattern: '{pattern}'\n")
|
|
136
|
+
scores = []
|
|
137
|
+
for key in test_choices:
|
|
138
|
+
score = completer._fuzzy_match_score(pattern, key.lower())
|
|
139
|
+
scores.append((score, key))
|
|
140
|
+
|
|
141
|
+
scores.sort(key=lambda x: x[0], reverse=True)
|
|
142
|
+
for score, key in scores:
|
|
143
|
+
print(f"{score:4d} {key}")
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
services:
|
|
2
|
+
gitea:
|
|
3
|
+
image: gitea/gitea:1.22
|
|
4
|
+
container_name: gitea
|
|
5
|
+
restart: always
|
|
6
|
+
environment:
|
|
7
|
+
- USER_UID=1000
|
|
8
|
+
- USER_GID=1000
|
|
9
|
+
- GITEA__database__DB_TYPE=postgres
|
|
10
|
+
- GITEA__database__HOST=gitea-db:5432
|
|
11
|
+
- GITEA__database__NAME=gitea
|
|
12
|
+
- GITEA__database__USER=gitea
|
|
13
|
+
- GITEA__database__PASSWD=gitea
|
|
14
|
+
- GITEA__server__ROOT_URL=http://localhost:3000/
|
|
15
|
+
- GITEA__server__SSH_DOMAIN=localhost
|
|
16
|
+
- GITEA__server__SSH_PORT=2222
|
|
17
|
+
- GITEA__server__LFS_START_SERVER=true
|
|
18
|
+
- GITEA__time__DEFAULT_UI_LOCATION=Asia/Shanghai
|
|
19
|
+
ports:
|
|
20
|
+
- '3000:3000'
|
|
21
|
+
- '2222:22'
|
|
22
|
+
volumes:
|
|
23
|
+
- './data:/data'
|
|
24
|
+
- '/etc/timezone:/etc/timezone:ro'
|
|
25
|
+
- '/etc/localtime:/etc/localtime:ro'
|
|
26
|
+
depends_on:
|
|
27
|
+
gitea-db:
|
|
28
|
+
condition: service_healthy
|
|
29
|
+
networks:
|
|
30
|
+
- gitea-net
|
|
31
|
+
|
|
32
|
+
gitea-db:
|
|
33
|
+
image: postgres:16-alpine
|
|
34
|
+
container_name: gitea-db
|
|
35
|
+
restart: always
|
|
36
|
+
environment:
|
|
37
|
+
- POSTGRES_USER=gitea
|
|
38
|
+
- POSTGRES_PASSWORD=gitea
|
|
39
|
+
- POSTGRES_DB=gitea
|
|
40
|
+
volumes:
|
|
41
|
+
- './db:/var/lib/postgresql/data'
|
|
42
|
+
healthcheck:
|
|
43
|
+
test: ['CMD', 'pg_isready', '-U', 'gitea']
|
|
44
|
+
interval: 10s
|
|
45
|
+
timeout: 5s
|
|
46
|
+
retries: 5
|
|
47
|
+
networks:
|
|
48
|
+
- gitea-net
|
|
49
|
+
|
|
50
|
+
networks:
|
|
51
|
+
gitea-net:
|
|
52
|
+
driver: bridge
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
https://docs.gitlab.com/install/docker/installation/#install-gitlab-by-using-docker-compose
|
|
2
|
+
https://hub.docker.com/r/gitlab/gitlab-ee
|
|
3
|
+
https://gitlab.com/gitlab-org/gitlab
|
|
4
|
+
https://hub.docker.com/r/gitlab/gitlab-ce
|
|
5
|
+
|
|
6
|
+
# gitlab 默认密码在 容器当中 /etc/gitlab/initxxx 文件中
|
|
7
|
+
# 默认用户名是root
|
|
8
|
+
sudo cat /opt/docker/gitlab_V1_0/config/initial_root_password
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# 本来想看一下 能不能直接在启动的时候设置root密码的最后发现完全不行
|
|
12
|
+
# GITLAB_ROOT_PASSWORD: 'kingSUNG509!'
|
|
13
|
+
# gitlab_rails['initial_root_password']= 'kingSUNG509!'
|
|
14
|
+
# 这两个设置都没用 最后只能在UI哪里设置了
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 目前 gitlab的部署还真的存在不小的问题
|
|
19
|
+
# 域名配合自签名证书用不了 现在测试的结果是 IP配合自签名证书可以用的
|
|
20
|
+
# 至于 SSH方式 从来就没有成功过 2222一直拒绝连接
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
services:
|
|
2
|
+
gitlab:
|
|
3
|
+
image: gitlab/gitlab-ce:17.10.8-ce.0
|
|
4
|
+
container_name: gitlab
|
|
5
|
+
restart: always
|
|
6
|
+
hostname: '10.10.10.13'
|
|
7
|
+
environment:
|
|
8
|
+
GITLAB_OMNIBUS_CONFIG: |
|
|
9
|
+
external_url 'https://10.10.10.13'
|
|
10
|
+
gitlab_rails['gitlab_shell_ssh_port'] = 2222
|
|
11
|
+
|
|
12
|
+
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.crt"
|
|
13
|
+
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.key"
|
|
14
|
+
|
|
15
|
+
gitlab_rails['time_zone'] = 'Asia/Shanghai'
|
|
16
|
+
nginx['redirect_http_to_https'] = true
|
|
17
|
+
|
|
18
|
+
ports:
|
|
19
|
+
- '80:80'
|
|
20
|
+
- '443:443'
|
|
21
|
+
- '2222:2222'
|
|
22
|
+
volumes:
|
|
23
|
+
- './config:/etc/gitlab'
|
|
24
|
+
- './logs:/var/log/gitlab'
|
|
25
|
+
- './data:/var/opt/gitlab'
|
|
26
|
+
shm_size: '256m'
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|