#204 zhengxx

Merged
liwei03 merged 155 commits from openioctopus/octopus:zhengxx into master 2 years ago
  1. +48
    -0
      .drone.yml
  2. +1
    -0
      .golangci.yaml
  3. +33
    -6
      Makefile
  4. +12
    -0
      admin-portal/src/api/cloudInterconnection.js
  5. +42
    -11
      admin-portal/src/api/dataManager.js
  6. +1
    -1
      admin-portal/src/api/globalVariable.js
  7. +9
    -9
      admin-portal/src/api/modelDev.js
  8. +95
    -0
      admin-portal/src/api/platformManager.js
  9. +24
    -0
      admin-portal/src/api/userManager.js
  10. +13
    -1
      admin-portal/src/error/index.js
  11. +1
    -0
      admin-portal/src/icons/svg/platform.svg
  12. +24
    -0
      admin-portal/src/router/index.js
  13. +9
    -0
      admin-portal/src/styles/dot.scss
  14. +128
    -0
      admin-portal/src/views/cloudInterconnection/index.vue
  15. +1
    -1
      admin-portal/src/views/clusterMonitor/clusterMonitor.vue
  16. +30
    -5
      admin-portal/src/views/dataManager/components/preDatasetCreation.vue
  17. +202
    -73
      admin-portal/src/views/dataManager/datasetConfig.vue
  18. +5
    -0
      admin-portal/src/views/dataManager/templateList.vue
  19. +5
    -0
      admin-portal/src/views/dataManager/userList.vue
  20. +33
    -29
      admin-portal/src/views/devManager/components/algorithm/algorithmConfig.vue
  21. +10
    -10
      admin-portal/src/views/devManager/components/algorithm/preAlgorithmCreation.vue
  22. +1
    -1
      admin-portal/src/views/devManager/components/algorithm/templateList.vue
  23. +1
    -1
      admin-portal/src/views/devManager/components/algorithm/userList.vue
  24. +135
    -0
      admin-portal/src/views/platformManager/components/createDialog.vue
  25. +60
    -0
      admin-portal/src/views/platformManager/components/detailsDialog.vue
  26. +134
    -0
      admin-portal/src/views/platformManager/components/editDialog.vue
  27. +165
    -0
      admin-portal/src/views/platformManager/components/platformConfig.vue
  28. +120
    -0
      admin-portal/src/views/platformManager/components/storageConfigCreation.vue
  29. +51
    -0
      admin-portal/src/views/platformManager/components/storageConfigDetails.vue
  30. +218
    -0
      admin-portal/src/views/platformManager/components/storageConfigList.vue
  31. +62
    -0
      admin-portal/src/views/platformManager/index.vue
  32. +210
    -0
      admin-portal/src/views/platformManager/platformList.vue
  33. +106
    -0
      admin-portal/src/views/platformManager/platformTrainingTaskList.vue
  34. +5
    -0
      admin-portal/src/views/timeManager/component/consumption.vue
  35. +160
    -0
      admin-portal/src/views/userManager/components/userConfig.vue
  36. +30
    -5
      admin-portal/src/views/userManager/user.vue
  37. +2
    -2
      admin-portal/vue.config.js
  38. +2
    -1
      build/application/api-doc/dockerfile
  39. +13
    -0
      build/application/platform-server/dockerfile
  40. +52
    -0
      deploy/charts/octopus/templates/_helpers.tpl
  41. +1
    -1
      deploy/charts/octopus/templates/api-doc.yaml
  42. +16
    -0
      deploy/charts/octopus/templates/base-server.yaml
  43. +6
    -0
      deploy/charts/octopus/templates/ingress.yaml
  44. +142
    -0
      deploy/charts/octopus/templates/platform-server.yaml
  45. +38
    -7
      deploy/charts/octopus/values.yaml
  46. +7
    -0
      openai-portal/src/api/Home.js
  47. +69
    -0
      openai-portal/src/api/cloudInterconnection.js
  48. +11
    -4
      openai-portal/src/api/datasetManager.js
  49. +7
    -7
      openai-portal/src/api/generalView.js
  50. +1
    -1
      openai-portal/src/api/globalVariable.js
  51. +2
    -3
      openai-portal/src/api/imageManager.js
  52. +1
    -1
      openai-portal/src/api/modelDev.js
  53. +5
    -5
      openai-portal/src/api/trainingManager.js
  54. +5
    -1
      openai-portal/src/error/index.js
  55. +36
    -1
      openai-portal/src/layout/components/Sidebar/index.vue
  56. +12
    -0
      openai-portal/src/router/index.js
  57. +198
    -0
      openai-portal/src/views/cloudInterconnection/index.vue
  58. +568
    -0
      openai-portal/src/views/cloudInterconnection/trainingTaskCreate.vue
  59. +41
    -10
      openai-portal/src/views/dataManager/components/myDatasetCreation.vue
  60. +5
    -0
      openai-portal/src/views/dataManager/myList.vue
  61. +5
    -0
      openai-portal/src/views/dataManager/presetList.vue
  62. +5
    -0
      openai-portal/src/views/dataManager/publicList.vue
  63. +10
    -10
      openai-portal/src/views/modelDev/components/algorithm/myAlgorithmCreation.vue
  64. +3
    -3
      openai-portal/src/views/modelDev/components/algorithm/myList.vue
  65. +3
    -3
      openai-portal/src/views/modelDev/components/algorithm/presetList.vue
  66. +3
    -3
      openai-portal/src/views/modelDev/components/algorithm/publicList.vue
  67. +0
    -8
      openai-portal/src/views/modelDev/components/notebook/notebookList.vue
  68. +2
    -2
      openai-portal/vue.config.js
  69. +34
    -57
      server/admin-server/api/v1/algorithm.proto
  70. +7
    -0
      server/admin-server/api/v1/base.swagger.json
  71. +78
    -12
      server/admin-server/api/v1/dataset.proto
  72. +77
    -0
      server/admin-server/api/v1/jointcloud.proto
  73. +336
    -0
      server/admin-server/api/v1/platform.proto
  74. +54
    -0
      server/admin-server/api/v1/user.proto
  75. +40
    -32
      server/admin-server/internal/data/data.go
  76. +2
    -0
      server/admin-server/internal/server/http.go
  77. +65
    -52
      server/admin-server/internal/service/algorithm.go
  78. +100
    -18
      server/admin-server/internal/service/dataset.go
  79. +49
    -0
      server/admin-server/internal/service/jointcloud.go
  80. +188
    -0
      server/admin-server/internal/service/platform.go
  81. +4
    -0
      server/admin-server/internal/service/service.go
  82. +41
    -0
      server/admin-server/internal/service/user.go
  83. +6
    -126
      server/base-server/api/v1/algorithm.proto
  84. +8
    -64
      server/base-server/api/v1/dataset.proto
  85. +1
    -1
      server/base-server/api/v1/image.proto
  86. +206
    -0
      server/base-server/api/v1/jointcloud.proto
  87. +120
    -0
      server/base-server/api/v1/lable.proto
  88. +1
    -1
      server/base-server/api/v1/model.proto
  89. +178
    -0
      server/base-server/api/v1/platform.proto
  90. +218
    -0
      server/base-server/api/v1/platformtrainJob.proto
  91. +39
    -1
      server/base-server/api/v1/user.proto
  92. +1
    -1
      server/base-server/api/v1/workspace.proto
  93. +4
    -2
      server/base-server/cmd/base-server/main.go
  94. +25
    -0
      server/base-server/configs/config.yaml
  95. +7
    -0
      server/base-server/internal/common/constant.go
  96. +29
    -0
      server/base-server/internal/conf/conf.go
  97. +28
    -0
      server/base-server/internal/conf/conf.proto
  98. +4
    -0
      server/base-server/internal/data/cluster/cluster.go
  99. +31
    -0
      server/base-server/internal/data/cluster/kubernetes.go
  100. +0
    -111
      server/base-server/internal/data/dao/algorithm_dao/algorithm_framework.go

+ 48
- 0
.drone.yml View File

@@ -162,6 +162,54 @@ steps:
commands:
- make openai-server_image_push need_latest=FALSE tag=${DRONE_TAG} docker_hub_project=$DOCKER_HUB_PROJECT docker_hub_host=$DOCKER_HUB_HOST docker_hub_userame=$DOCKER_HUB_USERNAME docker_hub_passwd=$DOCKER_HUB_PASSWD

---
kind: pipeline
name: platform-server
type: kubernetes
platform:
os: linux
arch: amd64
trigger:
event:
- tag
volumes:
- name: docker
host:
path: /var/run/
steps:
# - name: 代码检查
# image: golangci/golangci-lint:v1.40.1
# environment:
# GO111MODULE: on
# GOPROXY: https://goproxy.cn,direct
# commands:
# - make platform-server_lint

- name: 构建镜像
image: swr.cn-south-1.myhuaweicloud.com/openioctopus/docker:20.10.6-make
volumes:
- name: docker
path: /var/run/
commands:
- make platform-server_image tag=${DRONE_TAG}

- name: 镜像推送
image: swr.cn-south-1.myhuaweicloud.com/openioctopus/docker:20.10.6-make
volumes:
- name: docker
path: /var/run/
environment:
DOCKER_HUB_HOST:
from_secret: docker_hub_host
DOCKER_HUB_USERNAME:
from_secret: docker_hub_userame
DOCKER_HUB_PASSWD:
from_secret: docker_hub_passwd
DOCKER_HUB_PROJECT:
from_secret: docker_hub_project
commands:
- make platform-server_image_push need_latest=FALSE tag=${DRONE_TAG} docker_hub_project=$DOCKER_HUB_PROJECT docker_hub_host=$DOCKER_HUB_HOST docker_hub_userame=$DOCKER_HUB_USERNAME docker_hub_passwd=$DOCKER_HUB_PASSWD

---
kind: pipeline
name: taskset/pipeline


+ 1
- 0
.golangci.yaml View File

@@ -73,3 +73,4 @@ run:
- node.go
- develop.go
- train_job.go
- conf.go

+ 33
- 6
Makefile View File

@@ -42,7 +42,7 @@ LD_FLAGS=" \
# 编译
all_build: server_build

server_build: base-server_build admin-server_build openai-server_build taskset_build
server_build: base-server_build admin-server_build openai-server_build platform-server_build taskset_build

init:
mkdir -p ${SERVER_BINARY_DIR}
@@ -62,6 +62,11 @@ openai-server_build: init

cd ./server/openai-server && go build -ldflags ${LD_FLAGS} -o ${SERVER_BINARY_DIR} ./...

platform-server_build: init
cd ./server && go generate

cd ./server/platform-server && go build -ldflags ${LD_FLAGS} -o ${SERVER_BINARY_DIR} ./...

taskset_build: pipeline_build vc-controller_build scheduler_build

pipeline_build: init
@@ -78,7 +83,7 @@ api-doc_build: init
# 运行
all_run: server_run

server_run: base-server_run admin-server_run openai-server_run taskset_run
server_run: base-server_run admin-server_run openai-server_run platform-server_run taskset_run

base-server_run:
cd server && ./bin/base-server -conf base-server/configs &
@@ -89,6 +94,9 @@ admin-server_run:
openai-server_run:
cd server && ./bin/openai-server -conf openai-server/configs &

platform-server_run:
cd server && ./bin/platform-server -conf platform-server/configs &

taskset_run: pipeline_run vc-controller_run scheduler_run

pipeline_run:
@@ -114,6 +122,9 @@ admin-server_stop:
openai-server_stop:
kill -9 `ps -ef|grep "openai-server" |grep -v grep |awk '{print $2}'`

platform-server_stop:
kill -9 `ps -ef|grep "platform-server" |grep -v grep |awk '{print $2}'`

taskset_stop: pipeline_stop vc-controller_stop scheduler_stop

pipeline_stop:
@@ -128,7 +139,7 @@ scheduler_stop:
# 重启
all_stop: server_restart

server_restart: base-server_restart admin-server_restart openai-server_restart taskset_restart
server_restart: base-server_restart admin-server_restart openai-server_restart platform-server_restart taskset_restart

base-server_restart: base-server_stop server_run

@@ -136,6 +147,8 @@ admin-server_restart: admin-server_stop admin-server_run

openai-server_restart: openai-server_stop openai-server_run

platform-server_restart: platform-server_stop platform-server_run

taskset_restart: pipeline_restart vc-controller_restart scheduler_restart

pipeline_restart: pipeline_stop pipeline_run
@@ -167,7 +180,7 @@ taskset_lint: lint_init
cd ./server/taskset && golangci-lint run ./...

# 构建镜像
images: base-server_image admin-server_image openai-server_image taskset_image admin-portal_image openai-portal_image api-doc_image
images: base-server_image admin-server_image openai-server_image platform-server_image taskset_image admin-portal_image openai-portal_image api-doc_image

base-server_image:
docker build --no-cache -t base-server:${RELEASE_VER} -f ./build/application/base-server/dockerfile .
@@ -178,6 +191,9 @@ admin-server_image:
openai-server_image:
docker build --no-cache -t openai-server:${RELEASE_VER} -f ./build/application/openai-server/dockerfile .

platform-server_image:
docker build --no-cache -t platform-server:${RELEASE_VER} -f ./build/application/platform-server/dockerfile .

taskset_image: pipeline_image vc-controller_image scheduler_image

pipeline_image:
@@ -199,7 +215,7 @@ api-doc_image:
docker build --no-cache -t api-doc:${RELEASE_VER} -f ./build/application/api-doc/dockerfile .

# 镜像推送
images_push: base-server_image_push admin-server_image_push openai-server_image_push taskset_image_push admin-portal_image_push openai-portal_image_push api-doc_image_push
images_push: base-server_image_push admin-server_image_push openai-server_image_push platform-server_image_push taskset_image_push admin-portal_image_push openai-portal_image_push api-doc_image_push

image_push_init:
(echo ${DOCKER_HUB_PASSWD} | docker login ${DOCKER_HUB_HOST} -u ${DOCKER_HUB_USERNAME} --password-stdin) 1>/dev/null 2>&1
@@ -237,6 +253,17 @@ ifeq (${NEED_LATEST}, TRUE)
endif
endif

platform-server_image_push: image_push_init
docker tag platform-server:${RELEASE_VER} ${DOCKER_HUB_HOST}/${DOCKER_HUB_PROJECT}/platform-server:${RELEASE_VER}
docker push ${DOCKER_HUB_HOST}/${DOCKER_HUB_PROJECT}/platform-server:${RELEASE_VER}

ifneq (${RELEASE_VER}, latest)
ifeq (${NEED_LATEST}, TRUE)
docker tag platform-server:${RELEASE_VER} ${DOCKER_HUB_HOST}/${DOCKER_HUB_PROJECT}/platform-server:latest
docker push ${DOCKER_HUB_HOST}/${DOCKER_HUB_PROJECT}/platform-server:latest
endif
endif

taskset_image_push: pipeline_image_push vc-controller_image_push scheduler_image_push

pipeline_image_push: image_push_init
@@ -311,7 +338,7 @@ charts: charts_build charts_push

charts_build:
-mkdir -p ./tmp/charts
helm package ./deploy/charts/octopus --version ${RELEASE_VER} --app-version ${RELEASE_VER} -d ./tmp/charts
helm package ./deploy/charts/octopus --version ${RELEASE_VER} --app-version ${RELEASE_VER} -d ./tmp/charts

charts_push:
-helm repo add --ca-file=${HARBOR_HUB_CA_FILE} --cert-file=${HARBOR_HUB_CERT_FILE} --username=${HARBOR_HUB_USERNAME} --password=${HARBOR_HUB_PASSWD} chartrepo ${HARBOR_HUB_HOST}/chartrepo/${HARBOR_HUB_PROJECT}


+ 12
- 0
admin-portal/src/api/cloudInterconnection.js View File

@@ -0,0 +1,12 @@
import request from '@/utils/request'

export function getCloudTrainJobList(params) {
let conditions = []
conditions.push(`pageIndex=` + params.pageIndex);
conditions.push(`pageSize=` + params.pageSize);
params.ids?conditions.push(`ids=` + params.ids):null;
return request({
url: `/v1/jointcloudmanage/job?` + conditions.join("&"),
method: 'get',
})
}

+ 42
- 11
admin-portal/src/api/dataManager.js View File

@@ -1,15 +1,15 @@
import request from '@/utils/request'

export function judgeParam(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
params.createdAtGte ? conditions.push(`createdAtGte=` + params.createdAtGte) : null;
params.createdAtLt ? conditions.push(`createdAtLt=` + params.createdAtLt) : null;
params.path ? conditions.push(`path=` + params.path) : null;
let conditions = []
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex);
params.orderBy?conditions.push(`orderBy=`+params.orderBy):null;
params.sortBy?conditions.push(`sortBy=`+params.sortBy):null;
params.searchKey?conditions.push(`searchKey=`+params.searchKey):null;
params.createdAtGte?conditions.push(`createdAtGte=`+params.createdAtGte):null;
params.createdAtLt?conditions.push(`createdAtLt=`+params.createdAtLt):null;
params.path?conditions.push(`path=`+params.path):null;
return conditions
}

@@ -142,7 +142,7 @@ export async function addDatasetType(data) {
const res = await request({
url: `/v1/datasetmanage/datasettype`,
method: "post",
data: { typeDesc: data }
data: { lableDesc: data }
})
return res
}
@@ -160,4 +160,35 @@ export async function updateDatasetType(data) {
data: data
})
return res
}
}
export async function datasetUse(params) {
const res = await request({
url: `/v1/datasetmanage/datasetapply`,
method: "get",
params: params
})
return res
}
export async function addDatasetUse(data) {
const res = await request({
url: `/v1/datasetmanage/datasetapply`,
method: "post",
data: { lableDesc: data }
})
return res
}
export async function deleteDatasetUse(params) {
const res = await request({
url: `/v1/datasetmanage/datasetapply/${params}`,
method: "delete"
})
return res
}
export async function updateDatasetUse(data) {
const res = await request({
url: `/v1/datasetmanage/datasetapply/${data.id}`,
method: "put",
data: data
})
return res
}

+ 1
- 1
admin-portal/src/api/globalVariable.js View File

@@ -10,4 +10,4 @@ if (process.env.NODE_ENV === 'development') {
export default {
DOMAIN
}
// 本地调试执行npm run dev指令需要修改DOMAIN地址,将http://192.168.202.73替换成服务器地址
// 本地调试执行npm run dev指令需要修改DOMAIN地址,将http://192.168.202.73替换成服务器地址

+ 9
- 9
admin-portal/src/api/modelDev.js View File

@@ -2,8 +2,8 @@ import request from '@/utils/request'

export function judgeParam(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
conditions.push(`pageSize=` + params.pageSize);
conditions.push(`pageIndex=` + params.pageIndex);
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
@@ -148,7 +148,7 @@ export async function deletePreAlgorithm(algorithmId) {
}
export async function algorithmType(params) {
const res = await request({
url: `/v1/algorithmmanage/algorithmtype`,
url: `/v1/algorithmmanage/algorithmapply`,
method: "get",
params: params
})
@@ -156,22 +156,22 @@ export async function algorithmType(params) {
}
export async function addAlgorithmType(data) {
const res = await request({
url: `/v1/algorithmmanage/algorithmtype`,
url: `/v1/algorithmmanage/algorithmapply`,
method: "post",
data: { typeDesc: data }
data: { lableDesc: data }
})
return res
}
export async function deleteAlgorithmType(params) {
const res = await request({
url: `/v1/algorithmmanage/algorithmtype/${params}`,
url: `/v1/algorithmmanage/algorithmapply/${params}`,
method: "delete"
})
return res
}
export async function updateAlgorithmType(data) {
const res = await request({
url: `/v1/algorithmmanage/algorithmtype/${data.id}`,
url: `/v1/algorithmmanage/algorithmapply/${data.id}`,
method: "put",
data: data
})
@@ -189,7 +189,7 @@ export async function addFrameType(data) {
const res = await request({
url: `/v1/algorithmmanage/algorithmframework`,
method: "post",
data: { frameworkDesc: data }
data: { lableDesc: data }
})
return res
}
@@ -207,4 +207,4 @@ export async function updateFrameType(data) {
data: data
})
return res
}
}

+ 95
- 0
admin-portal/src/api/platformManager.js View File

@@ -0,0 +1,95 @@
import request from '@/utils/request'

export function judgeParam(params) {
let conditions = []
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex);
params.orderBy?conditions.push(`orderBy=`+params.orderBy):null;
params.sortBy?conditions.push(`sortBy=`+params.sortBy):null;
params.searchKey?conditions.push(`searchKey=`+params.searchKey):null;
params.createdAtGte?conditions.push(`createdAtGte=`+params.createdAtGte):null;
params.createdAtLt?conditions.push(`createdAtLt=`+params.createdAtLt):null;
params.name?conditions.push(`name=`+params.name):null;
params.status?conditions.push(`status=`+params.status):null;
params.platformId?conditions.push(`name=`+params.platformId):null;
return conditions
}

export function getPlatformList(params) {
let conditions = judgeParam(params)
return request({
url: '/v1/platformmanage/platform?' + conditions.join("&"),
method: 'get',
})
}

export function createPlatform(params) {
return request({
url: '/v1/platformmanage/platform',
method: 'post',
params
})
}

export function updatePlatform(params) {
return request({
url: '/v1/platformmanage/platform',
method: 'put',
params
})
}

export function getStorageConfigList(params) {
let conditions = judgeParam(params)
return request({
url: `/v1/platformmanage/platform/${params.id}/storageconfig?` + conditions.join("&"),
method: 'get',
})
}

export function createStorageConfig(platformId,params) {
return request({
url: `/v1/platformmanage/platform/${platformId}/storageconfig`,
method: 'post',
data: params
})
}

export function deleteStorageConfig(params) {
return request({
url: `/v1/platformmanage/platform/${params.platformId}/storageconfig/${params.name}`,
method: 'delete',
})
}

export function updatePlatformConfig(platformId,params) {
return request({
url: `/v1/platformmanage/platform/${platformId}/config`,
method: 'put',
data: {
config: params
}
})
}

export function getPlatformConfigKey() {
return request({
url: `/v1/platformmanage/platformconfigkey`,
method: 'get'
})
}

export function getPlatformConfigValue(platformId) {
return request({
url: `/v1/platformmanage/platform/${platformId}/config`,
method: 'get'
})
}

export function getPlatformTrainingTaskList(params) {
let conditions = judgeParam(params)
return request({
url: '/v1/platformmanage/platform/trainjob?' + conditions.join("&"),
method: 'get',
})
}

+ 24
- 0
admin-portal/src/api/userManager.js View File

@@ -90,4 +90,28 @@ export function deleteGroup(params) {
method: 'delete'
})
}
// 查询配置key列表
export function getUserConfigKey() {
return request({
url: `/v1/usermanage/userconfigkey`,
method: 'get'
})
}
// 查询用户配置
export function getUserConfig(userId) {
return request({
url: `/v1/usermanage/user/${userId}/config`,
method: 'get'
})
}
// 更新用户配置
export function updateUserConfig(userId,params) {
return request({
url: `/v1/usermanage/user/${userId}/config`,
method: 'put',
data: {
config: params
}
})
}


+ 13
- 1
admin-portal/src/error/index.js View File

@@ -164,13 +164,25 @@ const error = {
19003: '没有权限操作',
19004: ' 数据集重复',
19005: '状态不允许操作',
19502: '标签名重复',
12012: '算法类型被引用',
12013: '算法框架被引用',
12014: '算法类型重复',
12015: '算法框架重复',
19006: '数据集类型被引用',
19007: '数据集类型重复'
19007: '数据集类型重复',

/* 20001-21000 第三方平台管理错误*/
20001: '平台名称重复',
20002: '平台存储配置名称重复',
20003: '批量获取平台信息错误',
20004: '配置值不正确',
20005: '配置项不存在',
20006: 'http请求失败',

/* 21001-22000 云际错误*/
21001: '云际请求失败',
21002: '无权限访问'
}
export function getErrorMsg(errorCode) {
let message = ''


+ 1
- 0
admin-portal/src/icons/svg/platform.svg View File

@@ -0,0 +1 @@
<svg t="1637572898177" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2708" width="200" height="200"><path d="M874.666667 128h-725.333334A106.666667 106.666667 0 0 0 42.666667 234.666667v384A106.666667 106.666667 0 0 0 149.333333 725.333333h341.333334v128H256c-11.946667 0-21.333333 9.386667-21.333333 21.333334s9.386667 21.333333 21.333333 21.333333h512c11.946667 0 21.333333-9.386667 21.333333-21.333333s-9.386667-21.333333-21.333333-21.333334h-234.666667v-128h341.333334a106.666667 106.666667 0 0 0 106.666666-106.666666v-384A106.666667 106.666667 0 0 0 874.666667 128zM938.666667 618.666667c0 35.413333-28.586667 64-64 64h-725.333334c-35.413333 0-64-28.586667-64-64v-384C85.333333 199.253333 113.92 170.666667 149.333333 170.666667h725.333334c35.413333 0 64 28.586667 64 64v384z" fill="#ffffff" p-id="2709"></path><path d="M227.413333 317.013333h205.226667c11.946667 0 21.333333-9.386667 21.333333-21.333333s-9.386667-21.333333-21.333333-21.333333H227.413333c-11.946667 0-21.333333 9.386667-21.333333 21.333333s9.813333 21.333333 21.333333 21.333333zM227.413333 448h389.12c11.946667 0 21.333333-9.386667 21.333334-21.333333s-9.386667-21.333333-21.333334-21.333334H227.413333c-11.946667 0-21.333333 9.386667-21.333333 21.333334s9.813333 21.333333 21.333333 21.333333zM815.36 536.32H227.413333c-11.946667 0-21.333333 9.386667-21.333333 21.333333s9.386667 21.333333 21.333333 21.333334h587.946667c11.946667 0 21.333333-9.386667 21.333333-21.333334s-9.386667-21.333333-21.333333-21.333333z" fill="#ffffff" p-id="2710"></path></svg>

+ 24
- 0
admin-portal/src/router/index.js View File

@@ -200,6 +200,30 @@ export const constantRoutes = [
}
]
},
{
path: '/platformManager',
component: Layout,
children: [
{
path: 'index',
name: 'platformManager',
component: () => import('@/views/platformManager/index'),
meta: { title: '平台管理', icon: 'platform' }
},
]
},
{
path: '/cloudInterconnection',
component: Layout,
children: [
{
path: 'index',
name: 'cloudInterconnection',
component: () => import('@/views/cloudInterconnection/index'),
meta: { title: '云际互联', icon: 'example' }
}
]
},

// {
// path: 'external-link',


+ 9
- 0
admin-portal/src/styles/dot.scss View File

