Browse Source

merge dev

pull/146/head
cp3hnu 1 year ago
parent
commit
240867231c
100 changed files with 3809 additions and 501 deletions
  1. +6
    -1
      .gitignore
  2. +84
    -0
      k8s/10nexus3/nexus-deploy.yaml
  3. +13
    -0
      k8s/10nexus3/nexus-pvc.yaml
  4. +33
    -0
      k8s/build-java.sh
  5. +25
    -0
      k8s/build-java.sh.bak
  6. +25
    -0
      k8s/build-node.sh
  7. +21
    -0
      k8s/build-node.sh.bak
  8. +141
    -0
      k8s/build.sh
  9. +92
    -0
      k8s/build_and_deploy.sh
  10. +74
    -0
      k8s/build_and_deploy.sh.bak
  11. +13
    -0
      k8s/clusterrolebinding.yaml
  12. +181
    -0
      k8s/deploy.sh
  13. +162
    -0
      k8s/deploy.sh.bak
  14. +2
    -1
      k8s/dockerfiles/auth-dockerfile
  15. +8
    -8
      k8s/dockerfiles/buildimage.sh
  16. +131
    -41
      k8s/dockerfiles/conf/nginx.conf
  17. +64
    -0
      k8s/dockerfiles/conf/nginx.conf.20240705
  18. +131
    -0
      k8s/dockerfiles/conf/nginx.conf.20240909
  19. +60
    -0
      k8s/dockerfiles/conf/nginx.conf.bak
  20. +110
    -0
      k8s/dockerfiles/conf/nginx.conf.bak0719
  21. +2
    -1
      k8s/dockerfiles/file-dockerfile
  22. +2
    -1
      k8s/dockerfiles/gateway-dockerfile
  23. +2
    -1
      k8s/dockerfiles/gen-dockerfile
  24. +2
    -1
      k8s/dockerfiles/job-dockerfile
  25. +3
    -2
      k8s/dockerfiles/managent-dockerfile
  26. +2
    -1
      k8s/dockerfiles/nginx-dockerfile
  27. +2
    -1
      k8s/dockerfiles/system-dockerfile
  28. +2
    -1
      k8s/dockerfiles/visual-dockerfile
  29. +2
    -2
      k8s/helm-1mysql/values.yaml
  30. +1
    -1
      k8s/helm-2redis-ha/templates/redis-haproxy-deployment.yaml
  31. +2
    -2
      k8s/helm-2redis-ha/values.yaml
  32. +7
    -6
      k8s/k8s-12front.yaml
  33. +3
    -3
      k8s/k8s-3nacos.yaml
  34. +3
    -3
      k8s/k8s-4gateway.yaml
  35. +3
    -3
      k8s/k8s-5auth.yaml
  36. +3
    -3
      k8s/k8s-6system.yaml
  37. +13
    -5
      k8s/k8s-7management.yaml
  38. +54
    -0
      k8s/nginx.conf
  39. BIN
      k8s/redis.tgz
  40. +36
    -0
      k8s/template-yaml/deploy/k8s-12front.yaml
  41. +53
    -0
      k8s/template-yaml/deploy/k8s-7management.yaml
  42. +36
    -0
      k8s/template-yaml/k8s-10gen.yaml
  43. +36
    -0
      k8s/template-yaml/k8s-11visual.yaml
  44. +36
    -0
      k8s/template-yaml/k8s-12front.yaml
  45. +71
    -0
      k8s/template-yaml/k8s-3nacos.yaml
  46. +36
    -0
      k8s/template-yaml/k8s-4gateway.yaml
  47. +36
    -0
      k8s/template-yaml/k8s-5auth.yaml
  48. +36
    -0
      k8s/template-yaml/k8s-6system.yaml
  49. +54
    -0
      k8s/template-yaml/k8s-7management.yaml
  50. +36
    -0
      k8s/template-yaml/k8s-8file.yaml
  51. +36
    -0
      k8s/template-yaml/k8s-9job.yaml
  52. +0
    -0
      k8s/vim
  53. +8
    -1
      react-ui/.gitignore
  54. +1
    -1
      react-ui/config/proxy.ts
  55. +10
    -0
      react-ui/config/routes.ts
  56. +11
    -8
      react-ui/src/app.tsx
  57. +4
    -1
      react-ui/src/components/IFramePage/index.tsx
  58. +7
    -0
      react-ui/src/components/RightContent/AvatarDropdown.tsx
  59. +1
    -1
      react-ui/src/components/RobotFrame/index.tsx
  60. +0
    -0
      react-ui/src/pages/Authorize/index.less
  61. +50
    -0
      react-ui/src/pages/Authorize/index.tsx
  62. +1
    -1
      react-ui/src/pages/Experiment/components/LogGroup/index.tsx
  63. +7
    -0
      react-ui/src/pages/GitLink/index.tsx
  64. +147
    -128
      react-ui/src/pages/User/Login/index.tsx
  65. +221
    -0
      react-ui/src/pages/User/Login/login.tsx
  66. +16
    -0
      react-ui/src/services/auth/index.js
  67. +12
    -0
      react-ui/src/types.ts
  68. +2
    -0
      react-ui/src/utils/sessionStorage.ts
  69. +11
    -0
      react-ui/src/utils/ui.tsx
  70. +25
    -0
      ruoyi-auth/src/main/java/com/ruoyi/auth/config/Oauth2ClientProperties.java
  71. +75
    -4
      ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java
  72. +119
    -0
      ruoyi-auth/src/main/java/com/ruoyi/auth/form/AccessTokenVo.java
  73. +59
    -0
      ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
  74. +5
    -3
      ruoyi-auth/src/main/resources/bootstrap.yml
  75. +7
    -5
      ruoyi-gateway/src/main/resources/bootstrap.yml
  76. +5
    -0
      ruoyi-modules/management-platform/pom.xml
  77. +2
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/RuoYiManagementPlatformApplication.java
  78. +18
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/constant/Constant.java
  79. +10
    -7
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/aim/AimController.java
  80. +84
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetTempStorageController.java
  81. +76
    -40
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/NewDatasetFromGitController.java
  82. +1
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/devEnvironment/DevEnvironmentController.java
  83. +6
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentInsController.java
  84. +3
    -20
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/jupyter/JupyterController.java
  85. +136
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/NewModelFromGitController.java
  86. +146
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/service/ServiceController.java
  87. +29
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DatasetDependency.java
  88. +109
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DatasetTempStorage.java
  89. +9
    -142
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java
  90. +31
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ModelDependency1.java
  91. +53
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Service.java
  92. +56
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ServiceVersion.java
  93. +4
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/dependencydomain/TrainTaskDepency.java
  94. +7
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetDependencyDao.java
  95. +86
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetTempStorageDao.java
  96. +4
    -1
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ExperimentInsDao.java
  97. +31
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelDependency1Dao.java
  98. +39
    -0
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ServiceDao.java
  99. +66
    -46
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/ExperimentInstanceStatusTask.java
  100. +13
    -2
      ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/AimService.java

