| @@ -50,6 +50,11 @@ Thumbs.db | |||
| mvnw.cmd | |||
| mvnw | |||
| # Files or folders need to be retained | |||
| # ... | |||
| /k8s/template-yaml/deploy/ | |||
| /k8s/dockerfiles/html/ | |||
| /k8s/dockerfiles/jar | |||
| # web | |||
| **/node_modules | |||
| @@ -0,0 +1,84 @@ | |||
| # cat nexus3/nexus3.yaml | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| labels: | |||
| k8s-app: ci4s-nexus3 | |||
| name: ci4s-nexus3 | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| k8s-app: ci4s-nexus3 | |||
| template: | |||
| metadata: | |||
| labels: | |||
| k8s-app: ci4s-nexus3 | |||
| name: ci4s-nexus3 | |||
| namespace: ci4s-test | |||
| spec: | |||
| containers: | |||
| - name: ci4s-nexus3 | |||
| image: sonatype/nexus3:3.29.2 | |||
| imagePullPolicy: IfNotPresent | |||
| env: | |||
| - name: http_proxy | |||
| value: http://172.20.32.253:3128 | |||
| - name: https_proxy | |||
| value: http://172.20.32.253:3128 | |||
| ports: | |||
| - containerPort: 8081 | |||
| name: web | |||
| protocol: TCP | |||
| livenessProbe: | |||
| httpGet: | |||
| path: / | |||
| port: 8081 | |||
| initialDelaySeconds: 540 | |||
| periodSeconds: 30 | |||
| failureThreshold: 6 | |||
| readinessProbe: | |||
| httpGet: | |||
| path: / | |||
| port: 8081 | |||
| initialDelaySeconds: 540 | |||
| periodSeconds: 30 | |||
| failureThreshold: 6 | |||
| # resources: | |||
| # limits: | |||
| # cpu: 1000m | |||
| # memory: 2Gi | |||
| # requests: | |||
| # cpu: 500m | |||
| # memory: 512Mi | |||
| volumeMounts: | |||
| - name: nexus-data | |||
| mountPath: /nexus-data | |||
| volumes: | |||
| - name: nexus-data | |||
| persistentVolumeClaim: | |||
| claimName: ci4s-nexus-data-pvc | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: nexus3 | |||
| namespace: ci4s-test | |||
| labels: | |||
| k8s-app: nexus3 | |||
| spec: | |||
| selector: | |||
| k8s-app: nexus3 | |||
| type: NodePort | |||
| ports: | |||
| - name: web | |||
| protocol: TCP | |||
| port: 8081 | |||
| targetPort: 8081 | |||
| nodePort: 31211 | |||
| - name: dockerpod | |||
| protocol: TCP | |||
| port: 8082 | |||
| targetPort: 8082 | |||
| nodePort: 31212 | |||
| @@ -0,0 +1,13 @@ | |||
| --- | |||
| apiVersion: v1 | |||
| kind: PersistentVolumeClaim | |||
| metadata: | |||
| name: ci4s-nexus-data-pvc | |||
| namespace: ci4s-test | |||
| spec: | |||
| accessModes: | |||
| - ReadWriteMany | |||
| storageClassName: "storage-nfs" | |||
| resources: | |||
| requests: | |||
| storage: 500Gi | |||
| @@ -0,0 +1,33 @@ | |||
| #!/bin/bash | |||
| baseDir="/home/somuns/ci4s" | |||
| #判断$1是否为all,如果是,则编译所有模块,否则只编译management-platform模块 | |||
| if [ "$1" == "all" ]; then | |||
| buildDir=$baseDir | |||
| elif [ "$1" == "manage" ]; then | |||
| buildDir="$baseDir/ruoyi-modules/management-platform" | |||
| elif [ "$1" == "auth" ]; then | |||
| buildDir="$baseDir/ruoyi-auth" | |||
| elif [ "$1" == "gateway" ]; then | |||
| buildDir="$baseDir/ruoyi-gateway" | |||
| elif [ "$1" == "system" ]; then | |||
| buildDir="$baseDir/ruoyi-modules/ruoyi-system" | |||
| fi | |||
| echo "Building $buildDir" | |||
| cd $buildDir && mvn clean install | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to build ruoyi-modules" | |||
| exit 1 | |||
| fi | |||
| @@ -0,0 +1,25 @@ | |||
| #!/bin/bash | |||
| baseDir="/home/somuns/ci4s" | |||
| #判断$1是否为all,如果是,则编译所有模块,否则只编译management-platform模块 | |||
| if [ "$1" == "all" ]; then | |||
| buildDir=$baseDir | |||
| else | |||
| buildDir="$baseDir/ruoyi-modules/management-platform" | |||
| fi | |||
| echo "Building $buildDir" | |||
| cd $buildDir && mvn clean install | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to build ruoyi-modules" | |||
| exit 1 | |||
| fi | |||
| @@ -0,0 +1,25 @@ | |||
| #!/bin/bash | |||
| baseDir="/home/somuns/ci4s" | |||
| cd ${baseDir}/react-ui | |||
| npm config set registry https://registry.npmmirror.com/ | |||
| npm config set proxy http://172.20.32.253:3128 | |||
| npm config set https-proxy http://172.20.32.253:3128 | |||
| npm install --force | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to install npm depend package" | |||
| exit 1 | |||
| fi | |||
| npm run build | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to build react-ui" | |||
| exit 1 | |||
| fi | |||
| @@ -0,0 +1,21 @@ | |||
| #!/bin/bash | |||
| baseDir="/home/somuns/ci4s" | |||
| cd ${baseDir}/react-ui | |||
| npm install | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to install npm depend package" | |||
| exit 1 | |||
| fi | |||
| npm run build | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to build react-ui" | |||
| exit 1 | |||
| fi | |||
| @@ -0,0 +1,141 @@ | |||
| #!/bin/bash | |||
| #记录开始时间 | |||
| start=$(date +%s) | |||
| # 默认参数 | |||
| branch="master" | |||
| service="manage-front" | |||
| show_help() { | |||
| echo "Usage: $0 [-b branch] [-s service]" | |||
| echo | |||
| echo "Options:" | |||
| echo " -b Branch to deploy, default is master" | |||
| echo " -s Service to deploy (manage-front, manage, front, all, default is manage-front)" | |||
| echo " -h Show this help message" | |||
| } | |||
| # 解析命令行选项 | |||
| while getopts "b:s:h" opt; do | |||
| case $opt in | |||
| b) branch=$OPTARG ;; | |||
| s) service=$OPTARG ;; | |||
| h) show_help; exit 0 ;; | |||
| \?) echo "Invalid option -$OPTARG" >&2; show_help; exit 1 ;; | |||
| esac | |||
| done | |||
| echo "branch: $branch" | |||
| echo "service: $service" | |||
| valid_services=("manage-front" "manage" "front" "all" "auth" "gateway" "system") | |||
| if [[ ! " ${valid_services[@]} " =~ " $service " ]]; then | |||
| echo "Invalid service name: $service" >&2 | |||
| echo "Valid services are: ${valid_services[*]}" | |||
| exit 1 | |||
| fi | |||
| # 登录到目标环境 | |||
| baseDir="/home/somuns/ci4s" | |||
| cd ${baseDir} | |||
| # 创建目录 | |||
| mkdir -p ${baseDir}/k8s/dockerfiles/jar | |||
| mkdir -p ${baseDir}/k8s/dockerfiles/html | |||
| compile_front() { | |||
| # 清理前端构建文件 | |||
| if [ -d "${baseDir}/react-ui/dist" ]; then | |||
| rm -rf ${baseDir}/react-ui/dist | |||
| fi | |||
| # 编译前端 | |||
| docker run -v ${baseDir}:${baseDir} \ | |||
| -e http_proxy=http://172.20.32.253:3128 -e https_proxy=http://172.20.32.253:3128 \ | |||
| 172.20.32.187/ci4s/node:16.16.0 ${baseDir}/k8s/build-node.sh | |||
| if [ $? -ne 0 ]; then | |||
| echo "编译失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| # 复制前端文件 | |||
| cp -rf ${baseDir}/react-ui/dist/ ${baseDir}/k8s/dockerfiles/html | |||
| if [ $? -ne 0 ]; then | |||
| echo "复制html文件失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| } | |||
| compile_java() { | |||
| param=$1 | |||
| # 编译java | |||
| docker run -v ${baseDir}:${baseDir} -v /home/maven:/home/maven \ | |||
| -e http_proxy=http://172.20.32.253:3128 -e https_proxy=http://172.20.32.253:3128 \ | |||
| 172.20.32.187/ci4s/build:v3 ${baseDir}/k8s/build-java.sh $param | |||
| if [ $? -ne 0 ]; then | |||
| echo "编译失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| # 复制jar包 | |||
| cp -rf ${baseDir}/ruoyi-modules/management-platform/target/management-platform.jar ${baseDir}/k8s/dockerfiles/jar/management-platform.jar | |||
| if [ $? -ne 0 ]; then | |||
| echo "复制jar包失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| if [ "$param" == "all" ]; then | |||
| cp -rf ${baseDir}/ruoyi-modules/ruoyi-system/target/ruoyi-modules-system.jar ${baseDir}/k8s/dockerfiles/jar/ruoyi-modules-system.jar | |||
| if [ $? -ne 0 ]; then | |||
| echo "复制jar包失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| cp -rf ${baseDir}/ruoyi-auth/target/ruoyi-auth.jar ${baseDir}/k8s/dockerfiles/jar/ruoyi-auth.jar | |||
| if [ $? -ne 0 ]; then | |||
| echo "复制jar包失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| cp -rf ${baseDir}/ruoyi-gateway/target/ruoyi-gateway.jar ${baseDir}/k8s/dockerfiles/jar/ruoyi-gateway.jar | |||
| if [ $? -ne 0 ]; then | |||
| echo "复制jar包失败,请检查代码!" | |||
| exit 1 | |||
| fi | |||
| fi | |||
| } | |||
| if [ "$service" == "front" ]; then | |||
| # 编译前端 | |||
| compile_front | |||
| fi | |||
| if [ "$service" == "manage-front" ]; then | |||
| # 编译前端 | |||
| compile_front | |||
| # 编译java | |||
| compile_java "manage" | |||
| fi | |||
| if [ "$service" != "manage-front" ] && [ "$service" != "all" ] && [ "$service" != "front" ]; then | |||
| # 编译java | |||
| compile_java $service | |||
| fi | |||
| if [ "$service" == "all" ]; then | |||
| # 编译前端 | |||
| compile_front | |||
| # 编译java | |||
| compile_java "all" | |||
| fi | |||
| # 记录结束时间 | |||
| end=$(date +%s) | |||
| #计算运行时间 | |||
| runtime=$((end-start)) | |||
| echo "编译成功,耗时:$runtime 秒" | |||
| @@ -0,0 +1,92 @@ | |||
| #!/bin/bash | |||
| #记录开始时间 | |||
| startTime=$(date +%s) | |||
| # 登录到目标环境 | |||
| baseDir="/home/somuns/ci4s" | |||
| cd ${baseDir} | |||
| #build | |||
| # 默认参数 | |||
| branch="master" | |||
| service="manage-front" | |||
| env="dev" | |||
| # | |||
| show_help() { | |||
| echo "Usage: $0 [-b branch] [-s service] [-e environment]" | |||
| echo | |||
| echo "Options:" | |||
| echo " -b Branch to deploy, default: master" | |||
| echo " -s Service to deploy (manage-front, manage, front, all, default: manage-front)" | |||
| echo " -e Environment (e.g., dev, test, default: dev)" | |||
| echo " -h Show this help message" | |||
| } | |||
| # 解析命令行选项 | |||
| while getopts "b:s:e:h" opt; do | |||
| case $opt in | |||
| b) branch=$OPTARG ;; | |||
| s) service=$OPTARG ;; | |||
| e) env=$OPTARG ;; | |||
| h) show_help; exit 0 ;; | |||
| \?) echo "Invalid option -$OPTARG" >&2; show_help; exit 1 ;; | |||
| esac | |||
| done | |||
| # 拉取指定分支的最新代码 | |||
| echo "Checking out and pulling branch $branch..." | |||
| git stash | |||
| git checkout $branch | |||
| if [ $? -ne 0 ]; then | |||
| echo "切换到分支 $branch 失败,请检查分支名称是否正确!" | |||
| exit 1 | |||
| fi | |||
| git stash | |||
| git pull origin $branch | |||
| if [ $? -ne 0 ]; then | |||
| echo "拉取代码失败,请检查网络或联系管理员!" | |||
| exit 1 | |||
| fi | |||
| chmod +777 ${baseDir}/k8s/*.sh | |||
| valid_services=("manage-front" "manage" "front" "all" "auth" "gateway" "system") | |||
| if [[ ! " ${valid_services[@]} " =~ " $service " ]]; then | |||
| echo "Invalid service name: $service" >&2 | |||
| echo "Valid services are: ${valid_services[*]}" | |||
| exit 1 | |||
| fi | |||
| valid_envs=("dev" "test") | |||
| if [[ ! " ${valid_envs[@]} " =~ " $env " ]]; then | |||
| echo "Invalid environment: $env" >&2 | |||
| echo "Valid environments are: ${valid_envs[*]}" | |||
| exit 1 | |||
| fi | |||
| echo "start build" | |||
| sh ${baseDir}/k8s/build.sh -b ${branch} -s ${service} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Build failed" | |||
| exit 1 | |||
| fi | |||
| echo "build success" | |||
| # 部署 | |||
| echo "start deploy" | |||
| sh ${baseDir}/k8s/deploy.sh -s ${service} -e ${env} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Deploy failed" | |||
| exit 1 | |||
| fi | |||
| echo "deploy success" | |||
| # 记录结束时间 | |||
| endTime=$(date +%s) | |||
| # 计算运行时间 | |||
| duration=$(( $endTime - $startTime )) | |||
| echo "编译发布总耗时: $duration 秒" | |||
| @@ -0,0 +1,74 @@ | |||
| #!/bin/bash | |||
| #记录开始时间 | |||
| startTime=$(date +%s) | |||
| # 登录到目标环境 | |||
| baseDir="/home/somuns/ci4s" | |||
| cd ${baseDir} | |||
| #build | |||
| # 默认参数 | |||
| branch="master" | |||
| service="manage-front" | |||
| env="dev" | |||
| # | |||
| show_help() { | |||
| echo "Usage: $0 [-b branch] [-s service] [-e environment]" | |||
| echo | |||
| echo "Options:" | |||
| echo " -b Branch to deploy, default: master" | |||
| echo " -s Service to deploy (manage-front, manage, front, all, default: manage-front)" | |||
| echo " -e Environment (e.g., dev, test, default: dev)" | |||
| echo " -h Show this help message" | |||
| } | |||
| # 解析命令行选项 | |||
| while getopts "b:s:e:h" opt; do | |||
| case $opt in | |||
| b) branch=$OPTARG ;; | |||
| s) service=$OPTARG ;; | |||
| e) env=$OPTARG ;; | |||
| h) show_help; exit 0 ;; | |||
| \?) echo "Invalid option -$OPTARG" >&2; show_help; exit 1 ;; | |||
| esac | |||
| done | |||
| valid_services=("manage-front" "manage" "front" "all") | |||
| if [[ ! " ${valid_services[@]} " =~ " $service " ]]; then | |||
| echo "Invalid service name: $service" >&2 | |||
| echo "Valid services are: ${valid_services[*]}" | |||
| exit 1 | |||
| fi | |||
| valid_envs=("dev" "test") | |||
| if [[ ! " ${valid_envs[@]} " =~ " $env " ]]; then | |||
| echo "Invalid environment: $env" >&2 | |||
| echo "Valid environments are: ${valid_envs[*]}" | |||
| exit 1 | |||
| fi | |||
| echo "start build" | |||
| sh ${baseDir}/k8s/build.sh -b ${branch} -s ${service} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Build failed" | |||
| exit 1 | |||
| fi | |||
| echo "build success" | |||
| # 部署 | |||
| echo "start deploy" | |||
| sh ${baseDir}/k8s/deploy.sh -s ${service} -e ${env} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Deploy failed" | |||
| exit 1 | |||
| fi | |||
| echo "deploy success" | |||
| # 记录结束时间 | |||
| endTime=$(date +%s) | |||
| # 计算运行时间 | |||
| duration=$(( $endTime - $startTime )) | |||
| echo "编译发布总耗时: $duration 秒" | |||
| @@ -0,0 +1,13 @@ | |||
| apiVersion: rbac.authorization.k8s.io/v1 | |||
| kind: ClusterRoleBinding | |||
| metadata: | |||
| name: admin-service-account-binding | |||
| roleRef: | |||
| apiGroup: rbac.authorization.k8s.io | |||
| kind: ClusterRole | |||
| name: cluster-admin | |||
| subjects: | |||
| - kind: ServiceAccount | |||
| name: admin-service-account | |||
| namespace: default | |||
| @@ -0,0 +1,181 @@ | |||
| #!/bin/bash | |||
| # 记录开始时间 | |||
| start=$(date +%s) | |||
| # 默认参数 | |||
| service="manage-front" | |||
| env="dev" | |||
| show_help() { | |||
| echo "Usage: $0 [-s service] [-e environment]" | |||
| echo | |||
| echo "Options:" | |||
| echo " -s Service to deploy (manage-front, manage, front, all default: manage-front)" | |||
| echo " -e Environment (e.g., dev, test, default: dev)" | |||
| echo " -h Show this help message" | |||
| } | |||
| # 解析命令行参数 | |||
| while getopts "s:e:h" opt; do | |||
| case $opt in | |||
| s) service=$OPTARG ;; | |||
| e) env=$OPTARG ;; | |||
| h) show_help; exit 0 ;; | |||
| \?) echo "Invalid option -$OPTARG" >&2; exit 1 ;; | |||
| esac | |||
| done | |||
| echo "Deploy service: $service, environment: $env" | |||
| valid_services=("manage-front" "manage" "front" "all" "auth" "gateway" "system") | |||
| if [[ ! " ${valid_services[@]} " =~ " $service " ]]; then | |||
| echo "Invalid service name: $service" >&2 | |||
| echo "Valid services are: ${valid_services[*]}" | |||
| exit 1 | |||
| fi | |||
| valid_envs=("dev" "test") | |||
| if [[ ! " ${valid_envs[@]} " =~ " $env " ]]; then | |||
| echo "Invalid environment: $env" >&2 | |||
| echo "Valid environments are: ${valid_envs[*]}" | |||
| exit 1 | |||
| fi | |||
| # 根据环境设置 IP 地址 | |||
| if [ "$env" == "dev" ]; then | |||
| remote_ip="172.20.32.181" | |||
| elif [ "$env" == "test" ]; then | |||
| remote_ip="172.20.32.185" | |||
| else | |||
| echo "Invalid environment - $env" | |||
| exit 1 | |||
| fi | |||
| baseDir=/home/somuns/ci4s | |||
| tag=$(date +'%Y%m%d%H%M') | |||
| remote_deploy_dir=/home/deploy/manage-platform | |||
| # 构建镜像函数 | |||
| build_image() { | |||
| local dockerfile=$1 | |||
| local image=$2 | |||
| cd ${baseDir}/k8s/dockerfiles | |||
| docker build -t ${image} -f ${dockerfile} . | |||
| if [ $? -ne 0 ]; then | |||
| echo "Build ${image} image fail" | |||
| exit 1 | |||
| fi | |||
| docker push ${image} | |||
| } | |||
| # 复制和替换 YAML 文件函数 | |||
| prepare_yaml() { | |||
| local yaml_file=$1 | |||
| local image=$2 | |||
| placeholder="\${${yaml_file%.yaml}-image}" | |||
| cd ${baseDir}/k8s/template-yaml | |||
| cp -rf ${yaml_file} deploy/ | |||
| cd deploy/ | |||
| sed -i "s|${placeholder}|${image}|g" ${yaml_file} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Replace ${image} image fail" | |||
| exit 1 | |||
| fi | |||
| # 建立远程目录并备份文件 | |||
| ssh root@$remote_ip "mkdir -p ${remote_deploy_dir} && if [ -f ${remote_deploy_dir}/${yaml_file} ]; then mv ${remote_deploy_dir}/${yaml_file} ${remote_deploy_dir}/${yaml_file}.bak; fi" | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to create remote directory or backup ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully created remote directory and backup ${yaml_file}" | |||
| fi | |||
| scp ${baseDir}/k8s/template-yaml/deploy/${yaml_file} root@$remote_ip:${remote_deploy_dir}/${yaml_file} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to copy ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully copied ${yaml_file}" | |||
| fi | |||
| } | |||
| # 部署服务函数 | |||
| deploy_service() { | |||
| local yaml_file=$1 | |||
| ssh root@$remote_ip "kubectl apply -n argo -f ${remote_deploy_dir}/${yaml_file}" | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to deploy ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully deployed ${yaml_file}" | |||
| fi | |||
| } | |||
| deploy_nacos() { | |||
| local yaml_file=$1 | |||
| scp ${baseDir}/k8s/template-yaml/${yaml_file} root@$remote_ip:${remote_deploy_dir}/${yaml_file} | |||
| deploy_service ${yaml_file} | |||
| } | |||
| build_and_deploy() { | |||
| local dockerfile=$1 | |||
| local image=$2 | |||
| local yaml_file=$3 | |||
| build_image ${dockerfile} ${image} | |||
| prepare_yaml ${yaml_file} ${image} | |||
| deploy_service ${yaml_file} | |||
| } | |||
| if [ "$service" == "front" ]; then | |||
| build_and_deploy "nginx-dockerfile" "172.20.32.187/ci4s/ci4s-front:${tag}" "k8s-12front.yaml" | |||
| fi | |||
| # 构建和部署 manage 服务 | |||
| if [ "$service" == "manage" ]; then | |||
| build_and_deploy "managent-dockerfile" "172.20.32.187/ci4s/ci4s-managent:${tag}" "k8s-7management.yaml" | |||
| fi | |||
| if [ "$service" == "auth" ]; then | |||
| #部署认证中心 | |||
| build_and_deploy "auth-dockerfile" "172.20.32.187/ci4s/ci4s-auth:${tag}" "k8s-5auth.yaml" | |||
| fi | |||
| if [ "$service" == "gateway" ]; then | |||
| #部署网关 | |||
| build_and_deploy "gateway-dockerfile" "172.20.32.187/ci4s/ci4s-gateway:${tag}" "k8s-4gateway.yaml" | |||
| fi | |||
| if [ "$service" == "system" ]; then | |||
| #部署系统服务 | |||
| build_and_deploy "system-dockerfile" "172.20.32.187/ci4s/ci4s-system:${tag}" "k8s-6system.yaml" | |||
| fi | |||
| # 构建和部署 front 服务 | |||
| if [ "$service" == "manage-front" ]; then | |||
| build_and_deploy "nginx-dockerfile" "172.20.32.187/ci4s/ci4s-front:${tag}" "k8s-12front.yaml" | |||
| build_and_deploy "managent-dockerfile" "172.20.32.187/ci4s/ci4s-managent:${tag}" "k8s-7management.yaml" | |||
| fi | |||
| if [ "$service" == "all" ]; then | |||
| #部署前端 | |||
| build_and_deploy "nginx-dockerfile" "172.20.32.187/ci4s/ci4s-front:${tag}" "k8s-12front.yaml" | |||
| #部署管理平台 | |||
| build_and_deploy "managent-dockerfile" "172.20.32.187/ci4s/ci4s-managent:${tag}" "k8s-7management.yaml" | |||
| #部署认证中心 | |||
| build_and_deploy "auth-dockerfile" "172.20.32.187/ci4s/ci4s-auth:${tag}" "k8s-5auth.yaml" | |||
| #部署网关 | |||
| build_and_deploy "gateway-dockerfile" "172.20.32.187/ci4s/ci4s-gateway:${tag}" "k8s-4gateway.yaml" | |||
| #部署系统服务 | |||
| build_and_deploy "system-dockerfile" "172.20.32.187/ci4s/ci4s-system:${tag}" "k8s-6system.yaml" | |||
| #部署配置中心 | |||
| deploy_nacos "k8s-3nacos.yaml" | |||
| fi | |||
| # 记录结束时间 | |||
| end=$(date +%s) | |||
| echo "部署成功, 耗时: $((end-start))秒" | |||
| @@ -0,0 +1,162 @@ | |||
| #!/bin/bash | |||
| # 记录开始时间 | |||
| start=$(date +%s) | |||
| # 默认参数 | |||
| service="manage-front" | |||
| env="dev" | |||
| show_help() { | |||
| echo "Usage: $0 [-s service] [-e environment]" | |||
| echo | |||
| echo "Options:" | |||
| echo " -s Service to deploy (manage-front, manage, front, all default: manage-front)" | |||
| echo " -e Environment (e.g., dev, test, default: dev)" | |||
| echo " -h Show this help message" | |||
| } | |||
| # 解析命令行参数 | |||
| while getopts "s:e:h" opt; do | |||
| case $opt in | |||
| s) service=$OPTARG ;; | |||
| e) env=$OPTARG ;; | |||
| h) show_help; exit 0 ;; | |||
| \?) echo "Invalid option -$OPTARG" >&2; exit 1 ;; | |||
| esac | |||
| done | |||
| echo "Deploy service: $service, environment: $env" | |||
| valid_services=("manage-front" "manage" "front" "all") | |||
| if [[ ! " ${valid_services[@]} " =~ " $service " ]]; then | |||
| echo "Invalid service name: $service" >&2 | |||
| echo "Valid services are: ${valid_services[*]}" | |||
| exit 1 | |||
| fi | |||
| valid_envs=("dev" "test") | |||
| if [[ ! " ${valid_envs[@]} " =~ " $env " ]]; then | |||
| echo "Invalid environment: $env" >&2 | |||
| echo "Valid environments are: ${valid_envs[*]}" | |||
| exit 1 | |||
| fi | |||
| # 根据环境设置 IP 地址 | |||
| if [ "$env" == "dev" ]; then | |||
| remote_ip="172.20.32.181" | |||
| elif [ "$env" == "test" ]; then | |||
| remote_ip="172.20.32.185" | |||
| else | |||
| echo "Invalid environment - $env" | |||
| exit 1 | |||
| fi | |||
| baseDir=/home/somuns/ci4s | |||
| tag=$(date +'%Y%m%d%H%M') | |||
| remote_deploy_dir=/home/deploy/manage-platform | |||
| # 构建镜像函数 | |||
| build_image() { | |||
| local dockerfile=$1 | |||
| local image=$2 | |||
| cd ${baseDir}/k8s/dockerfiles | |||
| docker build -t ${image} -f ${dockerfile} . | |||
| if [ $? -ne 0 ]; then | |||
| echo "Build ${image} image fail" | |||
| exit 1 | |||
| fi | |||
| docker push ${image} | |||
| } | |||
| # 复制和替换 YAML 文件函数 | |||
| prepare_yaml() { | |||
| local yaml_file=$1 | |||
| local image=$2 | |||
| placeholder="\${${yaml_file%.yaml}-image}" | |||
| cd ${baseDir}/k8s/template-yaml | |||
| cp -rf ${yaml_file} deploy/ | |||
| cd deploy/ | |||
| sed -i "s|${placeholder}|${image}|g" ${yaml_file} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Replace ${image} image fail" | |||
| exit 1 | |||
| fi | |||
| # 建立远程目录并备份文件 | |||
| ssh root@$remote_ip "mkdir -p ${remote_deploy_dir} && if [ -f ${remote_deploy_dir}/${yaml_file} ]; then mv ${remote_deploy_dir}/${yaml_file} ${remote_deploy_dir}/${yaml_file}.bak; fi" | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to create remote directory or backup ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully created remote directory and backup ${yaml_file}" | |||
| fi | |||
| scp ${baseDir}/k8s/template-yaml/deploy/${yaml_file} root@$remote_ip:${remote_deploy_dir}/${yaml_file} | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to copy ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully copied ${yaml_file}" | |||
| fi | |||
| } | |||
| # 部署服务函数 | |||
| deploy_service() { | |||
| local yaml_file=$1 | |||
| ssh root@$remote_ip "kubectl apply -n argo -f ${remote_deploy_dir}/${yaml_file}" | |||
| if [ $? -ne 0 ]; then | |||
| echo "Failed to deploy ${yaml_file}" | |||
| exit 1 | |||
| else | |||
| echo "Successfully deployed ${yaml_file}" | |||
| fi | |||
| } | |||
| deploy_nacos() { | |||
| local yaml_file=$1 | |||
| scp ${baseDir}/k8s/${yaml_file} root@$remote_ip:${remote_deploy_dir}/${yaml_file} | |||
| deploy_service ${yaml_file} | |||
| } | |||
| build_and_deploy() { | |||
| local dockerfile=$1 | |||
| local image=$2 | |||
| local yaml_file=$3 | |||
| build_image ${dockerfile} ${image} | |||
| prepare_yaml ${yaml_file} ${image} | |||
| deploy_service ${yaml_file} | |||
| } | |||
| # 构建和部署 manage 服务 | |||
| if [ "$service" == "manage-front" ] || [ "$service" == "manage" ]; then | |||
| build_and_deploy "managent-dockerfile" "172.20.32.187/ci4s/ci4s-managent:${tag}" "k8s-7management.yaml" | |||
| fi | |||
| # 构建和部署 front 服务 | |||
| if [ "$service" == "manage-front" ] || [ "$service" == "front" ]; then | |||
| build_and_deploy "nginx-dockerfile" "172.20.32.187/ci4s/ci4s-front:${tag}" "k8s-12front.yaml" | |||
| fi | |||
| if [ "$service" == "all" ]; then | |||
| #部署前端 | |||
| build_and_deploy "nginx-dockerfile" "172.20.32.187/ci4s/ci4s-front:${tag}" "k8s-12front.yaml" | |||
| #部署管理平台 | |||
| build_and_deploy "managent-dockerfile" "172.20.32.187/ci4s/ci4s-managent:${tag}" "k8s-7management.yaml" | |||
| #部署认证中心 | |||
| build_and_deploy "auth-dockerfile" "172.20.32.187/ci4s/ci4s-auth:${tag}" "k8s-5auth.yaml" | |||
| #部署网关 | |||
| build_and_deploy "gateway-dockerfile" "172.20.32.187/ci4s/ci4s-gateway:${tag}" "k8s-4gateway.yaml" | |||
| #部署系统服务 | |||
| build_and_deploy "system-dockerfile" "172.20.32.187/ci4s/ci4s-system:${tag}" "k8s-6system.yaml" | |||
| #部署配置中心 | |||
| deploy_nacos "k8s-3nacos.yaml" | |||
| fi | |||
| # 记录结束时间 | |||
| end=$(date +%s) | |||
| echo "部署成功, 耗时: $((end-start))秒" | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,13 +1,13 @@ | |||
| #!/bin/bash | |||
| # 定义一个名为version的变量 | |||
| version=$1 | |||
| url=$2 | |||
| # 打印变量的值 | |||
| echo "版本号为: $version" | |||
| docker build -t ci4s-gateway:$version -f gateway-dockerfile . | |||
| docker build -t ci4s-auth:$version -f auth-dockerfile . | |||
| docker build -t ci4s-file:$version -f file-dockerfile . | |||
| docker build -t ci4s-gen:$version -f gen-dockerfile . | |||
| docker build -t ci4s-job:$version -f job-dockerfile . | |||
| docker build -t ci4s-visual:$version -f visual-dockerfile . | |||
| docker build -t ci4s-system:$version -f system-dockerfile . | |||
| docker build -t $url/ci4s-gateway:$version -f gateway-dockerfile . | |||
| docker build -t $url/ci4s-auth:$version -f auth-dockerfile . | |||
| docker build -t $url/ci4s-file:$version -f file-dockerfile . | |||
| docker build -t $url/ci4s-gen:$version -f gen-dockerfile . | |||
| docker build -t $url/ci4s-job:$version -f job-dockerfile . | |||
| docker build -t $url/ci4s-visual:$version -f visual-dockerfile . | |||
| docker build -t $url/ci4s-system:$version -f system-dockerfile . | |||
| @@ -1,41 +1,131 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location / { | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location /api/{ | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.ci4s-test.svc:8082/; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| client_max_body_size 20480m; | |||
| error_log /var/log/nginx/error.log debug; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| # rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/; | |||
| proxy_connect_timeout 500s; # 设置连接超时时间为 120 秒 | |||
| proxy_read_timeout 500s; # 设置读取超时时间为 120 秒 | |||
| proxy_send_timeout 500s; # 设置发送超时时间为 120 秒 | |||
| } | |||
| location /label-studio/ { | |||
| # rewrite ^/label-studio/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-service.argo.svc:8080/projects/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options ALLOWALL; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location /api/v1/model/ { | |||
| proxy_pass http://pipeline-convert-service.argo.svc:80; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| } | |||
| # location /api/v1/realtimeStatus { | |||
| # proxy_pass http://argo-server.argo.svc:2746/api/v1/workflow-events/argo; | |||
| # proxy_set_header REMOTE-HOST $remote_addr; | |||
| # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| # } | |||
| location /api/v1/tensorboard/show { | |||
| # 提取查询参数中的 `svc` 值 | |||
| set $svc ""; | |||
| if ($arg_svc) { | |||
| set $svc $arg_svc; | |||
| } | |||
| # 将请求转发到动态生成的内部服务地址 | |||
| proxy_pass http://$svc.argo.svc:6006; | |||
| # 传递必要的头信息 | |||
| proxy_set_header Host $host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| # 对于 WebSocket 应用很重要 | |||
| proxy_buffering off; | |||
| } | |||
| location /api/v1/realtimeStatus { | |||
| rewrite ^/api/v1/realtimeStatus(.*)$ /api/v1/workflow-events/argo$1 break; | |||
| proxy_pass https://argo-server.argo.svc:2746; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| # 保留查询参数 | |||
| proxy_set_header X-Original-URI $request_uri; | |||
| # 禁用缓冲 | |||
| proxy_buffering off; | |||
| # 增加超时时间 | |||
| proxy_read_timeout 3600s; | |||
| proxy_send_timeout 3600s; | |||
| proxy_connect_timeout 60s; | |||
| # 设置传递的请求头 | |||
| # proxy_set_header Connection ''; | |||
| # chunked_transfer_encoding off; | |||
| # 如果需要保留自定义头部 | |||
| proxy_set_header Accept 'text/event-stream'; | |||
| } | |||
| location /newlog/realtimeLog { | |||
| proxy_pass http://loki.loki-log.svc:3100/loki/api/v1/tail; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Upgrade $http_upgrade; | |||
| proxy_set_header Connection "Upgrade"; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| client_max_body_size 20480m; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| # rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/; | |||
| proxy_connect_timeout 500s; # 设置连接超时时间为 120 秒 | |||
| proxy_read_timeout 500s; # 设置读取超时时间为 120 秒 | |||
| proxy_send_timeout 500s; # 设置发送超时时间为 120 秒 | |||
| } | |||
| location /label-studio/ { | |||
| # rewrite ^/label-studio/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-service.argo.svc:8080/projects/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options ALLOWALL; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location /api/v1/model/ { | |||
| proxy_pass http://pipeline-convert-service.argo.svc:80; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,131 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| client_max_body_size 20480m; | |||
| error_log /var/log/nginx/error.log debug; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| # rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/; | |||
| proxy_connect_timeout 500s; # 设置连接超时时间为 120 秒 | |||
| proxy_read_timeout 500s; # 设置读取超时时间为 120 秒 | |||
| proxy_send_timeout 500s; # 设置发送超时时间为 120 秒 | |||
| } | |||
| location /label-studio/ { | |||
| # rewrite ^/label-studio/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-service.argo.svc:8080/projects/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options ALLOWALL; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location /api/v1/model/ { | |||
| proxy_pass http://pipeline-convert-service.argo.svc:80; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| } | |||
| # location /api/v1/realtimeStatus { | |||
| # proxy_pass http://argo-server.argo.svc:2746/api/v1/workflow-events/argo; | |||
| # proxy_set_header REMOTE-HOST $remote_addr; | |||
| # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| # } | |||
| location /api/v1/tensorboard/show { | |||
| # 提取查询参数中的 `svc` 值 | |||
| set $svc ""; | |||
| if ($arg_svc) { | |||
| set $svc $arg_svc; | |||
| } | |||
| # 将请求转发到动态生成的内部服务地址 | |||
| proxy_pass http://$svc.argo.svc:6006; | |||
| # 传递必要的头信息 | |||
| proxy_set_header Host $host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| # 对于 WebSocket 应用很重要 | |||
| proxy_buffering off; | |||
| } | |||
| location /api/v1/realtimeStatus { | |||
| rewrite ^/api/v1/realtimeStatus(.*)$ /api/v1/workflow-events/argo$1 break; | |||
| proxy_pass https://argo-server.argo.svc:2746; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| # 保留查询参数 | |||
| proxy_set_header X-Original-URI $request_uri; | |||
| # 禁用缓冲 | |||
| proxy_buffering off; | |||
| # 增加超时时间 | |||
| proxy_read_timeout 3600s; | |||
| proxy_send_timeout 3600s; | |||
| proxy_connect_timeout 60s; | |||
| # 设置传递的请求头 | |||
| # proxy_set_header Connection ''; | |||
| # chunked_transfer_encoding off; | |||
| # 如果需要保留自定义头部 | |||
| proxy_set_header Accept 'text/event-stream'; | |||
| } | |||
| location /newlog/realtimeLog { | |||
| proxy_pass http://loki.loki-log.svc:3100/loki/api/v1/tail; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Upgrade $http_upgrade; | |||
| proxy_set_header Connection "Upgrade"; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/; | |||
| } | |||
| location /label-studio { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-ls-app.label-data.svc:80/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options "ALLOW-FROM http://label-studio-ls-app.label-data.svc:80/"; | |||
| } | |||
| location /api/v1/model/ { | |||
| proxy_pass http://pipeline-convert-service.argo.svc:80; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,110 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| client_max_body_size 20480m; | |||
| error_log /var/log/nginx/error.log debug; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| # rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/; | |||
| proxy_connect_timeout 500s; # 设置连接超时时间为 120 秒 | |||
| proxy_read_timeout 500s; # 设置读取超时时间为 120 秒 | |||
| proxy_send_timeout 500s; # 设置发送超时时间为 120 秒 | |||
| } | |||
| location /label-studio/ { | |||
| # rewrite ^/label-studio/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-service.argo.svc:8080/projects/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options ALLOWALL; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location /api/v1/model/ { | |||
| proxy_pass http://pipeline-convert-service.argo.svc:80; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| } | |||
| # location /api/v1/realtimeStatus { | |||
| # proxy_pass http://argo-server.argo.svc:2746/api/v1/workflow-events/argo; | |||
| # proxy_set_header REMOTE-HOST $remote_addr; | |||
| # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| # } | |||
| location /api/v1/realtimeStatus { | |||
| rewrite ^/api/v1/realtimeStatus(.*)$ /api/v1/workflow-events/argo$1 break; | |||
| proxy_pass https://argo-server.argo.svc:2746; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| # 保留查询参数 | |||
| proxy_set_header X-Original-URI $request_uri; | |||
| # 禁用缓冲 | |||
| proxy_buffering off; | |||
| # 增加超时时间 | |||
| proxy_read_timeout 3600s; | |||
| proxy_send_timeout 3600s; | |||
| proxy_connect_timeout 60s; | |||
| # 设置传递的请求头 | |||
| # proxy_set_header Connection ''; | |||
| # chunked_transfer_encoding off; | |||
| # 如果需要保留自定义头部 | |||
| proxy_set_header Accept 'text/event-stream'; | |||
| } | |||
| location /newlog/realtimeLog { | |||
| proxy_pass http://loki.loki-log.svc:3100/loki/api/v1/tail; | |||
| proxy_http_version 1.1; | |||
| proxy_set_header Upgrade $http_upgrade; | |||
| proxy_set_header Connection "Upgrade"; | |||
| proxy_set_header Host $host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header X-Forwarded-Proto $scheme; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| #FROM openjdk:8-jre | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM 172.20.32.187/ci4s/openjdk:8u162 | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -12,4 +13,4 @@ WORKDIR /home/ruoyi | |||
| # 复制jar文件到路径 | |||
| COPY ./jar/management-platform.jar /home/ruoyi/management-platform.jar | |||
| # 启动系统服务 | |||
| ENTRYPOINT ["java","-jar","management-platform.jar"] | |||
| ENTRYPOINT ["java","-jar","-Djdk.tls.client.protocols=TLSv1.2","management-platform.jar"] | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM nginx | |||
| #FROM nginx:latest | |||
| FROM 172.20.32.187/ci4s/nginx:latest | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -1,5 +1,6 @@ | |||
| # 基础镜像 | |||
| FROM openjdk:8-jre | |||
| #FROM openjdk:8-jre | |||
| FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | |||
| # author | |||
| MAINTAINER ruoyi | |||
| @@ -3,7 +3,7 @@ | |||
| ## | |||
| image: "mysql" | |||
| imageTag: "5.7.30" | |||
| Namespace: argo | |||
| strategy: | |||
| type: Recreate | |||
| @@ -110,7 +110,7 @@ persistence: | |||
| ## set, choosing the default provisioner. (gp2 on AWS, standard on | |||
| ## GKE, AWS & OpenStack) | |||
| ## | |||
| storageClass: "storage-nfs" | |||
| storageClass: "nfs-client" | |||
| accessMode: ReadWriteOnce | |||
| size: 10Gi | |||
| annotations: {} | |||
| @@ -37,7 +37,7 @@ spec: | |||
| serviceAccountName: {{ template "redis-ha.serviceAccountName" . }}-haproxy | |||
| {{ end }} | |||
| nodeSelector: | |||
| {{ toYaml .Values.nodeSelector | indent 8 }} | |||
| {{ toYaml .Values.nodeSeletor | indent 8 }} | |||
| tolerations: | |||
| {{ toYaml .Values.tolerations | indent 8 }} | |||
| affinity: | |||
| @@ -133,7 +133,7 @@ sysctlImage: | |||
| command: [] | |||
| registry: docker.io | |||
| repository: busybox | |||
| tag: 1.31.1 | |||
| tag: 1.28 | |||
| pullPolicy: Always | |||
| mountHostSys: false | |||
| resources: {} | |||
| @@ -337,7 +337,7 @@ persistentVolume: | |||
| ## set, choosing the default provisioner. (gp2 on AWS, standard on | |||
| ## GKE, AWS & OpenStack) | |||
| ## | |||
| storageClass: "storage-nfs" | |||
| storageClass: "nfs-client" | |||
| accessModes: | |||
| - ReadWriteOnce | |||
| size: 2Gi | |||
| @@ -2,7 +2,7 @@ apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-front-deployment | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| @@ -14,17 +14,17 @@ spec: | |||
| app: ci4s-front | |||
| spec: | |||
| containers: | |||
| - name: ci4s-front | |||
| image: ci4s-front:20240126 | |||
| ports: | |||
| - containerPort: 8000 | |||
| - name: ci4s-front | |||
| image: 172.20.32.187/ci4s/ci4s-front:20240401 | |||
| ports: | |||
| - containerPort: 8000 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-front-service | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| @@ -33,3 +33,4 @@ spec: | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-front | |||
| @@ -1,7 +1,7 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| name: nacos-ci4s | |||
| labels: | |||
| app: nacos-ci4s | |||
| @@ -24,7 +24,7 @@ spec: | |||
| - name: MODE | |||
| value: standalone | |||
| - name: MYSQL_SERVICE_HOST | |||
| value: mysql.ci4s-test.svc | |||
| value: mysql.argo.svc | |||
| - name: MYSQL_SERVICE_PORT | |||
| value: "3306" | |||
| - name: MYSQL_SERVICE_DB_NAME | |||
| @@ -43,7 +43,7 @@ spec: | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| name: nacos-ci4s | |||
| labels: | |||
| app: nacos-ci4s | |||
| @@ -2,7 +2,7 @@ apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-gateway-deployment | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| @@ -15,7 +15,7 @@ spec: | |||
| spec: | |||
| containers: | |||
| - name: ci4s-gateway | |||
| image: ci4s-gateway:v1.0 | |||
| image: 172.20.32.187/ci4s/ci4s-gateway:20240401 | |||
| ports: | |||
| - containerPort: 8082 | |||
| @@ -24,7 +24,7 @@ apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-gateway-service | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| @@ -2,7 +2,7 @@ apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-auth-deployment | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| @@ -15,7 +15,7 @@ spec: | |||
| spec: | |||
| containers: | |||
| - name: ci4s-auth | |||
| image: ci4s-auth:v1.0 | |||
| image: 172.20.32.187/ci4s/ci4s-auth:20240401 | |||
| ports: | |||
| - containerPort: 9200 | |||
| @@ -24,7 +24,7 @@ apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-auth-service | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| @@ -2,7 +2,7 @@ apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-system-deployment | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| @@ -15,7 +15,7 @@ spec: | |||
| spec: | |||
| containers: | |||
| - name: ci4s-system | |||
| image: ci4s-system:v1.0 | |||
| image: 172.20.32.187/ci4s/ci4s-system:20240401 | |||
| ports: | |||
| - containerPort: 9201 | |||
| @@ -24,7 +24,7 @@ apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-system-service | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| @@ -2,7 +2,7 @@ apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-management-platform-deployment | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| @@ -15,20 +15,28 @@ spec: | |||
| spec: | |||
| containers: | |||
| - name: ci4s-management-platform | |||
| image: ci4s-managent:20240110 | |||
| image: 172.20.32.187/ci4s/managent:20240401 | |||
| ports: | |||
| - containerPort: 9300 | |||
| - containerPort: 9213 | |||
| volumeMounts: | |||
| - name: resource | |||
| mountPath: /home/resource/ | |||
| volumes: | |||
| - name: resource | |||
| hostPath: | |||
| path: /home/resource/ | |||
| type: DirectoryOrCreate | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-management-platform-service | |||
| namespace: ci4s-test | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9300 | |||
| - port: 9213 | |||
| nodePort: 31208 | |||
| protocol: TCP | |||
| selector: | |||
| @@ -0,0 +1,54 @@ | |||
| worker_processes 1; | |||
| events { | |||
| worker_connections 1024; | |||
| } | |||
| http { | |||
| include mime.types; | |||
| default_type application/octet-stream; | |||
| sendfile on; | |||
| keepalive_timeout 65; | |||
| server { | |||
| listen 8000; | |||
| server_name localhost; | |||
| location /api/{ | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header REMOTE-HOST $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_pass http://ci4s-gateway-service.argo.svc:8082/mmp/; | |||
| } | |||
| location /label-studio { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| proxy_pass http://label-studio-ls-app.label-data.svc:80/; | |||
| proxy_hide_header X-Frame-Options; | |||
| add_header X-Frame-Options "ALLOW-FROM http://label-studio-ls-app.label-data.svc:80/"; | |||
| } | |||
| location / { | |||
| rewrite ^/prod-api/(.*)$ /$1 break; | |||
| root /home/ruoyi/projects/ruoyi-ui; | |||
| try_files $uri $uri/ /index.html; | |||
| index index.html index.htm; | |||
| } | |||
| location @router { | |||
| rewrite ^.*$ /index.html last; | |||
| } | |||
| # 避免actuator暴露 | |||
| if ($request_uri ~ "/actuator") { | |||
| return 403; | |||
| } | |||
| error_page 500 502 503 504 /50x.html; | |||
| location = /50x.html { | |||
| root html; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-front-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-front | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-front | |||
| spec: | |||
| containers: | |||
| - name: ci4s-front | |||
| image: 172.20.32.187/ci4s/ci4s-front:202406120836 | |||
| ports: | |||
| - containerPort: 8000 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-front-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 8000 | |||
| nodePort: 31213 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-front | |||
| @@ -0,0 +1,53 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-management-platform-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-management-platform | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-management-platform | |||
| spec: | |||
| containers: | |||
| - name: ci4s-management-platform | |||
| image: 172.20.32.187/ci4s/ci4s-managent:202409201355 | |||
| env: | |||
| - name: TZ | |||
| value: Asia/Shanghai | |||
| - name: JAVA_TOOL_OPTIONS | |||
| value: "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005" | |||
| ports: | |||
| - containerPort: 9213 | |||
| volumeMounts: | |||
| - name: resource-volume | |||
| mountPath: /home/resource/ | |||
| volumes: | |||
| - name: resource-volume | |||
| persistentVolumeClaim: | |||
| claimName: platform-data-pvc-nfs | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-management-platform-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - name: http | |||
| port: 9213 | |||
| nodePort: 31208 | |||
| protocol: TCP | |||
| - name: debug | |||
| nodePort: 34567 | |||
| port: 5005 | |||
| protocol: TCP | |||
| targetPort: 5005 | |||
| selector: | |||
| app: ci4s-management-platform | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-gen-deployment | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-gen | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-gen | |||
| spec: | |||
| containers: | |||
| - name: ci4s-gen | |||
| image: ${k8s-10gen-image} | |||
| ports: | |||
| - containerPort: 9202 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-gen-service | |||
| namespace: ci4s-test | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9202 | |||
| nodePort: 31211 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-gen | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-visual-deployment | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-visual | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-visual | |||
| spec: | |||
| containers: | |||
| - name: ci4s-visual | |||
| image: ${k8s-11visual-image} | |||
| ports: | |||
| - containerPort: 9100 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-visual-service | |||
| namespace: ci4s-test | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9100 | |||
| nodePort: 31212 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-visual | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-front-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-front | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-front | |||
| spec: | |||
| containers: | |||
| - name: ci4s-front | |||
| image: ${k8s-12front-image} | |||
| ports: | |||
| - containerPort: 8000 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-front-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 8000 | |||
| nodePort: 31213 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-front | |||
| @@ -0,0 +1,71 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| namespace: argo | |||
| name: nacos-ci4s | |||
| labels: | |||
| app: nacos-ci4s | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: nacos-ci4s | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: nacos-ci4s | |||
| spec: | |||
| containers: | |||
| - name: nacos-ci4s | |||
| image: nacos/nacos-server:v2.2.0 | |||
| env: | |||
| - name: SPRING_DATASOURCE_PLATFORM | |||
| value: mysql | |||
| - name: MODE | |||
| value: standalone | |||
| - name: MYSQL_SERVICE_HOST | |||
| value: mysql.argo.svc | |||
| - name: MYSQL_SERVICE_PORT | |||
| value: "3306" | |||
| - name: MYSQL_SERVICE_DB_NAME | |||
| value: nacos-ci4s-config | |||
| - name: MYSQL_SERVICE_USER | |||
| value: root | |||
| - name: MYSQL_SERVICE_PASSWORD | |||
| value: qazxc123456. | |||
| ports: | |||
| - containerPort: 8848 | |||
| - containerPort: 9848 | |||
| - containerPort: 9849 | |||
| initContainers: | |||
| - name: init-mydb | |||
| image: busybox:1.31 | |||
| command: [ 'sh', '-c', 'nc -zv mysql.argo.svc 3306' ] | |||
| restartPolicy: Always | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| namespace: argo | |||
| name: nacos-ci4s | |||
| labels: | |||
| app: nacos-ci4s | |||
| spec: | |||
| type: NodePort | |||
| selector: | |||
| app: nacos-ci4s | |||
| ports: | |||
| - port: 8848 | |||
| targetPort: 8848 | |||
| nodePort: 31203 | |||
| name: web | |||
| - port: 9848 | |||
| targetPort: 9848 | |||
| nodePort: 32203 | |||
| name: podsa | |||
| - port: 9849 | |||
| targetPort: 9849 | |||
| nodePort: 32204 | |||
| name: tcp-9849 | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-gateway-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-gateway | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-gateway | |||
| spec: | |||
| containers: | |||
| - name: ci4s-gateway | |||
| image: ${k8s-4gateway-image} | |||
| ports: | |||
| - containerPort: 8082 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-gateway-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 8082 | |||
| nodePort: 31205 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-gateway | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-auth-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-auth | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-auth | |||
| spec: | |||
| containers: | |||
| - name: ci4s-auth | |||
| image: ${k8s-5auth-image} | |||
| ports: | |||
| - containerPort: 9200 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-auth-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9200 | |||
| nodePort: 31206 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-auth | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-system-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-system | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-system | |||
| spec: | |||
| containers: | |||
| - name: ci4s-system | |||
| image: ${k8s-6system-image} | |||
| ports: | |||
| - containerPort: 9201 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-system-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9201 | |||
| nodePort: 31207 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-system | |||
| @@ -0,0 +1,54 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-management-platform-deployment | |||
| namespace: argo | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-management-platform | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-management-platform | |||
| spec: | |||
| containers: | |||
| - name: ci4s-management-platform | |||
| image: ${k8s-7management-image} | |||
| env: | |||
| - name: TZ | |||
| value: Asia/Shanghai | |||
| - name: JAVA_TOOL_OPTIONS | |||
| value: "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005" | |||
| ports: | |||
| - containerPort: 9213 | |||
| volumeMounts: | |||
| - name: resource-volume | |||
| mountPath: /home/resource/ | |||
| subPath: mini-model-platform-data | |||
| volumes: | |||
| - name: resource-volume | |||
| hostPath: | |||
| path: /platform-data | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-management-platform-service | |||
| namespace: argo | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - name: http | |||
| port: 9213 | |||
| nodePort: 31208 | |||
| protocol: TCP | |||
| - name: debug | |||
| nodePort: 31219 | |||
| port: 5005 | |||
| protocol: TCP | |||
| targetPort: 5005 | |||
| selector: | |||
| app: ci4s-management-platform | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-file-deployment | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-file | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-file | |||
| spec: | |||
| containers: | |||
| - name: ci4s-file | |||
| image: ${k8s-8file-image} | |||
| ports: | |||
| - containerPort: 9300 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-file-service | |||
| namespace: ci4s-test | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9300 | |||
| nodePort: 31209 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-file | |||
| @@ -0,0 +1,36 @@ | |||
| apiVersion: apps/v1 | |||
| kind: Deployment | |||
| metadata: | |||
| name: ci4s-job-deployment | |||
| namespace: ci4s-test | |||
| spec: | |||
| replicas: 1 | |||
| selector: | |||
| matchLabels: | |||
| app: ci4s-job | |||
| template: | |||
| metadata: | |||
| labels: | |||
| app: ci4s-job | |||
| spec: | |||
| containers: | |||
| - name: ci4s-job | |||
| image: ${k8s-9job-image} | |||
| ports: | |||
| - containerPort: 9203 | |||
| --- | |||
| apiVersion: v1 | |||
| kind: Service | |||
| metadata: | |||
| name: ci4s-job-service | |||
| namespace: ci4s-test | |||
| spec: | |||
| type: NodePort | |||
| ports: | |||
| - port: 9203 | |||
| nodePort: 31210 | |||
| protocol: TCP | |||
| selector: | |||
| app: ci4s-job | |||
| @@ -40,4 +40,11 @@ screenshot | |||
| build | |||
| pnpm-lock.yaml | |||
| pnpm-lock.yaml | |||
| /src/services/codeConfig/index.js | |||
| /src/pages/CodeConfig/components/AddCodeConfigModal/index.less | |||
| /src/pages/CodeConfig/List/index.less | |||
| /src/pages/Dataset/components/ResourceItem/index.less | |||
| /src/pages/CodeConfig/components/AddCodeConfigModal/index.tsx | |||
| /src/pages/CodeConfig/components/CodeConfigItem/index.tsx | |||
| /src/pages/Dataset/components/ResourceItem/index.tsx | |||
| @@ -29,7 +29,7 @@ export default { | |||
| // pathRewrite: { '^/api': '' }, | |||
| }, | |||
| '/profile/avatar/': { | |||
| target: 'http://172.20.32.181:31213', | |||
| target: 'http://172.20.32.185:31213', | |||
| changeOrigin: true, | |||
| }, | |||
| }, | |||
| @@ -27,6 +27,16 @@ export default [ | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| path: '/authorize', | |||
| layout: false, | |||
| component: './Authorize/index', | |||
| }, | |||
| { | |||
| path: '/gitlink', | |||
| layout: true, | |||
| component: './GitLink/index', | |||
| }, | |||
| { | |||
| path: '/user', | |||
| layout: false, | |||
| @@ -7,7 +7,6 @@ import defaultSettings from '../config/defaultSettings'; | |||
| import '../public/fonts/font.css'; | |||
| import { getAccessToken } from './access'; | |||
| import './dayjsConfig'; | |||
| import { PageEnum } from './enums/pagesEnums'; | |||
| import './global.less'; | |||
| import { removeAllPageCacheState } from './hooks/pageCacheState'; | |||
| import { | |||
| @@ -24,6 +23,7 @@ import { type GlobalInitialState } from '@/types'; | |||
| import '@/utils/clipboard'; | |||
| import { menuItemRender } from '@/utils/menuRender'; | |||
| import ErrorBoundary from './components/ErrorBoundary'; | |||
| import { needAuth } from './utils'; | |||
| import { gotoLoginPage } from './utils/ui'; | |||
| /** | |||
| @@ -41,14 +41,17 @@ export async function getInitialState(): Promise<GlobalInitialState> { | |||
| roleNames: response.user.roles, | |||
| } as API.CurrentUser; | |||
| } catch (error) { | |||
| console.error(error); | |||
| console.error('1111', error); | |||
| gotoLoginPage(); | |||
| } | |||
| return undefined; | |||
| }; | |||
| // 如果不是登录页面,执行 | |||
| const { location } = history; | |||
| if (location.pathname !== PageEnum.LOGIN) { | |||
| console.log('getInitialState', needAuth(location.pathname)); | |||
| if (needAuth(location.pathname)) { | |||
| const currentUser = await fetchUserInfo(); | |||
| return { | |||
| fetchUserInfo, | |||
| @@ -95,7 +98,7 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | |||
| onPageChange: () => { | |||
| const { location } = history; | |||
| // 如果没有登录,重定向到 login | |||
| if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) { | |||
| if (!initialState?.currentUser && needAuth(location.pathname)) { | |||
| gotoLoginPage(); | |||
| } | |||
| }, | |||
| @@ -160,8 +163,8 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | |||
| export const onRouteChange: RuntimeConfig['onRouteChange'] = async (e) => { | |||
| const { location } = e; | |||
| const menus = getRemoteMenu(); | |||
| // console.log('onRouteChange', e); | |||
| if (menus === null && location.pathname !== PageEnum.LOGIN) { | |||
| console.log('onRouteChange', menus); | |||
| if (menus === null && needAuth(location.pathname)) { | |||
| history.go(0); | |||
| } | |||
| }; | |||
| @@ -171,12 +174,12 @@ export const patchRoutes: RuntimeConfig['patchRoutes'] = (e) => { | |||
| }; | |||
| export const patchClientRoutes: RuntimeConfig['patchClientRoutes'] = (e) => { | |||
| //console.log('patchClientRoutes', e); | |||
| console.log('patchClientRoutes', e); | |||
| patchRouteWithRemoteMenus(e.routes); | |||
| }; | |||
| export function render(oldRender: () => void) { | |||
| // console.log('render'); | |||
| console.log('render'); | |||
| const token = getAccessToken(); | |||
| if (!token || token?.length === 0) { | |||
| oldRender(); | |||
| @@ -12,6 +12,7 @@ export enum IframePageType { | |||
| DatasetAnnotation = 'DatasetAnnotation', // 数据标注 | |||
| AppDevelopment = 'AppDevelopment', // 应用开发 | |||
| DevEnv = 'DevEnv', // 开发环境 | |||
| GitLink = 'GitLink', | |||
| } | |||
| const getRequestAPI = (type: IframePageType): (() => Promise<any>) => { | |||
| @@ -19,13 +20,15 @@ const getRequestAPI = (type: IframePageType): (() => Promise<any>) => { | |||
| case IframePageType.DatasetAnnotation: | |||
| return getLabelStudioUrl; | |||
| case IframePageType.AppDevelopment: | |||
| return () => Promise.resolve({ code: 200, data: 'http://172.20.32.181:30080/' }); | |||
| return () => Promise.resolve({ code: 200, data: 'http://172.20.32.185:30080/' }); | |||
| case IframePageType.DevEnv: | |||
| return () => | |||
| Promise.resolve({ | |||
| code: 200, | |||
| data: SessionStorage.getItem(SessionStorage.editorUrlKey) || '', | |||
| }); | |||
| case IframePageType.GitLink: | |||
| return () => Promise.resolve({ code: 200, data: 'http://172.20.32.201:4000' }); | |||
| } | |||
| }; | |||
| @@ -1,6 +1,8 @@ | |||
| import { clearSessionToken } from '@/access'; | |||
| import { setRemoteMenu } from '@/services/session'; | |||
| import { logout } from '@/services/system/auth'; | |||
| import { ClientInfo } from '@/types'; | |||
| import SessionStorage from '@/utils/sessionStorage'; | |||
| import { gotoLoginPage } from '@/utils/ui'; | |||
| import { LogoutOutlined, UserOutlined } from '@ant-design/icons'; | |||
| import { setAlpha } from '@ant-design/pro-components'; | |||
| @@ -64,6 +66,11 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => { | |||
| clearSessionToken(); | |||
| setRemoteMenu(null); | |||
| gotoLoginPage(); | |||
| const clientInfo: ClientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true); | |||
| if (clientInfo) { | |||
| const { logoutUri } = clientInfo; | |||
| location.replace(logoutUri); | |||
| } | |||
| }; | |||
| const actionClassName = useEmotionCss(({ token }) => { | |||
| return { | |||
| @@ -9,7 +9,7 @@ type RobotFrameProps = { | |||
| }; | |||
| function RobotFrame({ onClose, visible }: RobotFrameProps) { | |||
| const url = 'http://172.20.32.181:30080/chat/EruwZfxVgDkWdLYs'; | |||
| const url = 'http://172.20.32.185:30080/chat/EruwZfxVgDkWdLYs'; | |||
| const openUrl = () => { | |||
| window.open(url, '_blank'); | |||
| }; | |||
| @@ -0,0 +1,50 @@ | |||
| import { setSessionToken } from '@/access'; | |||
| import { loginByOauth2Req } from '@/services/auth'; | |||
| import { to } from '@/utils/promise'; | |||
| import { history, useModel, useSearchParams } from '@umijs/max'; | |||
| import { message } from 'antd'; | |||
| import { useEffect } from 'react'; | |||
| import { flushSync } from 'react-dom'; | |||
| import styles from './index.less'; | |||
| function Authorize() { | |||
| const { initialState, setInitialState } = useModel('@@initialState'); | |||
| const [searchParams] = useSearchParams(); | |||
| const code = searchParams.get('code'); | |||
| const redirect = searchParams.get('redirect'); | |||
| useEffect(() => { | |||
| loginByOauth2(); | |||
| }, []); | |||
| // 登录 | |||
| const loginByOauth2 = async () => { | |||
| const params = { | |||
| code, | |||
| }; | |||
| const [res] = await to(loginByOauth2Req(params)); | |||
| debugger; | |||
| if (res && res.data) { | |||
| const { access_token, expires_in } = res.data; | |||
| setSessionToken(access_token, access_token, expires_in); | |||
| message.success('登录成功!'); | |||
| await fetchUserInfo(); | |||
| history.push(redirect || '/'); | |||
| } | |||
| }; | |||
| const fetchUserInfo = async () => { | |||
| const userInfo = await initialState?.fetchUserInfo?.(); | |||
| if (userInfo) { | |||
| flushSync(() => { | |||
| setInitialState((s) => ({ | |||
| ...s, | |||
| currentUser: userInfo, | |||
| })); | |||
| }); | |||
| } | |||
| }; | |||
| return <div className={styles.container}></div>; | |||
| } | |||
| export default Authorize; | |||
| @@ -135,7 +135,7 @@ function LogGroup({ | |||
| const setupSockect = () => { | |||
| let { host } = location; | |||
| if (process.env.NODE_ENV === 'development') { | |||
| host = '172.20.32.181:31213'; | |||
| host = '172.20.32.185:31213'; | |||
| } | |||
| const socket = new WebSocket( | |||
| `ws://${host}/newlog/realtimeLog?start=${start_time}&query={pod="${pod_name}"}`, | |||
| @@ -0,0 +1,7 @@ | |||
| import IframePage, { IframePageType } from '@/components/IFramePage'; | |||
| function GitLink() { | |||
| return <IframePage type={IframePageType.GitLink}></IframePage>; | |||
| } | |||
| export default GitLink; | |||
| @@ -1,11 +1,12 @@ | |||
| import { clearSessionToken, setSessionToken } from '@/access'; | |||
| import { getClientInfoReq } from '@/services/auth'; | |||
| import { getCaptchaImg, login } from '@/services/system/auth'; | |||
| import { parseJsonText } from '@/utils'; | |||
| import { safeInvoke } from '@/utils/functional'; | |||
| import LocalStorage from '@/utils/localStorage'; | |||
| import { to } from '@/utils/promise'; | |||
| import SessionStorage from '@/utils/sessionStorage'; | |||
| import { gotoOAuth2 } from '@/utils/ui'; | |||
| import { history, useModel } from '@umijs/max'; | |||
| import { Button, Checkbox, Flex, Form, Image, Input, message, type InputRef } from 'antd'; | |||
| import { Form, message, type InputRef } from 'antd'; | |||
| import CryptoJS from 'crypto-js'; | |||
| import { useEffect, useRef, useState } from 'react'; | |||
| import { flushSync } from 'react-dom'; | |||
| @@ -31,25 +32,35 @@ const Login = () => { | |||
| const captchaInputRef = useRef<InputRef>(null); | |||
| useEffect(() => { | |||
| getCaptchaCode(); | |||
| const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false'; | |||
| if (autoLogin === 'true') { | |||
| const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey); | |||
| const userJson = safeInvoke((text: string) => | |||
| CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8), | |||
| )(userStorage); | |||
| const user = safeInvoke(parseJsonText)(userJson); | |||
| if (user && typeof user === 'object' && user.version === VERSION) { | |||
| const { username, password } = user; | |||
| form.setFieldsValue({ username: username, password: password, autoLogin: true }); | |||
| } else { | |||
| form.setFieldsValue({ username: '', password: '', autoLogin: true }); | |||
| LocalStorage.removeItem(LocalStorage.loginUserKey); | |||
| } | |||
| } else { | |||
| form.setFieldsValue({ username: '', password: '', autoLogin: false }); | |||
| } | |||
| // getCaptchaCode(); | |||
| // const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false'; | |||
| // if (autoLogin === 'true') { | |||
| // const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey); | |||
| // const userJson = safeInvoke((text: string) => | |||
| // CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8), | |||
| // )(userStorage); | |||
| // const user = safeInvoke(parseJsonText)(userJson); | |||
| // if (user && typeof user === 'object' && user.version === VERSION) { | |||
| // const { username, password } = user; | |||
| // form.setFieldsValue({ username: username, password: password, autoLogin: true }); | |||
| // } else { | |||
| // form.setFieldsValue({ username: '', password: '', autoLogin: true }); | |||
| // LocalStorage.removeItem(LocalStorage.loginUserKey); | |||
| // } | |||
| // } else { | |||
| // form.setFieldsValue({ username: '', password: '', autoLogin: false }); | |||
| // } | |||
| getClientInfo(); | |||
| }, []); | |||
| const getClientInfo = async () => { | |||
| const [res] = await to(getClientInfoReq()); | |||
| if (res && res.data) { | |||
| const clientInfo = res.data; | |||
| SessionStorage.setItem(SessionStorage.clientInfoKey, clientInfo, true); | |||
| gotoOAuth2(); | |||
| } | |||
| }; | |||
| const getCaptchaCode = async () => { | |||
| const [res] = await to(getCaptchaImg()); | |||
| if (res) { | |||
| @@ -71,6 +82,12 @@ const Login = () => { | |||
| } | |||
| }; | |||
| const handleSubmit2 = async (values: API.LoginParams) => { | |||
| const url = | |||
| 'http://172.20.32.106:8080/oauth/authorize?client_id=ci4s&response_type=code&grant_type=authorization_code'; | |||
| window.location.href = url; | |||
| }; | |||
| // 登录 | |||
| const handleSubmit = async (values: API.LoginParams) => { | |||
| const [res, error] = await to(login({ ...values, uuid })); | |||
| @@ -109,113 +126,115 @@ const Login = () => { | |||
| } | |||
| }; | |||
| return ( | |||
| <div className={styles['user-login']}> | |||
| <div className={styles['user-login__left']}> | |||
| <div className={styles['user-login__left__top']}> | |||
| <img | |||
| src={require('@/assets/img/logo.png')} | |||
| style={{ width: '32px', marginRight: '12px' }} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| 智能材料科研平台 | |||
| </div> | |||
| <div className={styles['user-login__left__title']}> | |||
| <span>智能材料科研平台</span> | |||
| <img | |||
| src={require('@/assets/img/login-ai-logo.png')} | |||
| className={styles['user-login__left__title__img']} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div className={styles['user-login__left__message']}> | |||
| <span>大语言模型运维 统一管理平台</span> | |||
| </div> | |||
| <img | |||
| className={styles['user-login__left__bottom-img']} | |||
| src={require('@/assets/img/login-left-image.png')} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div className={styles['user-login__right']}> | |||
| <div> | |||
| <div className={styles['user-login__right__title']}> | |||
| <span style={{ color: '#111111' }}>欢迎登录</span> | |||
| <span>智能材料科研平台</span> | |||
| </div> | |||
| <div className={styles['user-login__right__content']}> | |||
| <div className={styles['user-login__right__content__title']}>账号登录</div> | |||
| <div className={styles['user-login__right__content__form']}> | |||
| <Form | |||
| labelCol={{ span: 0 }} | |||
| wrapperCol={{ span: 24 }} | |||
| initialValues={{ autoLogin: true }} | |||
| onFinish={handleSubmit} | |||
| autoComplete="off" | |||
| form={form} | |||
| > | |||
| <Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}> | |||
| <Input | |||
| placeholder="请输入用户名" | |||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| <Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}> | |||
| <Input.Password | |||
| placeholder="请输入密码" | |||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| <Flex align="start" style={{ height: '98px' }}> | |||
| <div style={{ flex: 1 }}> | |||
| <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}> | |||
| <Input | |||
| placeholder="请输入验证码" | |||
| prefix={ | |||
| <LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} /> | |||
| } | |||
| ref={captchaInputRef} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| </div> | |||
| <Image | |||
| className={styles['user-login__right__content__form__captcha']} | |||
| src={captchaCode} | |||
| alt="验证码" | |||
| preview={false} | |||
| onClick={() => getCaptchaCode()} | |||
| /> | |||
| </Flex> | |||
| <Form.Item | |||
| name="autoLogin" | |||
| valuePropName="checked" | |||
| labelCol={{ span: 0 }} | |||
| wrapperCol={{ span: 16 }} | |||
| > | |||
| <Checkbox>记住密码</Checkbox> | |||
| </Form.Item> | |||
| <Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> | |||
| <Button type="primary" htmlType="submit"> | |||
| 登录 | |||
| </Button> | |||
| </Form.Item> | |||
| </Form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ); | |||
| return <div className={styles['user-login']}></div>; | |||
| // return ( | |||
| // <div className={styles['user-login']}> | |||
| // <div className={styles['user-login__left']}> | |||
| // <div className={styles['user-login__left__top']}> | |||
| // <img | |||
| // src={require('@/assets/img/logo.png')} | |||
| // style={{ width: '32px', marginRight: '12px' }} | |||
| // draggable={false} | |||
| // alt="" | |||
| // /> | |||
| // 智能材料科研平台 | |||
| // </div> | |||
| // <div className={styles['user-login__left__title']}> | |||
| // <span>智能材料科研平台</span> | |||
| // <img | |||
| // src={require('@/assets/img/login-ai-logo.png')} | |||
| // className={styles['user-login__left__title__img']} | |||
| // draggable={false} | |||
| // alt="" | |||
| // /> | |||
| // </div> | |||
| // <div className={styles['user-login__left__message']}> | |||
| // <span>大语言模型运维 统一管理平台</span> | |||
| // </div> | |||
| // <img | |||
| // className={styles['user-login__left__bottom-img']} | |||
| // src={require('@/assets/img/login-left-image.png')} | |||
| // draggable={false} | |||
| // alt="" | |||
| // /> | |||
| // </div> | |||
| // <div className={styles['user-login__right']}> | |||
| // <div> | |||
| // <div className={styles['user-login__right__title']}> | |||
| // <span style={{ color: '#111111' }}>欢迎登录</span> | |||
| // <span>智能材料科研平台</span> | |||
| // </div> | |||
| // <div className={styles['user-login__right__content']}> | |||
| // <div className={styles['user-login__right__content__title']}>账号登录</div> | |||
| // <div className={styles['user-login__right__content__form']}> | |||
| // <Form | |||
| // labelCol={{ span: 0 }} | |||
| // wrapperCol={{ span: 24 }} | |||
| // initialValues={{ autoLogin: true }} | |||
| // onFinish={handleSubmit2} | |||
| // autoComplete="off" | |||
| // form={form} | |||
| // > | |||
| // <Form.Item name="username" rules={[{ required: false, message: '请输入用户名' }]}> | |||
| // <Input | |||
| // placeholder="请输入用户名" | |||
| // prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />} | |||
| // allowClear | |||
| // /> | |||
| // </Form.Item> | |||
| // <Form.Item name="password" rules={[{ required: false, message: '请输入密码' }]}> | |||
| // <Input.Password | |||
| // placeholder="请输入密码" | |||
| // prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />} | |||
| // allowClear | |||
| // /> | |||
| // </Form.Item> | |||
| // <Flex align="start" style={{ height: '98px' }}> | |||
| // <div style={{ flex: 1 }}> | |||
| // <Form.Item name="code" rules={[{ required: false, message: '请输入验证码' }]}> | |||
| // <Input | |||
| // placeholder="请输入验证码" | |||
| // prefix={ | |||
| // <LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} /> | |||
| // } | |||
| // ref={captchaInputRef} | |||
| // allowClear | |||
| // /> | |||
| // </Form.Item> | |||
| // </div> | |||
| // <Image | |||
| // className={styles['user-login__right__content__form__captcha']} | |||
| // src={captchaCode} | |||
| // alt="验证码" | |||
| // preview={false} | |||
| // onClick={() => getCaptchaCode()} | |||
| // /> | |||
| // </Flex> | |||
| // <Form.Item | |||
| // name="autoLogin" | |||
| // valuePropName="checked" | |||
| // labelCol={{ span: 0 }} | |||
| // wrapperCol={{ span: 16 }} | |||
| // > | |||
| // <Checkbox>记住密码</Checkbox> | |||
| // </Form.Item> | |||
| // <Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> | |||
| // <Button type="primary" htmlType="submit"> | |||
| // 登录 | |||
| // </Button> | |||
| // </Form.Item> | |||
| // </Form> | |||
| // </div> | |||
| // </div> | |||
| // </div> | |||
| // </div> | |||
| // </div> | |||
| // ); | |||
| }; | |||
| export default Login; | |||
| @@ -0,0 +1,221 @@ | |||
| import { clearSessionToken, setSessionToken } from '@/access'; | |||
| import { getCaptchaImg, login } from '@/services/system/auth'; | |||
| import { parseJsonText } from '@/utils'; | |||
| import { safeInvoke } from '@/utils/functional'; | |||
| import LocalStorage from '@/utils/localStorage'; | |||
| import { to } from '@/utils/promise'; | |||
| import { history, useModel } from '@umijs/max'; | |||
| import { Button, Checkbox, Flex, Form, Image, Input, message, type InputRef } from 'antd'; | |||
| import CryptoJS from 'crypto-js'; | |||
| import { useEffect, useRef, useState } from 'react'; | |||
| import { flushSync } from 'react-dom'; | |||
| import styles from './login.less'; | |||
| const VERSION = 1; | |||
| const AESKEY = 'OPENSOURCETECHNOLOGYCENTER'; | |||
| const LoginInputPrefix = ({ icon }: { icon: string }) => { | |||
| return ( | |||
| <div className={styles['login-input-prefix']}> | |||
| <img className={styles['login-input-prefix__icon']} src={icon} alt="" draggable={false} /> | |||
| <div className={styles['login-input-prefix__line']}></div> | |||
| </div> | |||
| ); | |||
| }; | |||
| const Login = () => { | |||
| const { initialState, setInitialState } = useModel('@@initialState'); | |||
| const [captchaCode, setCaptchaCode] = useState<string>(''); | |||
| const [uuid, setUuid] = useState<string>(''); | |||
| const [form] = Form.useForm(); | |||
| const captchaInputRef = useRef<InputRef>(null); | |||
| useEffect(() => { | |||
| getCaptchaCode(); | |||
| const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false'; | |||
| if (autoLogin === 'true') { | |||
| const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey); | |||
| const userJson = safeInvoke((text: string) => | |||
| CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8), | |||
| )(userStorage); | |||
| const user = safeInvoke(parseJsonText)(userJson); | |||
| if (user && typeof user === 'object' && user.version === VERSION) { | |||
| const { username, password } = user; | |||
| form.setFieldsValue({ username: username, password: password, autoLogin: true }); | |||
| } else { | |||
| form.setFieldsValue({ username: '', password: '', autoLogin: true }); | |||
| LocalStorage.removeItem(LocalStorage.loginUserKey); | |||
| } | |||
| } else { | |||
| form.setFieldsValue({ username: '', password: '', autoLogin: false }); | |||
| } | |||
| }, []); | |||
| const getCaptchaCode = async () => { | |||
| const [res] = await to(getCaptchaImg()); | |||
| if (res) { | |||
| const imgdata = `data:image/png;base64,${res.img}`; | |||
| setCaptchaCode(imgdata); | |||
| setUuid(res.uuid); | |||
| } | |||
| }; | |||
| const fetchUserInfo = async () => { | |||
| const userInfo = await initialState?.fetchUserInfo?.(); | |||
| if (userInfo) { | |||
| flushSync(() => { | |||
| setInitialState((s) => ({ | |||
| ...s, | |||
| currentUser: userInfo, | |||
| })); | |||
| }); | |||
| } | |||
| }; | |||
| // 登录 | |||
| const handleSubmit = async (values: API.LoginParams) => { | |||
| const [res, error] = await to(login({ ...values, uuid })); | |||
| if (res && res.data) { | |||
| const current = new Date(); | |||
| const expireTime = current.setTime(current.getTime() + 1000 * 12 * 60 * 60); | |||
| const { access_token } = res.data; | |||
| setSessionToken(access_token, access_token, expireTime); | |||
| message.success('登录成功!'); | |||
| LocalStorage.setItem(LocalStorage.rememberPasswordKey, values.autoLogin ? 'true' : 'false'); | |||
| if (values.autoLogin) { | |||
| const user = { | |||
| username: values.username, | |||
| password: values.password, | |||
| version: VERSION, | |||
| }; | |||
| const encrypted = CryptoJS.AES.encrypt(JSON.stringify(user), AESKEY).toString(); | |||
| LocalStorage.setItem(LocalStorage.loginUserKey, encrypted); | |||
| } else { | |||
| LocalStorage.removeItem(LocalStorage.loginUserKey); | |||
| } | |||
| await fetchUserInfo(); | |||
| const urlParams = new URL(window.location.href).searchParams; | |||
| history.push(urlParams.get('redirect') || '/'); | |||
| } else { | |||
| if (error?.data?.code === 500 && error?.data?.msg === '验证码错误') { | |||
| captchaInputRef.current?.focus({ | |||
| cursor: 'all', | |||
| }); | |||
| } | |||
| clearSessionToken(); | |||
| getCaptchaCode(); | |||
| } | |||
| }; | |||
| return ( | |||
| <div className={styles['user-login']}> | |||
| <div className={styles['user-login__left']}> | |||
| <div className={styles['user-login__left__top']}> | |||
| <img | |||
| src={require('@/assets/img/logo.png')} | |||
| style={{ width: '32px', marginRight: '12px' }} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| 智能材料科研平台 | |||
| </div> | |||
| <div className={styles['user-login__left__title']}> | |||
| <span>智能材料科研平台</span> | |||
| <img | |||
| src={require('@/assets/img/login-ai-logo.png')} | |||
| className={styles['user-login__left__title__img']} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div className={styles['user-login__left__message']}> | |||
| <span>大语言模型运维 统一管理平台</span> | |||
| </div> | |||
| <img | |||
| className={styles['user-login__left__bottom-img']} | |||
| src={require('@/assets/img/login-left-image.png')} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div className={styles['user-login__right']}> | |||
| <div> | |||
| <div className={styles['user-login__right__title']}> | |||
| <span style={{ color: '#111111' }}>欢迎登录</span> | |||
| <span>智能材料科研平台</span> | |||
| </div> | |||
| <div className={styles['user-login__right__content']}> | |||
| <div className={styles['user-login__right__content__title']}>账号登录</div> | |||
| <div className={styles['user-login__right__content__form']}> | |||
| <Form | |||
| labelCol={{ span: 0 }} | |||
| wrapperCol={{ span: 24 }} | |||
| initialValues={{ autoLogin: true }} | |||
| onFinish={handleSubmit} | |||
| autoComplete="off" | |||
| form={form} | |||
| > | |||
| <Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}> | |||
| <Input | |||
| placeholder="请输入用户名" | |||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| <Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}> | |||
| <Input.Password | |||
| placeholder="请输入密码" | |||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| <Flex align="start" style={{ height: '98px' }}> | |||
| <div style={{ flex: 1 }}> | |||
| <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}> | |||
| <Input | |||
| placeholder="请输入验证码" | |||
| prefix={ | |||
| <LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} /> | |||
| } | |||
| ref={captchaInputRef} | |||
| allowClear | |||
| /> | |||
| </Form.Item> | |||
| </div> | |||
| <Image | |||
| className={styles['user-login__right__content__form__captcha']} | |||
| src={captchaCode} | |||
| alt="验证码" | |||
| preview={false} | |||
| onClick={() => getCaptchaCode()} | |||
| /> | |||
| </Flex> | |||
| <Form.Item | |||
| name="autoLogin" | |||
| valuePropName="checked" | |||
| labelCol={{ span: 0 }} | |||
| wrapperCol={{ span: 16 }} | |||
| > | |||
| <Checkbox>记住密码</Checkbox> | |||
| </Form.Item> | |||
| <Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> | |||
| <Button type="primary" htmlType="submit"> | |||
| 登录 | |||
| </Button> | |||
| </Form.Item> | |||
| </Form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ); | |||
| }; | |||
| export default Login; | |||
| @@ -0,0 +1,16 @@ | |||
| import { request } from '@umijs/max'; | |||
| // 单点登录 | |||
| export function loginByOauth2Req(data) { | |||
| return request(`/api/auth/loginByOauth2`, { | |||
| method: 'POST', | |||
| data, | |||
| }); | |||
| } | |||
| // 登录获取客户端信息 | |||
| export function getClientInfoReq() { | |||
| return request(`/api/auth/oauth2ClientInfo`, { | |||
| method: 'GET', | |||
| }); | |||
| } | |||
| @@ -7,6 +7,17 @@ | |||
| import { ExperimentStatus, TensorBoardStatus } from '@/enums'; | |||
| import type { Settings as LayoutSettings } from '@ant-design/pro-components'; | |||
| export type ClientInfo = { | |||
| accessTokenUri: string; | |||
| checkTokenUri: string; | |||
| clientId: string; | |||
| clientSecret: string; | |||
| loginPage: string; | |||
| logoutUri: string; | |||
| redirectUri: string; | |||
| userAuthorizationUri: string; | |||
| }; | |||
| // 全局初始状态类型 | |||
| export type GlobalInitialState = { | |||
| settings?: Partial<LayoutSettings>; | |||
| @@ -14,6 +25,7 @@ export type GlobalInitialState = { | |||
| fetchUserInfo?: () => Promise<API.CurrentUser | undefined>; | |||
| loading?: boolean; | |||
| collapsed?: boolean; | |||
| clientInfo?: ClientInfo; | |||
| }; | |||
| // 流水线全局参数 | |||
| @@ -9,6 +9,8 @@ export default class SessionStorage { | |||
| static readonly serviceVersionInfoKey = 'service-version-info'; | |||
| // 编辑器 url | |||
| static readonly editorUrlKey = 'editor-url'; | |||
| // 客户端信息 | |||
| static readonly clientInfoKey = 'client-info'; | |||
| static getItem(key: string, isObject: boolean = false) { | |||
| const jsonStr = sessionStorage.getItem(key); | |||
| @@ -6,9 +6,11 @@ | |||
| import { PageEnum } from '@/enums/pagesEnums'; | |||
| import { removeAllPageCacheState } from '@/hooks/pageCacheState'; | |||
| import themes from '@/styles/theme.less'; | |||
| import { type ClientInfo } from '@/types'; | |||
| import { history } from '@umijs/max'; | |||
| import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; | |||
| import { closeAllModals } from './modal'; | |||
| import SessionStorage from './sessionStorage'; | |||
| type ModalConfirmProps = ModalFuncProps & { | |||
| isDelete?: boolean; | |||
| @@ -86,6 +88,15 @@ export const gotoLoginPage = (toHome: boolean = true) => { | |||
| } | |||
| }; | |||
| export const gotoOAuth2 = () => { | |||
| const clientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true) as ClientInfo; | |||
| if (clientInfo) { | |||
| const { clientId, userAuthorizationUri } = clientInfo; | |||
| const url = `${userAuthorizationUri}?client_id=${clientId}&response_type=code&grant_type=authorization_code`; | |||
| location.replace(url); | |||
| } | |||
| }; | |||
| /** | |||
| * 验证文件上传 | |||
| * | |||
| @@ -0,0 +1,25 @@ | |||
| package com.ruoyi.auth.config; | |||
| import lombok.Getter; | |||
| import lombok.Setter; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import org.springframework.cloud.context.config.annotation.RefreshScope; | |||
| import org.springframework.context.annotation.Configuration; | |||
| @Configuration | |||
| @RefreshScope | |||
| @ConfigurationProperties(prefix = "oauth2") | |||
| @Getter | |||
| @Setter | |||
| public class Oauth2ClientProperties { | |||
| private String clientId; | |||
| private String clientSecret; | |||
| private String scope; | |||
| private String userAuthorizationUri; | |||
| private String accessTokenUri; | |||
| private String redirectUri; | |||
| private String logoutUri; | |||
| private String checkTokenUri; | |||
| private String loginPage; | |||
| } | |||
| @@ -2,12 +2,19 @@ package com.ruoyi.auth.controller; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.ruoyi.auth.config.Oauth2ClientProperties; | |||
| import com.ruoyi.auth.form.AccessTokenVo; | |||
| import com.ruoyi.auth.form.LoginKeyBody; | |||
| import com.ruoyi.common.core.exception.ServiceException; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.DeleteMapping; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import org.springframework.http.HttpEntity; | |||
| import org.springframework.http.HttpHeaders; | |||
| import org.springframework.http.MediaType; | |||
| import org.springframework.http.ResponseEntity; | |||
| import org.springframework.util.LinkedMultiValueMap; | |||
| import org.springframework.util.MultiValueMap; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import com.ruoyi.auth.form.LoginBody; | |||
| import com.ruoyi.auth.form.RegisterBody; | |||
| import com.ruoyi.auth.service.SysLoginService; | |||
| @@ -18,6 +25,9 @@ import com.ruoyi.common.security.auth.AuthUtil; | |||
| import com.ruoyi.common.security.service.TokenService; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| import com.ruoyi.system.api.model.LoginUser; | |||
| import org.springframework.web.client.RestTemplate; | |||
| import java.util.Map; | |||
| /** | |||
| * token 控制 | |||
| @@ -33,6 +43,9 @@ public class TokenController | |||
| @Autowired | |||
| private SysLoginService sysLoginService; | |||
| @Autowired | |||
| private Oauth2ClientProperties oauth2ClientProperties; | |||
| @PostMapping("login") | |||
| public R<?> login(@RequestBody LoginBody form) | |||
| { | |||
| @@ -51,6 +64,64 @@ public class TokenController | |||
| return R.ok(tokenService.createToken(userInfo)); | |||
| } | |||
| @PostMapping("loginByOauth2") | |||
| public R<?> loginByOauth2(@RequestBody Map<String,String> params) | |||
| /** | |||
| * { | |||
| * "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZGVtby1hcHAiXSwiZXhwIjoxNzI5MTU0MTExLCJ1c2VyX25hbWUiOiJhZG1pbiIsImp0aSI6IjQzNGVkNmI0LWIzN2MtNDliMS04NTczLWZhNmU4YTg5YTUxYSIsImNsaWVudF9pZCI6IkFCQyIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdfQ.U591q4fUaUBtBt5Ex-S2daM7DIl9-Ov0MsveymNfHxI", | |||
| * "token_type": "bearer", | |||
| * "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZGVtby1hcHAiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiYXRpIjoiNDM0ZWQ2YjQtYjM3Yy00OWIxLTg1NzMtZmE2ZThhODlhNTFhIiwiZXhwIjoxNzMxNjQ5OTY4LCJqdGkiOiJiODFhNmJkMC02ZDQzLTQ4M2QtOThmMy1hZWIxNDcyZDUwNzciLCJjbGllbnRfaWQiOiJBQkMifQ.0uMYVqW1G7j0chwxIdWGwpjDr12ogZPcD1iQfPsAs5k", | |||
| * "expires_in": 7198, | |||
| * "scope": "read write", | |||
| * "account_info": { | |||
| * "id": 1, | |||
| * "clientId": "ABC", | |||
| * "username": "admin", | |||
| * "mobile": "1232378743", | |||
| * "email": "abc@123.com" | |||
| * } | |||
| * } | |||
| */ | |||
| { | |||
| if (params.containsKey("code") && StringUtils.isNotBlank(params.get("code"))){ | |||
| RestTemplate restTemplate = new RestTemplate(); | |||
| String url = oauth2ClientProperties.getAccessTokenUri(); | |||
| HttpHeaders headers = new HttpHeaders(); | |||
| headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |||
| MultiValueMap<String, String> map= new LinkedMultiValueMap<>(); | |||
| map.add("grant_type", "authorization_code"); | |||
| map.add("code", params.get("code")); | |||
| map.add("redirect_uri", oauth2ClientProperties.getRedirectUri()); | |||
| map.add("client_id", oauth2ClientProperties.getClientId()); | |||
| map.add("client_secret", oauth2ClientProperties.getClientSecret()); | |||
| HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); | |||
| ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class); | |||
| String body = response.getBody(); | |||
| AccessTokenVo accessTokenVo = JSON.parseObject(body, AccessTokenVo.class); | |||
| String accessToken = accessTokenVo.getAccess_token(); | |||
| AccessTokenVo.Account_info accountInfo = accessTokenVo.getAccount_info(); | |||
| // 用户登录 | |||
| LoginUser userInfo = sysLoginService.login(accountInfo); | |||
| // 获取登录token | |||
| Map<String, Object> token = tokenService.createToken(userInfo); | |||
| token.put("checkTokenUri",oauth2ClientProperties.getCheckTokenUri()); | |||
| token.put("logoutUri",oauth2ClientProperties.getLogoutUri()); | |||
| token.put("oauth2AccessToken",accessToken); | |||
| return R.ok(token); | |||
| } | |||
| throw new ServiceException("用户信息获取失败"); | |||
| } | |||
| @GetMapping("oauth2ClientInfo") | |||
| public R<?> getClientInfo() { | |||
| return R.ok(JSON.toJSON(oauth2ClientProperties)); | |||
| } | |||
| @DeleteMapping("logout") | |||
| public R<?> logout(HttpServletRequest request) | |||
| { | |||
| @@ -0,0 +1,119 @@ | |||
| package com.ruoyi.auth.form; | |||
| import java.io.Serializable; | |||
| import java.lang.Integer; | |||
| import java.lang.String; | |||
| public class AccessTokenVo implements Serializable { | |||
| private String access_token; | |||
| private String refresh_token; | |||
| private String scope; | |||
| private Account_info account_info; | |||
| private String token_type; | |||
| private Integer expires_in; | |||
| public String getAccess_token() { | |||
| return this.access_token; | |||
| } | |||
| public void setAccess_token(String access_token) { | |||
| this.access_token = access_token; | |||
| } | |||
| public String getRefresh_token() { | |||
| return this.refresh_token; | |||
| } | |||
| public void setRefresh_token(String refresh_token) { | |||
| this.refresh_token = refresh_token; | |||
| } | |||
| public String getScope() { | |||
| return this.scope; | |||
| } | |||
| public void setScope(String scope) { | |||
| this.scope = scope; | |||
| } | |||
| public Account_info getAccount_info() { | |||
| return this.account_info; | |||
| } | |||
| public void setAccount_info(Account_info account_info) { | |||
| this.account_info = account_info; | |||
| } | |||
| public String getToken_type() { | |||
| return this.token_type; | |||
| } | |||
| public void setToken_type(String token_type) { | |||
| this.token_type = token_type; | |||
| } | |||
| public Integer getExpires_in() { | |||
| return this.expires_in; | |||
| } | |||
| public void setExpires_in(Integer expires_in) { | |||
| this.expires_in = expires_in; | |||
| } | |||
| public static class Account_info implements Serializable { | |||
| private String clientId; | |||
| private String mobile; | |||
| private Integer id; | |||
| private String email; | |||
| private String username; | |||
| public String getClientId() { | |||
| return this.clientId; | |||
| } | |||
| public void setClientId(String clientId) { | |||
| this.clientId = clientId; | |||
| } | |||
| public String getMobile() { | |||
| return this.mobile; | |||
| } | |||
| public void setMobile(String mobile) { | |||
| this.mobile = mobile; | |||
| } | |||
| public Integer getId() { | |||
| return this.id; | |||
| } | |||
| public void setId(Integer id) { | |||
| this.id = id; | |||
| } | |||
| public String getEmail() { | |||
| return this.email; | |||
| } | |||
| public void setEmail(String email) { | |||
| this.email = email; | |||
| } | |||
| public String getUsername() { | |||
| return this.username; | |||
| } | |||
| public void setUsername(String username) { | |||
| this.username = username; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| package com.ruoyi.auth.service; | |||
| import com.ruoyi.auth.form.AccessTokenVo; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Component; | |||
| import com.ruoyi.common.core.constant.CacheConstants; | |||
| @@ -193,4 +194,62 @@ public class SysLoginService | |||
| } | |||
| return userInfo; | |||
| } | |||
| public LoginUser login(AccessTokenVo.Account_info accountInfo) { | |||
| String username = accountInfo.getUsername(); | |||
| // 用户名或密码为空 错误 | |||
| if (StringUtils.isAnyBlank(username)) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); | |||
| throw new ServiceException("用户/密码必须填写"); | |||
| } | |||
| // 用户名不在指定范围内 错误 | |||
| if (username.length() < UserConstants.USERNAME_MIN_LENGTH | |||
| || username.length() > UserConstants.USERNAME_MAX_LENGTH) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); | |||
| throw new ServiceException("用户名不在指定范围"); | |||
| } | |||
| // IP黑名单校验 | |||
| String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); | |||
| if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); | |||
| throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); | |||
| } | |||
| // 查询用户信息 | |||
| R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); | |||
| if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); | |||
| throw new ServiceException("登录用户:" + username + " 不存在"); | |||
| // register(username, "123456"); | |||
| // userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); | |||
| } | |||
| if (R.FAIL == userResult.getCode()) | |||
| { | |||
| throw new ServiceException(userResult.getMsg()); | |||
| } | |||
| LoginUser userInfo = userResult.getData(); | |||
| SysUser user = userResult.getData().getSysUser(); | |||
| if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); | |||
| throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); | |||
| } | |||
| if (UserStatus.DISABLE.getCode().equals(user.getStatus())) | |||
| { | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); | |||
| throw new ServiceException("对不起,您的账号:" + username + " 已停用"); | |||
| } | |||
| recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); | |||
| return userInfo; | |||
| } | |||
| } | |||
| @@ -14,14 +14,16 @@ spring: | |||
| nacos: | |||
| discovery: | |||
| # 服务注册地址 | |||
| server-addr: nacos-ci4s.ci4s-test.svc:8848 | |||
| server-addr: nacos-ci4s.argo.svc:8848 | |||
| username: nacos | |||
| password: nacos | |||
| password: h1n2x3j4y5@ | |||
| retry: | |||
| enabled: true | |||
| config: | |||
| username: nacos | |||
| password: h1n2x3j4y5@ | |||
| # 配置中心地址 | |||
| server-addr: nacos-ci4s.ci4s-test.svc:8848 | |||
| server-addr: nacos-ci4s.argo.svc:8848 | |||
| # 配置文件格式 | |||
| file-extension: yml | |||
| # 共享配置 | |||
| @@ -3,7 +3,7 @@ server: | |||
| port: 8082 | |||
| # Spring | |||
| spring: | |||
| spring: | |||
| application: | |||
| # 应用名称 | |||
| name: ruoyi-gateway | |||
| @@ -14,14 +14,16 @@ spring: | |||
| nacos: | |||
| discovery: | |||
| # 服务注册地址 | |||
| server-addr: nacos-ci4s.ci4s-test.svc:8848 | |||
| server-addr: nacos-ci4s.argo.svc:8848 | |||
| username: nacos | |||
| password: nacos | |||
| password: h1n2x3j4y5@ | |||
| retry: | |||
| enabled: true | |||
| config: | |||
| username: nacos | |||
| password: h1n2x3j4y5@ | |||
| # 配置中心地址 | |||
| server-addr: nacos-ci4s.ci4s-test.svc:8848 | |||
| server-addr: nacos-ci4s.argo.svc:8848 | |||
| # 配置文件格式 | |||
| file-extension: yml | |||
| # 共享配置 | |||
| @@ -42,7 +44,7 @@ spring: | |||
| datasource: | |||
| ds1: | |||
| nacos: | |||
| server-addr: nacos-ci4s.ci4s-test.svc:18848 | |||
| server-addr: 172.20.32.181:18848 | |||
| dataId: sentinel-ruoyi-gateway | |||
| groupId: DEFAULT_GROUP | |||
| data-type: json | |||
| @@ -243,6 +243,11 @@ | |||
| <version>3.6.0</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>cn.hutool</groupId> | |||
| <artifactId>hutool-all</artifactId> | |||
| <version>5.8.5</version> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| @@ -5,6 +5,7 @@ import com.ruoyi.common.security.annotation.EnableRyFeignClients; | |||
| import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.scheduling.annotation.EnableAsync; | |||
| import org.springframework.scheduling.annotation.EnableScheduling; | |||
| /** | |||
| @@ -17,6 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; | |||
| @EnableRyFeignClients | |||
| @SpringBootApplication | |||
| @EnableScheduling | |||
| @EnableAsync | |||
| public class RuoYiManagementPlatformApplication { | |||
| public static void main(String[] args) { | |||
| SpringApplication.run(RuoYiManagementPlatformApplication.class, args); | |||
| @@ -10,12 +10,29 @@ public class Constant { | |||
| public final static int State_valid = 1; // 有效 | |||
| public final static int State_invalid = 0; // 无效 | |||
| public final static int State_building = 2; //创建中 | |||
| public final static int State_failed = 3; //运行失败 | |||
| public final static int Used_State_used = 1; // 已占用 | |||
| public final static int Used_State_unused = 0; // 未占用 | |||
| public final static String Computing_Resource_CPU = "CPU"; // 计算资源_CPU | |||
| public final static String Computing_Resource_GPU = "GPU"; // 计算资源_GPU | |||
| public final static int Git_Category_Id = 39; | |||
| public final static String Source_Auto_Export = "auto_export"; | |||
| public final static String Source_Hand_Export = "hand_export"; | |||
| public final static String Source_Add = "add"; | |||
| public final static String Running = "Running"; | |||
| public final static String Failed = "Failed"; | |||
| public final static String Pending = "Pending"; | |||
| public final static String Init = "Init"; | |||
| public final static String Stopped = "Stopped"; | |||
| public final static String Succeeded = "Succeeded"; | |||
| public final static String Type_Train = "train"; | |||
| public final static String Type_Evaluate = "evaluate"; | |||
| } | |||
| @@ -1,11 +1,10 @@ | |||
| package com.ruoyi.platform.controller.aim; | |||
| import com.ruoyi.common.core.web.controller.BaseController; | |||
| import com.ruoyi.common.core.web.domain.AjaxResult; | |||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||
| import com.ruoyi.platform.service.AimService; | |||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||
| import com.ruoyi.platform.vo.InsMetricInfoVo; | |||
| import com.ruoyi.platform.vo.PodStatusVo; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||
| @@ -26,21 +25,25 @@ public class AimController extends BaseController { | |||
| @GetMapping("/getExpTrainInfos/{experiment_id}") | |||
| @ApiOperation("获取当前实验的模型训练指标信息") | |||
| @ApiResponse | |||
| public GenericsAjaxResult<List<InsMetricInfoVo>> getExpTrainInfos(@PathVariable("experiment_id") Integer experimentId) throws Exception { | |||
| return genericsSuccess(aimService.getExpTrainInfos(experimentId)); | |||
| public AjaxResult getExpTrainInfos(@RequestParam(value = "page") int page, | |||
| @RequestParam(value = "size") int size, | |||
| @PathVariable("experiment_id") Integer experimentId) { | |||
| return AjaxResult.success(aimService.getExpInfos(true, experimentId, page, size)); | |||
| } | |||
| @GetMapping("/getExpEvaluateInfos/{experiment_id}") | |||
| @ApiOperation("获取当前实验的模型推理指标信息") | |||
| @ApiResponse | |||
| public GenericsAjaxResult<List<InsMetricInfoVo>> getExpEvaluateInfos(@PathVariable("experiment_id") Integer experimentId) throws Exception { | |||
| return genericsSuccess(aimService.getExpEvaluateInfos(experimentId)); | |||
| public AjaxResult getExpEvaluateInfos(@RequestParam(value = "page") int page, | |||
| @RequestParam(value = "size") int size, | |||
| @PathVariable("experiment_id") Integer experimentId) { | |||
| return AjaxResult.success(aimService.getExpInfos(false, experimentId, page, size)); | |||
| } | |||
| @PostMapping("/getExpMetrics") | |||
| @ApiOperation("获取当前实验的指标对比地址") | |||
| @ApiResponse | |||
| public GenericsAjaxResult<String> getExpMetrics(@RequestBody List<String> runIds) throws Exception { | |||
| return genericsSuccess(aimService.getExpMetrics(runIds)); | |||
| return genericsSuccess(aimService.getExpMetrics(runIds)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,84 @@ | |||
| package com.ruoyi.platform.controller.dataset; | |||
| import com.ruoyi.platform.domain.DatasetTempStorage; | |||
| import com.ruoyi.platform.service.DatasetTempStorageService; | |||
| import org.springframework.data.domain.Page; | |||
| import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.http.ResponseEntity; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.annotation.Resource; | |||
| /** | |||
| * 数据集暂存的数据(DatasetTempStorage)表控制层 | |||
| * | |||
| * @author makejava | |||
| * @since 2024-09-12 09:42:09 | |||
| */ | |||
| @RestController | |||
| @RequestMapping("datasetTempStorage") | |||
| public class DatasetTempStorageController { | |||
| /** | |||
| * 服务对象 | |||
| */ | |||
| @Resource | |||
| private DatasetTempStorageService datasetTempStorageService; | |||
| /** | |||
| * 分页查询 | |||
| * | |||
| * @param datasetTempStorage 筛选条件 | |||
| * @param pageRequest 分页对象 | |||
| * @return 查询结果 | |||
| */ | |||
| @GetMapping | |||
| public ResponseEntity<Page<DatasetTempStorage>> queryByPage(DatasetTempStorage datasetTempStorage, PageRequest pageRequest) { | |||
| return ResponseEntity.ok(this.datasetTempStorageService.queryByPage(datasetTempStorage, pageRequest)); | |||
| } | |||
| /** | |||
| * 通过主键查询单条数据 | |||
| * | |||
| * @param id 主键 | |||
| * @return 单条数据 | |||
| */ | |||
| @GetMapping("{id}") | |||
| public ResponseEntity<DatasetTempStorage> queryById(@PathVariable("id") Integer id) { | |||
| return ResponseEntity.ok(this.datasetTempStorageService.queryById(id)); | |||
| } | |||
| /** | |||
| * 新增数据 | |||
| * | |||
| * @param datasetTempStorage 实体 | |||
| * @return 新增结果 | |||
| */ | |||
| @PostMapping | |||
| public ResponseEntity<DatasetTempStorage> add(DatasetTempStorage datasetTempStorage) { | |||
| return ResponseEntity.ok(this.datasetTempStorageService.insert(datasetTempStorage)); | |||
| } | |||
| /** | |||
| * 编辑数据 | |||
| * | |||
| * @param datasetTempStorage 实体 | |||
| * @return 编辑结果 | |||
| */ | |||
| @PutMapping | |||
| public ResponseEntity<DatasetTempStorage> edit(DatasetTempStorage datasetTempStorage) { | |||
| return ResponseEntity.ok(this.datasetTempStorageService.update(datasetTempStorage)); | |||
| } | |||
| /** | |||
| * 删除数据 | |||
| * | |||
| * @param id 主键 | |||
| * @return 删除是否成功 | |||
| */ | |||
| @DeleteMapping | |||
| public ResponseEntity<Boolean> deleteById(Integer id) { | |||
| return ResponseEntity.ok(this.datasetTempStorageService.deleteById(id)); | |||
| } | |||
| } | |||
| @@ -2,9 +2,8 @@ package com.ruoyi.platform.controller.dataset; | |||
| import com.ruoyi.common.core.web.domain.AjaxResult; | |||
| import com.ruoyi.platform.domain.Dataset; | |||
| import com.ruoyi.platform.service.DatasetService; | |||
| import com.ruoyi.platform.vo.DatasetVo; | |||
| import io.swagger.annotations.Api; | |||
| import com.ruoyi.platform.service.NewDatasetService; | |||
| import com.ruoyi.platform.vo.NewDatasetVo; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.springframework.core.io.InputStreamResource; | |||
| import org.springframework.data.domain.PageRequest; | |||
| @@ -13,16 +12,18 @@ import org.springframework.web.bind.annotation.*; | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| import javax.annotation.Resource; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @RestController | |||
| @RequestMapping("newdataset") | |||
| @Api(value = "新数据集管理") | |||
| //@Api(value = "新数据集管理") | |||
| public class NewDatasetFromGitController { | |||
| /** | |||
| * 服务对象 | |||
| */ | |||
| @Resource | |||
| private DatasetService datasetService; | |||
| private NewDatasetService newDatasetService; | |||
| /** | |||
| @@ -33,8 +34,8 @@ public class NewDatasetFromGitController { | |||
| */ | |||
| @PostMapping("/addDatasetAndVersion") | |||
| @ApiOperation("添加数据集和版本") | |||
| public AjaxResult addDatasetAndVersion(@RequestBody DatasetVo datasetVo) throws Exception { | |||
| return AjaxResult.success(this.datasetService.newCreateDataset(datasetVo)); | |||
| public AjaxResult addDatasetAndVersion(@RequestBody NewDatasetVo datasetVo) throws Exception { | |||
| return AjaxResult.success(this.newDatasetService.newCreateDataset(datasetVo)); | |||
| } | |||
| @@ -47,69 +48,104 @@ public class NewDatasetFromGitController { | |||
| */ | |||
| @PostMapping("/addVersion") | |||
| @ApiOperation("添加版本") | |||
| public AjaxResult addVersion(@RequestBody DatasetVo datasetVo) throws Exception { | |||
| return AjaxResult.success(this.datasetService.newCreateVersion(datasetVo)); | |||
| public AjaxResult addVersion(@RequestBody NewDatasetVo datasetVo) throws Exception { | |||
| return AjaxResult.success(this.newDatasetService.newCreateVersion(datasetVo)); | |||
| } | |||
| @GetMapping("/queryDatasets") | |||
| @ApiOperation("数据集广场公开数据集分页查询,根据data_type,data_tag筛选,true公开false私有") | |||
| public AjaxResult queryDatasets(@RequestParam("page") int page, | |||
| @RequestParam("size") int size, | |||
| @RequestParam(value = "is_public") Boolean isPublic, | |||
| @RequestParam(value = "data_type", required = false) String dataType, | |||
| @RequestParam(value = "data_tag", required = false) String dataTag, | |||
| @RequestParam(value = "name", required = false) String name) throws Exception { | |||
| PageRequest pageRequest = PageRequest.of(page, size); | |||
| Dataset dataset = new Dataset(); | |||
| dataset.setDataTag(dataTag); | |||
| dataset.setDataType(dataType); | |||
| dataset.setName(name); | |||
| if (isPublic) { | |||
| return AjaxResult.success(this.newDatasetService.newPubilcQueryByPage(dataset, pageRequest)); | |||
| } else { | |||
| return AjaxResult.success(this.newDatasetService.newPersonalQueryByPage(dataset, pageRequest)); | |||
| } | |||
| } | |||
| @GetMapping("/getVersionList") | |||
| @ApiOperation(value = "获取分支列表") | |||
| public AjaxResult getVersionList(@RequestParam("identifier") String repo, @RequestParam("owner") String owner) throws Exception { | |||
| return AjaxResult.success(this.newDatasetService.getVersionList(repo, owner)); | |||
| } | |||
| @GetMapping("/getDatasetDetail") | |||
| @ApiOperation(value = "获取数据集详情") | |||
| public AjaxResult getDatasetVersions(@RequestParam("name") String name, | |||
| @RequestParam("id") Integer id, | |||
| @RequestParam(value = "owner", required = false) String owner, | |||
| @RequestParam(value = "identifier", required = false) String identifier, | |||
| @RequestParam(value = "version", required = false) String version) throws Exception { | |||
| return AjaxResult.success(this.newDatasetService.getNewDatasetDesc(id, name, identifier, owner, version)); | |||
| } | |||
| @DeleteMapping("/deleteDataset") | |||
| @ApiOperation(value = "删除数据集") | |||
| public AjaxResult deleteDataset(@RequestParam("id") Integer id, @RequestParam("identifier") String identifier, @RequestParam("owner") String owner) throws Exception { | |||
| this.newDatasetService.deleteDatasetNew(id, identifier, owner); | |||
| return AjaxResult.success(); | |||
| } | |||
| @DeleteMapping("/deleteDatasetVersion") | |||
| @ApiOperation(value = "删除数据集版本") | |||
| public AjaxResult deleteDatasetVersion(@RequestParam("identifier") String repo, @RequestParam("owner") String owner, @RequestParam("version") String version, | |||
| @RequestParam("relative_paths") String relativePaths) throws Exception { | |||
| // 查询版本,如果是最后一个版本,则不能删除 | |||
| List<Map<String, Object>> versionList = this.newDatasetService.getVersionList(repo, owner); | |||
| if (versionList.size() == 1) { | |||
| return AjaxResult.error("当前数据集只有一个版本,不能删除该版本"); | |||
| } | |||
| this.newDatasetService.deleteDatasetVersionNew(repo, owner, version, relativePaths); | |||
| return AjaxResult.success(); | |||
| } | |||
| /** | |||
| * 上传数据集 | |||
| * | |||
| * @param files 上传的数据集文件 | |||
| * @param uuid 上传唯一标识,构建url | |||
| * @param uuid 上传唯一标识,构建url | |||
| * @return 上传结果 | |||
| */ | |||
| @CrossOrigin(origins = "*", allowedHeaders = "*") | |||
| @PostMapping("/upload") | |||
| @ApiOperation(value = "上传数据集") | |||
| public AjaxResult uploadDataset(@RequestParam("file") MultipartFile[] files, @RequestParam("uuid") String uuid) throws Exception { | |||
| return AjaxResult.success(this.datasetService.uploadDatasetlocal(files,uuid)); | |||
| return AjaxResult.success(this.newDatasetService.uploadDatasetlocal(files, uuid)); | |||
| } | |||
| /** | |||
| * 数据集打包下载 | |||
| * | |||
| * @param version 数据集版本 | |||
| * @param version 数据集版本 | |||
| * @return 单条数据 | |||
| */ | |||
| @GetMapping("/downloadAllFiles") | |||
| @ApiOperation(value = "下载同一版本下所有数据集,并打包") | |||
| public ResponseEntity<InputStreamResource> downloadAllDatasetFiles(@RequestParam("repository_name") String repositoryName, @RequestParam("version") String version) throws Exception { | |||
| return datasetService.downloadAllDatasetFilesNew(repositoryName, version); | |||
| public ResponseEntity<InputStreamResource> downloadAllDatasetFiles(@RequestParam("name") String name, @RequestParam("identifier") String identifier, @RequestParam("id") Integer id, @RequestParam("version") String version) throws Exception { | |||
| return newDatasetService.downloadAllDatasetFilesNew(name, identifier, id, version); | |||
| } | |||
| /** | |||
| * 下载数据集 | |||
| * | |||
| * @param dataset_version_id ps:这里的id是dataset_version表的主键 | |||
| * @param url ps:路径 | |||
| * @return 单条数据 | |||
| */ | |||
| @GetMapping("/download/{dataset_version_id}") | |||
| @GetMapping("/downloadSingleFile") | |||
| @ApiOperation(value = "下载单个数据集文件", notes = "根据数据集版本表id下载单个数据集文件") | |||
| public ResponseEntity<InputStreamResource> downloadDataset(@PathVariable("dataset_version_id") Integer dataset_version_id) throws Exception { | |||
| return datasetService.downloadDataset(dataset_version_id); | |||
| } | |||
| @GetMapping("/queryDatasets") | |||
| @ApiOperation("数据集广场公开数据集分页查询,根据data_type,data_tag筛选,true公开false私有") | |||
| public AjaxResult queryDatasets(Dataset dataset, @RequestParam("page") int page, | |||
| @RequestParam("size") int size, | |||
| @RequestParam(value = "is_public") Boolean isPublic, | |||
| @RequestParam(value = "data_type", required = false) String dataType, | |||
| @RequestParam(value = "data_tag", required = false) String dataTag) throws Exception { | |||
| PageRequest pageRequest = PageRequest.of(page, size); | |||
| if(isPublic){ | |||
| return AjaxResult.success(this.datasetService.newPubilcQueryByPage(dataset, pageRequest)); | |||
| }else { | |||
| return AjaxResult.success(this.datasetService.newPersonalQueryByPage(dataset, pageRequest)); | |||
| } | |||
| } | |||
| @GetMapping("/getdatasetDetail") | |||
| @ApiOperation(value = "获取数据集详情") | |||
| public AjaxResult getDatasetVersions(@PathVariable("datasetId") Integer datasetId) throws Exception { | |||
| return AjaxResult.success(this.datasetService.getDatasetVersions(datasetId)); | |||
| public ResponseEntity<InputStreamResource> downloadDataset(@RequestParam("url") String url) throws Exception { | |||
| return newDatasetService.downloadDatasetlocal(url); | |||
| } | |||
| } | |||
| @@ -83,7 +83,7 @@ public class DevEnvironmentController extends BaseController { | |||
| * @return 删除是否成功 | |||
| */ | |||
| @DeleteMapping("{id}") | |||
| public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) { | |||
| public GenericsAjaxResult<String> deleteById(@PathVariable("id") Integer id) throws Exception { | |||
| return genericsSuccess(this.devEnvironmentService.removeById(id)); | |||
| } | |||
| @@ -106,6 +106,12 @@ public class ExperimentInsController extends BaseController { | |||
| return genericsSuccess(this.experimentInsService.removeById(id)); | |||
| } | |||
| @DeleteMapping("batchDelete") | |||
| @ApiOperation("批量删除实验实例") | |||
| public GenericsAjaxResult<String> batchDelete(@RequestBody List<Integer> ids) throws Exception{ | |||
| return genericsSuccess(this.experimentInsService.batchDelete(ids)); | |||
| } | |||
| /** | |||
| * 终止实验实例 | |||
| * | |||
| @@ -4,10 +4,9 @@ import com.ruoyi.common.core.web.controller.BaseController; | |||
| import com.ruoyi.common.core.web.domain.AjaxResult; | |||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||
| import com.ruoyi.platform.domain.DevEnvironment; | |||
| import com.ruoyi.platform.service.DatasetService; | |||
| import com.ruoyi.platform.service.JupyterService; | |||
| import com.ruoyi.platform.vo.DatasetVo; | |||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||
| import com.ruoyi.platform.service.NewDatasetService; | |||
| import com.ruoyi.platform.vo.NewDatasetVo; | |||
| import com.ruoyi.platform.vo.PodStatusVo; | |||
| import com.ruoyi.platform.vo.VersionVo; | |||
| import io.swagger.annotations.Api; | |||
| @@ -30,7 +29,7 @@ public class JupyterController extends BaseController { | |||
| @Resource | |||
| private JupyterService jupyterService; | |||
| @Resource | |||
| private DatasetService datasetService; | |||
| private NewDatasetService newDatasetService; | |||
| @GetMapping(value = "/getURL") | |||
| @ApiOperation("得到访问地址") | |||
| public GenericsAjaxResult<String> getURL() throws IOException { | |||
| @@ -87,20 +86,4 @@ public class JupyterController extends BaseController { | |||
| return AjaxResult.success(); | |||
| } | |||
| @GetMapping(value = "/testdvc") | |||
| public AjaxResult testdvc() throws Exception { | |||
| DatasetVo datasetVo = new DatasetVo(); | |||
| datasetVo.setName("testdassad23"); | |||
| datasetVo.setDescription("sss"); | |||
| datasetVo.setAvailableRange(0); | |||
| datasetVo.setDataTag("计算机视觉"); | |||
| datasetVo.setDataType("机器翻译"); | |||
| datasetVo.setVersion("dev"); | |||
| List<VersionVo> datasetVersionVos = new ArrayList<>(); | |||
| VersionVo versionVo = new VersionVo(); | |||
| versionVo.setUrl("E:/test/bb/data/xssa.doc"); | |||
| datasetVersionVos.add(versionVo); | |||
| datasetVo.setDatasetVersionVos(datasetVersionVos); | |||
| return AjaxResult.success(datasetService.newCreateDataset(datasetVo)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,136 @@ | |||
| package com.ruoyi.platform.controller.model; | |||
| import com.ruoyi.common.core.web.domain.AjaxResult; | |||
| import com.ruoyi.platform.domain.ModelDependency1; | |||
| import com.ruoyi.platform.service.ModelsService; | |||
| import com.ruoyi.platform.vo.ModelsVo; | |||
| import com.ruoyi.platform.vo.QueryModelMetricsVo; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.springframework.core.io.InputStreamResource; | |||
| import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.http.ResponseEntity; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| import javax.annotation.Resource; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @RestController | |||
| @RequestMapping("newmodel") | |||
| @Api(value = "新模型管理") | |||
| public class NewModelFromGitController { | |||
| @Resource | |||
| private ModelsService modelsService; | |||
| @PostMapping("/addModel") | |||
| @ApiOperation("添加模型") | |||
| public AjaxResult addModelAndVersion(@RequestBody ModelsVo modelsVo) throws Exception { | |||
| return AjaxResult.success(this.modelsService.newCreateModel(modelsVo)); | |||
| } | |||
| @PostMapping("/addVersion") | |||
| @ApiOperation("添加版本") | |||
| public AjaxResult addVersion(@RequestBody ModelsVo modelsVo) throws Exception { | |||
| return AjaxResult.success(this.modelsService.newCreateVersion(modelsVo)); | |||
| } | |||
| @CrossOrigin(origins = "*", allowedHeaders = "*") | |||
| @PostMapping("/upload") | |||
| @ApiOperation(value = "上传模型", notes = "根据模型id上传模型文件,并将信息存入数据库。") | |||
| public AjaxResult uploadModel(@RequestParam("file") MultipartFile[] files, @RequestParam("uuid") String uuid) throws Exception { | |||
| return AjaxResult.success(this.modelsService.uploadModelLocal(files, uuid)); | |||
| } | |||
| @GetMapping("/downloadAllFiles") | |||
| @ApiOperation(value = "下载同一版本下所有模型,并打包") | |||
| public ResponseEntity<InputStreamResource> downloadAllDatasetFiles(@RequestParam("name") String name, @RequestParam("identifier") String identifier, @RequestParam("id") Integer id, @RequestParam("version") String version) throws Exception { | |||
| return modelsService.downloadAllModelFilesNew(name, identifier, id, version); | |||
| } | |||
| @GetMapping("/downloadSingleFile") | |||
| @ApiOperation(value = "下载单个模型文件", notes = "根据模型版本表id下载单个模型文件") | |||
| public ResponseEntity<InputStreamResource> downloadDatasetlocal(@RequestParam("url") String url) throws Exception { | |||
| return modelsService.downloadDatasetlocal(url); | |||
| } | |||
| @GetMapping("/queryModels") | |||
| @ApiOperation("模型广场公开模型分页查询,根据model_type,model_tag筛选,true公开false私有") | |||
| public AjaxResult queryModels(@RequestParam(value = "page") int page, | |||
| @RequestParam(value = "size") int size, | |||
| @RequestParam(value = "is_public", required = false) Boolean isPublic, | |||
| @RequestParam(value = "model_type", required = false) String modelType, | |||
| @RequestParam(value = "model_tag", required = false) String modelTag, | |||
| @RequestParam(value = "name", required = false) String name) throws Exception { | |||
| PageRequest pageRequest = PageRequest.of(page, size); | |||
| ModelsVo modelsVo = new ModelsVo(); | |||
| modelsVo.setModelType(modelType); | |||
| modelsVo.setModelTag(modelTag); | |||
| modelsVo.setName(name); | |||
| if (isPublic) { | |||
| return AjaxResult.success(this.modelsService.newPubilcQueryByPage(modelsVo, pageRequest)); | |||
| } else { | |||
| return AjaxResult.success(this.modelsService.newPersonalQueryByPage(modelsVo, pageRequest)); | |||
| } | |||
| } | |||
| @GetMapping("/queryVersions") | |||
| @ApiOperation("分页查询模型版本") | |||
| public AjaxResult queryVersions(@RequestParam(value = "page") int page, | |||
| @RequestParam(value = "size") int size, | |||
| @RequestParam("identifier") String identifier, | |||
| @RequestParam("owner") String owner, | |||
| @RequestParam("type") String type) throws Exception { | |||
| PageRequest pageRequest = PageRequest.of(page, size); | |||
| return AjaxResult.success(this.modelsService.queryVersions(pageRequest, identifier, owner, type)); | |||
| } | |||
| @PostMapping("/queryVersionsMetrics") | |||
| @ApiOperation("查询版本指标") | |||
| public AjaxResult queryVersionsMetrics(@RequestBody QueryModelMetricsVo queryModelMetricsVo) throws Exception { | |||
| return AjaxResult.success(this.modelsService.queryVersionsMetrics(queryModelMetricsVo)); | |||
| } | |||
| @GetMapping("/getVersionList") | |||
| @ApiOperation(value = "获取模型分支列表") | |||
| public AjaxResult getVersionList(@RequestParam("identifier") String identifier, @RequestParam("owner") String owner) throws Exception { | |||
| return AjaxResult.success(this.modelsService.getVersionList(identifier, owner)); | |||
| } | |||
| @GetMapping("/getModelDetail") | |||
| @ApiOperation(value = "获取模型详细信息") | |||
| public AjaxResult getModelDetail(@RequestParam("id") Integer id, @RequestParam("identifier") String identifier, @RequestParam("owner") String owner, @RequestParam("version") String version) throws Exception { | |||
| return AjaxResult.success(this.modelsService.getModelDetail(id, identifier, owner, version)); | |||
| } | |||
| @GetMapping("/getModelDependencyTree") | |||
| @ApiOperation(value = "获取模型依赖关系树") | |||
| public AjaxResult getModelDependencyTree(@RequestParam("id") Integer id, @RequestParam("identifier") String identifier, @RequestParam("version") String version) throws Exception { | |||
| return AjaxResult.success(this.modelsService.getModelDependencyTree(id, identifier, version)); | |||
| } | |||
| @DeleteMapping("/delete") | |||
| @ApiOperation(value = "删除模型") | |||
| public AjaxResult deleteModel(@RequestParam("id") Integer id, @RequestParam("identifier") String identifier, | |||
| @RequestParam("owner") String owner) throws Exception { | |||
| this.modelsService.deleteModel(id, identifier, owner); | |||
| return AjaxResult.success(); | |||
| } | |||
| @DeleteMapping("/deleteVersion") | |||
| @ApiOperation(value = "删除模型版本") | |||
| public AjaxResult deleteVersion(@RequestParam("id") Integer id, @RequestParam("identifier") String identifier, @RequestParam("owner") String owner, @RequestParam("version") String version | |||
| , @RequestParam("relative_paths") String relativePaths) throws Exception { | |||
| List<Map<String, Object>> versionList = this.modelsService.getVersionList(identifier, owner); | |||
| if (versionList.size() == 1) { | |||
| return AjaxResult.error("当前模型只有一个版本,不能删除该版本"); | |||
| } | |||
| this.modelsService.deleteVersion(id, identifier, owner, version, relativePaths); | |||
| return AjaxResult.success(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,146 @@ | |||
| package com.ruoyi.platform.controller.service; | |||
| import com.ruoyi.common.core.web.controller.BaseController; | |||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||
| import com.ruoyi.platform.domain.Service; | |||
| import com.ruoyi.platform.domain.ServiceVersion; | |||
| import com.ruoyi.platform.service.ServiceService; | |||
| import com.ruoyi.platform.vo.serviceVos.ServiceVersionVo; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.springframework.data.domain.Page; | |||
| import org.springframework.data.domain.PageRequest; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.annotation.Resource; | |||
| import java.io.IOException; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @RestController | |||
| @RequestMapping("service") | |||
| @Api("服务") | |||
| public class ServiceController extends BaseController { | |||
| @Resource | |||
| private ServiceService serviceService; | |||
| @GetMapping | |||
| @ApiOperation("分页查询服务列表") | |||
| public GenericsAjaxResult<Page<Service>> queryByPageService(@RequestParam(value = "service_name", required = false) String serviceName, | |||
| @RequestParam(value = "service_type", required = false) String serviceType, | |||
| @RequestParam("page") int page, | |||
| @RequestParam("size") int size) throws IOException { | |||
| Service service = new Service(); | |||
| service.setServiceName(serviceName); | |||
| service.setServiceType(serviceType); | |||
| PageRequest pageRequest = PageRequest.of(page, size); | |||
| return genericsSuccess(serviceService.queryByPageService(service, pageRequest)); | |||
| } | |||
| @GetMapping("/serviceVersion") | |||
| @ApiOperation("分页查询服务版本列表") | |||
| public GenericsAjaxResult<Page<ServiceVersionVo>> queryByPageServiceVersion(@RequestParam(value = "run_state", required = false) String runState, | |||
| @RequestParam(value = "version", required = false) String version, | |||
| @RequestParam("service_id") Long serviceId, | |||
| @RequestParam("page") int page, | |||
| @RequestParam("size") int size) throws IOException { | |||
| ServiceVersion serviceVersion = new ServiceVersion(); | |||
| serviceVersion.setRunState(runState); | |||
| serviceVersion.setVersion(version); | |||
| serviceVersion.setServiceId(serviceId); | |||
| return genericsSuccess(serviceService.queryByPageServiceVersion(serviceVersion, page, size)); | |||
| } | |||
| @PostMapping | |||
| @ApiOperation("新增服务") | |||
| public GenericsAjaxResult<Service> addService(@RequestBody Service service) { | |||
| return genericsSuccess(serviceService.addService(service)); | |||
| } | |||
| @PostMapping("/serviceVersion") | |||
| @ApiOperation("新增服务版本") | |||
| public GenericsAjaxResult<ServiceVersion> addServiceVersion(@RequestBody ServiceVersionVo serviceVersionVo) { | |||
| return genericsSuccess(serviceService.addServiceVersion(serviceVersionVo)); | |||
| } | |||
| @PutMapping | |||
| @ApiOperation("编辑服务") | |||
| public GenericsAjaxResult<Service> editService(@RequestBody Service service) { | |||
| return genericsSuccess(serviceService.editService(service)); | |||
| } | |||
| @PutMapping("/serviceVersion") | |||
| @ApiOperation("编辑服务版本") | |||
| public GenericsAjaxResult<String> editServiceVersion(@RequestBody ServiceVersionVo serviceVersionVo) { | |||
| return genericsSuccess(serviceService.editServiceVersion(serviceVersionVo)); | |||
| } | |||
| @GetMapping("/serviceDetail/{id}") | |||
| @ApiOperation("查询服务详细信息") | |||
| public GenericsAjaxResult<Service> getService(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.getService(id)); | |||
| } | |||
| @GetMapping("/serviceVersionDetail/{id}") | |||
| @ApiOperation("查询服务版本详细信息") | |||
| public GenericsAjaxResult<ServiceVersionVo> getServiceVersion(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.getServiceVersion(id)); | |||
| } | |||
| @GetMapping("serviceVersionCompare") | |||
| @ApiOperation("服务版本版本对比") | |||
| public GenericsAjaxResult<Map<String, Object>> serviceVersionCompare(@RequestParam("id1") Long id1, @RequestParam("id2") Long id2) throws IllegalAccessException { | |||
| return genericsSuccess(serviceService.serviceVersionCompare(id1, id2)); | |||
| } | |||
| @GetMapping("/serviceVersionList/{id}") | |||
| @ApiOperation("查询服务版本列表") | |||
| public GenericsAjaxResult<List<ServiceVersion>> serviceVersionList(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.serviceVersionList(id)); | |||
| } | |||
| @DeleteMapping("{id}") | |||
| @ApiOperation("删除服务") | |||
| public GenericsAjaxResult<String> deleteService(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.deleteService(id)); | |||
| } | |||
| @DeleteMapping("/serviceVersion/{id}") | |||
| @ApiOperation("删除服务版本") | |||
| public GenericsAjaxResult<String> deleteServiceVersion(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.deleteServiceVersion(id)); | |||
| } | |||
| // @PostMapping("/runServiceVersion/{id}") | |||
| // @ApiOperation("启动服务版本") | |||
| // public GenericsAjaxResult<String> runServiceVersion(@PathVariable("id") Long id) { | |||
| // return genericsSuccess(serviceService.runServiceVersion(id)); | |||
| // } | |||
| @DeleteMapping("/stopServiceVersion/{id}") | |||
| @ApiOperation("停止服务版本") | |||
| public GenericsAjaxResult<String> stopServiceVersion(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.stopServiceVersion(id)); | |||
| } | |||
| // @PutMapping("/updateServiceVersion") | |||
| // @ApiOperation("更新服务版本") | |||
| // public GenericsAjaxResult<String> updateServiceVersion(@RequestBody ServiceVersion serviceVersion) { | |||
| // return genericsSuccess(serviceService.updateServiceVersion(serviceVersion)); | |||
| // } | |||
| @GetMapping("/getServiceVersionLog") | |||
| @ApiOperation("获取服务版本日志") | |||
| public GenericsAjaxResult<HashMap<String, String>> getServiceVersionLog(@RequestParam("id") Long id, | |||
| @RequestParam("start_time") String startTime, @RequestParam("end_time") String endTime) { | |||
| return genericsSuccess(serviceService.getServiceVersionLog(id, startTime, endTime)); | |||
| } | |||
| @GetMapping("/getServiceVersionDocs/{id}") | |||
| @ApiOperation("获取服务版本文档") | |||
| public GenericsAjaxResult<Map<String, Object>> getServiceVersionDocs(@PathVariable("id") Long id) { | |||
| return genericsSuccess(serviceService.getServiceVersionDocs(id)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||
| import lombok.Data; | |||
| import java.io.Serializable; | |||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||
| @Data | |||
| public class DatasetDependency implements Serializable { | |||
| private Long id; | |||
| private String parentDataset; | |||
| private String datasetName; | |||
| private String version; | |||
| private Integer repoId; | |||
| private String identifier; | |||
| private String owner; | |||
| private Integer state; | |||
| private String meta; | |||
| } | |||
| @@ -0,0 +1,109 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import java.util.Date; | |||
| import java.io.Serializable; | |||
| /** | |||
| * 数据集暂存的数据(DatasetTempStorage)实体类 | |||
| * | |||
| * @author makejava | |||
| * @since 2024-09-12 09:42:09 | |||
| */ | |||
| public class DatasetTempStorage implements Serializable { | |||
| private static final long serialVersionUID = -44025176874790480L; | |||
| private Integer id; | |||
| private String name; | |||
| private String version; | |||
| private String source; | |||
| /** | |||
| * 为0失效,1生效 | |||
| */ | |||
| private Integer state; | |||
| private String createBy; | |||
| private Date createTime; | |||
| private String updateBy; | |||
| private Date updateTime; | |||
| public Integer getId() { | |||
| return id; | |||
| } | |||
| public void setId(Integer id) { | |||
| this.id = id; | |||
| } | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| public void setName(String name) { | |||
| this.name = name; | |||
| } | |||
| public String getVersion() { | |||
| return version; | |||
| } | |||
| public void setVersion(String version) { | |||
| this.version = version; | |||
| } | |||
| public String getSource() { | |||
| return source; | |||
| } | |||
| public void setSource(String source) { | |||
| this.source = source; | |||
| } | |||
| public Integer getState() { | |||
| return state; | |||
| } | |||
| public void setState(Integer state) { | |||
| this.state = state; | |||
| } | |||
| public String getCreateBy() { | |||
| return createBy; | |||
| } | |||
| public void setCreateBy(String createBy) { | |||
| this.createBy = createBy; | |||
| } | |||
| public Date getCreateTime() { | |||
| return createTime; | |||
| } | |||
| public void setCreateTime(Date createTime) { | |||
| this.createTime = createTime; | |||
| } | |||
| public String getUpdateBy() { | |||
| return updateBy; | |||
| } | |||
| public void setUpdateBy(String updateBy) { | |||
| this.updateBy = updateBy; | |||
| } | |||
| public Date getUpdateTime() { | |||
| return updateTime; | |||
| } | |||
| public void setUpdateTime(Date updateTime) { | |||
| this.updateTime = updateTime; | |||
| } | |||
| } | |||
| @@ -1,10 +1,12 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.fasterxml.jackson.annotation.JsonRawValue; | |||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||
| import io.swagger.annotations.ApiModel; | |||
| import io.swagger.annotations.ApiModelProperty; | |||
| import lombok.Data; | |||
| import java.io.Serializable; | |||
| import java.util.Date; | |||
| @@ -17,6 +19,7 @@ import java.util.Date; | |||
| */ | |||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||
| @ApiModel("实验实例对象") | |||
| @Data | |||
| public class ExperimentIns implements Serializable { | |||
| private static final long serialVersionUID = 623464560240790680L; | |||
| @ApiModelProperty(name = "id") | |||
| @@ -52,6 +55,10 @@ public class ExperimentIns implements Serializable { | |||
| @JsonRawValue | |||
| private String metricRecord; | |||
| @ApiModelProperty(value = "指标数值", notes = "以JSON字符串格式存储") | |||
| @JsonRawValue | |||
| private String metricValue; | |||
| @ApiModelProperty(value = "开始时间") | |||
| private Date startTime; | |||
| @@ -74,151 +81,11 @@ public class ExperimentIns implements Serializable { | |||
| private Integer state; | |||
| @ApiModelProperty(value = "实验实例对应的流水线ID") | |||
| private Long workflowId; | |||
| @TableField(exist = false) | |||
| private String experimentName; | |||
| public ExperimentIns() { | |||
| } | |||
| public Integer getId() { | |||
| return id; | |||
| } | |||
| public void setId(Integer id) { | |||
| this.id = id; | |||
| } | |||
| public Integer getExperimentId() { | |||
| return experimentId; | |||
| } | |||
| public void setExperimentId(Integer experimentId) { | |||
| this.experimentId = experimentId; | |||
| } | |||
| public String getArgoInsName() { | |||
| return argoInsName; | |||
| } | |||
| public void setArgoInsName(String argoInsName) { | |||
| this.argoInsName = argoInsName; | |||
| } | |||
| public String getArgoInsNs() { | |||
| return argoInsNs; | |||
| } | |||
| public void setArgoInsNs(String argoInsNs) { | |||
| this.argoInsNs = argoInsNs; | |||
| } | |||
| public String getStatus() { | |||
| return status; | |||
| } | |||
| public void setStatus(String status) { | |||
| this.status = status; | |||
| } | |||
| public String getNodesStatus() { | |||
| return nodesStatus; | |||
| } | |||
| public void setNodesStatus(String nodesStatus) { | |||
| this.nodesStatus = nodesStatus; | |||
| } | |||
| public String getNodesResult() { | |||
| return nodesResult; | |||
| } | |||
| public void setNodesResult(String nodesResult) { | |||
| this.nodesResult = nodesResult; | |||
| } | |||
| public String getNodesLogs() { | |||
| return nodesLogs; | |||
| } | |||
| public void setNodesLogs(String nodesLogs) { | |||
| this.nodesLogs = nodesLogs; | |||
| } | |||
| public String getGlobalParam() { | |||
| return globalParam; | |||
| } | |||
| public void setGlobalParam(String globalParam) { | |||
| this.globalParam = globalParam; | |||
| } | |||
| public void setStartTime(Date startTime) { | |||
| this.startTime = startTime; | |||
| } | |||
| public Date getStartTime() {return startTime;} | |||
| public void setFinishTime(Date finishTime) { | |||
| this.finishTime = finishTime; | |||
| } | |||
| public Date getFinishTime() {return finishTime;} | |||
| public String getCreateBy() { | |||
| return createBy; | |||
| } | |||
| public void setCreateBy(String createBy) { | |||
| this.createBy = createBy; | |||
| } | |||
| public Date getCreateTime() { | |||
| return createTime; | |||
| } | |||
| public void setCreateTime(Date createTime) { | |||
| this.createTime = createTime; | |||
| } | |||
| public String getUpdateBy() { | |||
| return updateBy; | |||
| } | |||
| public void setUpdateBy(String updateBy) { | |||
| this.updateBy = updateBy; | |||
| } | |||
| public Date getUpdateTime() { | |||
| return updateTime; | |||
| } | |||
| public void setUpdateTime(Date updateTime) { | |||
| this.updateTime = updateTime; | |||
| } | |||
| public Integer getState() { | |||
| return state; | |||
| } | |||
| public void setState(Integer state) { | |||
| this.state = state; | |||
| } | |||
| public Long getWorkflowId() {return workflowId;} | |||
| public void setWorkflowId(Long workflowId) {this.workflowId = workflowId;} | |||
| public String getMetricRecord() { | |||
| return metricRecord; | |||
| } | |||
| public void setMetricRecord(String metricRecord) { | |||
| this.metricRecord = metricRecord; | |||
| } | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||
| import lombok.Data; | |||
| import java.io.Serializable; | |||
| import java.util.List; | |||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||
| @Data | |||
| public class ModelDependency1 implements Serializable { | |||
| private Long id; | |||
| private String parentModel; | |||
| private String modelName; | |||
| private String version; | |||
| private Integer repoId; | |||
| private String identifier; | |||
| private String owner; | |||
| private Integer state; | |||
| private String meta; | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||
| import io.swagger.annotations.ApiModel; | |||
| import lombok.Data; | |||
| import java.io.Serializable; | |||
| import java.util.Date; | |||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||
| @ApiModel("服务") | |||
| @Data | |||
| public class Service implements Serializable { | |||
| private Long id; | |||
| private String serviceName; | |||
| private String serviceType; | |||
| @TableField(exist = false) | |||
| private String serviceTypeName; | |||
| private String description; | |||
| private String createBy; | |||
| private String updateBy; | |||
| private Date createTime; | |||
| private Date updateTime; | |||
| private Integer state; | |||
| @TableField(exist = false) | |||
| private Long versionCount; | |||
| public String getServiceTypeName() { | |||
| switch (serviceType) { | |||
| case "image": | |||
| return "图片"; | |||
| case "video": | |||
| return "视频"; | |||
| case "audio": | |||
| return "音频"; | |||
| case "text": | |||
| return "文本"; | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -0,0 +1,56 @@ | |||
| package com.ruoyi.platform.domain; | |||
| import com.fasterxml.jackson.databind.PropertyNamingStrategy; | |||
| import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||
| import io.swagger.annotations.ApiModel; | |||
| import lombok.Data; | |||
| import java.io.Serializable; | |||
| import java.util.Date; | |||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | |||
| @ApiModel("服务版本") | |||
| @Data | |||
| public class ServiceVersion implements Serializable { | |||
| private Long id; | |||
| private Long serviceId; | |||
| private String version; | |||
| private String description; | |||
| private String model; | |||
| private String image; | |||
| private String resource; | |||
| private Integer replicas; | |||
| private String mountPath; | |||
| private String envVariables; | |||
| private String codeConfig; | |||
| private String command; | |||
| private String url; | |||
| private String createBy; | |||
| private String updateBy; | |||
| private Date createTime; | |||
| private Date updateTime; | |||
| private Integer state; | |||
| private String runState; | |||
| private String deploymentName; | |||
| private String svcName; | |||
| } | |||
| @@ -13,5 +13,9 @@ public class TrainTaskDepency implements Serializable { | |||
| //实例id | |||
| private Integer insId; | |||
| //节点Id | |||
| private Long workflowId; | |||
| private Integer experimentId; | |||
| private String taskId; | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| package com.ruoyi.platform.mapper; | |||
| import com.ruoyi.platform.domain.DatasetDependency; | |||
| public interface DatasetDependencyDao { | |||
| int insert(DatasetDependency datasetDependency); | |||
| } | |||
| @@ -0,0 +1,86 @@ | |||
| package com.ruoyi.platform.mapper; | |||
| import com.ruoyi.platform.domain.DatasetTempStorage; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import org.springframework.data.domain.Pageable; | |||
| import java.util.List; | |||
| /** | |||
| * 数据集暂存的数据(DatasetTempStorage)表数据库访问层 | |||
| * | |||
| * @author makejava | |||
| * @since 2024-09-12 09:42:09 | |||
| */ | |||
| public interface DatasetTempStorageDao { | |||
| /** | |||
| * 通过ID查询单条数据 | |||
| * | |||
| * @param id 主键 | |||
| * @return 实例对象 | |||
| */ | |||
| DatasetTempStorage queryById(Integer id); | |||
| /** | |||
| * 查询指定行数据 | |||
| * | |||
| * @param datasetTempStorage 查询条件 | |||
| * @param pageable 分页对象 | |||
| * @return 对象列表 | |||
| */ | |||
| List<DatasetTempStorage> queryAllByLimit(DatasetTempStorage datasetTempStorage, @Param("pageable") Pageable pageable); | |||
| /** | |||
| * 统计总行数 | |||
| * | |||
| * @param datasetTempStorage 查询条件 | |||
| * @return 总行数 | |||
| */ | |||
| long count(DatasetTempStorage datasetTempStorage); | |||
| /** | |||
| * 新增数据 | |||
| * | |||
| * @param datasetTempStorage 实例对象 | |||
| * @return 影响行数 | |||
| */ | |||
| int insert(DatasetTempStorage datasetTempStorage); | |||
| /** | |||
| * 批量新增数据(MyBatis原生foreach方法) | |||
| * | |||
| * @param entities List<DatasetTempStorage> 实例对象列表 | |||
| * @return 影响行数 | |||
| */ | |||
| int insertBatch(@Param("entities") List<DatasetTempStorage> entities); | |||
| /** | |||
| * 批量新增或按主键更新数据(MyBatis原生foreach方法) | |||
| * | |||
| * @param entities List<DatasetTempStorage> 实例对象列表 | |||
| * @return 影响行数 | |||
| * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参 | |||
| */ | |||
| int insertOrUpdateBatch(@Param("entities") List<DatasetTempStorage> entities); | |||
| /** | |||
| * 修改数据 | |||
| * | |||
| * @param datasetTempStorage 实例对象 | |||
| * @return 影响行数 | |||
| */ | |||
| int update(DatasetTempStorage datasetTempStorage); | |||
| /** | |||
| * 通过主键删除数据 | |||
| * | |||
| * @param id 主键 | |||
| * @return 影响行数 | |||
| */ | |||
| int deleteById(Integer id); | |||
| DatasetTempStorage queryByDatasetTempStorage(DatasetTempStorage datasetTempStorage); | |||
| DatasetTempStorage queryByInsId(@Param("insId") String insId); | |||
| } | |||
| @@ -39,6 +39,10 @@ public interface ExperimentInsDao { | |||
| */ | |||
| long count(@Param("experimentIns") ExperimentIns experimentIns); | |||
| long countTorE(@Param("experimentId") Integer experimentId, @Param("isTrain") Boolean isTrain); | |||
| List<ExperimentIns> queryTorE(@Param("experimentId") Integer experimentId, @Param("isTrain") Boolean isTrain, @Param("pageable") Pageable pageable); | |||
| /* | |||
| 统计实验实例总数 | |||
| @@ -100,7 +104,6 @@ public interface ExperimentInsDao { | |||
| List<ExperimentIns> getLatestInsList(); | |||
| List<ExperimentIns> queryByExperiment(@Param("experimentIns") ExperimentIns experimentIns); | |||
| List<ExperimentIns> queryByExperimentId(Integer id); | |||
| @@ -0,0 +1,31 @@ | |||
| package com.ruoyi.platform.mapper; | |||
| import com.ruoyi.platform.domain.ModelDependency1; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import java.util.List; | |||
| public interface ModelDependency1Dao { | |||
| int insert(ModelDependency1 modelDependency1); | |||
| int updateState(@Param("repoId") Integer repoId, @Param("identifier") String identifier, @Param("version") String version, @Param("meta") String meta, @Param("state") Integer state); | |||
| List<ModelDependency1> queryModelDependency(@Param("modelName") String modelName, @Param("repoId") Integer repoId, @Param("owner") String owner); | |||
| ModelDependency1 getBuildingModel(@Param("repoId") Integer repoId, @Param("identifier") String identifier, @Param("version") String version); | |||
| ModelDependency1 queryByRepoAndVersion(@Param("repoId") Integer repoId, @Param("identifier") String identifier, @Param("version") String version); | |||
| List<ModelDependency1> queryByParentModel(@Param("parentModel") String parentModel); | |||
| ModelDependency1 queryByTrainTask(@Param("trainTask") String trainTask); | |||
| ModelDependency1 queryByInsId(@Param("insId") String insId); | |||
| int deleteModel(@Param("repoId") Integer repoId, @Param("identifier") String identifier, @Param("owner") String owner, @Param("version") String version); | |||
| int deleteModelDependency(@Param("parentModel") String parentModel); | |||
| String getMeta(@Param("identifier") String identifier, @Param("owner") String owner, @Param("version") String version); | |||
| } | |||
| @@ -0,0 +1,39 @@ | |||
| package com.ruoyi.platform.mapper; | |||
| import com.ruoyi.platform.domain.Service; | |||
| import com.ruoyi.platform.domain.ServiceVersion; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import org.springframework.data.domain.Pageable; | |||
| import java.util.List; | |||
| public interface ServiceDao { | |||
| long countService(@Param("service") com.ruoyi.platform.domain.Service service); | |||
| long countServiceVersion(@Param("serviceVersion") ServiceVersion serviceVersion); | |||
| List<Service> queryByPageService(@Param("service") com.ruoyi.platform.domain.Service service, @Param("pageable") Pageable pageable); | |||
| List<ServiceVersion> queryByPageServiceVersion(@Param("serviceVersion") ServiceVersion serviceVersion, @Param("pageable") Pageable pageable); | |||
| int insertService(@Param("service") com.ruoyi.platform.domain.Service service); | |||
| int insertServiceVersion(@Param("serviceVersion") ServiceVersion serviceVersion); | |||
| int updateService(@Param("service") Service service); | |||
| int updateServiceVersion(@Param("serviceVersion") ServiceVersion serviceVersion); | |||
| int updateRunState(@Param("deploymentName") String deploymentName, @Param("runState") String runState); | |||
| Service getServiceById(@Param("id") Long id); | |||
| ServiceVersion getServiceVersionById(@Param("id") Long id); | |||
| List<ServiceVersion> getServiceVersionList(@Param("serviceId") Long serviceId); | |||
| Service getServiceByName(@Param("serviceName") String serviceName); | |||
| ServiceVersion getSvByVersion(@Param("version") String version, @Param("serviceId") Long serviceId); | |||
| } | |||
| @@ -2,12 +2,13 @@ package com.ruoyi.platform.scheduling; | |||
| import com.ruoyi.platform.domain.Experiment; | |||
| import com.ruoyi.platform.domain.ExperimentIns; | |||
| import com.ruoyi.platform.domain.ModelDependency; | |||
| import com.ruoyi.platform.mapper.ExperimentDao; | |||
| import com.ruoyi.platform.mapper.ExperimentInsDao; | |||
| import com.ruoyi.platform.mapper.ModelDependencyDao; | |||
| import com.ruoyi.platform.service.AimService; | |||
| import com.ruoyi.platform.service.ExperimentInsService; | |||
| import com.ruoyi.platform.utils.JacksonUtil; | |||
| import com.ruoyi.platform.utils.JsonUtils; | |||
| import com.ruoyi.platform.vo.InsMetricInfoVo; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.scheduling.annotation.Scheduled; | |||
| @@ -26,11 +27,12 @@ public class ExperimentInstanceStatusTask { | |||
| @Resource | |||
| private ExperimentInsDao experimentInsDao; | |||
| @Resource | |||
| private ModelDependencyDao modelDependencyDao; | |||
| private AimService aimService; | |||
| private List<Integer> experimentIds = new ArrayList<>(); | |||
| @Scheduled(cron = "0/30 * * * * ?") // 每30S执行一次 | |||
| public void executeExperimentInsStatus() throws IOException { | |||
| public void executeExperimentInsStatus() throws Exception { | |||
| // 首先查到所有非终止态的实验实例 | |||
| List<ExperimentIns> experimentInsList = experimentInsService.queryByExperimentIsNotTerminated(); | |||
| // 去argo查询状态 | |||
| @@ -38,59 +40,77 @@ public class ExperimentInstanceStatusTask { | |||
| if (experimentInsList != null && experimentInsList.size() > 0) { | |||
| for (ExperimentIns experimentIns : experimentInsList) { | |||
| //当原本状态为null或非终止态时才调用argo接口 | |||
| String oldStatus = experimentIns.getStatus(); | |||
| try { | |||
| experimentIns = experimentInsService.queryStatusFromArgo(experimentIns); | |||
| } catch (Exception e) { | |||
| experimentIns.setStatus("Failed"); | |||
| } | |||
| experimentIns.setUpdateTime(new Date()); | |||
| // 线程安全的添加操作 | |||
| synchronized (experimentIds) { | |||
| experimentIds.add(experimentIns.getExperimentId()); | |||
| } | |||
| updateList.add(experimentIns); | |||
| } | |||
| } | |||
| if (updateList.size() > 0) { | |||
| experimentInsDao.insertOrUpdateBatch(updateList); | |||
| //运行成功的实验实例记录指标数值 | |||
| Map<String, Object> metricRecord = JacksonUtil.parseJSONStr2Map(experimentIns.getMetricRecord()); | |||
| List<Map<String, Object>> trainMetricRecords = (List<Map<String, Object>>) metricRecord.get("train"); | |||
| List<Map<String, Object>> evaluateMetricRecords = (List<Map<String, Object>>) metricRecord.get("evaluate"); | |||
| //遍历模型关系表,找到 | |||
| List<ModelDependency> modelDependencyList = new ArrayList<ModelDependency>(); | |||
| for (ExperimentIns experimentIns : updateList) { | |||
| ModelDependency modelDependencyquery = new ModelDependency(); | |||
| modelDependencyquery.setExpInsId(experimentIns.getId()); | |||
| modelDependencyquery.setState(2); | |||
| HashMap<String, Object> metricValue = new HashMap<>(); | |||
| HashMap<String, Object> trainMetricValues = new HashMap<>(); | |||
| HashMap<String, Object> evaluateMetricValues = new HashMap<>(); | |||
| List<ModelDependency> modelDependencyListquery = modelDependencyDao.queryByModelDependency(modelDependencyquery); | |||
| if (modelDependencyListquery == null || modelDependencyListquery.size() == 0) { | |||
| continue; | |||
| } | |||
| ModelDependency modelDependency = modelDependencyListquery.get(0); | |||
| //查看状态, | |||
| if (StringUtils.equals("Failed", experimentIns.getStatus())) { | |||
| //取出节点状态 | |||
| String trainTask = modelDependency.getTrainTask(); | |||
| Map<String, Object> trainMap = JacksonUtil.parseJSONStr2Map(trainTask); | |||
| String task_id = (String) trainMap.get("task_id"); | |||
| if (StringUtils.isEmpty(task_id)) { | |||
| continue; | |||
| if (trainMetricRecords != null && !trainMetricRecords.isEmpty()) { | |||
| for (Map<String, Object> trainMetricRecord : trainMetricRecords) { | |||
| HashMap<String, Object> trainMetricValue = new HashMap<>(); | |||
| String taskId = (String) trainMetricRecord.get("task_id"); | |||
| if (taskId.startsWith("model-train")) { | |||
| String runId = (String) trainMetricRecord.get("run_id"); | |||
| List<InsMetricInfoVo> expTrainInfos = aimService.getExpInfos1(true, experimentIns.getExperimentId(), runId); | |||
| for (InsMetricInfoVo expTrainInfo : expTrainInfos) { | |||
| Map metrics = expTrainInfo.getMetrics(); | |||
| trainMetricValue.putAll(metrics); | |||
| trainMetricValue.put("run_hash", expTrainInfo.getRunId()); | |||
| } | |||
| if (trainMetricValue.size() > 0) { | |||
| trainMetricValues.put(taskId, trainMetricValue); | |||
| } | |||
| } | |||
| } | |||
| String nodesStatus = experimentIns.getNodesStatus(); | |||
| Map<String, Object> nodeMaps = JacksonUtil.parseJSONStr2Map(nodesStatus); | |||
| Map<String, Object> nodeMap = JacksonUtil.parseJSONStr2Map(JacksonUtil.toJSONString(nodeMaps.get(task_id))); | |||
| } | |||
| if (nodeMap == null) { | |||
| continue; | |||
| } | |||
| if (!StringUtils.equals("Succeeded", (String) nodeMap.get("phase"))) { | |||
| modelDependency.setState(0); | |||
| modelDependencyList.add(modelDependency); | |||
| if (evaluateMetricRecords != null && !evaluateMetricRecords.isEmpty()) { | |||
| for (Map<String, Object> evaluateMetricRecord : evaluateMetricRecords) { | |||
| HashMap<String, Object> evaluateMetricValue = new HashMap<>(); | |||
| String taskId = (String) evaluateMetricRecord.get("task_id"); | |||
| if (taskId.startsWith("model-evaluate")) { | |||
| String runId = (String) evaluateMetricRecord.get("run_id"); | |||
| List<InsMetricInfoVo> expTrainInfos = aimService.getExpInfos1(false, experimentIns.getExperimentId(), runId); | |||
| for (InsMetricInfoVo expTrainInfo : expTrainInfos) { | |||
| Map metrics = expTrainInfo.getMetrics(); | |||
| evaluateMetricValue.putAll(metrics); | |||
| evaluateMetricValue.put("run_hash", expTrainInfo.getRunId()); | |||
| } | |||
| if (evaluateMetricValue.size() > 0) { | |||
| evaluateMetricValues.put(taskId, evaluateMetricValue); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if (trainMetricValues.size() > 0) { | |||
| metricValue.put("train", trainMetricValues); | |||
| } else { | |||
| metricValue.put("train", null); | |||
| } | |||
| if (evaluateMetricValues.size() > 0) { | |||
| metricValue.put("evaluate", evaluateMetricValues); | |||
| } else { | |||
| metricValue.put("evaluate", null); | |||
| } | |||
| experimentIns.setMetricValue(JsonUtils.mapToJson(metricValue)); | |||
| experimentIns.setUpdateTime(new Date()); | |||
| // 线程安全的添加操作 | |||
| synchronized (experimentIds) { | |||
| experimentIds.add(experimentIns.getExperimentId()); | |||
| } | |||
| updateList.add(experimentIns); | |||
| } | |||
| if (modelDependencyList.size() > 0) { | |||
| modelDependencyDao.insertOrUpdateBatch(modelDependencyList); | |||
| if (updateList.size() > 0) { | |||
| experimentInsDao.insertOrUpdateBatch(updateList); | |||
| } | |||
| } | |||
| } | |||
| @@ -105,7 +125,7 @@ public class ExperimentInstanceStatusTask { | |||
| for (Integer experimentId : experimentIds) { | |||
| // 获取当前实验的所有实例列表 | |||
| List<ExperimentIns> insList = experimentInsService.getByExperimentId(experimentId); | |||
| List<String> statusList = new ArrayList<String>(); | |||
| List<String> statusList = new ArrayList<>(); | |||
| // 更新实验状态列表 | |||
| for (int i = 0; i < insList.size(); i++) { | |||
| statusList.add(insList.get(i).getStatus()); | |||
| @@ -1,14 +1,25 @@ | |||
| package com.ruoyi.platform.service; | |||
| import com.ruoyi.platform.vo.InsMetricInfoVo; | |||
| import org.springframework.data.domain.Page; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| public interface AimService { | |||
| List<InsMetricInfoVo> getExpTrainInfos(Integer experimentId) throws Exception; | |||
| List<InsMetricInfoVo> getExpTrainInfos(Integer experimentId, String offset, int limit) throws Exception; | |||
| List<InsMetricInfoVo> getExpEvaluateInfos(Integer experimentId) throws Exception; | |||
| List<InsMetricInfoVo> getExpEvaluateInfos(Integer experimentId, String offset, int limit) throws Exception; | |||
| Page<InsMetricInfoVo> getExpInfos(boolean isTrain, Integer experimentId, int page, int size); | |||
| List<InsMetricInfoVo> getExpInfos1(boolean isTrain, Integer experimentId, String runId) throws Exception; | |||
| String getExpMetrics(List<String> runIds) throws Exception; | |||
| HashMap<String, Object> queryMetricsParams(String runId) throws Exception; | |||
| List<Map<String, Object>> getBatchMetric(String runHash, String body); | |||
| } | |||