diff --git a/deploy/chart/authhub/templates/backend/authhub-backend.yaml b/deploy/chart/authhub/templates/backend/authhub-backend.yaml index 4a19b4ad4938610de83801b4aa10d9e5c89b4f1e..54884d24bb57fa480fd2ef438ef81c41da37b073 100644 --- a/deploy/chart/authhub/templates/backend/authhub-backend.yaml +++ b/deploy/chart/authhub/templates/backend/authhub-backend.yaml @@ -37,7 +37,7 @@ spec: automountServiceAccountToken: false containers: - name: authhub-backend - image: {{ if .Values.authhub.backend.image }}{{ .Values.authhub.backend.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/authhub:0.9.3-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.authhub.backend.image | default (printf "%s/neocopilot/authhub:0.9.3-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 11120 @@ -61,7 +61,7 @@ spec: {{ toYaml .Values.authhub.backend.resourceLimits | nindent 14 }} initContainers: - name: authhub-backend-copy-secret - image: {{ if .Values.authhub.secret_inject.image }}{{ .Values.authhub.secret_inject.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/secret_inject:dev-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.authhub.secret_inject.image | default (printf "%s/neocopilot/secret_inject:dev-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} volumeMounts: - mountPath: /secrets/mysql-password diff --git a/deploy/chart/authhub/templates/mysql/mysql.yaml b/deploy/chart/authhub/templates/mysql/mysql.yaml index 6ff304051297cc27efa39213963a721738609a49..f9fdc318b3f7772499398acc42be914b1f36cdf7 100644 --- a/deploy/chart/authhub/templates/mysql/mysql.yaml +++ b/deploy/chart/authhub/templates/mysql/mysql.yaml @@ -37,7 +37,7 @@ spec: automountServiceAccountToken: false containers: - name: mysql - image: {{ if .Values.authhub.mysql.image }}{{ .Values.authhub.mysql.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/mysql:8-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.authhub.mysql.image | default (printf "%s/neocopilot/mysql:8-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} args: - "--character-set-server=utf8mb4" diff --git a/deploy/chart/authhub/templates/web/authhub-web.yaml b/deploy/chart/authhub/templates/web/authhub-web.yaml index 66d9e689ffbb37a481bec3e0b9de41c49298abf5..05ca0315eff485ae70dfa64bb1347f19913fefce 100644 --- a/deploy/chart/authhub/templates/web/authhub-web.yaml +++ b/deploy/chart/authhub/templates/web/authhub-web.yaml @@ -56,7 +56,7 @@ spec: automountServiceAccountToken: false containers: - name: authhub-web - image: {{ if .Values.authhub.web.image }}{{ .Values.authhub.web.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/authhub-web:0.9.3-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.authhub.web.image | default (printf "%s/neocopilot/authhub-web:0.9.3-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 8000 diff --git a/deploy/chart/databases/templates/minio/minio.yaml b/deploy/chart/databases/templates/minio/minio.yaml index 767d4daa27aa234519c2b7f7cdab789e085d4098..fd2fdc80db66d253cadc239d0e095f9805014408 100644 --- a/deploy/chart/databases/templates/minio/minio.yaml +++ b/deploy/chart/databases/templates/minio/minio.yaml @@ -59,7 +59,7 @@ spec: automountServiceAccountToken: false containers: - name: minio - image: {{ if .Values.databases.minio.image }}{{ .Values.databases.minio.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/minio:empty-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.databases.minio.image | default (printf "%s/neocopilot/minio:empty-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} args: - "server" diff --git a/deploy/chart/databases/templates/mongo/mongo.yaml b/deploy/chart/databases/templates/mongo/mongo.yaml index 93d2b256222ab07e4d61337cad4bf8ffa17574e9..ec5774b6b7fca848746da47d1ab0e93c93340295 100644 --- a/deploy/chart/databases/templates/mongo/mongo.yaml +++ b/deploy/chart/databases/templates/mongo/mongo.yaml @@ -37,7 +37,7 @@ spec: automountServiceAccountToken: false containers: - name: mongo - image: {{ if .Values.databases.mongo.image }}{{ .Values.databases.mongo.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/mongo:7.0.16-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.databases.mongo.image | default (printf "%s/neocopilot/mongo:7.0.16-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} command: - bash diff --git a/deploy/chart/databases/templates/pgsql/pgsql.yaml b/deploy/chart/databases/templates/pgsql/pgsql.yaml index 791e7975831e405126a36a1b17a19dd31332f966..3fa5eb482aeb0dfadf7af1fbcd1396121a2177b8 100644 --- a/deploy/chart/databases/templates/pgsql/pgsql.yaml +++ b/deploy/chart/databases/templates/pgsql/pgsql.yaml @@ -37,7 +37,7 @@ spec: automountServiceAccountToken: false containers: - name: pgsql - image: {{ if .Values.databases.pgsql.image }}{{ .Values.databases.pgsql.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/pgsql-empty:pg16-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.databases.pgsql.image | default (printf "%s/neocopilot/pgsql-empty:pg16-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 5432 diff --git a/deploy/chart/databases/templates/redis/redis.yaml b/deploy/chart/databases/templates/redis/redis.yaml index 6b269a6c7ef9991e54000748f8562a15048ac0eb..c9e4d6afca4c93d1bd048397bb2c1fd6a88ed3ea 100644 --- a/deploy/chart/databases/templates/redis/redis.yaml +++ b/deploy/chart/databases/templates/redis/redis.yaml @@ -35,7 +35,7 @@ spec: automountServiceAccountToken: false containers: - name: redis - image: {{ if .Values.databases.redis.image }}{{ .Values.databases.redis.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/redis:7.4-alpine-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.databases.redis.image | default (printf "%s/neocopilot/redis:7.4-alpine-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} command: - redis-server diff --git a/deploy/chart/euler_copilot/templates/framework/framework.yaml b/deploy/chart/euler_copilot/templates/framework/framework.yaml index 33f1862843078ce0945dd55f3ca82826ce69d8de..d5687123df2993963c8415b0e894daece5956e95 100644 --- a/deploy/chart/euler_copilot/templates/framework/framework.yaml +++ b/deploy/chart/euler_copilot/templates/framework/framework.yaml @@ -38,7 +38,7 @@ spec: fsGroup: 1001 containers: - name: framework - image: {{ if .Values.euler_copilot.framework.image }}{{ .Values.euler_copilot.framework.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/euler-copilot-framework:0.9.4-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.framework.image | default (printf "%s/neocopilot/euler-copilot-framework:0.9.4-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 8002 @@ -80,7 +80,7 @@ spec: {{ toYaml .Values.euler_copilot.framework.resourceLimits | nindent 14 }} initContainers: - name: framework-copy - image: {{ if .Values.euler_copilot.secret_inject.image }}{{ .Values.euler_copilot.secret_inject.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/secret_inject:dev-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.secret_inject.image | default (printf "%s/neocopilot/secret_inject:dev-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} volumeMounts: - mountPath: /config/.env diff --git a/deploy/chart/euler_copilot/templates/rag-web/rag-web.yaml b/deploy/chart/euler_copilot/templates/rag-web/rag-web.yaml index a067d48358230224f138a5d175e76e01bbcdad0f..7dcd40c5fa1ddbb678d4254bc7c8c06f8a399688 100644 --- a/deploy/chart/euler_copilot/templates/rag-web/rag-web.yaml +++ b/deploy/chart/euler_copilot/templates/rag-web/rag-web.yaml @@ -56,7 +56,7 @@ spec: automountServiceAccountToken: false containers: - name: rag-web - image: {{ if .Values.euler_copilot.rag_web.image }}{{ .Values.euler_copilot.rag_web.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/data_chain_web:0.9.4-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.rag_web.image | default (printf "%s/neocopilot/data_chain_web:0.9.4-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 9888 diff --git a/deploy/chart/euler_copilot/templates/rag/rag.yaml b/deploy/chart/euler_copilot/templates/rag/rag.yaml index 756609215c99f9f313ac9f4c60df6fc6e393c703..75dbd6ada5b925f90ac612db56e42bc8788db283 100644 --- a/deploy/chart/euler_copilot/templates/rag/rag.yaml +++ b/deploy/chart/euler_copilot/templates/rag/rag.yaml @@ -37,7 +37,7 @@ spec: automountServiceAccountToken: false containers: - name: rag - image: {{ if .Values.euler_copilot.rag.image }}{{ .Values.euler_copilot.rag.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/data_chain_back_end:0.9.4-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.rag.image | default (printf "%s/neocopilot/data_chain_back_end:0.9.4-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 9988 @@ -64,7 +64,7 @@ spec: {{ toYaml .Values.euler_copilot.rag.resourceLimits | nindent 14 }} initContainers: - name: rag-copy-secret - image: {{ if .Values.euler_copilot.secret_inject.image }}{{ .Values.euler_copilot.secret_inject.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/secret_inject:dev-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.secret_inject.image | default (printf "%s/neocopilot/secret_inject:dev-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} volumeMounts: - mountPath: /config/.env diff --git a/deploy/chart/euler_copilot/templates/web/web.yaml b/deploy/chart/euler_copilot/templates/web/web.yaml index e02a99d7a762bf9fc8f5e4a80b479d84c0c76c75..d0dacc4fe51671f637ccd763982dcf8a82b8ac42 100644 --- a/deploy/chart/euler_copilot/templates/web/web.yaml +++ b/deploy/chart/euler_copilot/templates/web/web.yaml @@ -57,7 +57,7 @@ spec: fsGroup: 1001 containers: - name: web - image: {{ if .Values.euler_copilot.web.image }}{{ .Values.euler_copilot.web.image }}{{ else }}{{ .Values.globals.imageRegistry | default "hub.oepkgs.net" }}/neocopilot/euler-copilot-web:0.9.4-{{ .Values.globals.arch | default "x86" }}{{ end }} + image: {{ .Values.euler_copilot.web.image | default (printf "%s/neocopilot/euler-copilot-web:0.9.4-%s" (.Values.globals.imageRegistry | default "hub.oepkgs.net") (ternary "arm" "x86" (eq (.Values.globals.arch | default "x86") "arm"))) }} imagePullPolicy: {{ default "IfNotPresent" .Values.globals.imagePullPolicy }} ports: - containerPort: 8080 diff --git a/deploy/scripts/1-check-env/check_env.sh b/deploy/scripts/1-check-env/check_env.sh old mode 100644 new mode 100755 index 930d73abd771d003436ea445c2fbc9934c3868a7..8d82a926874db25a9e62a18845b03592402242e0 --- a/deploy/scripts/1-check-env/check_env.sh +++ b/deploy/scripts/1-check-env/check_env.sh @@ -144,8 +144,8 @@ function check_ram { } function check_disk { - local DISK_THRESHOLD=50000 - local PERCENT_THRESHOLD=85 + local DISK_THRESHOLD=10000 # 修改为10G(单位:MB) + local PERCENT_THRESHOLD=70 read -r available size <<< $(df -m /var/lib | awk 'NR==2{print $4,$2}') echo -e "${COLOR_INFO}[Info] 磁盘可用空间: ${available}MB, 总大小: ${size}MB${COLOR_RESET}" diff --git a/deploy/scripts/2-install-tools/install_tools.sh b/deploy/scripts/2-install-tools/install_tools.sh old mode 100644 new mode 100755 diff --git a/deploy/scripts/3-install-ollama/install_ollama.sh b/deploy/scripts/3-install-ollama/install_ollama.sh index 368a7adb82042d258580618af5594ed8d5eed661..0e0850d455c6e0c94186dff830dc41579b0ae3cc 100755 --- a/deploy/scripts/3-install-ollama/install_ollama.sh +++ b/deploy/scripts/3-install-ollama/install_ollama.sh @@ -202,7 +202,7 @@ After=network-online.target [Service] Environment="OLLAMA_MODELS=/var/lib/ollama/.ollama/models" -Environment=1"OLLAMA_HOST=0.0.0.0:11434" +Environment="OLLAMA_HOST=0.0.0.0:11434" ExecStart=$OLLAMA_BIN_PATH serve User=ollama Group=ollama diff --git a/deploy/scripts/7-install-authhub/install_authhub.sh b/deploy/scripts/7-install-authhub/install_authhub.sh old mode 100644 new mode 100755 index cc84122471fe445e0cbe3a5fd583c5ee249d6022..3fca42fadec1cb5cecdb12980efe7e2762815963 --- a/deploy/scripts/7-install-authhub/install_authhub.sh +++ b/deploy/scripts/7-install-authhub/install_authhub.sh @@ -1,6 +1,5 @@ #!/bin/bash - set -eo pipefail RED='\033[31m' @@ -26,7 +25,8 @@ get_architecture() { return 1 ;; esac - echo -e "${GREEN}检测到系统架构:$(uname -m)${NC}" + echo -e "${GREEN}检测到系统架构:$(uname -m)${NC}" >&2 + echo "$arch" } create_namespace() { @@ -61,9 +61,9 @@ delete_pvcs() { local pvc_name pvc_name=$(kubectl get pvc -n euler-copilot | grep 'mysql-pvc' 2>/dev/null || true) - if [ -n "$pvc_list" ]; then + if [ -n "$pvc_name" ]; then echo -e "${YELLOW}找到以下PVC,开始清理...${NC}" - kubectl delete pvc mysql-pvc -n euler-copilot --force --grace-period=0 || echo -e "${RED}PVC删除失败,继续执行...${NC}" + kubectl delete pvc mysql-pvc -n euler-copilot --force --grace-period=0 || echo -e "${RED}PVC删除失败,继续执行...${NC}" else echo -e "${YELLOW}未找到需要清理的PVC${NC}" fi @@ -88,6 +88,7 @@ get_user_input() { } helm_install() { + local arch="$1" echo -e "${BLUE}==> 进入部署目录...${NC}" [ ! -d "${DEPLOY_DIR}/chart" ] && { echo -e "${RED}错误:部署目录不存在 ${DEPLOY_DIR}/chart ${NC}" @@ -105,34 +106,38 @@ helm_install() { } check_pods_status() { - echo -e "${BLUE}==> 等待初始化就绪(30秒)...${NC}" + echo -e "${BLUE}==> 等待初始化就绪(30秒)...${NC}" >&2 sleep 30 local timeout=300 local start_time=$(date +%s) - echo -e "${BLUE}开始监控Authhub Pod状态(总超时时间300秒)...${NC}" + echo -e "${BLUE}开始监控Pod状态(总超时时间300秒)...${NC}" >&2 while true; do local current_time=$(date +%s) local elapsed=$((current_time - start_time)) if [ $elapsed -gt $timeout ]; then - echo -e "${RED}错误:部署超时!${NC}" - kubectl get pods -n euler-copilot --selector=app.kubernetes.io/instance=authhub + echo -e "${YELLOW}警告:部署超时!请检查以下资源:${NC}" >&2 + kubectl get pods -n euler-copilot -o wide + echo -e "\n${YELLOW}建议检查:${NC}" + echo "1. 查看未就绪Pod的日志: kubectl logs -n euler-copilot " + echo "2. 检查PVC状态: kubectl get pvc -n euler-copilot" + echo "3. 检查Service状态: kubectl get svc -n euler-copilot" return 1 fi - # 检查所有属于authhub的Pod状态 - local not_running=$(kubectl get pods -n euler-copilot --selector=app.kubernetes.io/instance=authhub -o jsonpath='{range .items[*]}{.metadata.name} {.status.phase}{"\n"}{end}' | grep -v "Running") + local not_running=$(kubectl get pods -n euler-copilot -o jsonpath='{range .items[*]}{.metadata.name} {.status.phase} {.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}' \ + | awk '$2 != "Running" || $3 != "True" {print $1 " " $2}') if [ -z "$not_running" ]; then - echo -e "${GREEN}所有Authhub Pod已正常运行!${NC}" - kubectl get pods -n euler-copilot --selector=app.kubernetes.io/instance=authhub + echo -e "${GREEN}所有Pod已正常运行!${NC}" >&2 + kubectl get pods -n euler-copilot -o wide return 0 else echo "等待Pod就绪(已等待 ${elapsed} 秒)..." - echo "当前异常Pod:" + echo "当前未就绪Pod:" echo "$not_running" | awk '{print " - " $1 " (" $2 ")"}' sleep 10 fi @@ -140,15 +145,20 @@ check_pods_status() { } main() { - get_architecture - create_namespace - delete_pvcs - get_user_input - helm_install - check_pods_status + local arch + arch=$(get_architecture) || exit 1 + create_namespace || exit 1 + delete_pvcs || exit 1 + get_user_input || exit 1 + helm_install "$arch" || exit 1 + check_pods_status || { + echo -e "${RED}部署失败:Pod状态检查未通过!${NC}" + exit 1 + } echo -e "\n${GREEN}=========================" - echo "Authhub 部署完成!" + echo -e "Authhub 部署完成!" + echo -e "查看pod状态:kubectl get pod -n euler-copilot" echo -e "Authhub登录地址为: https://${authhub_domain}" echo -e "默认账号密码: administrator/changeme" echo -e "=========================${NC}" @@ -156,4 +166,3 @@ main() { trap 'echo -e "${RED}操作被中断!${NC}"; exit 1' INT main "$@" - diff --git a/deploy/scripts/8-install-EulerCopilot/install_eulercopilot.sh b/deploy/scripts/8-install-EulerCopilot/install_eulercopilot.sh old mode 100644 new mode 100755 index 64bad6ec12622a7c35198e938684382401c55cc4..5d18df1916ba4ba1686e1593a935f1af0ab022de --- a/deploy/scripts/8-install-EulerCopilot/install_eulercopilot.sh +++ b/deploy/scripts/8-install-EulerCopilot/install_eulercopilot.sh @@ -14,21 +14,17 @@ PLUGINS_DIR="/home/eulercopilot/semantics" # 获取系统架构 get_architecture() { - local arch - arch=$(uname -m) + local arch=$(uname -m) case "$arch" in - x86_64) - arch="x86" - ;; - aarch64) - arch="arm" - ;; + x86_64) arch="x86" ;; + aarch64) arch="arm" ;; *) echo -e "${RED}错误:不支持的架构 $arch${NC}" >&2 return 1 ;; esac - echo -e "${GREEN}检测到系统架构:$(uname -m)${NC}" >&2 + echo -e "${GREEN}检测到系统架构:${arch} (原始标识: $(uname -m))${NC}" >&2 + echo "$arch" } # 自动检测业务网口 @@ -68,65 +64,93 @@ get_network_ip() { echo "$host" } -get_client_info() { - # 调用Python脚本并捕获标准输出和标准错误 - output=$(python3 "${DEPLOY_DIR}/scripts/9-other-script/get_client_id_and_secret.py") - exit_code=$? - - # 检查执行结果 - if [ $exit_code -ne 0 ]; then - echo -e "${RED}获取客户端凭证失败:${output}${NC}" >&2 - exit 1 +get_client_info_auto() { + # 自动生成客户端名称(格式:client_随机8位字符) + local client_name="client_$(openssl rand -hex 4 | cut -c1-8)" + + # 生成输入应答(使用随机生成的client_name) + { + echo "$client_name" # 客户端名称(使用随机生成值) + echo "" # client_url(回车使用默认) + echo "" # redirect_urls(回车使用默认) + } | python3 "${DEPLOY_DIR}/scripts/9-other-script/get_client_id_and_secret.py" > client_info.tmp 2>&1 + + # 检查Python脚本执行结果 + if [ $? -ne 0 ]; then + echo -e "${RED}错误:Python脚本执行失败${NC}" + cat client_info.tmp fi - # 解析输出结果 - client_id=$(echo "$output" | grep "client_id: " | awk '{print $2}') - client_secret=$(echo "$output" | grep "client_secret: " | awk '{print $2}') + # 提取凭证信息(保持原有逻辑) + client_id=$(grep "client_id: " client_info.tmp | awk '{print $2}') + client_secret=$(grep "client_secret: " client_info.tmp | awk '{print $2}') + rm -f client_info.tmp - # 验证结果 + # 验证结果(保持原有逻辑) if [ -z "$client_id" ] || [ -z "$client_secret" ]; then echo -e "${RED}错误:无法获取有效的客户端凭证${NC}" >&2 - exit 1 fi - echo "==============================" - echo "Client ID: $client_id" - echo "Client Secret: $client_secret" - echo "==============================" + # 输出结果(保持原有格式) + echo -e "${GREEN}==============================${NC}" + echo -e "${GREEN}Client ID: ${client_id}${NC}" + echo -e "${GREEN}Client Secret: ${client_secret}${NC}" + echo -e "${GREEN}==============================${NC}" } -get_user_input() { - # 处理Copilot域名 - echo -e "${BLUE}请输入 EulerCopilot 域名(直接回车使用默认值 www.eulercopilot.local):${NC}" - read -p "EulerCopilot 的前端域名: " eulercopilot_domain +get_client_info_manual() { - if [[ -z "$eulercopilot_domain" ]]; then - eulercopilot_domain="www.eulercopilot.local" - echo -e "${GREEN}使用默认域名:${eulercopilot_domain}${NC}" - else - if ! [[ "${eulercopilot_domain}" =~ ^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$ ]]; then - echo -e "${RED}错误:输入的EulerCopilot域名格式不正确${NC}" >&2 - exit 1 - fi - echo -e "${GREEN}输入域名:${eulercopilot_domain}${NC}" + # 非交互模式直接使用默认值 + if [ -t 0 ]; then # 仅在交互式终端显示提示 + echo -e "${BLUE}请输入 Client ID: 域名(端点信息:Client ID): ${NC}" + read -p "> " input_id + [ -n "$input_id" ] && client_id=$input_id + + echo -e "${BLUE}请输入 Client Secret: 域名(端点信息:Client Secret):${NC}" + read -p "> " input_secret + [ -n "$input_secret" ] && client_secret=$input_secret fi - # 处理Authhub域名 - echo -e "${BLUE}请输入 Authhub 的域名配置(直接回车使用默认值 authhub.eulercopilot.local):${NC}" - read -p "Authhub 的前端域名: " authhub_domain - if [[ -z "$authhub_domain" ]]; then - authhub_domain="authhub.eulercopilot.local" - echo -e "${GREEN}使用默认域名:${authhub_domain}${NC}" - else - if ! [[ "${authhub_domain}" =~ ^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$ ]]; then - echo -e "${RED}错误:输入的AuthHub域名格式不正确${NC}" >&2 - exit 1 - fi - echo -e "${GREEN}输入域名:${authhub_domain}${NC}" + # 统一验证域名格式 + echo -e "${GREEN}使用配置:" + echo "Client ID: $client_id" + echo "Client Secret: $client_secret" + +} +# # 处理域名 +get_domain_input() { + # 从环境变量读取或使用默认值 + eulercopilot_domain=${EULERCOPILOT_DOMAIN:-"www.eulercopilot.local"} + authhub_domain=${AUTHHUB_DOMAIN:-"authhub.eulercopilot.local"} + + # 非交互模式直接使用默认值 + if [ -t 0 ]; then # 仅在交互式终端显示提示 + echo -e "${BLUE}请输入 EulerCopilot 域名(默认:$eulercopilot_domain):${NC}" + read -p "> " input_euler + [ -n "$input_euler" ] && eulercopilot_domain=$input_euler + + echo -e "${BLUE}请输入 Authhub 域名(默认:$authhub_domain):${NC}" + read -p "> " input_auth + [ -n "$input_auth" ] && authhub_domain=$input_auth + fi + + # 统一验证域名格式 + local domain_regex='^([a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,}$' + if ! [[ $eulercopilot_domain =~ $domain_regex ]]; then + echo -e "${RED}错误:EulerCopilot域名格式不正确${NC}" >&2 + exit 1 + fi + if ! [[ $authhub_domain =~ $domain_regex ]]; then + echo -e "${RED}错误:AuthHub域名格式不正确${NC}" >&2 + exit 1 fi + + echo -e "${GREEN}使用配置:" + echo "EulerCopilot域名: $eulercopilot_domain" + echo "Authhub域名: $authhub_domain" } -# 检查必要目录 +# 检查语义接口是否存在 check_directories() { echo -e "${BLUE}检查语义接口目录是否存在...${NC}" >&2 if [ -d "${PLUGINS_DIR}" ]; then @@ -141,7 +165,7 @@ check_directories() { fi } -# 安装前检查并删除已有部署 +# 检查是否存在已经部署的EulerCopilot check_and_delete_existing_deployment() { echo -e "${YELLOW}检查是否存在已部署的euler-copilot...${NC}" >&2 if helm list -n euler-copilot --short | grep -q "^euler-copilot$"; then @@ -158,7 +182,7 @@ check_and_delete_existing_deployment() { fi } -# 修改YAML配置文件的方法 +# 修改配置文件 modify_yaml() { local host=$1 echo -e "${BLUE}开始修改YAML配置文件...${NC}" >&2 @@ -183,7 +207,7 @@ modify_yaml() { echo -e "${GREEN}YAML文件修改成功!${NC}" >&2 } -# 进入Chart目录的方法 +# 检查目录 enter_chart_directory() { echo -e "${BLUE}进入Chart目录...${NC}" >&2 cd "${DEPLOY_DIR}/chart/" || { @@ -192,19 +216,20 @@ enter_chart_directory() { } } -# 执行Helm安装的方法 +# 执行安装 execute_helm_install() { local arch=$1 - echo -e "${BLUE}开始部署EulerCopilot...${NC}" >&2 + echo -e "${BLUE}开始部署EulerCopilot(架构: $arch)...${NC}" >&2 + enter_chart_directory - helm upgrade --install euler-copilot -n euler-copilot ./euler_copilot \ - --set globals.arch="$arch" || { + helm upgrade --install euler-copilot -n euler-copilot ./euler_copilot --set globals.arch=$arch --create-namespace || { echo -e "${RED}Helm 安装 EulerCopilot 失败!${NC}" >&2 exit 1 } echo -e "${GREEN}Helm安装EulerCopilot成功!${NC}" >&2 } +# 检查pod状态 check_pods_status() { echo -e "${BLUE}==> 等待初始化就绪(30秒)...${NC}" >&2 sleep 30 @@ -218,68 +243,73 @@ check_pods_status() { local current_time=$(date +%s) local elapsed=$((current_time - start_time)) - # 超时处理逻辑 if [ $elapsed -gt $timeout ]; then - echo -e "${YELLOW}警告:部署超时!请检查以下Pod状态:${NC}" >&2 - kubectl get pods -n euler-copilot + echo -e "${YELLOW}警告:部署超时!请检查以下资源:${NC}" >&2 + kubectl get pods -n euler-copilot -o wide + echo -e "\n${YELLOW}建议检查:${NC}" + echo "1. 查看未就绪Pod的日志: kubectl logs -n euler-copilot " + echo "2. 检查PVC状态: kubectl get pvc -n euler-copilot" + echo "3. 检查Service状态: kubectl get svc -n euler-copilot" return 1 fi - # 检查所有Pod状态 - local not_running - not_running=$(kubectl get pods -n euler-copilot -o jsonpath='{range .items[*]}{.metadata.name} {.status.phase} {.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}' \ + local not_running=$(kubectl get pods -n euler-copilot -o jsonpath='{range .items[*]}{.metadata.name} {.status.phase} {.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}' \ | awk '$2 != "Running" || $3 != "True" {print $1 " " $2}') if [ -z "$not_running" ]; then echo -e "${GREEN}所有Pod已正常运行!${NC}" >&2 - kubectl get pods -n euler-copilot + kubectl get pods -n euler-copilot -o wide return 0 else echo "等待Pod就绪(已等待 ${elapsed} 秒)..." - echo "当前未启动Pod:" + echo "当前未就绪Pod:" echo "$not_running" | awk '{print " - " $1 " (" $2 ")"}' sleep 10 fi done } -# 主函数执行各个步骤 main() { local arch host arch=$(get_architecture) || exit 1 host=$(get_network_ip) || exit 1 - if ! get_client_info; then - echo -e "${RED}获取客户端信息失败${NC}" - exit 1 + if not get_client_info_auto; then + echo -e "${YELLOW}需要手动登录Authhub域名并创建应用,获取client信息${NC}" + get_client_info_manual fi - get_user_input + get_domain_input check_directories check_and_delete_existing_deployment modify_yaml "$host" execute_helm_install "$arch" - # Pod状态检查并处理结果 if check_pods_status; then echo -e "${GREEN}所有组件已就绪!${NC}" else - echo -e "${YELLOW}注意:部分组件尚未就绪,可稍后手动检查${NC}" >&2 + echo -e "${YELLOW}注意:部分组件尚未就绪,请根据上述建议进行排查${NC}" >&2 fi # 最终部署信息输出 echo -e "\n${GREEN}==================================================${NC}" echo -e "${GREEN} EulerCopilot 部署完成! ${NC}" echo -e "${GREEN}==================================================${NC}" - echo -e "${YELLOW}EulerCopilot访问地址:\thttps://${eulercopilot_domain}${NC}" - echo -e "${YELLOW}AuthHub管理地址:\thttps://${authhub_domain}${NC}" - echo -e "${YELLOW}插件目录:\t\t${PLUGINS_DIR}${NC}" - echo -e "${YELLOW}Chart目录:\t${DEPLOY_DIR}/chart/${NC}" - echo - echo -e "${BLUE}温馨提示:" - echo -e "${BLUE}1. 请确保域名已正确解析到集群Ingress地址${NC}" - echo -e "${BLUE}2. 首次拉取RAG镜像可能需要约1-3分钟,Pod会稍后自动启动${NC}" - echo -e "${BLUE}3. 查看实时状态:kubectl get pods -n euler-copilot${NC}" - echo -e "${BLUE}4. 查看镜像:k3s crictl images${NC}" + echo -e "${YELLOW}访问地址:" + echo -e "EulerCopilot UI:\thttps://${eulercopilot_domain}" + echo -e "AuthHub 管理界面:\thttps://${authhub_domain}" + echo -e "\n${YELLOW}系统信息:" + echo -e "业务网络IP:\t${host}" + echo -e "系统架构:\t$(uname -m) (识别为: ${arch})" + echo -e "插件目录:\t${PLUGINS_DIR}" + echo -e "Chart目录:\t${DEPLOY_DIR}/chart/${NC}" + echo -e "" + echo -e "${BLUE}操作指南:" + echo -e "1. 查看集群状态: kubectl get all -n euler-copilot" + echo -e "2. 查看实时日志: kubectl logs -n euler-copilot -f deployment/euler-copilot" + echo -e "3. 查看POD状态:kubectl get pods -n euler-copilot" + echo -e "4. 查看数据库并使用base64密码:kubectl edit secret euler-copilot-system -n euler-copilot" + echo -e "5. 添加域名解析(示例):" + echo -e " ${host} ${eulercopilot_domain}" + echo -e " ${host} ${authhub_domain}${NC}" } -# 调用主函数 main diff --git a/deploy/scripts/9-other-script/get_client_id_and_secret.py b/deploy/scripts/9-other-script/get_client_id_and_secret.py index 49644f86c9111782950e3a904c3549a9620b1513..19638beca143b50a8640c1f6349666241f77a038 100755 --- a/deploy/scripts/9-other-script/get_client_id_and_secret.py +++ b/deploy/scripts/9-other-script/get_client_id_and_secret.py @@ -13,108 +13,121 @@ urllib3.disable_warnings() def get_service_cluster_ip(namespace, service_name): cmd = ["kubectl", "get", "service", service_name, "-n", namespace, "-o", "json"] result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - # 增强错误处理 + if result.returncode != 0: error_msg = result.stderr.decode().strip() print(f"获取服务信息失败: [命名空间: {namespace}] [服务名: {service_name}]") print(f"Kubectl错误详情: {error_msg}") - # 常见错误提示 if "NotFound" in error_msg: print("→ 请检查:") - print(" 1. 服务是否部署完成(kubectl get pods -n {namespace})") + print(f" 1. 服务是否部署完成(kubectl get pods -n {namespace})") print(" 2. 服务名称是否拼写正确") print(" 3. 是否在正确的Kubernetes上下文环境中") - - # 解析JSON输出 - service_info = json.loads(result.stdout.decode()) - - # 从解析后的JSON中获取Cluster IP - cluster_ip = service_info['spec'].get('clusterIP', 'No Cluster IP found') - - return cluster_ip + sys.exit(1) + service_info = json.loads(result.stdout.decode()) + return service_info['spec'].get('clusterIP', 'No Cluster IP found') def get_user_token(auth_hub_url, username="administrator", password="changeme"): url = auth_hub_url + "/oauth2/manager-login" - payload = { - "password": password, - "username": username, - } - headers = { - "Content-Type": "application/json", - } - response = requests.post(url, data=json.dumps(payload), headers=headers, verify=False) - if response.status_code == 200: - user_token = response.json()["data"]["user_token"] - return user_token - -def register_app(auth_hub_url, user_token, client_name, client_url, redierct_urls): - url = auth_hub_url + "/oauth2/applications/register" - payload = { - "client_name":client_name, - "client_uri":client_url, - "redirect_uris":redierct_urls, - "skip_authorization":True, - "register_callback_uris":[], - "logout_callback_uris":[], - "scope":["email","phone","username","openid","offline_access"], - "grant_types":["authorization_code"], - "response_types":["code"], - "token_endpoint_auth_method":"none" - } - headers = { - "Authorization": user_token, - "Content-Type": "application/json" - } - response = requests.post(url, json=payload, headers=headers) - return response.json() - - -def get_client_secret(auth_hub_url, user_token): # 修改参数列表 - url = auth_hub_url + "/oauth2/applications" - headers = { - "Authorization": user_token, - "Content-Type": "application/json" - } - response = requests.get(url, headers=headers) - for app in response.json()['data']["applications"]: - if app["client_metadata"]["client_name"] == "EulerCopilot": + response = requests.post( + url, + json={"password": password, "username": username}, + headers={"Content-Type": "application/json"}, + verify=False, + timeout=10 + ) + response.raise_for_status() + return response.json()["data"]["user_token"] + + +def register_app(auth_hub_url, user_token, client_name, client_url, redirect_urls): + requests.post( + auth_hub_url + "/oauth2/applications/register", + json={ + "client_name": client_name, + "client_uri": client_url, + "redirect_uris": redirect_urls, + "skip_authorization": True, + "scope": ["email", "phone", "username", "openid", "offline_access"], + "grant_types": ["authorization_code"], + "response_types": ["code"], + "token_endpoint_auth_method": "none" + }, + headers={"Authorization": user_token, "Content-Type": "application/json"} + ) + + +def get_client_secret(auth_hub_url, user_token, target_client_name): + response = requests.get( + auth_hub_url + "/oauth2/applications", + headers={"Authorization": user_token, "Content-Type": "application/json"}, + timeout=10 + ) + response.raise_for_status() + apps_data = response.json() + + for app in apps_data["data"]["applications"]: + # 处理 client_metadata 字段 + client_metadata = app.get("client_metadata") or {} + if isinstance(client_metadata, str): + try: + client_metadata = json.loads(client_metadata) + except json.JSONDecodeError: + client_metadata = {} + + # 优先从 client_metadata 获取名称 + candidate_names = [ + client_metadata.get("client_name"), + app.get("client_name"), + app.get("client_info", {}).get("client_name") + ] + + # 调试输出关键信息 + print(f"\n匹配进度 | 候选名称: {candidate_names} | 目标名称: {target_client_name}") + + # 不区分大小写匹配 + if any(str(name).lower() == target_client_name.lower() for name in candidate_names if name): return { "client_id": app["client_info"]["client_id"], "client_secret": app["client_info"]["client_secret"] } - return {"error": "Application not found"} + + raise ValueError(f"未找到匹配应用,请检查 client_name 是否准确(尝试使用全小写名称)") + if __name__ == "__main__": + # 获取服务信息 namespace = "euler-copilot" service_name = "authhub-web-service" - print(f"正在查询服务信息: [命名空间: {namespace}] [服务名: {service_name}]") cluster_ip = get_service_cluster_ip(namespace, service_name) - - # 增加更明确的错误提示 - if not cluster_ip or cluster_ip == 'No Cluster IP found': - print(f"无法获取ClusterIP,可能原因:") - print("1. 服务类型不是ClusterIP(可能是NodePort/LoadBalancer)") - print("2. 服务尚未分配IP(查看状态: kubectl get svc/{service_name} -n {namespace} -w)") - sys.exit(1) - auth_hub_url = f"http://{cluster_ip}:8000" - user_token = get_user_token(auth_hub_url) + + # 用户输入 + print("\n请填写应用注册信息(直接回车使用默认值)") + client_name = input("请输入 client_name (默认:EulerCopilot):").strip() or "EulerCopilot" + client_url = input("请输入 client_url (默认:https://www.eulercopilot.local):").strip() or "https://www.eulercopilot.local" - # 注册应用 - client_name = "EulerCopilot" - client_url = "https://www.eulercopilot.local" - redirect_urls = ["https://www.eulercopilot.local/api/auth/login"] - register_app(auth_hub_url, user_token, client_name, client_url, redirect_urls) + redirect_input = input( + "请输入 redirect_urls (逗号分隔,默认:https://www.eulercopilot.local/api/auth/login):" + ).strip() + redirect_urls = [url.strip() for url in redirect_input.split(",")] if redirect_input else [ + "https://www.eulercopilot.local/api/auth/login" + ] + + # 认证流程 + try: + user_token = get_user_token(auth_hub_url) + register_app(auth_hub_url, user_token, client_name, client_url, redirect_urls) + client_info = get_client_secret(auth_hub_url, user_token, client_name) + + print("\n认证信息获取成功:") + print(f"client_id: {client_info['client_id']}") + print(f"client_secret: {client_info['client_secret']}") - # 获取客户端凭证 - client_info = get_client_secret(auth_hub_url, user_token) # 传递user_token - if "error" in client_info: - print(client_info["error"]) + except Exception as e: + print(f"\n错误: {str(e)}") sys.exit(1) - - print(f"client_id: {client_info['client_id']}") - print(f"client_secret: {client_info['client_secret']}") diff --git a/deploy/scripts/9-other-script/install_oidc_eulercopilot.sh b/deploy/scripts/9-other-script/install_oidc_eulercopilot.sh old mode 100644 new mode 100755 diff --git a/deploy/scripts/9-other-script/modify_eulercopilot_yaml.py b/deploy/scripts/9-other-script/modify_eulercopilot_yaml.py index 0f474a578e04ef366989a7a4c82af18075038610..d8e70eba9f9b03e553308649d7c892b373afa53d 100755 --- a/deploy/scripts/9-other-script/modify_eulercopilot_yaml.py +++ b/deploy/scripts/9-other-script/modify_eulercopilot_yaml.py @@ -1,13 +1,36 @@ -import argparse import sys +import argparse +import subprocess +# 尝试导入 YAML 库 try: from ruamel.yaml import YAML from ruamel.yaml.comments import CommentedMap USING_RUAMEL = True except ImportError: - import yaml # PyYAML - USING_RUAMEL = False + try: + import yaml # 回退到 PyYAML + USING_RUAMEL = False + except ImportError: + print("未检测到 YAML 处理库,正在自动安装 ruamel.yaml...") + try: + # 优先尝试安装 ruamel.yaml + subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'ruamel.yaml']) + from ruamel.yaml import YAML + from ruamel.yaml.comments import CommentedMap + USING_RUAMEL = True + print("ruamel.yaml 安装成功") + except Exception as e: + print(f"安装 ruamel.yaml 失败: {e}, 改为尝试安装 PyYAML") + try: + # 回退安装 PyYAML + subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'PyYAML']) + import yaml + USING_RUAMEL = False + print("PyYAML 安装成功") + except Exception as e: + print(f"安装 PyYAML 也失败: {e}") + sys.exit(1) def parse_value(value): """智能转换值的类型"""