+ 6
- 1
.gitignore View File

@@ -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


+ 84
- 0
k8s/10nexus3/nexus-deploy.yaml View File

@@ -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

+ 13
- 0
k8s/10nexus3/nexus-pvc.yaml View File

@@ -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

+ 33
- 0
k8s/build-java.sh View File

@@ -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









+ 25
- 0
k8s/build-java.sh.bak View File

@@ -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









+ 25
- 0
k8s/build-node.sh View File

@@ -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




+ 21
- 0
k8s/build-node.sh.bak View File

@@ -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




+ 141
- 0
k8s/build.sh View File

@@ -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 秒"

+ 92
- 0
k8s/build_and_deploy.sh View File

@@ -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 秒"

+ 74
- 0
k8s/build_and_deploy.sh.bak View File

@@ -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 秒"

+ 13
- 0
k8s/clusterrolebinding.yaml View File

@@ -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


+ 181
- 0
k8s/deploy.sh View File

@@ -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))秒"

+ 162
- 0
k8s/deploy.sh.bak View File

@@ -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))秒"

+ 2
- 1
k8s/dockerfiles/auth-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
#FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
# author
MAINTAINER ruoyi



+ 8
- 8
k8s/dockerfiles/buildimage.sh View File

@@ -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 .

+ 131
- 41
k8s/dockerfiles/conf/nginx.conf View File

@@ -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;
}
}
}

+ 64
- 0
k8s/dockerfiles/conf/nginx.conf.20240705 View File