@@ -43,6 +43,15 @@
border-radius:50%;
margin-right: 5px;
}
// 重分派
.status-reassign{
display:inline-block;
width: 7px;
height:7px;
background:#006400;
border-radius:50%;
margin-right: 5px;
}
// 失败
.status-danger{
display:inline-block;


+ 128
- 0
admin-portal/src/views/cloudInterconnection/index.vue View File

@@ -0,0 +1,128 @@
<template>
<div>
<el-tabs class="Wrapper">
<el-tab-pane label="训练任务">
<el-table
:data="trainJobList"
style="width: 100%;font-size: 15px;"
:header-cell-style="{'text-align':'left','color':'black'}"
:cell-style="{'text-align':'left'}"
>
<el-table-column label="任务名称">
<template slot-scope="scope">
<span>{{ scope.row.taskName }}</span>
</template>
</el-table-column>
<el-table-column label="学习框架">
<template slot-scope="scope">
<span>{{ scope.row.framework }}</span>
</template>
</el-table-column>
<el-table-column label="解释器">
<template slot-scope="scope">
<span>{{ scope.row.interpreter }}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<span :class="statusOption[scope.row.status][0]"></span>
<span>{{ statusOption[scope.row.status][1] }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>

<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="searchData.pageIndex"
:page-sizes="[10, 20, 50, 80]"
:page-size="searchData.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { parseTime } from '@/utils/index'
import { getErrorMsg } from '@/error/index'
import { getCloudTrainJobList } from "@/api/cloudInterconnection"
export default {
name: "cloudInterconnection",
data() {
return {
searchData: {
pageIndex: 1,
pageSize: 10,
},
trainJobList: [],
total: 0,
statusOption: {
'0': ['status-ready', '初始中'],
'1': ['status-agent', '已分派'],
'2': ['status-running', '分中心处理中'],
'-1': ['status-danger', '失败'],
'3': ['status-success', '成功'],
'4': ['status-stopping', '停止'],
'7': ['status-reassign', '重分派'],
}
}
},
created(){
this.getCloudTrainJobList(this.searchData)
},
methods: {
getCloudTrainJobList(params){
getCloudTrainJobList(params).then(response => {
if (response.success) {
this.trainJobList = response.data.list;
this.total = response.data.totalSize
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
})
}
})
},
handleSizeChange(val) {
this.searchData.pageSize = val
this.getCloudTrainJobList(this.searchData)
},
handleCurrentChange(val) {
this.searchData.pageIndex = val
this.getCloudTrainJobList(this.searchData)
},
parseTime(val) {
return parseTime(val)
},
getErrorMsg(code) {
return getErrorMsg(code)
},
}
}
</script>
<style lang="scss" scoped>
.Wrapper {
margin: 15px!important;
background-color:#fff;
padding: 20px;
min-height: 900px
}
.create {
float: right;
}
.block {
float: right;
margin: 20px;
}
</style>

+ 1
- 1
admin-portal/src/views/clusterMonitor/clusterMonitor.vue View File

@@ -1,7 +1,7 @@
<template>
<div>
<iframe
src="http://192.168.202.73/grafana/d/ft1oaQnWk/clustermetrics?orgId=1&refresh=10s&from=now-5m&to=now&var-Node=All"
src="http://192.168.203.156/grafana/d/ft1oaQnWk/clustermetrics?orgId=1&refresh=10s&from=now-5m&to=now&var-Node=All"
:height="iFrameHeight"
>
</iframe>


+ 30
- 5
admin-portal/src/views/dataManager/components/preDatasetCreation.vue View File

@@ -8,7 +8,13 @@
</el-form-item>
<el-form-item label="数据类型" :label-width="formLabelWidth" prop="typeId">
<el-select v-model="ruleForm.typeId" :disabled="disabled" placeholder="请选择数据集类型">
<el-option v-for="item in options" :key="item.id" :label="item.typeDesc" :value="item.id">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="数据用途" :label-width="formLabelWidth" prop="typeId">
<el-select v-model="ruleForm.applyId" :disabled="disabled" placeholder="请选择数据集用途">
<el-option v-for="item in useOptions" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
@@ -30,7 +36,7 @@