@@ -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;
}
}
}

+ 131
- 0
k8s/dockerfiles/conf/nginx.conf.20240909 View File

@@ -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;
}
}
}

+ 60
- 0
k8s/dockerfiles/conf/nginx.conf.bak View File

@@ -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;
}
}
}

+ 110
- 0
k8s/dockerfiles/conf/nginx.conf.bak0719 View File

@@ -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;
}
}
}

+ 2
- 1
k8s/dockerfiles/file-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
#FROM openjdk:8-jre
# author
MAINTAINER ruoyi



+ 2
- 1
k8s/dockerfiles/gateway-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
#FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
# author
MAINTAINER ruoyi



+ 2
- 1
k8s/dockerfiles/gen-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
#FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
# author
MAINTAINER ruoyi



+ 2
- 1
k8s/dockerfiles/job-dockerfile View File

@@ -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
- 2
k8s/dockerfiles/managent-dockerfile View File

@@ -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"]

+ 2
- 1
k8s/dockerfiles/nginx-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM nginx
#FROM nginx:latest
FROM 172.20.32.187/ci4s/nginx:latest
# author
MAINTAINER ruoyi



+ 2
- 1
k8s/dockerfiles/system-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
#FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
# author
MAINTAINER ruoyi



+ 2
- 1
k8s/dockerfiles/visual-dockerfile View File

@@ -1,5 +1,6 @@
# 基础镜像
FROM openjdk:8-jre
#FROM openjdk:8-jre
FROM 172.20.32.187/ci4s/openjdk-dvc:2024829
# author
MAINTAINER ruoyi



+ 2
- 2
k8s/helm-1mysql/values.yaml View File

@@ -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: {}


+ 1
- 1
k8s/helm-2redis-ha/templates/redis-haproxy-deployment.yaml View File

@@ -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:


+ 2
- 2
k8s/helm-2redis-ha/values.yaml View File

@@ -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


+ 7
- 6
k8s/k8s-12front.yaml View File

@@ -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


+ 3
- 3
k8s/k8s-3nacos.yaml View File

@@ -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


+ 3
- 3
k8s/k8s-4gateway.yaml View File

@@ -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:


+ 3
- 3
k8s/k8s-5auth.yaml View File

@@ -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:


+ 3
- 3
k8s/k8s-6system.yaml View File

@@ -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:


+ 13
- 5
k8s/k8s-7management.yaml View File

@@ -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:


+ 54
- 0
k8s/nginx.conf View File

@@ -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;
}
}
}

BIN
k8s/redis.tgz View File


+ 36
- 0
k8s/template-yaml/deploy/k8s-12front.yaml View File

@@ -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


+ 53
- 0
k8s/template-yaml/deploy/k8s-7management.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-10gen.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-11visual.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-12front.yaml View File

@@ -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


+ 71
- 0
k8s/template-yaml/k8s-3nacos.yaml View File

@@ -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

+ 36
- 0
k8s/template-yaml/k8s-4gateway.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-5auth.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-6system.yaml View File

@@ -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


+ 54
- 0
k8s/template-yaml/k8s-7management.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-8file.yaml View File

@@ -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


+ 36
- 0
k8s/template-yaml/k8s-9job.yaml View 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


+ 0
- 0
k8s/vim View File


+ 8
- 1
react-ui/.gitignore View File

@@ -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

+ 1
- 1
react-ui/config/proxy.ts View File

@@ -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,
},
},


+ 10
- 0
react-ui/config/routes.ts View File

@@ -27,6 +27,16 @@ export default [
},
],
},
{
path: '/authorize',
layout: false,
component: './Authorize/index',
},
{
path: '/gitlink',
layout: true,
component: './GitLink/index',
},
{
path: '/user',
layout: false,


+ 11
- 8
react-ui/src/app.tsx View File

@@ -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();


+ 4
- 1
react-ui/src/components/IFramePage/index.tsx View File

@@ -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' });
}
};



+ 7
- 0
react-ui/src/components/RightContent/AvatarDropdown.tsx View File

@@ -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 {


+ 1
- 1
react-ui/src/components/RobotFrame/index.tsx View File

@@ -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
react-ui/src/pages/Authorize/index.less View File


+ 50
- 0
react-ui/src/pages/Authorize/index.tsx View File

@@ -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;

+ 1
- 1
react-ui/src/pages/Experiment/components/LogGroup/index.tsx View File

@@ -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}"}`,


+ 7
- 0
react-ui/src/pages/GitLink/index.tsx View File

@@ -0,0 +1,7 @@
import IframePage, { IframePageType } from '@/components/IFramePage';

function GitLink() {
return <IframePage type={IframePageType.GitLink}></IframePage>;
}

export default GitLink;

+ 147
- 128
react-ui/src/pages/User/Login/index.tsx View File

@@ -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;

+ 221
- 0
react-ui/src/pages/User/Login/login.tsx View File

@@ -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;

+ 16
- 0
react-ui/src/services/auth/index.js View File

@@ -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',
});
}

+ 12
- 0
react-ui/src/types.ts View File

@@ -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;
};

// 流水线全局参数


+ 2
- 0
react-ui/src/utils/sessionStorage.ts View File

@@ -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);


+ 11
- 0
react-ui/src/utils/ui.tsx View File

@@ -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);
}
};

/**
* 验证文件上传
*


+ 25
- 0
ruoyi-auth/src/main/java/com/ruoyi/auth/config/Oauth2ClientProperties.java View File

@@ -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;
}

+ 75
- 4
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java View File

@@ -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)
{


+ 119
- 0
ruoyi-auth/src/main/java/com/ruoyi/auth/form/AccessTokenVo.java View File

@@ -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;
}
}
}

+ 59
- 0
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java View File

@@ -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;
}
}

+ 5
- 3
ruoyi-auth/src/main/resources/bootstrap.yml View File

@@ -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
# 共享配置


+ 7
- 5
ruoyi-gateway/src/main/resources/bootstrap.yml View File

@@ -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


+ 5
- 0
ruoyi-modules/management-platform/pom.xml View File

@@ -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>


+ 2
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/RuoYiManagementPlatformApplication.java View File

@@ -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);


+ 18
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/constant/Constant.java View File

@@ -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";
}

+ 10
- 7
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/aim/AimController.java View File

@@ -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));
}
}

+ 84
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/DatasetTempStorageController.java View File

@@ -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));
}

}


+ 76
- 40
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/dataset/NewDatasetFromGitController.java View File

@@ -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);
}
}

+ 1
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/devEnvironment/DevEnvironmentController.java View File

@@ -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));
}



+ 6
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/experiment/ExperimentInsController.java View File

@@ -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));
}

/**
* 终止实验实例
*


+ 3
- 20
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/jupyter/JupyterController.java View File

@@ -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));
}
}

+ 136
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/model/NewModelFromGitController.java View File

@@ -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();
}

}

+ 146
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/controller/service/ServiceController.java View File

@@ -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));
}
}

+ 29
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DatasetDependency.java View File

@@ -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;
}

+ 109
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/DatasetTempStorage.java View File

@@ -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;
}

}


+ 9
- 142
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ExperimentIns.java View File

@@ -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;
}
}


+ 31
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ModelDependency1.java View File

@@ -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;
}

+ 53
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/Service.java View File

@@ -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;
}
}

+ 56
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/ServiceVersion.java View File

@@ -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;
}

+ 4
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/domain/dependencydomain/TrainTaskDepency.java View File

@@ -13,5 +13,9 @@ public class TrainTaskDepency implements Serializable {
//实例id
private Integer insId;
//节点Id
private Long workflowId;

private Integer experimentId;

private String taskId;
}

+ 7
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetDependencyDao.java View File

@@ -0,0 +1,7 @@
package com.ruoyi.platform.mapper;

import com.ruoyi.platform.domain.DatasetDependency;

public interface DatasetDependencyDao {
int insert(DatasetDependency datasetDependency);
}

+ 86
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/DatasetTempStorageDao.java View File

@@ -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);
}


+ 4
- 1
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ExperimentInsDao.java View File

@@ -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);


+ 31
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ModelDependency1Dao.java View File

@@ -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);
}

+ 39
- 0
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/mapper/ServiceDao.java View File

@@ -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);
}

+ 66
- 46
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/scheduling/ExperimentInstanceStatusTask.java View File

@@ -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());


+ 13
- 2
ruoyi-modules/management-platform/src/main/java/com/ruoyi/platform/service/AimService.java View File

@@ -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);
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save