<script>
import upload from '@/components/upload/index.vue'
import { createPreDataset, datasetType } from "@/api/dataManager"
import { createPreDataset, datasetType,datasetUse } from "@/api/dataManager"
import { getErrorMsg } from '@/error/index'
export default {
name: "PreDatasetCreation",
@@ -45,7 +51,8 @@
}
},
created() {
this.datasetType()
this.datasetType(),
this.datasetUse()
},
data() {
return {
@@ -63,6 +70,9 @@
typeId: [
{ required: true, message: '请选择数据集类型', trigger: 'change' }
],
applyId: [
{ required: true, message: '请选择数据集用途', trigger: 'change' }
],
path: [
{ required: true, message: '请上传数据集', trigger: 'change' }
]
@@ -70,7 +80,8 @@
CreateFormVisible: true,
formLabelWidth: '120px',
close: true,
options:[]
typeOptions:[],
useOptions:[]
}
},
methods: {
@@ -115,7 +126,21 @@
datasetType() {
datasetType({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.options = response.data.datasetTypes
this.typeOptions = response.data.lables
} else {
// this.showUpload = false
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
// 获取数据集用途
datasetUse() {
datasetUse({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.useOptions = response.data.lables
} else {
// this.showUpload = false
this.$message({


+ 202
- 73
admin-portal/src/views/dataManager/datasetConfig.vue View File

@@ -1,68 +1,186 @@
<template>
<div>
<div class="title">算法类型</div>
<el-tag v-for="(tag,index) in dynamicTags" :key="index" closable :disable-transitions="false"
@click="editTag(tag,index)" @close="handleClose(tag)">
<span v-if="index!=num"> {{tag.typeDesc }}</span>
<input class="custom_input" type="text" v-model="inputValue" v-if="index==num" ref="editInput"
@keyup.enter.native="handleInput(tag)" @blur="handleInput(tag)">
</el-tag>
<el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small"
@keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm">
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">{{'+ 新标签'}}</el-button>
<div class="title">数据集类型</div>
<div>
<el-tag v-for="(tag,index) in dynamicType" :key="index" :closable="tag.sourceType!==1"
:disable-transitions="false" @click="editTag(tag,index,'TYPE')" @close="handleClose(tag,'TYPE')">
<span v-if="index!=typeNum"> {{tag.lableDesc }}</span>
<input class="custom_input" type="text" v-model="typeValue" v-if="index==typeNum" ref="editeTypeInput"
@keyup.enter.native="handleInput(tag,'TYPE')" @blur="handleInput(tag,'TYPE')">
</el-tag>
<el-input class="input-new-tag" v-if="inputTypeVisible" v-model="typeValue" ref="saveTypeInput" size="small"
@keyup.enter.native="handleInputConfirm('TYPE')" @blur="handleInputConfirm('TYPE')">
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput('TYPE')">{{'+ 新标签'}}</el-button>
</div>
<el-divider></el-divider>
<div class="title">数据集用途</div>
<div>
<el-tag v-for="(tag,index) in dynamicFrame" :key="index" :closable="tag.sourceType!==1"
:disable-transitions="false" @click="editTag(tag,index,'FRAME')" @close="handleClose(tag,'FRAME')">
<span v-if="index!=frameNum"> {{tag.lableDesc }}</span>
<input class="custom_input" type="text" v-model="frameValue" v-if="index==frameNum"
ref="editeFrameInput" @keyup.enter.native="handleInput(tag,'FRAME')"
@blur="handleInput(tag,'FRAME')">
</el-tag>
<el-input class="input-new-tag" v-if="inputFrameVisible" v-model="frameValue" ref="saveFrameInput"
size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm">
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">{{'+ 新标签'}}</el-button>
</div>
</div>
</template>
<script>
import { datasetType, addDatasetType, deleteDatasetType, updateDatasetType } from "@/api/dataManager"
import { datasetType,addDatasetType,deleteDatasetType,updateDatasetType,datasetUse,addDatasetUse,deleteDatasetUse,updateDatasetUse } from "@/api/dataManager.js"
import { getErrorMsg } from '@/error/index'
export default {
name: 'star-input-tag',
created() {
this.getType();
this.datasetType();
this.datasetUse()
},
data() {
return {
inputVisible: false,
inputValue: '',
id: '',
num: -1,
dynamicTags: []
//算法类型
inputTypeVisible: false,
typeValue: '',
typeId: '',
typeNum: -1,
dynamicType: [],
//算法框架
inputFrameVisible: false,
frameValue: '',
frameId: '',
frameNum: -1,
dynamicFrame: []
}
},

methods: {
handleClose(tag) {
deleteDatasetType(tag.id).then(response => {
if (response.success) {
this.getType()
handleClose(tag, val) {
if (val === 'TYPE') {
deleteDatasetType(tag.id).then(response => {
if (response.success) {
this.datasetType()
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
}
else {
deleteDatasetUse(tag.id).then(response => {
if (response.success) {
this.datasetUse()
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
}

},

showInput(val) {
if (val === 'TYPE') {
this.inputTypeVisible = true;
this.$nextTick(_ => {
this.$refs.saveTypeInput.$refs.input.focus();
});
}
else {
this.inputFrameVisible = true;
this.$nextTick(_ => {
this.$refs.saveFrameInput.$refs.input.focus();
});
}


},

handleInputConfirm(val) {
if (val === 'TYPE') {
let typeValue = this.typeValue;
typeValue = typeValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '')
// 点击添加时,追加
if (typeValue) {
if (typeValue) {
addDatasetType(typeValue).then(response => {
if (response.success) {
this.datasetType()
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})

}
}
this.inputTypeVisible = false;
this.typeValue = '';
}
else {
let frameValue = this.frameValue;
frameValue = frameValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '')
// 点击添加时,追加
if (frameValue) {
if (frameValue) {
addDatasetUse(frameValue).then(response => {
if (response.success) {
this.datasetUse()
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})

}
}
this.inputFrameVisible = false;
this.frameValue = '';
}
},
editTag(tag, index, val) {
if (tag.sourceType == 1) {
return
} else {
if (val === 'TYPE') {
this.typeNum = index;
this.$nextTick(_ => {
this.$refs.editeTypeInput[0].focus();
});
this.typeValue = tag.lableDesc;
this.typeId = tag.id
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
this.frameNum = index;
this.$nextTick(_ => {
this.$refs.editeFrameInput[0].focus();
});
this.frameValue = tag.lableDesc;
this.frameId = tag.id
}
})
},

showInput() {
this.inputVisible = true;
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus();
});
}

},

handleInputConfirm() {
let inputValue = this.inputValue;
inputValue = inputValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '')
// 点击添加时,追加
if (inputValue) {
if (inputValue) {
addDatasetType(inputValue).then(response => {
handleInput(tag, val) {
if (val === 'TYPE') {
updateDatasetType({ id: this.typeId, lableDesc: this.typeValue }).then(
response => {
if (response.success) {
this.getType()
this.datasetType()
}
else {
this.$message({
@@ -70,26 +188,42 @@
type: 'warning'
});
}
})

}
this.typeValue = '';
this.typeNum = -1;
}
)
}
this.inputVisible = false;
this.inputValue = '';
else {
updateDatasetUse({ id: this.frameId, lableDesc: this.frameValue }).then(
response => {
if (response.success) {
this.datasetUse()
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
this.frameValue = '';
this.frameNum = -1;
}
)
}

},
editTag(tag, index) {
this.num = index;
this.$nextTick(_ => {
this.$refs.editInput[0].focus();
});
this.inputValue = tag.typeDesc;
this.id = tag.id
getErrorMsg(code) {
return getErrorMsg(code)
},
handleInput(tag) {
updateDatasetType({ id: this.id, typeDesc: this.inputValue }).then(
datasetType() {
datasetType({ pageIndex: 1, pageSize: 20 }).then(
response => {
if (response.success) {
this.getType()
this.dynamicType = response.data.lables
if (this.dynamicType == null) {
this.dynamicType = []
}

}
else {
this.$message({
@@ -97,22 +231,16 @@
type: 'warning'
});
}
this.inputValue = '';
this.num = -1;
}
)

},
getErrorMsg(code) {
return getErrorMsg(code)
},
getType() {
datasetType({ pageIndex: 1, pageSize: 20 }).then(
datasetUse() {
datasetUse({ pageIndex: 1, pageSize: 20 }).then(
response => {
if (response.success) {
this.dynamicTags = response.data.datasetTypes
if (this.dynamicTags == null) {
this.dynamicTags = []
this.dynamicFrame = response.data.lables
if (this.dynamicFrame == null) {
this.dynamicFrame = []
}
}
else {
@@ -128,11 +256,6 @@
}
</script>
<style scoped lang="scss">
.title {
margin-bottom: 20px;
font-size: 16px;
font-weight: 800;
}
.el-tag+.el-tag {
margin-left: 15px;
}
@@ -160,4 +283,10 @@
font-size: 12px;
color: #E6A23C;
}

.title {
margin-bottom: 20px;
font-size: 16px;
font-weight: 800;
}
</style>

+ 5
- 0
admin-portal/src/views/dataManager/templateList.vue View File

@@ -33,6 +33,11 @@
<span>{{ scope.row.typeDesc }}</span>
</template>
</el-table-column>
<el-table-column label="数据用途">
<template slot-scope="scope">
<span>{{ scope.row.applyDesc }}</span>
</template>
</el-table-column>
<el-table-column label="最新版本号">
<template slot-scope="scope">
<span>{{ scope.row.latestVersion }}</span>


+ 5
- 0
admin-portal/src/views/dataManager/userList.vue View File

@@ -25,6 +25,11 @@
<span>{{ scope.row.typeDesc }}</span>
</template>
</el-table-column>
<el-table-column label="数据用途">
<template slot-scope="scope">
<span>{{ scope.row.applyDesc }}</span>
</template>
</el-table-column>
<el-table-column label="最新版本号">
<template slot-scope="scope">
<span>{{ scope.row.latestVersion }}</span>


+ 33
- 29
admin-portal/src/views/devManager/components/algorithm/algorithmConfig.vue View File

@@ -1,11 +1,10 @@

<template>
<div>
<div class="title">算法类型</div>
<div class="title">模型类别</div>
<div>
<el-tag v-for="(tag,index) in dynamicType" :key="index" closable :disable-transitions="false"
@click="editTag(tag,index,'TYPE')" @close="handleClose(tag,'TYPE')">
<span v-if="index!=typeNum"> {{tag.typeDesc }}</span>
<el-tag v-for="(tag,index) in dynamicType" :key="index" :closable="tag.sourceType!==1"
:disable-transitions="false" @click="editTag(tag,index,'TYPE')" @close="handleClose(tag,'TYPE')">
<span v-if="index!=typeNum"> {{tag.lableDesc }}</span>
<input class="custom_input" type="text" v-model="typeValue" v-if="index==typeNum" ref="editeTypeInput"
@keyup.enter.native="handleInput(tag,'TYPE')" @blur="handleInput(tag,'TYPE')">
</el-tag>
@@ -15,11 +14,11 @@
<el-button v-else class="button-new-tag" size="small" @click="showInput('TYPE')">{{'+ 新标签'}}</el-button>
</div>
<el-divider></el-divider>
<div class="title">算法框架</div>
<div class="title">框架类型</div>
<div>
<el-tag v-for="(tag,index) in dynamicFrame" :key="index" closable :disable-transitions="false"
@click="editTag(tag,index,'FRAME')" @close="handleClose(tag,'FRAME')">
<span v-if="index!=frameNum"> {{tag.frameworkDesc }}</span>
<el-tag v-for="(tag,index) in dynamicFrame" :key="index" :closable="tag.sourceType!==1"
:disable-transitions="false" @click="editTag(tag,index,'FRAME')" @close="handleClose(tag,'FRAME')">
<span v-if="index!=frameNum"> {{tag.lableDesc }}</span>
<input class="custom_input" type="text" v-model="frameValue" v-if="index==frameNum"
ref="editeFrameInput" @keyup.enter.native="handleInput(tag,'FRAME')"
@blur="handleInput(tag,'FRAME')">
@@ -154,26 +153,31 @@
}
},
editTag(tag, index, val) {
if (val === 'TYPE') {
this.typeNum = index;
this.$nextTick(_ => {
this.$refs.editeTypeInput[0].focus();
});
this.typeValue = tag.typeDesc;
this.typeId = tag.id
}
else {
this.frameNum = index;
this.$nextTick(_ => {
this.$refs.editeFrameInput[0].focus();
});
this.frameValue = tag.frameworkDesc;
this.frameId = tag.id
if (tag.sourceType == 1) {
return
} else {
if (val === 'TYPE') {
this.typeNum = index;
this.$nextTick(_ => {
this.$refs.editeTypeInput[0].focus();
});
this.typeValue = tag.lableDesc;
this.typeId = tag.id
}
else {
this.frameNum = index;
this.$nextTick(_ => {
this.$refs.editeFrameInput[0].focus();
});
this.frameValue = tag.lableDesc;
this.frameId = tag.id
}
}

},
handleInput(tag, val) {
if (val === 'TYPE') {
updateAlgorithmType({ id: this.typeId, typeDesc: this.typeValue }).then(
updateAlgorithmType({ id: this.typeId, lableDesc: this.typeValue }).then(
response => {
if (response.success) {
this.algorithmType()
@@ -190,10 +194,10 @@
)
}
else {
updateFrameType({ id: this.frameId, frameworkDesc: this.frameValue }).then(
updateFrameType({ id: this.frameId, lableDesc: this.frameValue }).then(
response => {
if (response.success) {
this.frameType()
this.frameType()
}
else {
this.$message({
@@ -215,7 +219,7 @@
algorithmType({ pageIndex: 1, pageSize: 20 }).then(
response => {
if (response.success) {
this.dynamicType = response.data.algorithmTypes
this.dynamicType = response.data.lables
if (this.dynamicType == null) {
this.dynamicType = []
}
@@ -234,7 +238,7 @@
frameType({ pageIndex: 1, pageSize: 20 }).then(
response => {
if (response.success) {
this.dynamicFrame = response.data.algorithmFrameworks
this.dynamicFrame = response.data.lables
if (this.dynamicFrame == null) {
this.dynamicFrame = []
}


+ 10
- 10
admin-portal/src/views/devManager/components/algorithm/preAlgorithmCreation.vue View File

@@ -6,15 +6,15 @@
<el-form-item label="算法名称" :label-width="formLabelWidth" prop="algorithmName">
<el-input v-model="ruleForm.algorithmName" :disabled="disabled" placeholder="请输入算法名称" />
</el-form-item>
<el-form-item label="算法类型" :label-width="formLabelWidth" prop="typeId">
<el-select v-model="ruleForm.typeId" placeholder="请选择">
<el-option v-for="item in optionType" :key="item.id" :label="item.typeDesc" :value="item.id">
<el-form-item label="模型类别" :label-width="formLabelWidth" prop="applyId">
<el-select v-model="ruleForm.applyId" placeholder="请选择">
<el-option v-for="item in optionType" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="算法框架" :label-width="formLabelWidth" prop="frameworkId">
<el-form-item label="框架类型" :label-width="formLabelWidth" prop="frameworkId">
<el-select v-model="ruleForm.frameworkId" placeholder="请选择">
<el-option v-for="item in optionFrame" :key="item.id" :label="item.frameworkDesc" :value="item.id">
<el-option v-for="item in optionFrame" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
@@ -61,7 +61,7 @@
path: '',
modelName: '',
desc: '',
typeId: '',
applyId: '',
frameworkId: ''
},
uploadData: { data: {}, type: undefined },
@@ -99,7 +99,7 @@
trigger: "blur"
}
],
typeId: [{ required: true, message: '请选择算法类型', trigger: 'change' }],
applyId: [{ required: true, message: '请选择算法类型', trigger: 'change' }],
frameworkId: [{ required: true, message: '请选择算法框架', trigger: 'change' }]
},
CreateFormVisible: true,
@@ -132,7 +132,7 @@
modelname: this.ruleForm.modelName,
isEmpty: false,
frameworkId: this.ruleForm.frameworkId,
typeId: this.ruleForm.typeId
applyId: this.ruleForm.applyId
}
addPreAlgorithm(param).then(response => {
if (response.success) {
@@ -167,7 +167,7 @@
algorithmType() {
algorithmType({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.optionType = response.data.algorithmTypes
this.optionType = response.data.lables
} else {
// this.showUpload = false
this.$message({
@@ -181,7 +181,7 @@
algorithmFrame() {
frameType({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.optionFrame = response.data.algorithmFrameworks
this.optionFrame = response.data.lables
} else {
// this.showUpload = false
this.$message({


+ 1
- 1
admin-portal/src/views/devManager/components/algorithm/templateList.vue View File

@@ -33,7 +33,7 @@
</el-table-column>
<el-table-column label="算法类型">
<template slot-scope="scope">
<span>{{ scope.row.typeName }}</span>
<span>{{ scope.row.applyName }}</span>
</template>
</el-table-column>
<el-table-column label="算法框架">


+ 1
- 1
admin-portal/src/views/devManager/components/algorithm/userList.vue View File

@@ -25,7 +25,7 @@
</el-table-column>
<el-table-column label="算法类型">
<template slot-scope="scope">
<span>{{ scope.row.typeName }}</span>
<span>{{ scope.row.applyName }}</span>
</template>
</el-table-column>
<el-table-column label="算法框架">


+ 135
- 0
admin-portal/src/views/platformManager/components/createDialog.vue View File

@@ -0,0 +1,135 @@
<template>
<div>
<el-dialog
title="创建平台"
width="35%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="平台名称" :label-width="formLabelWidth" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="联系人" :label-width="formLabelWidth" prop="contactName">
<el-input v-model="ruleForm.contactName"></el-input>
</el-form-item>
<el-form-item label="联系方式" :label-width="formLabelWidth" prop="contactInfo">
<el-input v-model="ruleForm.contactInfo"></el-input>
</el-form-item>
<el-form-item label="资源池" :label-width="formLabelWidth" prop="resourcePool">
<el-select v-model="ruleForm.resourcePool" placeholder="请选择">
<el-option
v-for="item in resourcePools"
:key="item.id"
:label="item.id"
:value="item.name"
>
</el-option>
</el-select>
</el-form-item>
</el-form>

<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="create('ruleForm')">确 定</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import { createPlatform } from "@/api/platformManager"
import { getResourcePool } from '@/api/resourceManager.js'
import { getErrorMsg } from '@/error/index'
export default {
name: "createDialog",
data() {
return {
formLabelWidth: '120px',
CreateFormVisible: true,
resourcePools: [],
ruleForm: {
name: "",
contactName: "",
contactInfo: undefined,
resourcePool: ""
},
rules: {
name: [
{
required: true,
message: "请输入名称",
trigger: "blur"
}
],
resourcePool: [
{
required: true,
message: "请选择资源",
trigger: "blur"
}
]
}
}
},
created() {
this.getResourcePool();
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
handleDialogClose() {
this.$emit('close', false)
},
cancel() {
this.$emit('cancel', false)
},
getResourcePool() {
getResourcePool().then(response => {
if (response.success) {
if (response.data !== null && response.data.resourcePools !== null) {
this.resourcePools = response.data.resourcePools
}
else {
this.resourcePools = []
}
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
create(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
createPlatform(this.ruleForm).then(response => {
if(response.success) {
this.$message.success("创建成功");
this.$emit('confirm', false)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
} else {
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>

+ 60
- 0
admin-portal/src/views/platformManager/components/detailsDialog.vue View File

@@ -0,0 +1,60 @@
<template>
<div>
<el-dialog
title="详情"
width="35%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-form
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="平台名称:" :label-width="formLabelWidth">
{{ this.platformDetail.name }}
</el-form-item>
<el-form-item label="联系人:" :label-width="formLabelWidth">
{{ this.platformDetail.contactName }}
</el-form-item>
<el-form-item label="联系方式:" :label-width="formLabelWidth">
{{ this.platformDetail.contactInfo }}
</el-form-item>
<el-form-item label="资源池:" :label-width="formLabelWidth">
{{ this.platformDetail.resourcePool }}
</el-form-item>
<el-form-item label="客户端ID:" :label-width="formLabelWidth">
{{ this.platformDetail.id }}
</el-form-item>
<el-form-item label="客户端Secret:" :label-width="formLabelWidth">
{{ this.platformDetail.clientSecret }}
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>

<script>
export default {
name: "detailsDialog",
props: {
platformDetail: {
type: Object,
default: () => {}
}
},
data() {
return {
formLabelWidth: '120px',
CreateFormVisible: true,
}
},
methods: {
handleDialogClose() {
this.$emit('close', false)
},
}
}
</script>
<style lang="scss" scoped>
</style>

+ 134
- 0
admin-portal/src/views/platformManager/components/editDialog.vue View File

@@ -0,0 +1,134 @@
<template>
<div>
<el-dialog
title="编辑"
width="35%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="联系人" :label-width="formLabelWidth" prop="contactName">
<el-input v-model="ruleForm.contactName"></el-input>
</el-form-item>
<el-form-item label="联系方式" :label-width="formLabelWidth" prop="contactInfo">
<el-input v-model="ruleForm.contactInfo"></el-input>
</el-form-item>
<el-form-item label="资源池" :label-width="formLabelWidth" prop="resourcePool">
<el-select v-model="ruleForm.resourcePool" placeholder="请选择">
<el-option
v-for="item in resourcePools"
:key="item.id"
:label="item.id"
:value="item.name"
>
</el-option>
</el-select>
</el-form-item>
</el-form>

<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="update('ruleForm')">确 定</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import { updatePlatform } from "@/api/platformManager"
import { getResourcePool } from '@/api/resourceManager.js'
import { getErrorMsg } from '@/error/index'
export default {
name: "editDialog",
props: {
platformDetail: {
type: Object,
default: () => {}
}
},
data() {
return {
formLabelWidth: '120px',
CreateFormVisible: true,
resourcePools: [],
ruleForm: {
contactName: "",
contactInfo: undefined,
resourcePool: ""
},
rules: {
resourcePool: [
{
required: true,
message: "请选择资源",
trigger: "blur"
}
]
}
}
},
created() {
let { contactName, contactInfo } = this.platformDetail
this.ruleForm = { contactName, contactInfo }
this.getResourcePool();
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
getResourcePool() {
getResourcePool().then(response => {
if (response.success) {
if (response.data !== null && response.data.resourcePools !== null) {
this.resourcePools = response.data.resourcePools
}
else {
this.resourcePools = []
}
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
update(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
const param = this.ruleForm
param.id = this.platformDetail.id
updatePlatform(param).then(response => {
if(response.success) {
this.$message.success("创建成功");
this.$emit('confirm', false)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
} else {
return false
}
})
},
handleDialogClose() {
this.$emit('close', false)
},
cancel() {
this.$emit('cancel', false)
}
}
}
</script>
<style lang="scss" scoped>
</style>

+ 165
- 0
admin-portal/src/views/platformManager/components/platformConfig.vue View File

@@ -0,0 +1,165 @@
<template>
<div>
<el-dialog
title="平台配置"
:visible.sync="createFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
>
<el-form-item>
<div v-for="(item, index) in ruleForm.platformConfig" :key="index">
<el-form-item>
<strong>{{item.key+": "}}</strong>
<el-popover
placement="top"
width="400"
trigger="hover"
:content="item.desc"
style="margin-right:2%"
>
<i v-if="item.desc?true:false" style="color:orange" class="el-icon-question" slot="reference"></i>
</el-popover>
<el-input v-if="item.type === 'input'" v-model="item.value" style="width: 40%;"></el-input>
<el-radio-group v-if="item.type === 'radio'" v-model="item.options">
<el-radio :label="'yes'"></el-radio>
<el-radio :label="'no'"></el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form-item>
</el-form>

<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="update('ruleForm')">确 定</el-button>
</div>

</el-dialog>
</div>
</template>
<script>
import { getPlatformConfigKey, getPlatformConfigValue, updatePlatformConfig } from "@/api/platformManager"
import { getErrorMsg } from '@/error/index'
export default {
name: "platformConfig",
props: {
platformDetail: {
type: Object,
default: () => {}
}
},
data() {
return {
createFormVisible: true,
platformConfigKeyList: [],
ruleForm: {
platformConfig: []
},
rules: {
platformConfig: {
required: true, message: '请选择配置信息', trigger: ['change', 'blur']
},
}
}
},
created() {
this.getPlatformConfigKey()
this.getPlatformConfigValue()
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
handleDialogClose() {
this.$emit('close', false)
},
getPlatformConfigKey() {
getPlatformConfigKey().then(response => {
if (response.success) {
this.platformConfigKeyList = response.data.configKeys
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
getPlatformConfigValue() {
const platformId = this.platformDetail.id
getPlatformConfigValue(platformId).then(response => {
if (response.success) {
let configValue = response.data.config
this.judgeObjectEmpty(configValue)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
judgeObjectEmpty(obj){
if(obj && Object.getOwnPropertyNames(obj).length) {
this.platformConfigKeyList.map(item => {
if (obj[item.key]) {
this.ruleForm.platformConfig.push({
key: item.key,
value: obj[item.key],
type: item.type,
options: item.options,
title: item.title
})
}
})
} else {
this.platformConfigKeyList.map(item => {
this.ruleForm.platformConfig.push({
key: item.key,
value: "",
type: item.type,
options: item.options,
title: item.title,
desc: item.desc
})
})
}
// this.ruleForm.platformConfig.push({
// key: "test1",
// value: "",
// type: "radio",
// options: "yes",
// title: "test title",
// desc: "this is desc"
// })
},
update(formName) {
const params = {}
this.ruleForm.platformConfig.map(item => {
params[item.key] = item.value?item.value:item.options
})
updatePlatformConfig(this.platformDetail.id,params).then(response => {
if(response.success) {
this.$message.success("平台配置更新成功");
this.$emit('confirm', false)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
cancel() {
this.$emit('cancel', false)
},
}
}
</script>
<style lang="scss" scoped>
</style>

+ 120
- 0
admin-portal/src/views/platformManager/components/storageConfigCreation.vue View File

@@ -0,0 +1,120 @@
<template>
<div>
<el-dialog
title="存储配置创建"
width="35%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
:append-to-body="true"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
>
<el-form-item label="平台" :label-width="formLabelWidth" prop="platform">
<el-input v-model="ruleForm.platform" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="名称" :label-width="formLabelWidth" prop="storageConfigName">
<el-input v-model="ruleForm.storageConfigName" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="存储类型" :label-width="formLabelWidth" prop="type">
<el-select v-model="ruleForm.type" placeholder="请选择类型">
<el-option label="juicefs" value="juicefs"></el-option>
</el-select>
</el-form-item>
<el-divider></el-divider>
<el-form-item label="name" :label-width="formLabelWidth">
<el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="Meta Url" :label-width="formLabelWidth">
<el-input v-model="ruleForm.metaUrl" placeholder="请输入名称"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="create('ruleForm')">创建</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getErrorMsg } from '@/error/index'
import { createStorageConfig } from "@/api/platformManager"
export default {
name: "storageConfig",
props: {
platformDetail: {
type: Object,
default: () => {}
},
},
data() {
return {
formLabelWidth: "120px",
CreateFormVisible: true,
ruleForm: {
platform: this.platformDetail.name,
storageConfigName: "",
type: "juicefs",
metaUrl: "",
name: "",
},
rules: {
storageConfigName: [
{ required: true, message: '请填写配置名称', trigger: 'blur' }
],
type: [
{ required: true, message: '请选择存储配置类型', trigger: 'change' }
],
}
}
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
handleDialogClose() {
this.$emit('close', false)
},
cancel() {
this.$emit('cancel', false)
},
create() {
this.$refs['ruleForm'].validate((valid) => {
if (valid) {
const params = {
name: this.ruleForm.storageConfigName,
type: this.ruleForm.type,
options: {
juicefs: {
metaUrl: this.ruleForm.metaUrl,
name: this.ruleForm.name
}
}
}
createStorageConfig(this.platformDetail.id,params).then(response => {
if (response.success) {
this.$message({
message: '创建存储配置成功',
type: 'success'
});
this.$emit('confirm', false)
}
else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>

</style>

+ 51
- 0
admin-portal/src/views/platformManager/components/storageConfigDetails.vue View File

@@ -0,0 +1,51 @@
<template>
<div>
<el-dialog
title="配置详情"
width="35%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
:append-to-body="true"
>
<el-form
label-width="100px"
class="demo-ruleForm"
>
<div v-for="(item, index) in propList" :key="index">
<el-form-item :label="item.key + ':'">
{{item.value}}
</el-form-item>
</div>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
name: "storageConfigDetails",
props: {
storageConfigDetail: {
type: Array,
default: []
},
},
data() {
return {
CreateFormVisible: true,
propList: []
}
},
created() {
this.propList = this.storageConfigDetail
},
methods: {
handleDialogClose() {
this.$emit('close', false)
}
}
}
</script>
<style lang="scss" scoped>

</style>

+ 218
- 0
admin-portal/src/views/platformManager/components/storageConfigList.vue View File

@@ -0,0 +1,218 @@
<template>
<div>
<el-dialog
title="存储配置列表"
width="70%"
:visible.sync="createFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-button type="primary" size="medium" @click="create" class="create">
创建
</el-button>
<el-table
:data="storageList"
style="width: 100%;font-size: 15px;"
:header-cell-style="{'text-align':'left','color':'black'}"
:cell-style="{'text-align':'left'}"
>
<el-table-column label="配置类型">
<span>{{ this.platformDetail.name }}</span>
</el-table-column>
<el-table-column label="配置名称">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="confirmDeletion(scope.row)">删除</el-button>
<el-button type="text" @click="showStorageConfigDetailVisible(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>

<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="searchData.pageIndex"
:page-sizes="[10, 20, 50, 80]"
:page-size="searchData.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>

<storageConfigCreation
v-if="storageConfigCreationVisible"
:platform-detail="platformDetail"
@cancel="cancel"
@confirm="confirm"
@close="close"
>
</storageConfigCreation>

<storageConfigDetails
v-if="storageConfigDetailsVisible"
:storage-config-detail="storageConfigDetail"
@close="close"
>
</storageConfigDetails>
</el-dialog>
</div>
</template>
<script>
import storageConfigCreation from "./storageConfigCreation.vue"
import storageConfigDetails from "./storageConfigDetails.vue"
import { getErrorMsg } from '@/error/index'
import { parseTime } from '@/utils/index'
import { getStorageConfigList, deleteStorageConfig } from "@/api/platformManager"
export default {
name: "storageConfigList",
components: {
storageConfigCreation,
storageConfigDetails
},
props: {
platformDetail: {
type: Object,
default: () => {}
},
},
data() {
return {
createFormVisible: true,
storageConfigCreationVisible: false,
storageConfigDetailsVisible: false,
storageConfigDetail: [],
storageList: [],
searchData: {
pageIndex: 1,
pageSize: 10,
},
total: 0
}
},
created() {
this.getStorageConfigList()
},
methods: {
close(val) {
this.storageConfigCreationVisible = val;
this.storageConfigDetailsVisible = val;
this.getStorageConfigList();
},
cancel(val) {
this.storageConfigCreationVisible = val;
this.getStorageConfigList();
},
confirm(val) {
this.storageConfigCreationVisible = val
this.getStorageConfigList();
},
handleSizeChange(val) {
this.searchData.pageSize = val
this.getStorageConfigList()
},
handleCurrentChange(val) {
this.searchData.pageIndex = val
this.getStorageConfigList()
},
getErrorMsg(code) {
return getErrorMsg(code)
},
handleDialogClose() {
this.$emit('close', false)
},
create() {
this.storageConfigCreationVisible = true;
},
showStorageConfigDetailVisible(row){
this.storageConfigDetailsVisible = true
let list = []
let obj = row.options
for (let item in obj) {
let option = obj[item]
for(let param in option) {
list.push({
key: param,
value: option[param]
})
}
this.storageConfigDetail = list
}
},
getStorageConfigList() {
const params = {
id: this.platformDetail.id,
pageIndex: this.searchData.pageIndex,
pageSize: this.searchData.pageSize
}
getStorageConfigList(params).then(response => {
if(response.success){
this.storageList = response.data.platformStorageConfigs;
this.total = response.data.totalSize
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
confirmDeletion(row) {
this.$confirm('是否删除存储配置?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
this.deleteStorageConfig(row)
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
});
},
deleteStorageConfig(row) {
const params = {
platformId: this.platformDetail.id,
name: row.name
}
deleteStorageConfig(params).then(response => {
if (response.success) {
this.$message.success("已删除");
this.$emit('cancel', false);
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
})
}
})
},
parseTime(val) {
return parseTime(val)
},
}
}
</script>
<style lang="scss" scoped>
.Wrapper {
margin: 20px !important;
}
.block {
float: right;
}
.create {
float: right;
}
</style>

+ 62
- 0
admin-portal/src/views/platformManager/index.vue View File

@@ -0,0 +1,62 @@
<template>
<div>
<el-tabs v-model="activeName" class="Wrapper" @tab-click="handleClick">
<el-tab-pane label="平台列表" name="platformList">
<platformList></platformList>
</el-tab-pane>
<el-tab-pane label="平台训练任务列表" name="trainingTask">
<platformTrainingTaskList></platformTrainingTaskList>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import platformList from "./platformList.vue"
import platformTrainingTaskList from "./platformTrainingTaskList.vue"
export default {
name: "index",
components: {
platformList,
platformTrainingTaskList
},
data() {
return {
activeName: 'platformList',
tabRefresh: {
platformMenu: true,
trainingTaskMenu: false,
},
}
},
methods: {
handleClick(tab, event) {
this.activeName = tab.name
switch (this.activeName) {
case 'platformList':
this.switchTab('platformMenu')
break
case 'trainingTask':
this.switchTab('trainingTaskMenu')
break
}
},
switchTab(tab) {
for (const key in this.tabRefresh) {
if (key === tab) {
this.tabRefresh[key] = true
} else {
this.tabRefresh[key] = false
}
}
}
}
}
</script>
<style lang="scss" scoped>
.Wrapper {
margin: 15px!important;
background-color:#fff;
padding: 20px;
min-height: 900px
}
</style>

+ 210
- 0
admin-portal/src/views/platformManager/platformList.vue View File

@@ -0,0 +1,210 @@
<template>
<div>
<div class="create">
<el-button type="primary" @click="create">创建</el-button>
</div>
<el-table
:data="platformList"
style="width: 100%;font-size: 15px;"
:header-cell-style="{'text-align':'left','color':'black'}"
:cell-style="{'text-align':'left'}"
>
<el-table-column label="名称" align="center">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="联系人" align="center">
<template slot-scope="scope">
<span>{{ scope.row.contactName }}</span>
</template>
</el-table-column>
<el-table-column label="联系方式" align="center">
<template slot-scope="scope">
<span>{{ scope.row.contactInfo }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="detail(scope.row)">详情</el-button>
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="getPlatformConfig(scope.row)">平台配置</el-button>
<el-button type="text" @click="showStorageConfigList(scope.row)">存储配置</el-button>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:current-page="searchData.pageIndex"
:page-sizes="[10, 20, 50, 80]"
:page-size="searchData.pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>

<createDialog
v-if="createVisible"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>

<detailsDialog
v-if="detailsVisible"
:platform-detail="platformDetail"
@close="close"
/>

<editDialog
v-if="editVisible"
:platform-detail="platformDetail"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>

<platformConfig
v-if="platformConfigVisible"
:platform-detail="platformDetail"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>
<storageConfigList
v-if="storageConfigListVisible"
:platform-detail="platformDetail"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>
</div>
</template>
<script>
import searchForm from '@/components/search/index.vue'
import createDialog from "./components/createDialog.vue"
import detailsDialog from "./components/detailsDialog.vue"
import editDialog from "./components/editDialog.vue"
import platformConfig from "./components/platformConfig.vue"
import storageConfigList from "./components/storageConfigList.vue"
import { getPlatformList } from "@/api/platformManager"
import { parseTime } from '@/utils/index'
import { getErrorMsg } from '@/error/index'
export default {
name: "platformList",
components: {
createDialog,
detailsDialog,
editDialog,
platformConfig,
storageConfigList
},
data() {
return {
createVisible: false,
detailsVisible: false,
editVisible: false,
platformConfigVisible: false,
platformList: [],
platformDetail: {},
storageConfigListVisible: false,
total: 0,
searchData: {
pageIndex: 1,
pageSize: 10,
}
}
},
created() {
this.getPlatformList(this.searchData);
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
getPlatformList(param){
getPlatformList(param).then(response => {
if(response.success){
this.platformList = response.data.platforms;
this.total = response.data.totalSize
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
handleSizeChange(val){
this.searchData.pageSize = val
this.getPlatformList(this.searchData)
},
handleCurrentChange(val) {
this.searchData.pageIndex = val
this.getPlatformList(this.searchData)
},
cancel(val) {
this.createVisible = val
this.editVisible = val
this.platformConfigVisible = val
this.storageConfigListVisible = val
this.getPlatformList(this.searchData);
},
confirm(val) {
this.createVisible = val
this.editVisible = val
this.platformConfigVisible = val
this.storageConfigListVisible = val
this.getPlatformList(this.searchData);
},
close(val) {
this.createVisible = val
this.detailsVisible = val
this.editVisible = val
this.platformConfigVisible = val
this.storageConfigListVisible = val
this.getPlatformList(this.searchData);
},
create() {
this.createVisible = true
},
detail(row) {
this.detailsVisible = true
this.platformDetail = row
},
edit(row) {
this.editVisible = true
this.platformDetail = row
},
getPlatformConfig(row) {
this.platformConfigVisible = true
this.platformDetail = row
},
showStorageConfigList(row) {
this.platformDetail = row
this.storageConfigListVisible = true
},
//时间戳转换日期
parseTime(val) {
return parseTime(val)
}
}
}
</script>
<style lang="scss" scoped>
.create {
float: right;
}
.block {
float: right;
margin: 20px;
}
</style>

+ 106
- 0
admin-portal/src/views/platformManager/platformTrainingTaskList.vue View File

@@ -0,0 +1,106 @@
<template>
<div>
<el-table
:data="taskList"
style="width: 100%;font-size: 15px;"
:header-cell-style="{'text-align':'left','color':'black'}"
:cell-style="{'text-align':'left'}"
>
<el-table-column label="名称" align="center">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="数据集" align="center">
<template slot-scope="scope">
<span>{{ scope.row.datasets }}</span>
</template>
</el-table-column>
<el-table-column label="联系方式" align="center">
<template slot-scope="scope">
<span>{{ scope.row.contactInfo }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdAt) }}</span>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:current-page="searchData.pageIndex"
:page-sizes="[10, 20, 50, 80]"
:page-size="searchData.pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>


</div>
</template>
<script>
import searchForm from '@/components/search/index.vue'
import { getPlatformTrainingTaskList } from "@/api/platformManager"
import { parseTime } from '@/utils/index'
import { getErrorMsg } from '@/error/index'
export default {
name: "platformTrainingTaskList",
components: {
searchForm
},
data() {
return {
taskList: [],
total: 0,
searchData: {
pageIndex: 1,
pageSize: 10,
}
}
},
created() {
this.getPlatformTrainingTaskList(this.searchData);
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
getPlatformTrainingTaskList(param){
getPlatformTrainingTaskList(param).then(response => {
console.log("res:",response.data.trainJobs)
if(response.success){
this.taskList = response.data.trainJobs;
this.total = response.data.totalSize
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
handleSizeChange(val){
this.searchData.pageSize = val
this.getPlatformTrainingTaskList(this.searchData)
},
handleCurrentChange(val) {
this.searchData.pageIndex = val
this.getPlatformTrainingTaskList(this.searchData)
},
//时间戳转换日期
parseTime(val) {
return parseTime(val)
}
}
}
</script>
<style lang="scss" scoped>
.block {
float: right;
margin: 20px;
}
</style>

+ 5
- 0
admin-portal/src/views/timeManager/component/consumption.vue View File

@@ -26,6 +26,11 @@
<span>{{ parseTime(scope.row.endedAt) }}</span>
</template>
</el-table-column>
<el-table-column label="类型" align="center" v-if="type=='user'">
<template slot-scope="scope">
<span>{{ scope.row.bizType==1?'训练':'notebook' }}</span>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination :current-page="pageIndex" :page-sizes="[10, 20, 50, 80]" :page-size="pageSize" :total="total"


+ 160
- 0
admin-portal/src/views/userManager/components/userConfig.vue View File

@@ -0,0 +1,160 @@
<template>
<div>
<el-dialog
title="用户配置"
:visible.sync="createFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
v-loading="loading"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
>
<el-form-item>
<div v-for="(item, index) in ruleForm.userConfig" :key="index">
<el-form-item>
<strong>{{item.key+": "}}</strong>
<el-popover
placement="top"
width="400"
trigger="hover"
:content="item.desc"
style="margin-right:2%"
>
<i v-if="item.desc?true:false" style="color:orange" class="el-icon-question" slot="reference"></i>
</el-popover>
<el-input v-if="item.type === 'input'" v-model="item.value" style="width: 40%;"></el-input>
<el-radio-group v-if="item.type === 'radio'" v-model="item.value">
<el-radio :label="'yes'"></el-radio>
<el-radio :label="'no'"></el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form-item>
</el-form>

<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="update('ruleForm')">确 定</el-button>
</div>

</el-dialog>
</div>
</template>
<script>
import { getUserConfigKey, getUserConfig, updateUserConfig } from '@/api/userManager.js'
import { getErrorMsg } from '@/error/index'
export default {
name: "userConfig",
props: {
row: {
tyep: Object,
default: () => {}
}
},
data() {
return {
createFormVisible: true,
userConfigKeyList: [],
ruleForm: {
userConfig: []
},
rules: {
userConfig: {
required: true, message: '请选择配置信息', trigger: ['change', 'blur']
},
},
loading: true
}
},
created() {
this.getUserConfigKey()
this.getUserConfig()
},
methods: {
handleDialogClose() {
this.$emit('close', false)
},
cancel() {
this.$emit('cancel', false)
},
getErrorMsg(code) {
return getErrorMsg(code)
},
getUserConfigKey() {
getUserConfigKey().then(response => {
if (response.success) {
this.userConfigKeyList = response.data.configKeys
}else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
getUserConfig() {
getUserConfig(this.row.id).then(response => {
if (response.success) {
let configValue = response.data.config
this.judgeObjectEmpty(configValue)
this.loading = false
}else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
this.loading = false
}
})
},
judgeObjectEmpty(obj){
if(obj && Object.getOwnPropertyNames(obj).length) {
this.userConfigKeyList.map(item => {
if (obj[item.key]) {
this.ruleForm.userConfig.push({
key: item.key,
value: obj[item.key],
type: item.type,
options: item.options,
title: item.title
})
}
})
} else {
this.userConfigKeyList.map(item => {
this.ruleForm.userConfig.push({
key: item.key,
value: "",
type: item.type,
options: item.options,
title: item.title,
desc: item.desc
})
})
}
},
update(formName) {
const params = {}
this.ruleForm.userConfig.map(item => {
params[item.key] = item.value
})
updateUserConfig(this.row.id,params).then(response => {
if(response.success) {
this.$message.success("平台配置更新成功");
this.$emit('confirm', false)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
}
}
</script>
<style lang="scss" scoped>
</style>

+ 30
- 5
admin-portal/src/views/userManager/user.vue View File

@@ -53,6 +53,7 @@
<el-button v-if="group" type="text" @click="handleEdite(scope.row)">编辑</el-button>
<!-- <el-button @click="handleDelete(scope.row)" type="text" v-if="group">删除</el-button> -->
<el-button type="text" @click="handleDetail(scope.row)">{{ user?'用户详情':'群组详情' }}</el-button>
<el-button v-if="user" type="text" @click="handleUserConfig(scope.row)">用户配置</el-button>
</template>
</el-table-column>
</el-table>
@@ -64,8 +65,23 @@
<!-- 新增对话框 -->
<addDialog v-if="CreateVisible" :flag="flag" @cancel="cancel" @confirm="confirm" @close="close" />
<!-- 创修改信息对话框 -->
<operateDialog v-if="operateVisible" :row="row" :user-type="change" @cancel="cancel" @confirm="confirm"
@close="close" />
<operateDialog
v-if="operateVisible"
:row="row"
:user-type="change"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>
<!-- 用户配置对话框 -->
<userConfig
v-if="userConfigVisible"
:row="row"
@cancel="cancel"
@confirm="confirm"
@close="close"
>
</userConfig>
<!-- 详情对话框 -->
<el-dialog :title="user?'用户名' + userName:'群组名' + groupName" :visible.sync="detailVisible" width="30%" center
class="title" :close-on-click-modal="false">
@@ -88,6 +104,7 @@
import { parseTime } from '@/utils/index'
import operateDialog from "./components/operateDialog.vue";
import addDialog from "./components/addDialog.vue";
import userConfig from "./components/userConfig.vue";
import searchForm from '@/components/search/index.vue'
import { getErrorMsg } from '@/error/index'
export default {
@@ -95,8 +112,8 @@
components: {
operateDialog,
addDialog,
searchForm
searchForm,
userConfig
},
props: {
userTabType: { type: Number, default: undefined }
@@ -108,6 +125,7 @@
CreateVisible: false,
operateVisible: false,
detailVisible: false,
userConfigVisible: false,
show: false,
user: false,
group: false,
@@ -214,6 +232,10 @@
this.row = row
this.operateVisible = true
},
handleUserConfig(row) {
this.row = row
this.userConfigVisible = true
},
handleDetail(row) {
if (this.user) {
this.id = row.id
@@ -253,16 +275,19 @@
cancel(val) {
this.CreateVisible = val
this.operateVisible = val
this.userConfigVisible = val
this.getList(this.searchData)
},
confirm(val) {
this.CreateVisible = val
this.operateVisible = val
this.userConfigVisible = val
this.getList(this.searchData)
},
close(val) {
this.CreateVisible = val
this.operateVisible = val
this.userConfigVisible = val
this.getList(this.searchData)
},
create() {
@@ -335,4 +360,4 @@
font-size: 16px;
font-weight: 600;
}
</style>
</style>

+ 2
- 2
admin-portal/vue.config.js View File

@@ -38,14 +38,14 @@ module.exports = {
},
proxy: {
[process.env.VUE_APP_BASE_API]: {
target: 'http://192.168.202.73',
target: 'http://192.168.202.73/',
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: '/adminserver'
}
},
[process.env.VUE_APP_BASE_API2]: {
target: 'http://192.168.202.73',
target: 'http://192.168.202.73/',
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''


+ 2
- 1
build/application/api-doc/dockerfile View File

@@ -6,4 +6,5 @@ RUN make api-doc_build

FROM swaggerapi/swagger-ui:v3.52.3
COPY --from=builder /app/server/admin-server/api/v1/swagger.json /usr/share/nginx/html/admin.swagger.json
COPY --from=builder /app/server/openai-server/api/v1/swagger.json /usr/share/nginx/html/openai.swagger.json
COPY --from=builder /app/server/openai-server/api/v1/swagger.json /usr/share/nginx/html/openai.swagger.json
COPY --from=builder /app/server/platform-server/api/v1/swagger.json /usr/share/nginx/html/platform.swagger.json

+ 13
- 0
build/application/platform-server/dockerfile View File

@@ -0,0 +1,13 @@
from swr.cn-south-1.myhuaweicloud.com/openioctopus/kratos:v2 as builder
WORKDIR /app
COPY ./ ./

RUN make platform-server_build binary_dir="/app/server/bin"

FROM alpine
WORKDIR /app
COPY --from=builder /app/server/bin/platform-server /app/platform-server
RUN chmod +x /app/platform-server
EXPOSE 8004

ENTRYPOINT ["/app/platform-server"]

+ 52
- 0
deploy/charts/octopus/templates/_helpers.tpl View File

@@ -250,6 +250,58 @@ octopus.pcl.ac.cn/resource: {{ .Values.common.resourceTagValuePrefix }}_{{ inclu
{{- end -}}


{{/******************platform-server******************/}}

{{- define "platformserver.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "platformserver.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- printf "%s-platformserver" .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{- define "platformserver.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "platformserver.core-labels" -}}
helm.sh/chart: {{ include "platformserver.chart" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{- define "platformserver.select-labels" -}}
app.kubernetes.io/name: {{ include "platformserver.name" . }}
app.kubernetes.io/instance: {{ include "platformserver.fullname" . }}
app.kubernetes.io/part-of: {{ include "platformserver.name" . }}
{{- end -}}

{{- define "platformserver.resource-labels" -}}
octopus.pcl.ac.cn/resource: {{ .Values.common.resourceTagValuePrefix }}_{{ include "platformserver.fullname" . }}_{{ default .Chart.AppVersion .Values.platformserver.image.tag }}
{{- end -}}


{{- define "platformserver.labels" -}}
{{ include "platformserver.core-labels" . }}
{{ include "platformserver.select-labels" . }}
{{ include "platformserver.resource-labels" . }}
{{- end -}}

{{- define "platformserver.port" -}}
{{- printf "8004" -}}
{{- end -}}


{{/******************base-server******************/}}



+ 1
- 1
deploy/charts/octopus/templates/api-doc.yaml View File

@@ -51,7 +51,7 @@ spec:
mountPath: /etc/localtime
env:
- name: URLS
value: "[{url:\"{{ .Values.ingress.apidocPath }}/admin.swagger.json\",name:\"admin\"},{url:\"{{ .Values.ingress.apidocPath }}/openai.swagger.json\",name:\"openai\"}]"
value: "[{url:\"{{ .Values.ingress.apidocPath }}/admin.swagger.json\",name:\"admin\"},{url:\"{{ .Values.ingress.apidocPath }}/openai.swagger.json\",name:\"openai\"},{url:\"{{ .Values.ingress.apidocPath }}/platform.swagger.json\",name:\"platform\"}]"
ports:
- name: http
containerPort: {{ template "apidoc.targetPort" . }}


+ 16
- 0
deploy/charts/octopus/templates/base-server.yaml View File

@@ -136,6 +136,11 @@ data:
username: {{ .Values.influxdb.setDefaultUser.user.username }}
password: {{ .Values.influxdb.setDefaultUser.user.password }}
database: octopus
jointCloud:
baseUrl: {{ .Values.baseserver.data.jointCloud.baseUrl }}
username: {{ .Values.baseserver.data.jointCloud.username }}
password: {{ .Values.baseserver.data.jointCloud.password }}
sessionExpirySec: {{ .Values.baseserver.data.jointCloud.sessionExpirySec }}
service:
nfsRootPath: /octopus-storage
baseServerAddr: {{ include "baseserver.httpServiceAddr" . }}
@@ -159,6 +164,17 @@ data:
discoveryLeaderLeaseLockName: resourcediscovery
discoveryDuration: 15s
ignoreSystemResources: hugepages-1Gi,pods,hugepages-2Mi,ephemeral-storage
platform:
configKeys:
- key: jobStatusCallbackAddr
title: 任务状态回调地址
type: input
user:
configKeys:
- key: jointCloudPermission
title: 云际权限
type: radio
options: yes,no
administrator:
username: {{ .Values.baseserver.administrator.username }}
password: "{{ .Values.baseserver.administrator.password }}"


+ 6
- 0
deploy/charts/octopus/templates/ingress.yaml View File

@@ -2,11 +2,13 @@
{{- $fullName := include "octopus.fullname" . -}}
{{- $adminserverName := include "adminserver.fullname" . -}}
{{- $openaiserverName := include "openaiserver.fullname" . -}}
{{- $platformserverName := include "platformserver.fullname" . -}}
{{- $adminportalName := include "adminportal.fullname" . -}}
{{- $openaiportalName := include "openaiportal.fullname" . -}}
{{- $apidocName := include "apidoc.fullname" . -}}
{{- $adminserverPath := .Values.ingress.adminserverPath -}}
{{- $openaiserverPath := .Values.ingress.openaiserverPath -}}
{{- $platformserverPath := .Values.ingress.platformserverPath -}}
{{- $adminportalPath := trimSuffix "/" .Values.ingress.adminportalPath -}}
{{- $openaiportalPath := trimSuffix "/" .Values.ingress.openaiportalPath -}}
{{- $minioName := include "minio.fullname" . -}}
@@ -37,6 +39,10 @@ spec:
serviceName: {{ $openaiserverName }}
servicePort: {{ template "openaiserver.port" . }}
path: {{ $openaiserverPath }}(/|$)(.*)
- backend:
serviceName: {{ $platformserverName }}
servicePort: {{ template "platformserver.port" . }}
path: {{ $platformserverPath }}(/|$)(.*)

---



+ 142
- 0
deploy/charts/octopus/templates/platform-server.yaml View File

@@ -0,0 +1,142 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "platformserver.fullname" . }}

---

apiVersion: v1
kind: Service
metadata:
name: {{ template "platformserver.fullname" . }}
labels:
{{ include "platformserver.labels" . | indent 4 }}
spec:
ports:
- name: http
protocol: TCP
port: {{ template "platformserver.port" . }}
targetPort: {{ template "platformserver.port" . }}
selector:
{{ include "platformserver.select-labels" . | indent 8 }}


---

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "platformserver.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ template "platformserver.fullname" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "platformserver.fullname" . }}
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- watch
- list
- create
- update
- patch
- delete

---

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "platformserver.fullname" . }}
labels:
{{ include "platformserver.labels" . | indent 4 }}
data:
platformserver-config.yml: |
app:
name: platformserver
version: v1.0
isDev: false
logLevel: {{ .Values.platformserver.app.logLevel }}
server:
http:
addr: 0.0.0.0:8004
timeout: 60s
jwtSecrect: asdf
data:
baseServerAddr: {{ include "baseserver.grpcServiceAddr" . }}
baseServerRequestTimeout: 30s
redis:
addr: {{ include "redis.serviceAddr" . }}
username: {{ .Values.platformserver.data.redis.username }}
password: {{ .Values.platformserver.data.redis.password }}
service:
port: {{ template "platformserver.port" . }}
targetPort: {{ template "platformserver.port" . }}
tokenExpirationSec: 86400

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "platformserver.fullname" . }}
spec:
selector:
matchLabels:
{{ include "platformserver.select-labels" . | indent 8 }}
replicas: {{ .Values.platformserver.replicas }}
template:
metadata:
labels:
{{ include "platformserver.labels" . | indent 8 }}
spec:
serviceAccountName: {{ template "platformserver.fullname" . }}
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: platformserver-config
configMap:
name: {{ template "platformserver.fullname" . }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.global.image.repository.address }}{{ .Values.global.image.repository.pathname }}/{{ .Values.platformserver.image.name }}:{{ default .Chart.AppVersion .Values.platformserver.image.tag }}"
imagePullPolicy: {{ .Values.global.image.pullPolicy }}
args: [ "-conf", "/etc/platformserver/platformserver-config.yml" ]
volumeMounts:
- name: localtime
mountPath: /etc/localtime
- name: platformserver-config
mountPath: /etc/platformserver
ports:
- name: {{ template "platformserver.name" . }}
containerPort: {{ template "platformserver.port" . }}
resources:
{{ toYaml .Values.resources | indent 10 }}
{{- with .Values.global.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

+ 38
- 7
deploy/charts/octopus/values.yaml View File

@@ -12,7 +12,7 @@ global:
address: "swr.cn-south-1.myhuaweicloud.com"
pathname: "/openioctopus"
pullPolicy: IfNotPresent
nodeSelector:
nodeSelector: &nodeSelector
octopus.openi.pcl.cn/node: "server"

common:
@@ -23,6 +23,7 @@ ingress:
enabled: true
adminserverPath: /adminserver
openaiserverPath: /openaiserver
platformserverPath: /platformserver
adminportalPath: /admin
openaiportalPath: /openai
loggerHttpdPath: /log
@@ -113,6 +114,11 @@ baseserver:
redis:
username: ""
password: "abcde"
jointCloud: #需要修改为实际的值
baseUrl: jointCloudBaseUrl
username: jointCloudUsername
password: jointCloudPassword
sessionExpirySec: 540 #实际有效期为600
service:
billingPeriodSec: 1800
develop:
@@ -137,7 +143,20 @@ openaiserver:
redis:
username: ""
password: "abcde"

# platform-server
platformserver:
image:
pullPolicy: ""
address: ""
pathname: ""
name: "platform-server"
app:
logLevel: info
data:
redis:
username: ""
password: "abcde"

# admin-server
adminserver:
@@ -192,12 +211,14 @@ logger:
filebeat:
resources: {}
logstash:
nodeSelector: {}
nodeSelector:
<<: *nodeSelector
httpd:
replicaCount: 1
image:
pullPolicy: Always
nodeSelector: {}
nodeSelector:
<<: *nodeSelector


# minio
@@ -222,6 +243,8 @@ minio:
type: NodePort
nodePort: "31311"
port: "9000"
nodeSelector:
<<: *nodeSelector
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
@@ -261,6 +284,8 @@ mysql:
- name: mysql-initdb
configMap:
name: mysql-initdb-config
nodeSelector:
<<: *nodeSelector
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
@@ -288,6 +313,8 @@ redis:
persistence:
size: "50Gi"
existingClaim: "octopus-redis-pvc"
nodeSelector:
<<: *nodeSelector
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
@@ -371,6 +398,8 @@ influxdb:
- name: influxdb-initdb
mountPath: /docker-entrypoint-initdb.d
readOnly: true
nodeSelector:
<<: *nodeSelector
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
@@ -386,7 +415,7 @@ influxdb:
- key: beta.kubernetes.io/arch
operator: In
values: ["amd64", "x64", "x86-64", "x86_64"]

# grafana
grafana:
@@ -414,7 +443,8 @@ grafana:
path: /grafana
resources: {}
affinity: {}
nodeSelector: {}
nodeSelector:
<<: *nodeSelector

#prometheus
prometheus:
@@ -432,7 +462,8 @@ prometheus:
targetPort: "9090"
resources: {}
affinity: {}
nodeSelector: {}
nodeSelector:
<<: *nodeSelector

# apidoc
apidoc:


+ 7
- 0
openai-portal/src/api/Home.js View File

@@ -34,4 +34,11 @@ export function changeSpace(data) {
data: { workspaceId: data.workspaceId }
})
}
// 查询用户配置
export function getUserConfig() {
return request({
url: `/v1/usermanage/config`,
method: 'get',
})
}


+ 69
- 0
openai-portal/src/api/cloudInterconnection.js View File

@@ -0,0 +1,69 @@
import request from '@/utils/request'

export function createCloudTrainJob(params) {
return request({
url: `/v1/jointcloudmanage/jointcloudtrainjob`,
method: 'post',
data: params
})
}

export function stopCloudTrainJob(id) {
return request({
url: `/v1/jointcloudmanage/trainjob/${id}/stop`,
method: 'post',
})
}

export function getCloudTrainJobList(params) {
let conditions = []
conditions.push(`pageIndex=` + params.pageIndex);
conditions.push(`pageSize=` + params.pageSize);
params.ids?conditions.push(`ids=` + params.ids):null;
return request({
url: `/v1/jointcloudmanage/job?` + conditions.join("&"),
method: 'get',
})
}

export function getCloudDatasetList(params) {
return request({
url: `/v1/jointcloudmanage/dataset?pageIndex=${params.pageIndex}&pageSize=${params.pageSize}`,
method: 'get',
})
}

export function getCloudDatasetVersionList(params) {
return request({
url: `/v1/jointcloudmanage/dataset/${params.dataSetCode}/version?pageIndex=${params.pageIndex}&pageSize=${params.pageSize}`,
method: 'get',
})
}

export function getCloudFrameworkList() {
return request({
url: `/v1/jointcloudmanage/framework`,
method: 'get',
})
}

export function getCloudFrameworkVersionList(key) {
return request({
url: `/v1/jointcloudmanage/framework/${key}/version`,
method: 'get',
})
}

export function getCloudInterpreterList() {
return request({
url: `/v1/jointcloudmanage/interpreter`,
method: 'get',
})
}

export function getCloudInterpreterVersionList(key) {
return request({
url: `/v1/jointcloudmanage/interpreter/${key}/version`,
method: 'get',
})
}

+ 11
- 4
openai-portal/src/api/datasetManager.js View File

@@ -1,9 +1,9 @@
import request from '@/utils/request'

export function judgeParam(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
let conditions = []
conditions.push(`pageSize=` + params.pageSize);
conditions.push(`pageIndex=` + params.pageIndex);
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
@@ -12,7 +12,6 @@ export function judgeParam(params) {
params.shared ? conditions.push(`shared=` + params.shared) : null;
params.path ? conditions.push(`path=` + params.path) : null;
params.status ? conditions.push(`status=` + params.status) : null;
params.nameLike ? conditions.push(`nameLike=` + params.nameLike) : null;
return conditions
}

@@ -167,3 +166,11 @@ export async function datasetType(params) {
})
return res
}
export async function datasetUse(params) {
const res = await request({
url: `/v1/datasetmanage/datasetapply`,
method: "get",
params: params
})
return res
}

+ 7
- 7
openai-portal/src/api/generalView.js View File

@@ -1,12 +1,12 @@
import request from '@/utils/request'

export function judgeParam(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
let conditions = []
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex);
params.orderBy?conditions.push(`orderBy=`+params.orderBy):null;
params.sortBy?conditions.push(`sortBy=`+params.sortBy):null;
params.searchKey?conditions.push(`searchKey=`+params.searchKey):null;
return conditions
}

@@ -60,4 +60,4 @@ export async function getGroupRechargeRecord(payload) {
method: "get"
})
return res
}
}

+ 1
- 1
openai-portal/src/api/globalVariable.js View File

@@ -9,4 +9,4 @@ if (process.env.NODE_ENV === 'development') {
export default {
DOMAIN
}
// 本地调试执行npm run dev指令需要修改DOMAIN地址,将http://192.168.202.73替换成服务器地址
// 本地调试执行npm run dev指令需要修改DOMAIN地址,将http://192.168.202.73替换成服务器地址

+ 2
- 3
openai-portal/src/api/imageManager.js View File

@@ -6,9 +6,8 @@ export function judgeParam(params) {
params.imageStatus ? conditions.push(`imageStatus=` + params.imageStatus) : null;
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
params.imageAddrLike ? conditions.push(`imageAddrLike=` + params.imageAddrLike) : null;
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex); params.imageAddrLike ? conditions.push(`imageAddrLike=` + params.imageAddrLike) : null;
params.imageNameLike ? conditions.push(`imageNameLike=` + params.imageNameLike) : null;
params.userId ? conditions.push(`userId=` + params.userId) : null;
params.spaceId ? conditions.push(`spaceId=` + params.spaceId) : null;


+ 1
- 1
openai-portal/src/api/modelDev.js View File

@@ -220,7 +220,7 @@ export async function myAlgorithmFinishUpload(payload) {
}
export async function algorithmType(params) {
const res = await request({
url: `/v1/algorithmmanage/algorithmtype`,
url: `/v1/algorithmmanage/algorithmapply`,
method: "get",
params: params
})


+ 5
- 5
openai-portal/src/api/trainingManager.js View File

@@ -3,8 +3,8 @@ import requestLog from '@/utils/requestLog'
// 训练任务接口
export function getList(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex);
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
@@ -68,8 +68,8 @@ export function getTempalteInfo(params) {
// 任务模板接口
export function getTemplate(params) {
const conditions = []
params.pageSize ? conditions.push(`pageSize=` + params.pageSize) : null;
params.pageIndex ? conditions.push(`pageIndex=` + params.pageIndex) : null;
conditions.push(`pageSize=`+params.pageSize);
conditions.push(`pageIndex=`+params.pageIndex);
params.orderBy ? conditions.push(`orderBy=` + params.orderBy) : null;
params.sortBy ? conditions.push(`sortBy=` + params.sortBy) : null;
params.searchKey ? conditions.push(`searchKey=` + params.searchKey) : null;
@@ -126,4 +126,4 @@ export function showLog(params) {
// url: `/log/download/user/trainjob/${params.jobId}/${params.subName}/index.log`,
// method: 'get'
// })
// }
// }

+ 5
- 1
openai-portal/src/error/index.js View File

@@ -162,7 +162,11 @@ const error = {
19002: '数据集已分享',
19003: '没有权限操作',
19004: ' 数据集重复',
19005: '状态不允许操作'
19005: '状态不允许操作',

/* 21001-22000 云际错误*/
21001: '云际请求失败',
21002: '无权限访问'
}
export function getErrorMsg(errorCode) {
let message = ''


+ 36
- 1
openai-portal/src/layout/components/Sidebar/index.vue View File

@@ -12,7 +12,15 @@
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
<div v-for="route in routes" :key="route.path">
<sidebar-item
v-if="route.path === '/cloudInterconnection' && isPermission === 'no' ? false : true"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</div>
<!-- <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" /> -->
</el-menu>
</el-scrollbar>
</div>
@@ -23,9 +31,36 @@ import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
import { getUserConfig } from '@/api/Home'
import { getErrorMsg } from '@/error/index'

export default {
components: { SidebarItem, Logo },
data(){
return {
isPermission: 'no'
}
},
created() {
this.getUserConfig()
},
methods: {
getErrorMsg(code) {
return getErrorMsg(code)
},
getUserConfig() {
getUserConfig().then(response => {
if (response.success) {
this.isPermission = response.data.config&&response.data.config.jointCloudPermission?response.data.config.jointCloudPermission:'no'
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
}
},
computed: {
...mapGetters([
'sidebar'


+ 12
- 0
openai-portal/src/router/index.js View File

@@ -123,6 +123,18 @@ export const constantRoutes = [
}
]
},
{
path: '/cloudInterconnection',
component: Layout,
children: [
{
path: 'index',
name: 'cloudInterconnection',
component: () => import('@/views/cloudInterconnection/index'),
meta: { title: '云际互联', icon: 'example' }
}
]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]


+ 198
- 0
openai-portal/src/views/cloudInterconnection/index.vue View File

@@ -0,0 +1,198 @@
<template>
<div>
<el-tabs class="Wrapper">
<el-tab-pane label="训练任务">
<div class="create">
<el-button type="primary" @click="create">创建训练任务</el-button>
</div>
<el-table
:data="trainJobList"
style="width: 100%;font-size: 15px;"
:header-cell-style="{'text-align':'left','color':'black'}"
:cell-style="{'text-align':'left'}"
>
<el-table-column label="任务名称">
<template slot-scope="scope">
<span>{{ scope.row.taskName }}</span>
</template>
</el-table-column>
<el-table-column label="学习框架">
<template slot-scope="scope">
<span>{{ scope.row.framework }}</span>
</template>
</el-table-column>
<el-table-column label="解释器">
<template slot-scope="scope">
<span>{{ scope.row.interpreter }}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<span :class="statusOption[scope.row.status][0]"></span>
<span>{{ statusOption[scope.row.status][1] }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
v-if="({'0':true,'1':true,'2':true,'7':true})[scope.row.status] || false"
type="text"
slot="reference"
@click="confirmStop(scope.row)"
>
停止
</el-button>
</template>
</el-table-column>
</el-table>

<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="searchData.pageIndex"
:page-sizes="[10, 20, 50, 80]"
:page-size="searchData.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>

<trainingTaskCreate
v-if="createVisible"
@cancel="cancel"
@confirm="confirm"
@close="close"
/>
</div>
</template>
<script>
import { parseTime } from '@/utils/index'
import { getErrorMsg } from '@/error/index'
import trainingTaskCreate from './trainingTaskCreate.vue'
import { getCloudTrainJobList, stopCloudTrainJob } from "@/api/cloudInterconnection"
export default {
name: "cloudInterconnection",
components: {
trainingTaskCreate
},
data() {
return {
createVisible: false,
searchData: {
pageIndex: 1,
pageSize: 10,
},
trainJobList: [],
total: 0,
statusOption: {
'0': ['status-ready', '初始中'],
'1': ['status-agent', '已分派'],
'2': ['status-running', '分中心处理中'],
'-1': ['status-danger', '失败'],
'3': ['status-success', '成功'],
'4': ['status-stopping', '停止'],
'7': ['status-reassign', '重分派'],
}
}
},
created(){
this.getCloudTrainJobList(this.searchData)
},
methods: {
getCloudTrainJobList(params){
getCloudTrainJobList(params).then(response => {
if (response.success) {
this.trainJobList = response.data.list;
this.total = response.data.totalSize
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
})
}
})
},
confirmStop(row) {
this.$confirm('是否停止Notebook?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
this.stopCloudTrainJob(row)
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
});
},
stopCloudTrainJob(row) {
stopCloudTrainJob(row.taskId).then(response => {
if (response.success) {
this.$message.success("已停止");
this.getCloudTrainJobList(this.searchData);
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
})
}
})
},
handleSizeChange(val) {
this.searchData.pageSize = val
this.getCloudTrainJobList(this.searchData)
},
handleCurrentChange(val) {
this.searchData.pageIndex = val
this.getCloudTrainJobList(this.searchData)
},
create() {
this.createVisible = true
},
close(val) {
this.createVisible = val;
this.getCloudTrainJobList(this.searchData)
},
cancel(val) {
this.createVisible = val;
this.getCloudTrainJobList(this.searchData)
},
confirm(val) {
this.createVisible = val
this.getCloudTrainJobList(this.searchData)
},
parseTime(val) {
return parseTime(val)
},
getErrorMsg(code) {
return getErrorMsg(code)
},
}
}
</script>
<style lang="scss" scoped>
.Wrapper {
margin: 15px!important;
background-color:#fff;
padding: 20px;
min-height: 900px
}
.create {
float: right;
}
.block {
float: right;
margin: 20px;
}
</style>

+ 568
- 0
openai-portal/src/views/cloudInterconnection/trainingTaskCreate.vue View File

@@ -0,0 +1,568 @@
<template>
<div>
<el-dialog
title="创建训练任务"
width="55%"
:visible.sync="CreateFormVisible"
:before-close="handleDialogClose"
:close-on-click-modal="false"
>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
:label-width="formLabelWidth"
class="demo-ruleForm"
>
<el-form-item label="任务名称" :label-width="formLabelWidth" prop="taskName">
<el-input v-model="ruleForm.taskName" placeholder="请输入任务名称"></el-input>
</el-form-item>
<el-form-item label="描述" :label-width="formLabelWidth" prop="remark">
<el-input
:autosize="{ minRows: 2, maxRows: 4}"
placeholder="请输入notebook描述"
maxlength="300"
show-word-limit
v-model="ruleForm.remark"
/>
</el-form-item>
<!-- 框架 -->
<div>
<el-form-item label="学习框架" prop="framework" :class="{inline:frameworkVersionVisible}">
<el-select
v-model="ruleForm.framework"
placeholder="请选择学习框架"
@change="changeFramework"
>
<el-option
v-for="item in frameworkOption"
:key="item.key"
:label="item.value"
:value='item.key'
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="框架版本"
prop="frameworkVersion"
v-if="frameworkVersionVisible"
style="display: inline-block;"
>
<el-select
v-model="ruleForm.frameworkVersion"
placeholder="请选择框架版本"
>
<el-option
v-for="item in frameworkVersionOption"
:key="item.key"
:label="item.value"
:value='item.key'
>
</el-option>
</el-select>
</el-form-item>
</div>
<!-- 解释器 -->
<div>
<el-form-item label="解释器" prop="interpreter" :class="{inline:interpreterVersionVisible}">
<el-select
v-model="ruleForm.interpreter"
placeholder="请选择解释器"
@change="changeInterpreter"
>
<el-option
v-for="item in interpreterOption"
:key="item.key"
:label="item.value"
:value='item.key'
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="解释器版本"
prop="interpreterVersion"
v-if="interpreterVersionVisible"
style="display: inline-block;"
>
<el-select
v-model="ruleForm.interpreterVersion"
placeholder="请选择解释器版本"
>
<el-option
v-for="item in interpreterVersionOption"
:key="item.key"
:label="item.value"
:value='item.key'
>
</el-option>
</el-select>
</el-form-item>
</div>
<!-- 数据集 -->
<div>
<el-form-item label="数据集" prop="dataSet" :class="{inline:dataSetVersionVisible}">
<el-select
value-key="dataSetCode"
v-model="ruleForm.dataSet"
placeholder="请选择数据集"
v-loadmore='loadDataSetName'
@change="changeDataSetName"
>
<el-option
v-for="item in dataSetNameOption"
:key="item.dataSetCode"
:label="item.name"
:value='item'
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="数据集版本"
prop="dataSetVersion"
v-if="dataSetVersionVisible"
style="display: inline-block;"
>
<el-select
v-model="ruleForm.dataSetVersion"
placeholder="请选择数据集版本"
v-loadmore="loadDataSetVersion"
@change="changeMountPath"
>
<el-option
v-for="item in dataSetVersionOption"
:key="item.version"
:label="item.version"
:value='item.version'
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
v-if="mountPathVisible"
label="挂载目录"
prop="mountPath"
style="display: inline-block;"
>
<el-input v-model="ruleForm.mountPath" placeholder="请输入挂载目录"></el-input>
</el-form-item>
</div>
<div>
<el-form-item label="运行命令" prop="execCommand">
<el-input type="textarea" v-model="ruleForm.execCommand"></el-input>
</el-form-item>
</div>
<div>
<el-form-item
label="模型输出位置"
prop="outputPath"
style="display: inline-block;"
>
<el-input v-model="ruleForm.outputPath" placeholder="请输入模型输出目录"></el-input>
</el-form-item>
</div>

<!-- <div>
<el-row >
<el-col :span="6">
<el-form-item label="内存" prop="memorySize">
<el-input v-model="ruleForm.memorySize" placeholder="请填写内存大小">
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="内存" prop="memoryUnits">
<el-select v-model="ruleForm.memoryUnits">
<el-option label="Gi" value="Gi"></el-option>
<el-option label="Mi" value="Mi"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6"></el-col>
<el-col :span="6"></el-col>
</el-row>
</div> -->


<div>
<el-form-item label="内存大小" prop="memorySize" style="display: inline-block;">
<el-input v-model.number="ruleForm.memorySize" placeholder="请填写内存大小">
</el-input>
</el-form-item>
<el-form-item label="内存单位" prop="memoryUnits" style="display: inline-block;">
<el-select v-model="ruleForm.memoryUnits">
<el-option label="Gi" value="Gi"></el-option>
<el-option label="Mi" value="Mi"></el-option>
</el-select>
</el-form-item>
</div>
<div>
<el-form-item label="GPU个数" prop="gpuSize" style="display: inline-block;">
<el-input v-model.number="ruleForm.gpuSize" placeholder="请填写GPU个数">
</el-input>
</el-form-item>
<el-form-item label="GPU类型" prop="gpuUnits" style="display: inline-block;">
<el-select v-model="ruleForm.gpuUnits">
<el-option label="nvidia.com/gpu" value="nvidia.com/gpu"></el-option>
<el-option label="npu.huawei.com/NPU" value="npu.huawei.com/NPU"></el-option>
<el-option label="cambricon.com/mlu" value="cambricon.com/mlu"></el-option>
<el-option label="不限" value="default"></el-option>
</el-select>
</el-form-item>
</div>
<div>
<el-form-item label="CPU个数" prop="cpuSize" style="display: inline-block;">
<el-input v-model.number="ruleForm.cpuSize" placeholder="请填写CPU个数">
</el-input>
</el-form-item>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="submit('ruleForm')">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getErrorMsg } from '@/error/index'
import {
createCloudTrainJob,
getCloudDatasetList,
getCloudDatasetVersionList,
getCloudFrameworkList,
getCloudFrameworkVersionList,
getCloudInterpreterList,
getCloudInterpreterVersionList
} from "@/api/cloudInterconnection"
export default {
name: "trainingTaskCreate",
data() {
return {
CreateFormVisible: true,
formLabelWidth: "130px",
ruleForm: {
taskName: '',
remark: '',
framework: '',
frameworkVersion: '',
interpreter: '',
interpreterVersion: '',
dataSet: "",
dataSetVersion: '',
mountPath: '/dataset ',
execCommand: '',
outputPath: "/model",
memorySize: 1,
memoryUnits: "Gi",
cpuSize: 1,
gpuSize: 1,
gpuUnits: "nvidia.com/gpu",
parameters: [{
key: "",
value: ""
}],
},
rules: {
taskName: [
{ required: true, message: '请输入任务名称', trigger: 'blur' },
],
framework: [
{ required: true, message: '请选择引擎框架', trigger: 'blur' },
],
frameworkVersion: [
{ required: true, message: '请选择引擎版本', trigger: 'blur' },
],
interpreter: [
{ required: true, message: '请选择引擎解释器', trigger: 'blur' },
],
interpreterVersion: [
{ required: true, message: '请选择引擎解释器版本', trigger: 'blur' },
],
dataSet: [
{ required: true, message: '请选择数据集', trigger: 'blur' },
],
dataSetVersion: [
{ required: true, message: '请选择数据集版本', trigger: 'blur' },
],
mountPath: [
{ required: true, message: '请选择挂载目录', trigger: 'blur' },
],
execCommand: [
{ required: true, message: '请输入运行命令', trigger: 'blur' },
],
outputPath: [
{ required: true, message: '请填写模型输出路径', trigger: 'blur' },
],
memorySize:[
{ required: true, message: '请填写内存大小', trigger: 'blur' }
],
memoryUnits: [
{ required: true, message: '请选择内存类型', trigger: 'blur' },
],
cpuSize: [
{ required: true, message: '请填写CPU个数', trigger: 'blur' },
],
gpuUnits: [
{ required: true, message: '请选择GPU类型', trigger: 'blur' },
],
gpuSize: [
{ required: true, message: '请填写GPU个数', trigger: 'blur' },
],
},
// 引擎框架
frameworkOption: [],
frameworkVersionVisible: false,
frameworkVersionOption: [],
// 解释器
interpreterOption: [],
interpreterVersionVisible: false,
interpreterVersionOption: [],
// 数据集
dataSetNameOption: [],
dataSetNameCount: 1,
dataSetNameTotal: undefined,
dataSetVersionVisible: false,
dataSetVersionCount: 1,
dataSetVersionOption: [],
dataSetVersionTotal: undefined,
mountPathVisible: false
}
},
created(){
this.getCloudFrameworkList()
this.getCloudDatasetList()
this.getCloudInterpreterList()
},
directives: {
loadmore: {
inserted: function (el, binding) {
const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap');
SELECTWRAP_DOM.addEventListener('scroll', function () {
const CONDITION = this.scrollHeight - this.scrollTop <= this.clientHeight;
if (CONDITION) {
binding.value();
}
})
}
}
},
methods: {
// 训练框架
getCloudFrameworkList(){
getCloudFrameworkList().then(response => {
if(response.data !== null && response.data.frameworks !== null) {
this.frameworkOption = response.data.frameworks
} else {
this.$message({
message: '获取训练学习框架失败',
type: 'warning'
})
}
})
},
changeFramework() {
this.frameworkVersionVisible = true
this.frameworkVersionOption = [],
this.ruleForm.frameworkVersion = '',
this.getCloudFrameworkVersionList()
},
getCloudFrameworkVersionList() {
const key = this.ruleForm.framework
getCloudFrameworkVersionList(key).then(response => {
if (response.data !== null && response.data.versions !== null) {
this.frameworkVersionOption = response.data.versions
} else {
this.$message({
message: '获取训练学习框架版本失败',
type: 'warning'
})
}
})
},
// 解释器
getCloudInterpreterList(){
getCloudInterpreterList().then(response => {
if(response.data !== null && response.data.interpreters !== null) {
this.interpreterOption = response.data.interpreters
} else {
this.$message({
message: '获取训练训练解释器失败',
type: 'warning'
})
}
})
},
changeInterpreter() {
this.interpreterVersionVisible = true
this.frameworkVersionOption = [],
this.ruleForm.interpreterVersion = '',
this.getCloudInterpreterVersionList()
},
getCloudInterpreterVersionList() {
const key = this.ruleForm.interpreter
getCloudInterpreterVersionList(key).then(response => {
if (response.data !== null && response.data.versions !== null) {
this.interpreterVersionOption = response.data.versions
} else {
this.$message({
message: '获取训练学习框架版本失败',
type: 'warning'
})
}
})
},
// 数据集
getCloudDatasetList(){
const param = {
pageIndex: this.dataSetNameCount,
pageSize: 10
}
getCloudDatasetList(param).then(response => {
if(response.data !== null && response.data.dataSets !== null) {
this.dataSetNameOption = this.dataSetNameOption.concat(response.data.dataSets)
this.dataSetNameTotal = response.data.totalSize
} else {
this.$message({
message: '获取数据集失败',
type: 'warning'
})
}
})
},
loadDataSetName(){
this.dataSetNameCount = this.dataSetNameCount + 1
if (this.dataSetNameOption.length < this.dataSetNameTotal) {
this.getCloudDatasetList()
}
},
changeDataSetName() {
this.dataSetVersionVisible = true
this.dataSetVersionCount = 1
this.dataSetVersionOption = [],
this.ruleForm.dataSetVersion = '',
this.getDataSetVersionList()
},
getDataSetVersionList() {
let data = {}
data.dataSetCode = this.ruleForm.dataSet.dataSetCode
data.pageIndex = this.dataSetVersionCount
data.pageSize = 10
getCloudDatasetVersionList(data).then(response => {
if (response.data !== null && response.data.versions !== null) {
this.dataSetVersionOption = this.dataSetVersionOption.concat(response.data.versions)
this.dataSetVersionTotal = response.data.totalSize
} else {
this.$message({
message: '获取数据集版本失败',
type: 'warning'
})
}
})
},
loadDataSetVersion() {
this.dataSetVersionCount = this.dataSetVersionCount + 1
if (this.dataSetVersionOption.length < this.dataSetVersionTotal) {
this.getDataSetVersionList()
}
},
changeMountPath(){
this.mountPathVisible = true
},
getErrorMsg(code) {
return getErrorMsg(code)
},
handleDialogClose() {
this.$emit("close", false);
},
submit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let resourceList = []
if(this.ruleForm.memorySize != 0){
let memoryParam = {}
memoryParam.name = "memory"
memoryParam.type = "memory"
memoryParam.unit = this.ruleForm.memoryUnits
memoryParam.size = this.ruleForm.memorySize
resourceList.push(memoryParam)
}
if(this.ruleForm.gpuSize != 0){
let gpuParam = {}
gpuParam.name = this.ruleForm.gpuUnits
gpuParam.type = "gpu"
gpuParam.unit = "个"
gpuParam.size = this.ruleForm.gpuSize
resourceList.push(gpuParam)
}
if(this.ruleForm.cpuSize != 0){
let cpuParam = {}
cpuParam.name = "cpu"
cpuParam.type = "cpu"
cpuParam.unit = "个"
cpuParam.size = this.ruleForm.cpuSize
resourceList.push(cpuParam)
}
const params = {
taskName: this.ruleForm.taskName,
remark: this.ruleForm.remark,
framework: this.ruleForm.framework + this.ruleForm.frameworkVersion,
interpreter: this.ruleForm.interpreter + this.ruleForm.interpreterVersion,
dataSetVersionVoList: [{
dataSetCode:this.ruleForm.dataSet.dataSetCode,
dataSetName:this.ruleForm.dataSet.name,
path:this.ruleForm.mountPath,
version:this.ruleForm.dataSetVersion,
}],
execCommand: this.ruleForm.execCommand,
outputPath: this.ruleForm.outputPath,
resourceParams: resourceList
}
createCloudTrainJob(params).then(response => {
if(response.success) {
this.$message.success("创建成功");
this.$emit('confirm', false)
} else {
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
} else {
return false;
}
})
},
cancel() {
this.$confirm('此操作将被取消,是否继续?','提示',{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$emit('cancel', false)
}).catch(() => {
this.$message({
type: 'info',
message: '已中断取消操作'
});
})
},
}
}
</script>
<style lang="scss" scoped>
.line {
text-align: center;
}

.inline {
display: inline-block !important;
}

.block {
display: block !important;
}
</style>

+ 41
- 10
openai-portal/src/views/dataManager/components/myDatasetCreation.vue View File

@@ -7,8 +7,14 @@
<el-input v-model="ruleForm.name" :disabled="disabled" placeholder="请输入数据集名称,长度在 4 到 30 个字符" />
</el-form-item>
<el-form-item label="数据类型" :label-width="formLabelWidth" prop="type">
<el-select v-model="ruleForm.type" :disabled="disabled" placeholder="请选择数据集类型">
<el-option v-for="item in options" :key="item.id" :label="item.typeDesc" :value="item.id">
<el-select v-model="ruleForm.typeId" :disabled="disabled" placeholder="请选择数据集类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="数据集用途" :label-width="formLabelWidth" prop="type">
<el-select v-model="ruleForm.applyId" :disabled="disabled" placeholder="请选择数据集用途">
<el-option v-for="item in useOptions" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
@@ -30,7 +36,7 @@

<script>
import upload from '@/components/upload/index.vue'
import { createMyDataset, datasetType } from "@/api/datasetManager.js"
import { createMyDataset, datasetType, datasetUse } from "@/api/datasetManager.js"
import { getErrorMsg } from '@/error/index'
export default {
name: "MyDatasetCreation",
@@ -45,6 +51,7 @@
},
created() {
this.datasetType()
this.datasetUse()
},
data() {
return {
@@ -54,21 +61,29 @@
ruleForm: {
name: '',
desc: '',
type: '',
path: ''
typeId: '',
path: '',
applyId: ''
},
rules: {
name: [
{ required: true, message: "请输入数据集名称", trigger: "blur" },
{ min: 4, max: 30, message: "长度在 4 到 30 个字符", trigger: "blur" }
],
type: [
typeId: [
{
required: true,
message: "请选择数据集类型",
trigger: "change"
}
],
applyId: [
{
required: true,
message: "请选择数据集用途",
trigger: "change"
}
],
path: [
{
required: true,
@@ -80,7 +95,8 @@
CreateFormVisible: true,
formLabelWidth: "120px",
close: true,
options: []
typeOptions: [],
useOptions: []
};
},
methods: {
@@ -93,8 +109,9 @@
delete this.ruleForm.path
const param = {
name: this.ruleForm.name,
typeId: this.ruleForm.type,
desc: this.ruleForm.desc
typeId: this.ruleForm.typeId,
desc: this.ruleForm.desc,
applyId:this.ruleForm.applyId
}
createMyDataset(param).then(response => {
if (response.success) {
@@ -132,7 +149,21 @@
datasetType() {
datasetType({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.options = response.data.datasetTypes
this.typeOptions = response.data.lables
} else {
// this.showUpload = false
this.$message({
message: this.getErrorMsg(response.error.subcode),
type: 'warning'
});
}
})
},
// 获取数据集用途
datasetUse() {
datasetUse({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.useOptions = response.data.lables
} else {
// this.showUpload = false
this.$message({


+ 5
- 0
openai-portal/src/views/dataManager/myList.vue View File

@@ -28,6 +28,11 @@
<span>{{ scope.row.typeDesc }}</span>
</template>
</el-table-column>
<el-table-column label="数据集用途">
<template slot-scope="scope">
<span>{{ scope.row.applyDesc }}</span>
</template>
</el-table-column>
<el-table-column label="最新版本号">
<template slot-scope="scope">
<span>{{ scope.row.latestVersion }}</span>


+ 5
- 0
openai-portal/src/views/dataManager/presetList.vue View File

@@ -25,6 +25,11 @@
<span>{{ scope.row.typeDesc }}</span>
</template>
</el-table-column>
<el-table-column label="数据集用途">
<template slot-scope="scope">
<span>{{ scope.row.applyDesc }}</span>
</template>
</el-table-column>
<el-table-column label="最新版本号">
<template slot-scope="scope">
<span>{{ scope.row.latestVersion }}</span>


+ 5
- 0
openai-portal/src/views/dataManager/publicList.vue View File

@@ -25,6 +25,11 @@
<span>{{ scope.row.typeDesc }}</span>
</template>
</el-table-column>
<el-table-column label="数据集用途">
<template slot-scope="scope">
<span>{{ scope.row.applyDesc }}</span>
</template>
</el-table-column>
<el-table-column label="最新版本号">
<template slot-scope="scope">
<span>{{ scope.row.latestVersion }}</span>


+ 10
- 10
openai-portal/src/views/modelDev/components/algorithm/myAlgorithmCreation.vue View File

@@ -6,15 +6,15 @@
<el-form-item label="算法名称" :label-width="formLabelWidth" prop="algorithmName">
<el-input v-model="ruleForm.algorithmName" :disabled="disabled" placeholder="请输入算法名称" />
</el-form-item>
<el-form-item label="算法类型" :label-width="formLabelWidth" prop="typeId">
<el-select v-model="ruleForm.typeId" placeholder="请选择">
<el-option v-for="item in optionType" :key="item.id" :label="item.typeDesc" :value="item.id">
<el-form-item label="算法类型" :label-width="formLabelWidth" prop="applyId">
<el-select v-model="ruleForm.applyId" placeholder="请选择">
<el-option v-for="item in optionType" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="算法框架" :label-width="formLabelWidth" prop="frameworkId">
<el-select v-model="ruleForm.frameworkId" placeholder="请选择">
<el-option v-for="item in optionFrame" :key="item.id" :label="item.frameworkDesc" :value="item.id">
<el-option v-for="item in optionFrame" :key="item.id" :label="item.lableDesc" :value="item.id">
</el-option>
</el-select>
</el-form-item>
@@ -73,7 +73,7 @@
modelName: '',
desc: "",
path: "",
typeId: '',
applyId: '',
frameworkId:''
},
uploadData: { data: {}, type: undefined },
@@ -104,7 +104,7 @@
trigger: "blur"
}
],
typeId: [{ required: true, message: '请选择算法类型', trigger: 'change' }],
applyId: [{ required: true, message: '请选择算法类型', trigger: 'change' }],
frameworkId: [{ required: true, message: '请选择算法框架', trigger: 'change' }]
},
CreateFormVisible: true,
@@ -141,7 +141,7 @@
algorithmDescript: this.ruleForm.desc,
modelName: this.ruleForm.modelName,
isEmpty: this.isEmpty,
typeId:this.ruleForm.typeId,
applyId:this.ruleForm.applyId,
frameworkId:this.ruleForm.frameworkId
}
addMyAlgorithm(param).then(response => {
@@ -181,7 +181,7 @@
AlgorithmDescript: this.ruleForm.desc,
modelname: this.ruleForm.modelName,
isEmpty: this.isEmpty,
typeId:this.ruleForm.typeId,
applyId:this.ruleForm.applyId,
frameworkId:this.ruleForm.frameworkId
}
addMyAlgorithm(param).then(response => {
@@ -208,7 +208,7 @@
algorithmType() {
algorithmType({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.optionType = response.data.algorithmTypes
this.optionType = response.data.lables
} else {
// this.showUpload = false
this.$message({
@@ -222,7 +222,7 @@
algorithmFrame() {
algorithmFrame({ pageIndex: 1, pageSize: 20 }).then(response => {
if (response.success) {
this.optionFrame = response.data.algorithmFrameworks
this.optionFrame = response.data.lables
} else {
// this.showUpload = false
this.$message({


+ 3
- 3
openai-portal/src/views/modelDev/components/algorithm/myList.vue View File

@@ -32,12 +32,12 @@
<span>{{ scope.row.algorithmVersion }}</span>
</template>
</el-table-column>
<el-table-column label="算法类型">
<el-table-column label="模型类别">
<template slot-scope="scope">
<span>{{ scope.row.typeName }}</span>
<span>{{ scope.row.applyName }}</span>
</template>
</el-table-column>
<el-table-column label="算法框架">
<el-table-column label="框架类型">
<template slot-scope="scope">
<span>{{ scope.row.frameworkName }}</span>
</template>


+ 3
- 3
openai-portal/src/views/modelDev/components/algorithm/presetList.vue View File

@@ -23,12 +23,12 @@
<span>{{ scope.row.algorithmVersion }}</span>
</template>
</el-table-column>
<el-table-column label="算法类型">
<el-table-column label="模型类别">
<template slot-scope="scope">
<span>{{ scope.row.typeName }}</span>
<span>{{ scope.row.applyName }}</span>
</template>
</el-table-column>
<el-table-column label="算法框架">
<el-table-column label="框架类型">
<template slot-scope="scope">
<span>{{ scope.row.frameworkName }}</span>
</template>


+ 3
- 3
openai-portal/src/views/modelDev/components/algorithm/publicList.vue View File

@@ -23,12 +23,12 @@
<span>{{ scope.row.algorithmVersion }}</span>
</template>
</el-table-column>
<el-table-column label="算法类型">
<el-table-column label="模型类别">
<template slot-scope="scope">
<span>{{ scope.row.typeName }}</span>
<span>{{ scope.row.applyName }}</span>
</template>
</el-table-column>
<el-table-column label="算法框架">
<el-table-column label="框架类型">
<template slot-scope="scope">
<span>{{ scope.row.frameworkName }}</span>
</template>


+ 0
- 8
openai-portal/src/views/modelDev/components/notebook/notebookList.vue View File

@@ -135,14 +135,6 @@
{ type: 'Time', label: '创建时间', prop: 'time', placeholder: '请选择创建时间' },
{
type: 'Select', label: '状态', prop: 'status', placeholder: '请选择状态',
options: [
{ label: '运行中', value: 'running' },
{ label: '等待中', value: 'pending' },
{ label: '已停止', value: 'stopped' },
{ label: '成功', value: 'succeeded' },
{ label: '失败', value: 'failed' },
{ label: '初始中', value: 'preparing' }
]
}
],
searchData: {


+ 2
- 2
openai-portal/vue.config.js View File

@@ -38,14 +38,14 @@ module.exports = {
},
proxy: {
[process.env.VUE_APP_BASE_API]: {
target: 'http://192.168.202.73',
target: 'http://192.168.202.73/',
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: '/openaiserver'
}
},
[process.env.VUE_APP_BASE_API2]: {
target: 'http://192.168.202.73',
target: 'http://192.168.202.73/',
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''


+ 34
- 57
server/admin-server/api/v1/algorithm.proto View File

@@ -10,32 +10,31 @@ import "google/api/annotations.proto";
import "validate/validate.proto";

service Algorithm {
// 新增算法类型
rpc AddAlgorithmType (AddAlgorithmTypeRequest) returns (AddAlgorithmTypeReply) {
// 新增算法用途
rpc AddAlgorithmApply (AddAlgorithmApplyRequest) returns (AddAlgorithmApplyReply) {
option (google.api.http) = {
post: "/v1/algorithmmanage/algorithmtype"
post: "/v1/algorithmmanage/algorithmapply"
body: "*"
};
}

// 查询算法类型列表
rpc ListAlgorithmType (ListAlgorithmTypeRequest) returns (ListAlgorithmTypeReply) {
// 查询算法用途列表
rpc ListAlgorithmApply (ListAlgorithmApplyRequest) returns (ListAlgorithmApplyReply) {
option (google.api.http) = {
get: "/v1/algorithmmanage/algorithmtype"
get: "/v1/algorithmmanage/algorithmapply"
};
}

// 删除算法类型
rpc DeleteAlgorithmType (DeleteAlgorithmTypeRequest) returns (DeleteAlgorithmTypeReply) {
// 删除算法用途
rpc DeleteAlgorithmApply (DeleteAlgorithmApplyRequest) returns (DeleteAlgorithmApplyReply) {
option (google.api.http) = {
delete: "/v1/algorithmmanage/algorithmtype/{id}"
delete: "/v1/algorithmmanage/algorithmapply/{id}"
};
}

// 修改算法类型描述
rpc UpdateAlgorithmType (UpdateAlgorithmTypeRequest) returns (UpdateAlgorithmTypeReply) {
// 修改算法用途描述
rpc UpdateAlgorithmApply (UpdateAlgorithmApplyRequest) returns (UpdateAlgorithmApplyReply) {
option (google.api.http) = {
put: "/v1/algorithmmanage/algorithmtype/{id}"
put: "/v1/algorithmmanage/algorithmapply/{id}"
};
}

@@ -159,66 +158,53 @@ service Algorithm {
}

message AlgorithmType {
message AlgorithmLable {
string id = 1;
string typeDesc = 2;
string lableDesc = 2;
int32 sourceType = 3;
}

message AddAlgorithmTypeRequest {
string typeDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
message AddAlgorithmApplyRequest {
string lableDesc = 1[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message AddAlgorithmTypeReply {
AlgorithmType algorithmType = 1;
message AddAlgorithmApplyReply {
AlgorithmLable lable = 1;
}

message ListAlgorithmTypeRequest {
message ListAlgorithmApplyRequest {
int64 pageIndex = 1;
int64 pageSize = 2[(validate.rules).int64 = {lt:100}];
}

message ListAlgorithmTypeReply {
message ListAlgorithmApplyReply {
int64 totalSize = 1;
repeated AlgorithmType algorithmTypes = 2;
}

message GetAlgorithmTypeRequest {
string id = 1;
repeated AlgorithmLable lables = 2;
}

message GetAlgorithmTypeReply {
message DeleteAlgorithmApplyRequest {
string id = 1;
string typeDesc = 2;
}

message DeleteAlgorithmTypeRequest {
string id = 1;
}

message DeleteAlgorithmTypeReply {
message DeleteAlgorithmApplyReply {
int64 deletedAt = 1;
}

message UpdateAlgorithmTypeRequest {
message UpdateAlgorithmApplyRequest {
string id = 1;
string typeDesc = 2;
string lableDesc = 2;
}

message UpdateAlgorithmTypeReply {
message UpdateAlgorithmApplyReply {
int64 updatedAt = 1;
}

message AlgorithmFramework {
string id = 1;
string frameworkDesc = 2;
}

message AddAlgorithmFrameworkRequest {
string frameworkDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
string lableDesc = 1[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message AddAlgorithmFrameworkReply {
AlgorithmFramework algorithmFramework = 1;
AlgorithmLable lable = 1;
}

message ListAlgorithmFrameworkRequest {
@@ -228,16 +214,7 @@ message ListAlgorithmFrameworkRequest {

message ListAlgorithmFrameworkReply {
int64 totalSize = 1;
repeated AlgorithmFramework algorithmFrameworks = 2;
}

message GetAlgorithmFrameworkRequest {
string id = 1;
}

message GetAlgorithmFrameworkReply {
string id = 1;
string frameworkDesc = 2;
repeated AlgorithmLable lables = 2;
}

message DeleteAlgorithmFrameworkRequest {
@@ -250,7 +227,7 @@ message DeleteAlgorithmFrameworkReply {

message UpdateAlgorithmFrameworkRequest {
string id = 1;
string frameworkDesc = 2;
string lableDesc = 2;
}

message UpdateAlgorithmFrameworkReply {
@@ -272,8 +249,8 @@ message AlgorithmDetail {
string path = 12;
bool isPrefab = 13;
int64 createdAt = 14;
string typeId = 15;
string typeName = 16;
string applyId = 15;
string applyName = 16;
string frameworkId = 17;
string frameworkName = 18;
}
@@ -347,7 +324,7 @@ message AddAlgorithmRequest {
string algorithmName = 5[(validate.rules).string = {min_len:1,max_len:128}];
string modelName = 6[(validate.rules).string = {min_len:1,max_len:128}];
string algorithmDescript = 7;
string typeId = 8;
string applyId = 8;
string frameworkId = 9;
}
message AddAlgorithmReply {


+ 7
- 0
server/admin-server/api/v1/base.swagger.json View File

@@ -0,0 +1,7 @@
{
"info": {
"title": "octopus api",
"version": "",
"description": "鉴权采用Bearer Token,接口按照以下格式:\n\n成功格式:\n\n```json\n{\n \"success\": true,\n \"payload\": {},\n \"error\": null\n}\n```\n\n失败格式:\n\n```json\n{\n \"success\": false,\n \"payload\": null,\n \"error\": {\n \"code\": 0,\n \"subcode\": 0,\n \"message\": \"\"\n }\n}\n```\n"
}
}

+ 78
- 12
server/admin-server/api/v1/dataset.proto View File

@@ -37,6 +37,33 @@ service DatasetService {
};
}

// 新增数据集用途
rpc AddDatasetApply (AddDatasetApplyRequest) returns (AddDatasetApplyReply) {
option (google.api.http) = {
post: "/v1/datasetmanage/datasetapply"
body: "*"
};
}
// 查询数据集用途列表
rpc ListDatasetApply (ListDatasetApplyRequest) returns (ListDatasetApplyReply) {
option (google.api.http) = {
get: "/v1/datasetmanage/datasetapply"
};
}
// 删除数据集用途
rpc DeleteDatasetApply (DeleteDatasetApplyRequest) returns (DeleteDatasetApplyReply) {
option (google.api.http) = {
delete: "/v1/datasetmanage/datasetapply/{id}"
};
}

// 修改数据集用途
rpc UpdateDatasetApply (UpdateDatasetApplyRequest) returns (UpdateDatasetApplyReply) {
option (google.api.http) = {
put: "/v1/datasetmanage/datasetapply/{id}"
};
}

// 查询预置数据集列表
rpc ListPreDataset (ListPreDatasetRequest) returns (ListPreDatasetReply) {
option (google.api.http) = {
@@ -103,27 +130,28 @@ service DatasetService {
}
}

message DatasetType {
message DatasetLable {
string id = 1;
string typeDesc = 2;
string lableDesc = 2;
int32 sourceType = 3;
}

message AddDatasetTypeRequest {
string typeDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
string lableDesc = 1[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message AddDatasetTypeReply {
DatasetType datasetType = 1;
DatasetLable lable = 1;
}

message ListDatasetTypeRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageIndex = 1;
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
}

message ListDatasetTypeReply {
int64 totalSize = 1;
repeated DatasetType datasetTypes = 2;
repeated DatasetLable lables = 2;
}

message DeleteDatasetTypeRequest {
@@ -136,17 +164,53 @@ message DeleteDatasetTypeReply {

message UpdateDatasetTypeRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string typeDesc = 2[(validate.rules).string = {min_len: 1, max_len: 128}];
string lableDesc = 2[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message UpdateDatasetTypeReply {
int64 updatedAt = 1;
}

message AddDatasetApplyRequest {
string lableDesc = 1[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message AddDatasetApplyReply {
DatasetLable lable = 1;
}

message ListDatasetApplyRequest {
int64 pageIndex = 1;
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
}

message ListDatasetApplyReply {
int64 totalSize = 1;
repeated DatasetLable lables = 2;
}

message DeleteDatasetApplyRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
}

message DeleteDatasetApplyReply {
int64 deletedAt = 1;
}

message UpdateDatasetApplyRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string lableDesc = 2[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message UpdateDatasetApplyReply {
int64 updatedAt = 1;
}

message CreateDatasetRequest {
string name = 1[(validate.rules).string = {min_len: 1, max_len: 30}];
string typeId = 2[(validate.rules).string = {min_len: 1 max_len: 64}];
string desc = 3[(validate.rules).string = {max_len: 300}];
string applyId = 3[(validate.rules).string = {min_len: 1 max_len: 64}];
string desc = 4[(validate.rules).string = {max_len: 300}];
}

message CreateDatasetReply {
@@ -164,10 +228,12 @@ message Dataset {
string name = 7;
string typeId = 8;
string typeDesc = 9;
string desc = 10;
string latestVersion = 11;
string spaceName = 12;
string userName = 13;
string applyId = 10;
string applyDesc = 11;
string desc = 12;
string latestVersion = 13;
string spaceName = 14;
string userName = 15;
}

message ListPreDatasetRequest {


+ 77
- 0
server/admin-server/api/v1/jointcloud.proto View File

@@ -0,0 +1,77 @@
syntax = "proto3";

package openaiserver.api.v1;

option go_package = "server/openai-server/api/v1;v1";

import "google/api/annotations.proto";
import "validate/validate.proto";

service JointCloudService {
// 查询任务列表
rpc ListJointCloudJob (ListJointCloudJobRequest) returns (ListJointCloudJobReply) {
option (google.api.http) = {
get: "/v1/jointcloudmanage/job"
};
}
}

message JointCloudParam {
string key = 1;
string value = 2;
}

message JointCloudResourceParam {
string name = 1;
int32 size = 2;
string type = 3;
string unit = 4;
}

message ListJointCloudJobRequest {
int32 pageIndex = 1;
int32 pageSize = 2;
string ids = 3;
}
message ListJointCloudJobReply {
int32 totalSize = 1;
repeated JointCloudJReplyJob list = 2;
}
message JointCloudJReplyJob {
string taskId = 1;
string taskName = 2;
string interpreter = 3;
string framework = 4;
int64 cloudVendorId = 5;
string cloudVendorName = 6;
string imageUrl = 7;
int64 creator = 8;
string creatorName = 9;
string execCommand = 10;
string outputPath = 11;
int64 status = 12;
string remark = 13;
string jobId = 14;
int64 createTime = 15;
string userId = 16;
string workspaceId = 17;
repeated JointCloudReplyDataSetVersionVo dataSetList = 18;
repeated JointCloudParam taskParams = 19;
repeated JointCloudResourceParam resourceParams = 20;
}

message JointCloudReplyDataSetVersionVo {
string category = 1;
string dataSetCode = 2;
string version = 3;
string remark = 4;
string name = 5;
int64 cloudVendorId = 6;
string cloudVendorName = 7;
int64 versionNumber = 8;
string label = 9;
int64 creator = 10;
int64 createTime = 11;
}

+ 336
- 0
server/admin-server/api/v1/platform.proto View File

@@ -0,0 +1,336 @@
syntax = "proto3";

package adminserver.api.v1;

option go_package = "server/admin-server/api/v1;v1";


import "google/api/annotations.proto";
import "validate/validate.proto";

service PlatformService {
// 查询第三方平台列表
rpc ListPlatform (ListPlatformRequest) returns (ListPlatformReply) {
option (google.api.http) = {
get: "/v1/platformmanage/platform"
};
};
// 创建第三方平台
rpc CreatePlatform (CreatePlatformRequest) returns (CreatePlatformReply) {
option (google.api.http) = {
post: "/v1/platformmanage/platform"
body: "*"
};
};
// 更新第三方平台
rpc UpdatePlatform (UpdatePlatformRequest) returns (UpdatePlatformReply) {
option (google.api.http) = {
put: "/v1/platformmanage/platform"
body: "*"
};
};
// 查询存储配置列表
rpc ListPlatformStorageConfig (ListPlatformStorageConfigRequest) returns (ListPlatformStorageConfigReply) {
option (google.api.http) = {
get: "/v1/platformmanage/platform/{platformId}/storageconfig"
};
};
// 创建存储配置
rpc CreatePlatformStorageConfig (CreatePlatformStorageConfigRequest) returns (CreatePlatformStorageConfigReply) {
option (google.api.http) = {
post: "/v1/platformmanage/platform/{platformId}/storageconfig"
body: "*"
};
};
// 删除存储配置
rpc DeletePlatformStorageConfig (DeletePlatformStorageConfigRequest) returns (DeletePlatformStorageConfigReply) {
option (google.api.http) = {
delete: "/v1/platformmanage/platform/{platformId}/storageconfig/{name}"
};
}
// 查询配置key列表
rpc ListPlatformConfigKey (ListPlatformConfigKeyRequest) returns (ListPlatformConfigKeyReply) {
option (google.api.http) = {
get: "/v1/platformmanage/platformconfigkey"
};
}

// 查询平台配置
rpc GetPlatformConfig (GetPlatformConfigRequest) returns (GetPlatformConfigReply) {
option (google.api.http) = {
get: "/v1/platformmanage/platform/{platformId}/config"
};
};

// 更新平台配置
rpc UpdatePlatformConfig (UpdatePlatformConfigRequest) returns (UpdatePlatformConfigReply) {
option (google.api.http) = {
put: "/v1/platformmanage/platform/{platformId}/config"
body: "*"
};
};
//获取平台任务列表
rpc PlatformTrainJobList(PlatformTrainJobListRequest) returns (PlatformTrainJobListReply){
option (google.api.http) = {
get: "/v1/platformmanage/platform/trainjob"
};
};
}

message ListPlatformRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
string sortBy = 3;
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
int64 createdAtGte = 5;
int64 createdAtLt = 6;
string searchKey = 7;
}

message Platform {
int64 createdAt = 1;
int64 updatedAt = 2;
string id = 3;
string name = 4;
string clientSecret = 5;
string contactName = 6;
string contactInfo = 7;
string resourcePool = 8;
}

message ListPlatformReply {
int64 totalSize = 1;
repeated Platform platforms = 2;
}

message CreatePlatformRequest {
// 名称,必填
string name = 1[(validate.rules).string = {min_len: 1, max_len: 30}];
// 联系人姓名,选填
string contactName = 2;
// 联系方式,选填
string contactInfo = 3;
// 资源池,必填
string resourcePool = 4[(validate.rules).string = {min_len: 1}];
}

message CreatePlatformReply {
string id = 1;
}

message UpdatePlatformRequest {
string id = 1;
string contactName = 2;
string contactInfo = 3;
string resourcePool = 4[(validate.rules).string = {min_len: 1}];
}

message UpdatePlatformReply {

}


message StorageOptions {
message Juicefs {
string name = 1;
string metaUrl = 2;
}

Juicefs juicefs = 1;
}

message ListPlatformStorageConfigRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
string sortBy = 3;
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
int64 createdAtGte = 5;
int64 createdAtLt = 6;
string searchKey = 7;
string platformId = 8;
string name = 9;
}

message PlatformStorageConfig {
int64 createdAt = 1;
int64 updatedAt = 2;
string platformId = 3;
string name = 4;
string type = 5;
StorageOptions options = 6;
}

message ListPlatformStorageConfigReply {
int64 totalSize = 1;
repeated PlatformStorageConfig platformStorageConfigs = 2;
}

message CreatePlatformStorageConfigRequest {
string platformId = 1[(validate.rules).string = {min_len: 1}];
string name = 2[(validate.rules).string = {min_len: 1, max_len: 30, not_contains: "/"}];
string type = 3[(validate.rules).string = {in: ["juicefs"]}];
StorageOptions options = 4;
}

message CreatePlatformStorageConfigReply {
}


message DeletePlatformStorageConfigRequest {
string platformId = 1;
string name = 2;
}

message DeletePlatformStorageConfigReply {

}

message ListPlatformConfigKeyRequest {

}

message ListPlatformConfigKeyReply {
message ConfigKey {
string key = 1; // 键值,必填,保存配置时传入
string title = 2; // 标题,必填
string type = 3; // 类型,必填,input、radio、checkbox,默认为input
string desc = 4; // 描述,选填
string options = 5; // 选项,选填,radio、checkbox时必填,逗号分隔
string regexp = 6; // 正则,选填
bool required = 7; // 选填,默认为false
}
repeated ConfigKey configKeys = 1;
}

message GetPlatformConfigRequest {
string platformId = 1;
}

message GetPlatformConfigReply {
map<string, string> config = 1;
}

message UpdatePlatformConfigRequest {
string platformId = 1[(validate.rules).string = {min_len: 1}];
map<string, string> config = 2[(validate.rules).map.min_pairs = 1];
}

message UpdatePlatformConfigReply {

}

message PlatformImage {
string name = 1[(validate.rules).string = {min_len: 1, max_len: 300}];
string version = 2[(validate.rules).string = {min_len: 1, max_len: 30}];
}

message PlatformDataset {
//存储配置名称,必填
string storageConfigName = 1[(validate.rules).string = {max_len: 30}];
//数据集子目录
string addr = 2[(validate.rules).string = {max_len: 300}];
//数据集名称,必填
string name = 3[(validate.rules).string = {max_len: 300}];
//数据集容器内路径
string path = 4[(validate.rules).string = {max_len: 300}];;
}

message PlatformOutput {
//存储配置名称,必填
string storageConfigName = 1[(validate.rules).string = {max_len: 30}];
//存储子目录
string addr = 2[(validate.rules).string = {max_len: 300}];
//容器内输出路径
string path = 3[(validate.rules).string = {max_len: 300}];
}

message PlatformTask {
//子任务名称,非必填,校验规则"^[0-9a-zA-Z_]*$",最大长度30个字符
string name = 1[(validate.rules).string = {min_len: 1, max_len:30}];
//子任务执行命令
string command = 2[(validate.rules).string = {min_len: 0, max_len: 300}];
//command执行命令参数,key-value,数组
repeated PlatformParameter parameters = 3;
//资源
repeated PlatformResource resources = 4;
//副本个数,非必填
int64 taskNumber = 5[(validate.rules).int64 = {gte:1}];
//子任务最小失败数,非必填
int64 minFailedTaskCount = 6[(validate.rules).int64 = {gte:1}];
//子任务最小成功数,非必填
int64 minSucceededTaskCount = 7[(validate.rules).int64 = {gte:1}];
//是否主任务,非必填
bool isMainRole = 8;
}

message PlatformParameter {
//命令参数key,非必填
string key = 1;
//命令参数value,非必填
string value = 2;
}

message PlatformResource {
//命令参数key,必填
string name = 1;
//命令参数value,必填
string size = 2;
}

message PlatformTrainJobListRequest{
// 页码,从1开始,非必填
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
// 页大小,最小1条,最大100条,非必填
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
// 分组依据,非必填
string sortBy = 3;
//升序、降序,非必填
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
//大于某个时间创建,非必填
int64 createdAtGte = 5;
//小于某个时间创建,非必填
int64 createdAtLt = 6;
//状态查询,非必填
string status = 7;
//模糊查找字段,可用于name等模糊查找,非必填
string searchKey = 8;
//platformId,不传则查全部平台
string platformId = 9;
}

message PlatformTrainJobListReply {
//查询结果总数
int64 totalSize = 1;
//任务
repeated PlatformTrainJob trainJobs = 2;
}

message PlatformTrainJob{
//任务ID
string id = 1;
//job名称
string name = 2;
//platformId
string platformId = 3;
//job描述
string desc = 4;
//数据集
repeated PlatformDataset datasets = 5;
//镜像
PlatformImage image = 6;
//子任务配置信息
repeated PlatformTask tasks = 7;
//创建时间
int64 createdAt = 8;
//更新时间
int64 updatedAt = 9;
//任务状态
string status = 10;
//job完成时间
int64 completedAt = 11;
//运行时
int64 runSec = 12;
//启动时间
int64 startedAt = 13;
}


+ 54
- 0
server/admin-server/api/v1/user.proto View File

@@ -43,6 +43,26 @@ service User {
post: "/v1/usermanage/user/{userId}/thaw"
};
};
// 查询配置key列表
rpc ListUserConfigKey (ListUserConfigKeyRequest) returns (ListUserConfigKeyReply) {
option (google.api.http) = {
get: "/v1/usermanage/userconfigkey"
};
}
// 查询用户配置
rpc GetUserConfig (GetUserConfigRequest) returns (GetUserConfigReply) {
option (google.api.http) = {
get: "/v1/usermanage/user/{userId}/config"
};
};

// 更新用户配置
rpc UpdateUserConfig (UpdateUserConfigRequest) returns (UpdateUserConfigReply) {
option (google.api.http) = {
put: "/v1/usermanage/user/{userId}/config"
body: "*"
};
};
}

message UserItem {
@@ -123,4 +143,38 @@ message ThawUserRequest {

message ThawUserReply {
int64 thawedAt = 1;
}

message ListUserConfigKeyRequest {

}

message ListUserConfigKeyReply {
message ConfigKey {
string key = 1; // 键值,必填,保存配置时传入
string title = 2; // 标题,必填
string type = 3; // 类型,必填,input、radio、checkbox,默认为input
string desc = 4; // 描述,选填
string options = 5; // 选项,选填,radio、checkbox时必填,逗号分隔
string regexp = 6; // 正则,选填
bool required = 7; // 选填,默认为false
}
repeated ConfigKey configKeys = 1;
}

message GetUserConfigRequest {
string userId = 1;
}

message GetUserConfigReply {
map<string, string> config = 1;
}

message UpdateUserConfigRequest {
string userId = 1[(validate.rules).string = {min_len: 1}];
map<string, string> config = 2[(validate.rules).map.min_pairs = 1];
}

message UpdateUserConfigReply {

}

+ 40
- 32
server/admin-server/internal/data/data.go View File

@@ -17,22 +17,26 @@ import (
)

type Data struct {
log *log.Helper
AlgorithmClient api.AlgorithmClient
AdminUserClient api.AdminUserClient
UserClient api.UserClient
DevelopClient api.DevelopClient
WorkspaceClient api.WorkspaceClient
ModelClient api.ModelClient
TrainJobClient api.TrainJobServiceClient
ImageClient api.ImageClient
NodeClient api.NodeServiceClient
ResourceClient api.ResourceServiceClient
ResourceSpecClient api.ResourceSpecServiceClient
ResourcePoolClient api.ResourcePoolServiceClient
DatasetClient api.DatasetServiceClient
SessionClient session.SessionClient
BillingClient api.BillingServiceClient
log *log.Helper
AlgorithmClient api.AlgorithmServiceClient
AdminUserClient api.AdminUserClient
UserClient api.UserServiceClient
DevelopClient api.DevelopClient
WorkspaceClient api.WorkspaceServiceClient
ModelClient api.ModelServiceClient
TrainJobClient api.TrainJobServiceClient
ImageClient api.ImageServiceClient
NodeClient api.NodeServiceClient
ResourceClient api.ResourceServiceClient
ResourceSpecClient api.ResourceSpecServiceClient
ResourcePoolClient api.ResourcePoolServiceClient
DatasetClient api.DatasetServiceClient
SessionClient session.SessionClient
BillingClient api.BillingServiceClient
LableClient api.LableServiceClient
PlatformClient api.PlatformServiceClient
JointCloudClient api.JointCloudServiceClient
PlatformTrainJobClient api.PlatformTrainJobServiceClient
}

func NewData(confData *conf.Data, logger log.Logger) (*Data, error) {
@@ -59,21 +63,25 @@ func NewData(confData *conf.Data, logger log.Logger) (*Data, error) {
}

return &Data{
log: log,
AlgorithmClient: api.NewAlgorithmClient(conn),
AdminUserClient: api.NewAdminUserClient(conn),
UserClient: api.NewUserClient(conn),
DevelopClient: api.NewDevelopClient(conn),
WorkspaceClient: api.NewWorkspaceClient(conn),
ModelClient: api.NewModelClient(conn),
TrainJobClient: api.NewTrainJobServiceClient(conn),
ImageClient: api.NewImageClient(conn),
NodeClient: api.NewNodeServiceClient(conn),
ResourceClient: api.NewResourceServiceClient(conn),
ResourceSpecClient: api.NewResourceSpecServiceClient(conn),
ResourcePoolClient: api.NewResourcePoolServiceClient(conn),
DatasetClient: api.NewDatasetServiceClient(conn),
SessionClient: session.NewSessionClient(confData, logger),
BillingClient: api.NewBillingServiceClient(conn),
log: log,
AlgorithmClient: api.NewAlgorithmServiceClient(conn),
AdminUserClient: api.NewAdminUserClient(conn),
UserClient: api.NewUserServiceClient(conn),
DevelopClient: api.NewDevelopClient(conn),
WorkspaceClient: api.NewWorkspaceServiceClient(conn),
ModelClient: api.NewModelServiceClient(conn),
TrainJobClient: api.NewTrainJobServiceClient(conn),
ImageClient: api.NewImageServiceClient(conn),
NodeClient: api.NewNodeServiceClient(conn),
ResourceClient: api.NewResourceServiceClient(conn),
ResourceSpecClient: api.NewResourceSpecServiceClient(conn),
ResourcePoolClient: api.NewResourcePoolServiceClient(conn),
DatasetClient: api.NewDatasetServiceClient(conn),
SessionClient: session.NewSessionClient(confData, logger),
BillingClient: api.NewBillingServiceClient(conn),
LableClient: api.NewLableServiceClient(conn),
PlatformClient: api.NewPlatformServiceClient(conn),
JointCloudClient: api.NewJointCloudServiceClient(conn),
PlatformTrainJobClient: api.NewPlatformTrainJobServiceClient(conn),
}, nil
}

+ 2
- 0
server/admin-server/internal/server/http.go View File

@@ -69,5 +69,7 @@ func NewHTTPServer(c *conf.Server, service *service.Service) *http.Server {
srv.HandlePrefix("/v1/datasetmanage", api.NewDatasetServiceHandler(service.DatasetService, options...))
srv.HandlePrefix("/v1/imagemanage", api.NewImageServiceHandler(service.ImageService, options...))
srv.HandlePrefix("/v1/billingmanage", api.NewBillingServiceHandler(service.BillingService, options...))
srv.HandlePrefix("/v1/platformmanage/platform", api.NewPlatformServiceHandler(service.PlatformService, options...))
srv.HandlePrefix("/v1/jointcloudmanage", api.NewJointCloudServiceHandler(service.JointCloudService, options...))
return srv
}

+ 65
- 52
server/admin-server/internal/service/algorithm.go View File

@@ -7,7 +7,6 @@ import (
"server/admin-server/internal/data"
innerapi "server/base-server/api/v1"
innterapi "server/base-server/api/v1"
"server/common/errors"
"server/common/log"

"github.com/jinzhu/copier"
@@ -28,38 +27,43 @@ func NewAlgorithmService(conf *conf.Bootstrap, logger log.Logger, data *data.Dat
}
}

// 新增算法类型
func (s *AlgorithmService) AddAlgorithmType(ctx context.Context, req *api.AddAlgorithmTypeRequest) (*api.AddAlgorithmTypeReply, error) {
innerReq := &innerapi.AddAlgorithmTypeRequest{}
innerReq.TypeDesc = req.TypeDesc
// 新增算法用途
func (s *AlgorithmService) AddAlgorithmApply(ctx context.Context, req *api.AddAlgorithmApplyRequest) (*api.AddAlgorithmApplyReply, error) {
innerReq := &innerapi.AddLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_ALGORITHM),
LableType: int32(innerapi.Type_LABLE_TYPE_ALGORITHM_APPLY),
LableDesc: req.LableDesc,
}

innerReply, err := s.data.AlgorithmClient.AddAlgorithmType(ctx, innerReq)
innerReply, err := s.data.LableClient.AddLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.AddAlgorithmTypeReply{
AlgorithmType: &api.AlgorithmType{
Id: innerReply.AlgorithmType.Id,
TypeDesc: innerReply.AlgorithmType.TypeDesc,
return &api.AddAlgorithmApplyReply{
Lable: &api.AlgorithmLable{
Id: innerReply.Lable.Id,
LableDesc: innerReply.Lable.LableDesc,
SourceType: innerReply.Lable.SourceType,
},
}, nil
}

// 查询算法类型列表
func (s *AlgorithmService) ListAlgorithmType(ctx context.Context, req *api.ListAlgorithmTypeRequest) (*api.ListAlgorithmTypeReply, error) {
innerReq := &innerapi.ListAlgorithmTypeRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
// 查询算法用途列表
func (s *AlgorithmService) ListAlgorithmApply(ctx context.Context, req *api.ListAlgorithmApplyRequest) (*api.ListAlgorithmApplyReply, error) {
innerReq := &innerapi.ListLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_ALGORITHM),
LableType: int32(innerapi.Type_LABLE_TYPE_ALGORITHM_APPLY),
PageIndex: req.PageIndex,
PageSize: req.PageSize,
}

innerReply, err := s.data.AlgorithmClient.ListAlgorithmType(ctx, innerReq)
innerReply, err := s.data.LableClient.ListLable(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListAlgorithmTypeReply{}
reply := &api.ListAlgorithmApplyReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
@@ -68,64 +72,71 @@ func (s *AlgorithmService) ListAlgorithmType(ctx context.Context, req *api.ListA
return reply, nil
}

// 删除算法类型
func (s *AlgorithmService) DeleteAlgorithmType(ctx context.Context, req *api.DeleteAlgorithmTypeRequest) (*api.DeleteAlgorithmTypeReply, error) {
innerReq := &innerapi.DeleteAlgorithmTypeRequest{}
innerReq.Id = req.Id
// 删除算法用途
func (s *AlgorithmService) DeleteAlgorithmApply(ctx context.Context, req *api.DeleteAlgorithmApplyRequest) (*api.DeleteAlgorithmApplyReply, error) {
innerReq := &innerapi.DeleteLableRequest{
Id: req.Id,
}

innerReply, err := s.data.AlgorithmClient.DeleteAlgorithmType(ctx, innerReq)
innerReply, err := s.data.LableClient.DeleteLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.DeleteAlgorithmTypeReply{
return &api.DeleteAlgorithmApplyReply{
DeletedAt: innerReply.DeletedAt,
}, nil
}

// 修改算法类型描述
func (s *AlgorithmService) UpdateAlgorithmType(ctx context.Context, req *api.UpdateAlgorithmTypeRequest) (*api.UpdateAlgorithmTypeReply, error) {
innerReq := &innerapi.UpdateAlgorithmTypeRequest{}
innerReq.Id = req.Id
innerReq.TypeDesc = req.TypeDesc
// 修改算法用途描述
func (s *AlgorithmService) UpdateAlgorithmApply(ctx context.Context, req *api.UpdateAlgorithmApplyRequest) (*api.UpdateAlgorithmApplyReply, error) {
innerReq := &innerapi.UpdateLableRequest{
Id: req.Id,
LableDesc: req.LableDesc,
}

innerReply, err := s.data.AlgorithmClient.UpdateAlgorithmType(ctx, innerReq)
innerReply, err := s.data.LableClient.UpdateLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.UpdateAlgorithmTypeReply{
return &api.UpdateAlgorithmApplyReply{
UpdatedAt: innerReply.UpdatedAt,
}, nil
}

// 新增算法框架
func (s *AlgorithmService) AddAlgorithmFramework(ctx context.Context, req *api.AddAlgorithmFrameworkRequest) (*api.AddAlgorithmFrameworkReply, error) {
innerReq := &innerapi.AddAlgorithmFrameworkRequest{}
innerReq.FrameworkDesc = req.FrameworkDesc
innerReq := &innerapi.AddLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_ALGORITHM),
LableType: int32(innerapi.Type_LABLE_TYPE_ALGORITHM_FRAMEWORK),
LableDesc: req.LableDesc,
}

innerReply, err := s.data.AlgorithmClient.AddAlgorithmFramework(ctx, innerReq)
innerReply, err := s.data.LableClient.AddLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.AddAlgorithmFrameworkReply{
AlgorithmFramework: &api.AlgorithmFramework{
Id: innerReply.AlgorithmFramework.Id,
FrameworkDesc: innerReply.AlgorithmFramework.FrameworkDesc,
Lable: &api.AlgorithmLable{
Id: innerReply.Lable.Id,
LableDesc: innerReply.Lable.LableDesc,
SourceType: innerReply.Lable.SourceType,
},
}, nil
}

// 查询算法类型框架
func (s *AlgorithmService) ListAlgorithmFramework(ctx context.Context, req *api.ListAlgorithmFrameworkRequest) (*api.ListAlgorithmFrameworkReply, error) {
innerReq := &innerapi.ListAlgorithmFrameworkRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
innerReq := &innerapi.ListLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_ALGORITHM),
LableType: int32(innerapi.Type_LABLE_TYPE_ALGORITHM_FRAMEWORK),
PageIndex: req.PageIndex,
PageSize: req.PageSize,
}

innerReply, err := s.data.AlgorithmClient.ListAlgorithmFramework(ctx, innerReq)
innerReply, err := s.data.LableClient.ListLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -141,10 +152,11 @@ func (s *AlgorithmService) ListAlgorithmFramework(ctx context.Context, req *api.

// 删除算法框架
func (s *AlgorithmService) DeleteAlgorithmFramework(ctx context.Context, req *api.DeleteAlgorithmFrameworkRequest) (*api.DeleteAlgorithmFrameworkReply, error) {
innerReq := &innerapi.DeleteAlgorithmFrameworkRequest{}
innerReq.Id = req.Id
innerReq := &innerapi.DeleteLableRequest{
Id: req.Id,
}

innerReply, err := s.data.AlgorithmClient.DeleteAlgorithmFramework(ctx, innerReq)
innerReply, err := s.data.LableClient.DeleteLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -156,11 +168,12 @@ func (s *AlgorithmService) DeleteAlgorithmFramework(ctx context.Context, req *ap

// 修改算法类型框架
func (s *AlgorithmService) UpdateAlgorithmFramework(ctx context.Context, req *api.UpdateAlgorithmFrameworkRequest) (*api.UpdateAlgorithmFrameworkReply, error) {
innerReq := &innerapi.UpdateAlgorithmFrameworkRequest{}
innerReq.Id = req.Id
innerReq.FrameworkDesc = req.FrameworkDesc
innerReq := &innerapi.UpdateLableRequest{
Id: req.Id,
LableDesc: req.LableDesc,
}

innerReply, err := s.data.AlgorithmClient.UpdateAlgorithmFramework(ctx, innerReq)
innerReply, err := s.data.LableClient.UpdateLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -346,7 +359,7 @@ func (s *AlgorithmService) AddPreAlgorithm(ctx context.Context, req *api.AddAlgo
AlgorithmName: req.AlgorithmName,
ModelName: req.ModelName,
AlgorithmDescript: req.AlgorithmDescript,
TypeId: req.TypeId,
ApplyId: req.ApplyId,
FrameworkId: req.FrameworkId,
})
if err != nil {
@@ -446,8 +459,8 @@ func (s *AlgorithmService) algorithmTransfer(ctx context.Context, algorithm *inn
FileStatus: algorithm.FileStatus,
IsPrefab: algorithm.IsPrefab,
CreatedAt: algorithm.CreatedAt,
TypeId: algorithm.TypeId,
TypeName: algorithm.TypeName,
ApplyId: algorithm.ApplyId,
ApplyName: algorithm.ApplyName,
FrameworkId: algorithm.FrameworkId,
FrameworkName: algorithm.FrameworkName,
}


+ 100
- 18
server/admin-server/internal/service/dataset.go View File

@@ -29,30 +29,35 @@ func NewDatasetService(conf *conf.Bootstrap, logger log.Logger, data *data.Data)
}

func (s *DatasetService) AddDatasetType(ctx context.Context, req *api.AddDatasetTypeRequest) (*api.AddDatasetTypeReply, error) {
innerReq := &innerapi.AddDatasetTypeRequest{}
innerReq.TypeDesc = req.TypeDesc
innerReq := &innerapi.AddLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_DATASET),
LableType: int32(innerapi.Type_LABLE_TYPE_DATASET_TYPE),
LableDesc: req.LableDesc,
}

innerReply, err := s.data.DatasetClient.AddDatasetType(ctx, innerReq)
innerReply, err := s.data.LableClient.AddLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.AddDatasetTypeReply{
DatasetType: &api.DatasetType{
Id: innerReply.DatasetType.Id,
TypeDesc: innerReply.DatasetType.TypeDesc,
Lable: &api.DatasetLable{
Id: innerReply.Lable.Id,
LableDesc: innerReply.Lable.LableDesc,
SourceType: innerReply.Lable.SourceType,
},
}, nil
}

func (s *DatasetService) ListDatasetType(ctx context.Context, req *api.ListDatasetTypeRequest) (*api.ListDatasetTypeReply, error) {
innerReq := &innerapi.ListDatasetTypeRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
innerReq := &innerapi.ListLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_DATASET),
LableType: int32(innerapi.Type_LABLE_TYPE_DATASET_TYPE),
PageIndex: req.PageIndex,
PageSize: req.PageSize,
}

innerReply, err := s.data.DatasetClient.ListDatasetType(ctx, innerReq)
innerReply, err := s.data.LableClient.ListLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -67,10 +72,11 @@ func (s *DatasetService) ListDatasetType(ctx context.Context, req *api.ListDatas
}

func (s *DatasetService) DeleteDatasetType(ctx context.Context, req *api.DeleteDatasetTypeRequest) (*api.DeleteDatasetTypeReply, error) {
innerReq := &innerapi.DeleteDatasetTypeRequest{}
innerReq.Id = req.Id
innerReq := &innerapi.DeleteLableRequest{
Id: req.Id,
}

innerReply, err := s.data.DatasetClient.DeleteDatasetType(ctx, innerReq)
innerReply, err := s.data.LableClient.DeleteLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -81,11 +87,12 @@ func (s *DatasetService) DeleteDatasetType(ctx context.Context, req *api.DeleteD
}

func (s *DatasetService) UpdateDatasetType(ctx context.Context, req *api.UpdateDatasetTypeRequest) (*api.UpdateDatasetTypeReply, error) {
innerReq := &innerapi.UpdateDatasetTypeRequest{}
innerReq.Id = req.Id
innerReq.TypeDesc = req.TypeDesc
innerReq := &innerapi.UpdateLableRequest{
Id: req.Id,
LableDesc: req.LableDesc,
}

innerReply, err := s.data.DatasetClient.UpdateDatasetType(ctx, innerReq)
innerReply, err := s.data.LableClient.UpdateLable(ctx, innerReq)
if err != nil {
return nil, err
}
@@ -95,6 +102,80 @@ func (s *DatasetService) UpdateDatasetType(ctx context.Context, req *api.UpdateD
}, nil
}

func (s *DatasetService) AddDatasetApply(ctx context.Context, req *api.AddDatasetApplyRequest) (*api.AddDatasetApplyReply, error) {
innerReq := &innerapi.AddLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_DATASET),
LableType: int32(innerapi.Type_LABLE_TYPE_DATASET_APPLY),
LableDesc: req.LableDesc,
}

innerReply, err := s.data.LableClient.AddLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.AddDatasetApplyReply{
Lable: &api.DatasetLable{
Id: innerReply.Lable.Id,
LableDesc: innerReply.Lable.LableDesc,
SourceType: innerReply.Lable.SourceType,
},
}, nil
}

func (s *DatasetService) ListDatasetApply(ctx context.Context, req *api.ListDatasetApplyRequest) (*api.ListDatasetApplyReply, error) {
innerReq := &innerapi.ListLableRequest{
RelegationType: int32(innerapi.Relegation_LABLE_RELEGATION_DATASET),
LableType: int32(innerapi.Type_LABLE_TYPE_DATASET_APPLY),
PageIndex: req.PageIndex,
PageSize: req.PageSize,
}

innerReply, err := s.data.LableClient.ListLable(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListDatasetApplyReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}

func (s *DatasetService) DeleteDatasetApply(ctx context.Context, req *api.DeleteDatasetApplyRequest) (*api.DeleteDatasetApplyReply, error) {
innerReq := &innerapi.DeleteLableRequest{
Id: req.Id,
}

innerReply, err := s.data.LableClient.DeleteLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.DeleteDatasetApplyReply{
DeletedAt: innerReply.DeletedAt,
}, nil
}

func (s *DatasetService) UpdateDatasetApply(ctx context.Context, req *api.UpdateDatasetApplyRequest) (*api.UpdateDatasetApplyReply, error) {
innerReq := &innerapi.UpdateLableRequest{
Id: req.Id,
LableDesc: req.LableDesc,
}

innerReply, err := s.data.LableClient.UpdateLable(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.UpdateDatasetApplyReply{
UpdatedAt: innerReply.UpdatedAt,
}, nil
}

func (s *DatasetService) ListUserDataset(ctx context.Context, req *api.ListUserDatasetRequest) (*api.ListUserDatasetReply, error) {
innerReq := &innerapi.ListDatasetRequest{}
err := copier.Copy(innerReq, req)
@@ -169,6 +250,7 @@ func (s *DatasetService) CreateDataset(ctx context.Context, req *api.CreateDatas
SourceType: innerapi.DatasetSourceType_DST_PRE,
Name: req.Name,
TypeId: req.TypeId,
ApplyId: req.ApplyId,
Desc: req.Desc,
}



+ 49
- 0
server/admin-server/internal/service/jointcloud.go View File

@@ -0,0 +1,49 @@
package service

import (
"context"
api "server/admin-server/api/v1"
"server/admin-server/internal/conf"
"server/admin-server/internal/data"
"server/common/errors"

innerapi "server/base-server/api/v1"

"github.com/jinzhu/copier"
)

type JointCloudService struct {
api.UnimplementedJointCloudServiceServer
conf *conf.Bootstrap
data *data.Data
}

func NewJointCloudService(conf *conf.Bootstrap, data *data.Data) api.JointCloudServiceServer {
s := &JointCloudService{
conf: conf,
data: data,
}

return s
}

func (s *JointCloudService) ListJointCloudJob(ctx context.Context, req *api.ListJointCloudJobRequest) (*api.ListJointCloudJobReply, error) {
innerReq := &innerapi.ListJointCloudJobRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.JointCloudClient.ListJointCloudJob(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListJointCloudJobReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}

+ 188
- 0
server/admin-server/internal/service/platform.go View File

@@ -0,0 +1,188 @@
package service

import (
"context"
api "server/admin-server/api/v1"
"server/admin-server/internal/conf"
"server/admin-server/internal/data"
innerapi "server/base-server/api/v1"
"server/common/errors"

"github.com/jinzhu/copier"
)

type platformService struct {
api.UnimplementedPlatformServiceServer
conf *conf.Bootstrap
data *data.Data
}

func NewPlatformService(conf *conf.Bootstrap, data *data.Data) api.PlatformServiceServer {
s := &platformService{
conf: conf,
data: data,
}

return s
}

func (s *platformService) ListPlatform(ctx context.Context, req *api.ListPlatformRequest) (*api.ListPlatformReply, error) {
innerReq := &innerapi.ListPlatformRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.PlatformClient.ListPlatform(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListPlatformReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}

func (s *platformService) CreatePlatform(ctx context.Context, req *api.CreatePlatformRequest) (*api.CreatePlatformReply, error) {
innerReq := &innerapi.CreatePlatformRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, err
}

innerReply, err := s.data.PlatformClient.CreatePlatform(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.CreatePlatformReply{Id: innerReply.Id}, nil
}
func (s *platformService) UpdatePlatform(ctx context.Context, req *api.UpdatePlatformRequest) (*api.UpdatePlatformReply, error) {
innerReq := &innerapi.UpdatePlatformRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, err
}

_, err = s.data.PlatformClient.UpdatePlatform(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.UpdatePlatformReply{}, nil
}

func (s *platformService) ListPlatformConfigKey(ctx context.Context, req *api.ListPlatformConfigKeyRequest) (*api.ListPlatformConfigKeyReply, error) {
innerReq := &innerapi.ListPlatformConfigKeyRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.PlatformClient.ListPlatformConfigKey(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListPlatformConfigKeyReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}

func (s *platformService) ListPlatformStorageConfig(ctx context.Context, req *api.ListPlatformStorageConfigRequest) (*api.ListPlatformStorageConfigReply, error) {
innerReq := &innerapi.ListPlatformStorageConfigRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.PlatformClient.ListPlatformStorageConfig(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.ListPlatformStorageConfigReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}
func (s *platformService) CreatePlatformStorageConfig(ctx context.Context, req *api.CreatePlatformStorageConfigRequest) (*api.CreatePlatformStorageConfigReply, error) {
innerReq := &innerapi.CreatePlatformStorageConfigRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, err
}

_, err = s.data.PlatformClient.CreatePlatformStorageConfig(ctx, innerReq)
if err != nil {
return nil, err
}

return &api.CreatePlatformStorageConfigReply{}, nil
}

func (s *platformService) DeletePlatformStorageConfig(ctx context.Context, req *api.DeletePlatformStorageConfigRequest) (*api.DeletePlatformStorageConfigReply, error) {
_, err := s.data.PlatformClient.DeletePlatformStorageConfig(ctx, &innerapi.DeletePlatformStorageConfigRequest{PlatformId: req.PlatformId, Name: req.Name})
if err != nil {
return nil, err
}

return &api.DeletePlatformStorageConfigReply{}, nil
}

func (s *platformService) GetPlatformConfig(ctx context.Context, req *api.GetPlatformConfigRequest) (*api.GetPlatformConfigReply, error) {
reply, err := s.data.PlatformClient.GetPlatformConfig(ctx, &innerapi.GetPlatformConfigRequest{PlatformId: req.PlatformId})
if err != nil {
return nil, err
}
return &api.GetPlatformConfigReply{Config: reply.Config}, nil
}
func (s *platformService) UpdatePlatformConfig(ctx context.Context, req *api.UpdatePlatformConfigRequest) (*api.UpdatePlatformConfigReply, error) {
_, err := s.data.PlatformClient.UpdatePlatformConfig(ctx, &innerapi.UpdatePlatformConfigRequest{PlatformId: req.PlatformId, Config: req.Config})
if err != nil {
return nil, err
}
return &api.UpdatePlatformConfigReply{}, nil
}

// 训练任务列表
func (s *platformService) PlatformTrainJobList(ctx context.Context, req *api.PlatformTrainJobListRequest) (*api.PlatformTrainJobListReply, error) {

innerReq := &innerapi.PlatformTrainJobListRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.PlatformTrainJobClient.TrainJobList(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &api.PlatformTrainJobListReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

if reply.TrainJobs == nil {
reply := &api.PlatformTrainJobListReply{
TotalSize: 0,
TrainJobs: nil,
}
return reply, nil
}

return reply, nil
}

+ 4
- 0
server/admin-server/internal/service/service.go View File

@@ -22,6 +22,8 @@ type Service struct {
ResourcePoolService api.ResourcePoolServiceServer
DatasetService api.DatasetServiceServer
BillingService api.BillingServiceServer
PlatformService api.PlatformServiceServer
JointCloudService api.JointCloudServiceServer
}

func NewService(conf *conf.Bootstrap, logger log.Logger, data *data.Data) *Service {
@@ -40,6 +42,8 @@ func NewService(conf *conf.Bootstrap, logger log.Logger, data *data.Data) *Servi
service.ResourcePoolService = NewResourcePoolService(conf, logger, data)
service.DatasetService = NewDatasetService(conf, logger, data)
service.BillingService = NewBillingService(conf, logger, data)
service.PlatformService = NewPlatformService(conf, data)
service.JointCloudService = NewJointCloudService(conf, data)

return service
}

+ 41
- 0
server/admin-server/internal/service/user.go View File

@@ -5,9 +5,13 @@ import (
pb "server/admin-server/api/v1"
"server/admin-server/internal/conf"
"server/admin-server/internal/data"
innerapi "server/base-server/api/v1"
innterapi "server/base-server/api/v1"
"server/common/errors"
"server/common/log"
"time"

"github.com/jinzhu/copier"
)

type UserService struct {
@@ -214,3 +218,40 @@ func (s *UserService) ThawUser(ctx context.Context, req *pb.ThawUserRequest) (*p
}
return &pb.ThawUserReply{ThawedAt: time.Now().Unix()}, nil
}

func (s *UserService) ListUserConfigKey(ctx context.Context, req *pb.ListUserConfigKeyRequest) (*pb.ListUserConfigKeyReply, error) {
innerReq := &innerapi.ListUserConfigKeyRequest{}
err := copier.Copy(innerReq, req)
if err != nil {
return nil, errors.Errorf(err, errors.ErrorStructCopy)
}

innerReply, err := s.data.UserClient.ListUserConfigKey(ctx, innerReq)
if err != nil {
return nil, err
}

reply := &pb.ListUserConfigKeyReply{}
err = copier.Copy(reply, innerReply)
if err != nil {
return nil, err
}

return reply, nil
}

func (s *UserService) GetUserConfig(ctx context.Context, req *pb.GetUserConfigRequest) (*pb.GetUserConfigReply, error) {
reply, err := s.data.UserClient.GetUserConfig(ctx, &innerapi.GetUserConfigRequest{UserId: req.UserId})
if err != nil {
return nil, err
}
return &pb.GetUserConfigReply{Config: reply.Config}, nil
}

func (s *UserService) UpdateUserConfig(ctx context.Context, req *pb.UpdateUserConfigRequest) (*pb.UpdateUserConfigReply, error) {
_, err := s.data.UserClient.UpdateUserConfig(ctx, &innerapi.UpdateUserConfigRequest{UserId: req.UserId, Config: req.Config})
if err != nil {
return nil, err
}
return &pb.UpdateUserConfigReply{}, nil
}

+ 6
- 126
server/base-server/api/v1/algorithm.proto View File

@@ -8,29 +8,7 @@ option go_package = "server/base-server/api/v1;v1";

import "validate/validate.proto";

service Algorithm {
// 新增算法类型
rpc AddAlgorithmType (AddAlgorithmTypeRequest) returns (AddAlgorithmTypeReply);
// 查询算法类型列表
rpc ListAlgorithmType (ListAlgorithmTypeRequest) returns (ListAlgorithmTypeReply);
// 查询单个算法类型
rpc GetAlgorithmType (GetAlgorithmTypeRequest) returns (GetAlgorithmTypeReply);
// 删除算法类型
rpc DeleteAlgorithmType (DeleteAlgorithmTypeRequest) returns (DeleteAlgorithmTypeReply);
// 修改算法类型描述
rpc UpdateAlgorithmType (UpdateAlgorithmTypeRequest) returns (UpdateAlgorithmTypeReply);

// 新增算法框架
rpc AddAlgorithmFramework (AddAlgorithmFrameworkRequest) returns (AddAlgorithmFrameworkReply);
// 查询算法框架列表
rpc ListAlgorithmFramework (ListAlgorithmFrameworkRequest) returns (ListAlgorithmFrameworkReply);
// 查询单个算法框架
rpc GetAlgorithmFramework (GetAlgorithmFrameworkRequest) returns (GetAlgorithmFrameworkReply);
// 删除算法框架
rpc DeleteAlgorithmFramework (DeleteAlgorithmFrameworkRequest) returns (DeleteAlgorithmFrameworkReply);
// 修改算法框架描述
rpc UpdateAlgorithmFramework (UpdateAlgorithmFrameworkRequest) returns (UpdateAlgorithmFrameworkReply);

service AlgorithmService {
// 查询预置算法列表
rpc ListPreAlgorithm (ListPreAlgorithmRequest) returns (ListPreAlgorithmReply);
// 查询我的算法列表
@@ -96,104 +74,6 @@ service Algorithm {
rpc DownloadAlgorithmVersion (DownloadAlgorithmVersionRequest) returns (DownloadAlgorithmVersionReply);
}

message AlgorithmType {
string id = 1;
string typeDesc = 2;
}

message AddAlgorithmTypeRequest {
string typeDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
}

message AddAlgorithmTypeReply {
AlgorithmType algorithmType = 1;
}

message ListAlgorithmTypeRequest {
int64 pageIndex = 1;
int64 pageSize = 2[(validate.rules).int64 = {lt:100}];
}

message ListAlgorithmTypeReply {
int64 totalSize = 1;
repeated AlgorithmType algorithmTypes = 2;
}

message GetAlgorithmTypeRequest {
string id = 1;
}

message GetAlgorithmTypeReply {
string id = 1;
string typeDesc = 2;
}

message DeleteAlgorithmTypeRequest {
string id = 1;
}

message DeleteAlgorithmTypeReply {
int64 deletedAt = 1;
}

message UpdateAlgorithmTypeRequest {
string id = 1;
string typeDesc = 2;
}

message UpdateAlgorithmTypeReply {
int64 updatedAt = 1;
}

message AlgorithmFramework {
string id = 1;
string frameworkDesc = 2;
}

message AddAlgorithmFrameworkRequest {
string frameworkDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
}

message AddAlgorithmFrameworkReply {
AlgorithmFramework algorithmFramework = 1;
}

message ListAlgorithmFrameworkRequest {
int64 pageIndex = 1;
int64 pageSize = 2[(validate.rules).int64 = {lt:100}];
}

message ListAlgorithmFrameworkReply {
int64 totalSize = 1;
repeated AlgorithmFramework algorithmFrameworks = 2;
}

message GetAlgorithmFrameworkRequest {
string id = 1;
}

message GetAlgorithmFrameworkReply {
string id = 1;
string frameworkDesc = 2;
}

message DeleteAlgorithmFrameworkRequest {
string id = 1;
}

message DeleteAlgorithmFrameworkReply {
int64 deletedAt = 1;
}

message UpdateAlgorithmFrameworkRequest {
string id = 1;
string frameworkDesc = 2;
}

message UpdateAlgorithmFrameworkReply {
int64 updatedAt = 1;
}

message AlgorithmInfo {
string algorithmId = 1;
string algorithmName = 2;
@@ -210,8 +90,8 @@ message AlgorithmDetail {
int64 fileStatus = 7;
int64 latestCompressed = 8;
string algorithmDescript = 9;
string typeId = 10;
string typeName = 11;
string applyId = 10;
string applyName = 11;
string frameworkId = 12;
string frameworkName = 13;
string path = 14;
@@ -390,7 +270,7 @@ message AddAlgorithmRequest {
string algorithmName = 5[(validate.rules).string = {min_len:1,max_len:128}];
string modelName = 6[(validate.rules).string = {min_len:1,max_len:128}];
string algorithmDescript = 7[(validate.rules).string = {max_len: 300}];
string typeId = 8;
string applyId = 8;
string frameworkId = 9;
}
message AddAlgorithmReply {
@@ -420,7 +300,7 @@ message CopyAlgorithmVersionRequest {
string newAlgorithmName = 5[(validate.rules).string = {min_len:1,max_len:128}];
string modelName = 6[(validate.rules).string = {min_len:1,max_len:128}];
string algorithmDescript = 7[(validate.rules).string = {max_len: 300}];
string typeId = 8;
string applyId = 8;
string frameworkId = 9;
}
message CopyAlgorithmVersionReply {
@@ -442,7 +322,7 @@ message ConfirmUploadAlgorithmReply {

message UpdateAlgorithmRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string typeId = 2;
string applyId = 2;
string frameworkId = 3;
string algorithmDescript = 4[(validate.rules).string = {max_len: 300}];
}


+ 8
- 64
server/base-server/api/v1/dataset.proto View File

@@ -9,17 +9,6 @@ option go_package = "server/base-server/api/v1;v1";
import "validate/validate.proto";

service DatasetService {
// 新增数据集类型
rpc AddDatasetType (AddDatasetTypeRequest) returns (AddDatasetTypeReply);
// 查询数据集类型列表
rpc ListDatasetType (ListDatasetTypeRequest) returns (ListDatasetTypeReply);
// 查询单个数据集类型
rpc GetDatasetType (GetDatasetTypeRequest) returns (GetDatasetTypeReply);
// 删除数据集类型
rpc DeleteDatasetType (DeleteDatasetTypeRequest) returns (DeleteDatasetTypeReply);
// 修改数据集类型描述
rpc UpdateDatasetType (UpdateDatasetTypeRequest) returns (UpdateDatasetTypeReply);

// 创建数据集
rpc CreateDataset (CreateDatasetRequest) returns (CreateDatasetReply);
// 查询数据集列表
@@ -72,62 +61,14 @@ enum DatasetVersionStatus {
DVS_UnzipFailed = 4;
}

message DatasetType {
string id = 1;
string typeDesc = 2;
}

message AddDatasetTypeRequest {
string typeDesc = 1[(validate.rules).string = {min_len: 1, max_len: 128}];
}

message AddDatasetTypeReply {
DatasetType datasetType = 1;
}

message ListDatasetTypeRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
}

message ListDatasetTypeReply {
int64 totalSize = 1;
repeated DatasetType datasetTypes = 2;
}

message GetDatasetTypeRequest {
string id = 1;
}

message GetDatasetTypeReply {
string id = 1;
string typeDesc = 2;
}

message DeleteDatasetTypeRequest {
string id = 1;
}

message DeleteDatasetTypeReply {
int64 deletedAt = 1;
}

message UpdateDatasetTypeRequest {
string id = 1;
string typeDesc = 2;
}

message UpdateDatasetTypeReply {
int64 updatedAt = 1;
}

message CreateDatasetRequest {
string spaceId = 1;
string userId = 2;
DatasetSourceType sourceType = 3[(validate.rules).enum = {in: [1,2]}];
string name = 4[(validate.rules).string = {min_len: 1}];
string typeId = 5;
string desc = 6[(validate.rules).string = {max_len: 300}];
string applyId = 6;
string desc = 7[(validate.rules).string = {max_len: 300}];
}

message CreateDatasetReply {
@@ -160,8 +101,10 @@ message Dataset {
string name = 7;
string typeId = 8;
string typeDesc = 9;
string desc = 10;
string latestVersion = 11;
string applyId = 10;
string applyDesc = 11;
string desc = 12;
string latestVersion = 13;
}

message ListDatasetReply {
@@ -251,7 +194,8 @@ message DeleteDatasetReply {
message UpdateDatasetRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string typeId = 2;
string desc = 3[(validate.rules).string = {max_len: 300}];
string applyId = 3;
string desc = 4[(validate.rules).string = {max_len: 300}];
}

message UpdateDatasetReply {


+ 1
- 1
server/base-server/api/v1/image.proto View File

@@ -8,7 +8,7 @@ option go_package = "server/base-server/api/v1;v1";

import "validate/validate.proto";

service Image {
service ImageService {
// 查询预置镜像列表
rpc ListPreImage (ListPreImageRequest) returns (ListPreImageReply);
// 查询用户镜像列表


+ 206
- 0
server/base-server/api/v1/jointcloud.proto View File

@@ -0,0 +1,206 @@
syntax = "proto3";

package baseserver.api.v1;

option go_package = "server/base-server/api/v1;v1";



import "validate/validate.proto";

service JointCloudService {
// 查询数据集列表
rpc ListJointCloudDataset (ListJointCloudDatasetRequest) returns (ListJointCloudDatasetReply);
// 查询数据集版本列表
rpc ListJointCloudDatasetVersion (ListJointCloudDatasetVersionRequest) returns (ListJointCloudDatasetVersionReply);
// 查询训练框架
rpc ListJointCloudFramework (ListJointCloudFrameworkRequest) returns (ListJointCloudFrameworkReply);
// 查询训练框架版本
rpc ListJointCloudFrameworkVersion (ListJointCloudFrameworkVersionRequest) returns (ListJointCloudFrameworkVersionReply);
// 查询训练解释器
rpc ListJointCloudInterpreter (ListJointCloudInterpreterRequest) returns (ListJointCloudInterpreterReply);
// 查询训练解释器版本
rpc ListJointCloudInterpreterVersion (ListJointCloudInterpreterVersionRequest) returns (ListJointCloudInterpreterVersionReply);
//创建训练任务
rpc TrainJob (JointCloudTrainJobRequest) returns (JointCloudTrainJobReply);
// 查询任务列表
rpc ListJointCloudJob (ListJointCloudJobRequest) returns (ListJointCloudJobReply);
//停止训练任务
rpc StopJob (JointCloudStopJobRequest) returns (JointCloudStopJobReply);
}

message ListJointCloudDatasetRequest {
int32 pageIndex = 1;
int32 pageSize = 2;
}

message ListJointCloudDatasetReply {
message DataSet {
string dataSetCode = 1;
string name = 2;
string remark = 3;
}
int64 totalSize = 1;
repeated DataSet dataSets = 2;
}

message ListJointCloudDatasetVersionRequest {
int32 pageIndex = 1;
int32 pageSize = 2;
string dataSetCode = 3;
}

message ListJointCloudDatasetVersionReply {
message DataSetVersion {
string version = 1;
string remark = 2;
}
int64 totalSize = 1;
repeated DataSetVersion versions = 2;
}

message ListJointCloudFrameworkRequest {

}

message ListJointCloudFrameworkReply {
message Framework {
string key = 1;
string value = 2;
}
repeated Framework frameworks = 1;
}

message ListJointCloudFrameworkVersionRequest {
string key = 1;
}

message ListJointCloudFrameworkVersionReply {
message Version {
string key = 1;
string value = 2;
}
repeated Version versions = 1;
}

message ListJointCloudInterpreterRequest {

}

message ListJointCloudInterpreterReply {
message Interpreter {
string key = 1;
string value = 2;
}
repeated Interpreter interpreters = 1;
}

message ListJointCloudInterpreterVersionRequest {
string key = 1;
}

message ListJointCloudInterpreterVersionReply {
message Version {
string key = 1;
string value = 2;
}
repeated Version versions = 1;
}

message JointCloudTrainJobRequest {
string taskName = 1[(validate.rules).string = {min_len: 1, max_len: 150}];
string execCommand = 2[(validate.rules).string = {max_len: 300}];
string interpreter = 3;
string framework = 4;
string outputPath = 5;
repeated JointCloudDataSetVersionVo dataSetVersionVoList = 6;
repeated JointCloudParam params = 7;
repeated JointCloudResourceParam resourceParams = 8;
string remark = 9;
string userId = 10;
string workspaceId = 11;
}

message JointCloudTrainJobReply {
string jobId = 1;
string taskId = 2;
}

message JointCloudDataSetVersionVo {
string dataSetName = 1;
string dataSetCode = 2;
string version = 3;
string path = 4;
}

message JointCloudParam {
string key = 1;
string value = 2;
}

message JointCloudResourceParam {
string name = 1;
int32 size = 2;
string type = 3;
string unit = 4;
}

message ListJointCloudJobRequest {
int32 pageIndex = 1;
int32 pageSize = 2;
string ids = 3;
string spaceId = 4;
string userId = 5;
}
message ListJointCloudJobReply {
int32 totalSize = 1;
repeated JointCloudJReplyJob list = 2;
}

message JointCloudJReplyJob {
string taskId = 1;
string taskName = 2;
string interpreter = 3;
string framework = 4;
int64 cloudVendorId = 5;
string cloudVendorName = 6;
string imageUrl = 7;
int64 creator = 8;
string creatorName = 9;
string execCommand = 10;
string outputPath = 11;
int64 status = 12;
string remark = 13;
string jobId = 14;
int64 createTime = 15;
string userId = 16;
string workspaceId = 17;
repeated JointCloudReplyDataSetVersionVo dataSetList = 18;
repeated JointCloudParam taskParams = 19;
repeated JointCloudResourceParam resourceParams = 20;
}

message JointCloudReplyDataSetVersionVo {
string category = 1;
string dataSetCode = 2;
string version = 3;
string remark = 4;
string name = 5;
int64 cloudVendorId = 6;
string cloudVendorName = 7;
int64 versionNumber = 8;
string label = 9;
int64 creator = 10;
int64 createTime = 11;
}

message JointCloudStopJobRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string platformId = 2;
string operation = 3;
}

message JointCloudStopJobReply {
int64 stoppedAt = 1;
}

+ 120
- 0
server/base-server/api/v1/lable.proto View File

@@ -0,0 +1,120 @@
syntax = "proto3";

package baseserver.api.v1;

option go_package = "server/base-server/api/v1;v1";



import "validate/validate.proto";

service LableService {
// 新增标签
rpc AddLable (AddLableRequest) returns (AddLableReply);
// 查询标签列表
rpc ListLable (ListLableRequest) returns (ListLableReply);
// 查询单个标签
rpc GetLable (GetLableRequest) returns (GetLableReply);
// 删除标签
rpc DeleteLable (DeleteLableRequest) returns (DeleteLableReply);
// 修改标签描述
rpc UpdateLable (UpdateLableRequest) returns (UpdateLableReply);
// 增加标签引用次数
rpc IncreaseLableReferTimes (IncreaseLableReferTimesRequest) returns (IncreaseLableReferTimesReply);
// 减少标签引用次数
rpc ReduceLableReferTimes (ReduceLableReferTimesRequest) returns (ReduceLableReferTimesReply);
}

enum Relegation {
LABLE_RELEGATION_INIT = 0; // 占位
LABLE_RELEGATION_DATASET = 1; // 标签所属模块:数据集
LABLE_RELEGATION_ALGORITHM = 2; // 标签所属模块:算法
}

enum Source {
LABLE_SOURCE_INIT = 0; // 占位
LABLE_SOURCE_PRESET = 1; // 预置标签
LABLE_SOURCE_CUSTOMIZE = 2; // 自定义标签
}

enum Type {
LABLE_TYPE_INIT = 0; // 占位
LABLE_TYPE_DATASET_TYPE = 1; // 标签类型,数据集类型
LABLE_TYPE_DATASET_APPLY = 2; // 标签类型,数据集用途

LABLE_TYPE_ALGORITHM_APPLY = 11; // 标签类型,算法用途
LABLE_TYPE_ALGORITHM_FRAMEWORK = 12; // 标签类型,算法框架
}

message Lable {
string id = 1;
int32 relegationType = 2;
int32 sourceType = 3;
int32 lableType = 4;
string lableDesc = 5;
int32 referTimes = 6;
}

message AddLableRequest {
int32 relegationType = 1;
int32 lableType = 2;
string lableDesc = 3[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message AddLableReply {
Lable lable = 1;
}

message ListLableRequest {
int32 relegationType = 1;
int32 sourceType = 2;
int32 lableType = 3;
int64 pageIndex = 4;
int64 pageSize = 5[(validate.rules).int64 = {gte:1,lt:100}];
}

message ListLableReply {
int64 totalSize = 1;
repeated Lable lables = 2;
}

message GetLableRequest {
string id = 1;
}

message GetLableReply {
Lable lable = 1;
}

message DeleteLableRequest {
string id = 1;
}

message DeleteLableReply {
int64 deletedAt = 1;
}

message UpdateLableRequest {
string id = 1;
string lableDesc = 2[(validate.rules).string = {min_len: 1, max_len: 10}];
}

message UpdateLableReply {
int64 updatedAt = 1;
}

message IncreaseLableReferTimesRequest {
string id = 1;
}

message IncreaseLableReferTimesReply {
int64 updatedAt = 1;
}

message ReduceLableReferTimesRequest {
string id = 1;
}

message ReduceLableReferTimesReply {
int64 updatedAt = 1;
}

+ 1
- 1
server/base-server/api/v1/model.proto View File

@@ -8,7 +8,7 @@ option go_package = "server/base-server/api/v1;v1";

import "validate/validate.proto";

service Model {
service ModelService {
// 查询预置模型列表
rpc ListPreModel (ListPreModelRequest) returns (ListPreModelReply);
// 查询我的模型列表


+ 178
- 0
server/base-server/api/v1/platform.proto View File

@@ -0,0 +1,178 @@
syntax = "proto3";

package baseserver.api.v1;

option go_package = "server/base-server/api/v1;v1";



import "validate/validate.proto";

service PlatformService {
rpc ListPlatform (ListPlatformRequest) returns (ListPlatformReply);
rpc BatchGetPlatform (BatchGetPlatformRequest) returns (BatchGetPlatformReply);
rpc CreatePlatform (CreatePlatformRequest) returns (CreatePlatformReply);
rpc UpdatePlatform (UpdatePlatformRequest) returns (UpdatePlatformReply);
rpc ListPlatformConfigKey (ListPlatformConfigKeyRequest) returns (ListPlatformConfigKeyReply);

rpc ListPlatformStorageConfig (ListPlatformStorageConfigRequest) returns (ListPlatformStorageConfigReply);
rpc CreatePlatformStorageConfig (CreatePlatformStorageConfigRequest) returns (CreatePlatformStorageConfigReply);
rpc DeletePlatformStorageConfig (DeletePlatformStorageConfigRequest) returns (DeletePlatformStorageConfigReply);
rpc GetPlatformStorageConfig (GetPlatformStorageConfigRequest) returns (GetPlatformStorageConfigReply);

rpc GetPlatformConfig (GetPlatformConfigRequest) returns (GetPlatformConfigReply);
rpc UpdatePlatformConfig (UpdatePlatformConfigRequest) returns (UpdatePlatformConfigReply);
}

message ListPlatformRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
string sortBy = 3;
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
int64 createdAtGte = 5;
int64 createdAtLt = 6;
string searchKey = 7;
}

message Platform {
int64 createdAt = 1;
int64 updatedAt = 2;
string id = 3;
string name = 4;
string clientSecret = 5;
string contactName = 6;
string contactInfo = 7;
string resourcePool = 8;
}

message ListPlatformReply {
int64 totalSize = 1;
repeated Platform platforms = 2;
}

message BatchGetPlatformRequest {
repeated string ids = 1;
}

message BatchGetPlatformReply {
repeated Platform platforms = 1;
}

message CreatePlatformRequest {
string name = 1[(validate.rules).string = {min_len: 1}];
string contactName = 2;
string contactInfo = 3;
string resourcePool = 4[(validate.rules).string = {min_len: 1}];
}

message CreatePlatformReply {
string id = 1;
}

message UpdatePlatformRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string contactName = 2;
string contactInfo = 3;
string resourcePool = 4[(validate.rules).string = {min_len: 1}];
}

message UpdatePlatformReply {

}

message ListPlatformConfigKeyRequest {

}

message ListPlatformConfigKeyReply {
message ConfigKey {
string key = 1; // 键值,必填,保存配置时传入
string title = 2; // 标题,必填
string type = 3; // 类型,选填,input、radio、checkbox,默认为input
string desc = 4; // 描述,选填
string options = 5; // 选项,选填,radio、checkbox时必填,逗号分隔
string regexp = 6; // 正则,选填
bool required = 7; // 选填,默认为false
}
repeated ConfigKey configKeys = 1;
}

message StorageOptions {
message Juicefs {
string name = 1;
string metaUrl = 2;
}

Juicefs juicefs = 1;
}

message ListPlatformStorageConfigRequest {
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
string sortBy = 3;
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
int64 createdAtGte = 5;
int64 createdAtLt = 6;
string searchKey = 7;
string platformId = 8;
string name = 9;
}

message PlatformStorageConfig {
int64 createdAt = 1;
int64 updatedAt = 2;
string platformId = 3;
string name = 4;
string type = 5;
StorageOptions options = 6;
}

message ListPlatformStorageConfigReply {
int64 totalSize = 1;
repeated PlatformStorageConfig platformStorageConfigs = 2;
}

message CreatePlatformStorageConfigRequest {
string platformId = 1[(validate.rules).string = {min_len: 1}];
string name = 2[(validate.rules).string = {min_len: 1, not_contains: "/"}];
string type = 3[(validate.rules).string = {in: ["juicefs"]}];
StorageOptions options = 4;
}

message CreatePlatformStorageConfigReply {
}

message DeletePlatformStorageConfigRequest {
string platformId = 1;
string name = 2;
}

message DeletePlatformStorageConfigReply {

}

message GetPlatformStorageConfigRequest {
string platformId = 1;
string name = 2;
}

message GetPlatformStorageConfigReply {
PlatformStorageConfig platformStorageConfig = 1;
}

message GetPlatformConfigRequest {
string platformId = 1;
}

message GetPlatformConfigReply {
map<string, string> config = 1;
}

message UpdatePlatformConfigRequest {
string platformId = 1[(validate.rules).string = {min_len: 1}];
map<string, string> config = 2[(validate.rules).map.min_pairs = 1];
}

message UpdatePlatformConfigReply {

}

+ 218
- 0
server/base-server/api/v1/platformtrainJob.proto View File

@@ -0,0 +1,218 @@
syntax = "proto3";

package baseserver.api.v1;

option go_package = "server/base-server/api/v1;v1";



import "validate/validate.proto";

service PlatformTrainJobService {
//创建训练任务
rpc TrainJob (PlatformTrainJobRequest) returns (PlatformTrainJobReply);
//停止训练任务
rpc StopJob (PlatformStopJobRequest) returns (PlatformStopJobReply);
//获取训练任务详情
rpc GetTrainJobInfo(PlatformTrainJobInfoRequest) returns (PlatformTrainJobInfoReply);
//获取训练任务列表
rpc TrainJobList(PlatformTrainJobListRequest) returns (PlatformTrainJobListReply);
//获取训练任务统计信息
rpc TrainJobStastics(TrainJobStasticsRequest) returns (TrainJobStasticsReply);
//获取集群资源信息
rpc PlatformResources(PlatformResourcesRequest) returns (PlatformResourcesReply);
}


message PlatformTrainJobRequest {
//训练任务名称,必填,长度1-30
string name = 1[(validate.rules).string = {min_len: 1, max_len: 30}];
//训练任务描述,非必填
string desc = 2[(validate.rules).string = {max_len: 300}];
//platformId
string platformId = 3;
//resourcepool
string resourcePool = 4;
//镜像信息
PlatformImage image = 5;
//输出信息
PlatformOutput output = 6;
//数据集信息
repeated PlatformDataset datasets = 7;
//子任务信息
repeated PlatformTask tasks = 8;
}

message PlatformOutput {
//存储配置名称,必填
string storageConfigName = 1[(validate.rules).string = {max_len: 30}];
//存储子目录
string addr = 2[(validate.rules).string = {max_len: 300}];
//容器内输出路径
string path = 3[(validate.rules).string = {max_len: 300}];
}


message PlatformImage {
string name = 1[(validate.rules).string = {min_len: 1, max_len: 300}];
string version = 2[(validate.rules).string = {min_len: 1, max_len: 30}];
}

message PlatformDataset {
//存储配置名称,必填
string storageConfigName = 1[(validate.rules).string = {max_len: 30}];
//数据集子目录
string addr = 2[(validate.rules).string = {max_len: 300}];
//数据集名称,必填
string name = 3[(validate.rules).string = {max_len: 300}];
//数据集容器内路径
string path = 4[(validate.rules).string = {max_len: 300}];;
}

message PlatformTask {
//子任务名称,非必填,校验规则"^[0-9a-zA-Z_]*$",最大长度30个字符
string name = 1[(validate.rules).string = {min_len: 1, max_len:30}];
//子任务执行命令
string command = 2[(validate.rules).string = {min_len: 0, max_len: 300}];
//command执行命令参数,key-value,数组
repeated PlatformParameter parameters = 3;
//资源
repeated PlatformResource resources = 4;
//副本个数,非必填
int64 taskNumber = 5[(validate.rules).int64 = {gte:1}];
//子任务最小失败数,非必填
int64 minFailedTaskCount = 6[(validate.rules).int64 = {gte:1}];
//子任务最小成功数,非必填
int64 minSucceededTaskCount = 7[(validate.rules).int64 = {gte:1}];
//是否主任务,非必填
bool isMainRole = 8;
}

message PlatformResource {
//命令参数key,必填
string name = 1;
//命令参数value,必填
string size = 2;
}

message PlatformParameter {
string key = 1;
string value = 2;
}

message PlatformTrainJobReply {
string jobId = 1;
}

message PlatformStopJobRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
string platformId = 2;
string operation = 3;
}

message PlatformStopJobReply {
int64 stoppedAt = 1;
}

message PlatformTrainJobListRequest{
// 页码,从1开始,非必填
int64 pageIndex = 1[(validate.rules).int64 = {gte:1}];
// 页大小,最小1条,最大100条,非必填
int64 pageSize = 2[(validate.rules).int64 = {gte:1,lt:100}];
// 分组依据,非必填
string sortBy = 3;
//升序、降序,非必填
string orderBy = 4[(validate.rules).string = {in: ["", "asc", "desc"]}];
//大于某个时间创建,非必填
int64 createdAtGte = 5;
//小于某个时间创建,非必填
int64 createdAtLt = 6;
//状态查询,非必填
string status = 7;
//模糊查找字段,可用于name等模糊查找,非必填
string searchKey = 8;
string platformId = 9;
}

message PlatformTrainJobListReply {
int64 totalSize = 1;
repeated PlatformTrainJob trainJobs = 2;
}


message PlatformTrainJob{
//任务ID
string id = 1;
//job名称
string name = 2;
//platformId
string platformId = 3;
//job描述
string desc = 4;
//数据集
repeated PlatformDataset datasets = 5;
//镜像
PlatformImage image = 6;
//子任务配置信息
repeated PlatformTask tasks = 7;
//创建时间
int64 createdAt = 8;
//更新时间
int64 updatedAt = 9;
//任务状态
string status = 10;
//job完成时间
int64 completedAt = 11;
//运行时
int64 runSec = 12;
//启动时间
int64 startedAt = 13;
}


message PlatformTrainJobInfoRequest {
string id = 1[(validate.rules).string = {min_len: 1}];
}

message PlatformTrainJobInfoReply{
PlatformTrainJob trainJob = 1;
}

message TrainJobStasticsRequest {
//大于某个时间创建,非必填
int64 createdAtGte = 5;
//小于某个时间创建,非必填
int64 createdAtLt = 6;
}

message TrainJobStasticsReply {
//任务数量
int64 totalSize = 1;
//成功数量
int64 succeededSize = 2;
//失败数量
int64 failedSize = 3;
//停止数量
int64 stoppedSize = 4;
//正在运行数量
int64 runningSize = 5;
//等待数量
int64 waitingSize = 6;

}

message PlatformNode {
string nodeName = 1;
string ip = 2;
string status = 3;
map<string,string> capacity = 4;
map<string,string> allocated = 5;
}

message PlatformResourcesRequest {
string resourcePool = 1;
}

message PlatformResourcesReply {
repeated PlatformNode resources = 1;
}

+ 39
- 1
server/base-server/api/v1/user.proto View File

@@ -8,12 +8,16 @@ option go_package = "server/base-server/api/v1;v1";

import "validate/validate.proto";

service User {
service UserService {
rpc ListUser (ListUserRequest) returns (ListUserReply);
rpc FindUser (FindUserRequest) returns (FindUserReply);
rpc AddUser (AddUserRequest) returns (AddUserReply);
rpc UpdateUser (UpdateUserRequest) returns (UpdateUserReply);
rpc ListUserInCond (ListUserInCondRequest) returns (ListUserInCondReply);

rpc ListUserConfigKey (ListUserConfigKeyRequest) returns (ListUserConfigKeyReply);
rpc GetUserConfig (GetUserConfigRequest) returns (GetUserConfigReply);
rpc UpdateUserConfig (UpdateUserConfigRequest) returns (UpdateUserConfigReply);
}

enum UserStatus
@@ -101,4 +105,38 @@ message ListUserInCondRequest {

message ListUserInCondReply {
repeated UserItem users = 1;
}

message ListUserConfigKeyRequest {

}

message ListUserConfigKeyReply {
message ConfigKey {
string key = 1; // 键值,必填,保存配置时传入
string title = 2; // 标题,必填
string type = 3; // 类型,必填,input、radio、checkbox,默认为input
string desc = 4; // 描述,选填
string options = 5; // 选项,选填,radio、checkbox时必填,逗号分隔
string regexp = 6; // 正则,选填
bool required = 7; // 选填,默认为false
}
repeated ConfigKey configKeys = 1;
}

message GetUserConfigRequest {
string userId = 1;
}

message GetUserConfigReply {
map<string, string> config = 1;
}

message UpdateUserConfigRequest {
string userId = 1[(validate.rules).string = {min_len: 1}];
map<string, string> config = 2[(validate.rules).map.min_pairs = 1];
}

message UpdateUserConfigReply {

}

+ 1
- 1
server/base-server/api/v1/workspace.proto View File

@@ -8,7 +8,7 @@ option go_package = "server/base-server/api/v1;v1";

import "validate/validate.proto";

service Workspace {
service WorkspaceService {
rpc CreateWorkspace (CreateWorkspaceRequest) returns (CreateWorkspaceReply);
rpc UpdateWorkspace (UpdateWorkspaceRequest) returns (UpdateWorkspaceReply);
rpc DeleteWorkspace (DeleteWorkspaceRequest) returns (DeleteWorkspaceReply);


+ 4
- 2
server/base-server/cmd/base-server/main.go View File

@@ -17,9 +17,10 @@ import (

"server/common/log"

"server/common/third_party/kratos/config"
"server/common/third_party/kratos/config/file"

"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/transport/grpc"
"gopkg.in/yaml.v2"

@@ -48,6 +49,7 @@ func init() {
flag.StringVar(&flagconf, "conf", "", "config path, eg: -conf config.yaml")
}

// marshalJson error, when values contains map[interface{}]interface{}. 临时修改代码后放入third_party, 后续升级kratos解决
func main() {
flag.Parse()
if v {


+ 25
- 0
server/base-server/configs/config.yaml View File

@@ -47,6 +47,11 @@ data:
username: octopus
password: octopus
database: octopus
jointCloud:
baseUrl: http://192.168.207.141:8709
username: test
password: 7ee15bc8fee766cad1bd70ccf5f4dc14
sessionExpirySec: 540 #实际有效期为600
service:
baseServerAddr: http://127.0.0.1:8001
dockerDatasetPath: /dataset
@@ -69,6 +74,26 @@ service:
discoveryLeaderLeaseLockName: resourcediscovery
discoveryDuration: 15s
ignoreSystemResources: hugepages-1Gi,pods,hugepages-2Mi,ephemeral-storage
platform:
# 数组内字段为
# key:键值,必填,保存配置时传入
# title:标题,必填
# type:类型,必填,input、radio、checkbox
# desc:描述,选填
# options:选项,选填,radio、checkbox时必填,逗号分隔
# regexp:正则,选填
# required: 选填,默认为false
configKeys:
- key: jobStatusCallbackAddr
title: 任务状态回调地址
type: input
user:
# 参考平台配置
configKeys:
- key: jointCloudPermission
title: 云际权限
type: radio
options: yes,no
administrator:
username: "admin"
password: "123456"


+ 7
- 0
server/base-server/internal/common/constant.go View File

@@ -3,3 +3,10 @@ package common
const (
BillingPrecision = 2
)

const (
StorageTypeJuicefs string = "juicefs"
ConfigKeyTypeInput string = "input"
ConfigKeyTypeRadio string = "radio"
ConfigKeyTypeCheckBox string = "checkbox"
)

+ 29
- 0
server/base-server/internal/conf/conf.go View File

@@ -0,0 +1,29 @@
package conf

import (
"regexp"
"server/base-server/internal/common"
"server/common/errors"
"server/common/utils"
"strings"
)

func (k *ConfigKey) ValidateValue(v string) error {
if k.Required && v == "" {
return errors.Errorf(nil, errors.ErrorConfigValueValidateFailed)
}

if (k.Type == common.ConfigKeyTypeRadio || k.Type == common.ConfigKeyTypeCheckBox) && v != "" &&
!utils.StringSliceContainsValue(strings.Split(k.Options, ","), v) {
return errors.Errorf(nil, errors.ErrorConfigValueValidateFailed)
}

if k.Regexp != "" {
matched, err := regexp.MatchString(k.Regexp, v)
if err != nil || !matched {
return errors.Errorf(nil, errors.ErrorConfigValueValidateFailed)
}
}

return nil
}

+ 28
- 0
server/base-server/internal/conf/conf.proto View File

@@ -95,6 +95,7 @@ message Data {
Harbor harbor = 5;
Redis redis = 6;
Influxdb influxdb = 7;
JointCloud jointCloud = 8;
}

message Develop {
@@ -116,6 +117,31 @@ message Resource {
string ignoreSystemResources = 11;
}

message ConfigKey {
string key = 1; // 键值,必填,保存配置时传入
string title = 2; // 标题,必填
string desc = 3; // 描述,选填
string type = 4; // 类型,选填,input、radio、checkbox,默认为input radio
string options = 5; // 选项,选填,radio、checkbox时必填,逗号分隔 yes,no
string regexp = 6; // 正则,选填
bool required = 7; // 选填,默认为false
}

message Platform {
repeated ConfigKey configKeys = 1;
}

message User {
repeated ConfigKey configKeys = 1;
}

message JointCloud {
string baseUrl = 1;
string username = 2;
string password = 3;
int32 sessionExpirySec = 4;
}

message Service {
string baseServerAddr = 2;
string dockerDatasetPath = 3;
@@ -125,6 +151,8 @@ message Service {
Resource resource = 7;
string resourceLabelKey = 8;
int64 billingPeriodSec = 9;
Platform platform = 10;
User user = 11;
}

message Administrator {


+ 4
- 0
server/base-server/internal/data/cluster/cluster.go View File

@@ -31,4 +31,8 @@ type Cluster interface {
CreateAndListenJob(ctx context.Context, job *batchv1.Job, callback func(e error)) error
CreatePersistentVolume(ctx context.Context, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
CreatePersistentVolumeClaim(ctx context.Context, pvc *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error)
CreateSecret(ctx context.Context, secret *v1.Secret) (*v1.Secret, error)
DeletePersistentVolume(ctx context.Context, name string) error
DeletePersistentVolumeClaim(ctx context.Context, namespace string, name string) error
DeleteSecret(ctx context.Context, namespace string, name string) error
}

+ 31
- 0
server/base-server/internal/data/cluster/kubernetes.go View File

@@ -403,3 +403,34 @@ func (kc *kubernetesCluster) CreatePersistentVolumeClaim(ctx context.Context, pv
}
return p, nil
}
func (kc *kubernetesCluster) CreateSecret(ctx context.Context, secret *v1.Secret) (*v1.Secret, error) {
p, err := kc.kubeclient.CoreV1().Secrets(secret.Namespace).Create(ctx, secret, metav1.CreateOptions{})
if err != nil {
return nil, err
}
return p, nil
}

func (kc *kubernetesCluster) DeletePersistentVolume(ctx context.Context, name string) error {
err := kc.kubeclient.CoreV1().PersistentVolumes().Delete(ctx, name, metav1.DeleteOptions{})
if err != nil {
return errors.Errorf(err, errors.ErrorK8sDeletePVFailed)
}
return nil
}

func (kc *kubernetesCluster) DeletePersistentVolumeClaim(ctx context.Context, namespace string, name string) error {
err := kc.kubeclient.CoreV1().PersistentVolumeClaims(namespace).Delete(ctx, name, metav1.DeleteOptions{})
if err != nil {
return errors.Errorf(err, errors.ErrorK8sDeletePVCFailed)
}
return nil
}

func (kc *kubernetesCluster) DeleteSecret(ctx context.Context, namespace string, name string) error {
err := kc.kubeclient.CoreV1().Secrets(namespace).Delete(ctx, name, metav1.DeleteOptions{})
if err != nil {
return errors.Errorf(err, errors.ErrorK8sDeleteSecretFailed)
}
return nil
}

+ 0
- 111
server/base-server/internal/data/dao/algorithm_dao/algorithm_framework.go View File

@@ -1,111 +0,0 @@
package algorithm_dao

import (
"context"
"server/base-server/internal/data/dao/model"
"server/common/errors"

stderrors "errors"

"gorm.io/gorm"
)

// 新增算法类型
func (d *algorithmDao) AddAlgorithmFramework(ctx context.Context, req *model.AlgorithmFramework) error {
db := d.db.Model(&model.AlgorithmFramework{})
db = db.Create(req)
if db.Error != nil {
return errors.Errorf(db.Error, errors.ErrorDBCreateFailed)
}

return nil
}

// 查询算法类型列表
func (d *algorithmDao) ListAlgorithmFramework(ctx context.Context, req *model.AlgorithmFrameworkQuery) ([]*model.AlgorithmFramework, int64, error) {
db := d.db.Model(&model.AlgorithmFramework{})
algorithmFrameworks := make([]*model.AlgorithmFramework, 0)

var totalSize int64
res := db.Count(&totalSize)
if res.Error != nil {
return nil, 0, errors.Errorf(res.Error, errors.ErrorDBCountFailed)
}

if req.PageIndex != 0 {
db = db.Limit(req.PageSize).Offset((req.PageIndex - 1) * req.PageSize)
}

res = db.Find(&algorithmFrameworks)
if res.Error != nil {
return nil, 0, errors.Errorf(res.Error, errors.ErrorDBFindFailed)
}

return algorithmFrameworks, totalSize, nil
}

// 查询单个算法类型
func (d *algorithmDao) GetAlgorithmFramework(ctx context.Context, id string) (*model.AlgorithmFramework, error) {
db := d.db

nb := &model.AlgorithmFramework{}
res := db.First(nb, "id = ?", id)

if res.Error != nil {
if stderrors.Is(res.Error, gorm.ErrRecordNotFound) {
return nil, errors.Errorf(res.Error, errors.ErrorDBFindEmpty)
} else {
return nil, errors.Errorf(res.Error, errors.ErrorDBFirstFailed)
}
}
return nb, nil
}

func (d *algorithmDao) QueryAlgorithmFramework(ctx context.Context, FrameworkDesc string) (*model.AlgorithmFramework, error) {
db := d.db

nb := &model.AlgorithmFramework{}
res := db.First(nb, "`desc` = ?", FrameworkDesc)

if res.Error != nil {
if stderrors.Is(res.Error, gorm.ErrRecordNotFound) {
return nil, errors.Errorf(res.Error, errors.ErrorDBFindEmpty)
} else {
return nil, errors.Errorf(res.Error, errors.ErrorDBFirstFailed)
}
}
return nb, nil
}

// 删除算法类型
func (d *algorithmDao) DeleteAlgorithmFramework(ctx context.Context, id string) error {
db := d.db

if id == "" {
return errors.Errorf(nil, errors.ErrorInvalidRequestParameter)
}

res := db.Where("id = ? ", id).Delete(&model.AlgorithmFramework{})
if res.Error != nil {
return errors.Errorf(nil, errors.ErrorDBDeleteFailed)
}

return nil
}

// 修改算法类型描述
func (d *algorithmDao) UpdateAlgorithmFramework(ctx context.Context, req *model.AlgorithmFramework) error {
db := d.db
if req.Id == "" {
return errors.Errorf(nil, errors.ErrorInvalidRequestParameter)
}
res := db.Model(&model.AlgorithmFramework{}).Where("id = ? ", req.Id).Updates(map[string]interface{}{
"desc": req.Desc,
"refer_times": req.ReferTimes,
})

if res.Error != nil {
return errors.Errorf(res.Error, errors.ErrorDBUpdateFailed)
}
return nil
}

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

Loading…
Cancel
Save