| @@ -0,0 +1,39 @@ | |||||
| package com.ruoyi.platform.controller.aim; | |||||
| import com.ruoyi.common.core.web.controller.BaseController; | |||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | |||||
| import com.ruoyi.platform.service.AimService; | |||||
| import com.ruoyi.platform.service.TensorBoardService; | |||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| import com.ruoyi.platform.vo.TensorboardStatusVo; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | |||||
| import org.springframework.web.bind.annotation.PostMapping; | |||||
| import org.springframework.web.bind.annotation.RequestBody; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| import javax.annotation.Resource; | |||||
| @RestController | |||||
| @RequestMapping("aim") | |||||
| @Api("Aim管理") | |||||
| public class AimController extends BaseController { | |||||
| @Resource | |||||
| private AimService aimService; | |||||
| /** | |||||
| * 启动tensorBoard接口 | |||||
| * | |||||
| * @param frameLogPathVo 存储路径 | |||||
| * @return url | |||||
| */ | |||||
| @PostMapping("/run") | |||||
| @ApiOperation("启动aim`") | |||||
| @ApiResponse | |||||
| public GenericsAjaxResult<String> runAim(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception { | |||||
| return genericsSuccess(aimService.runAim(frameLogPathVo)); | |||||
| } | |||||
| } | |||||
| @@ -5,6 +5,7 @@ import com.ruoyi.common.core.web.domain.AjaxResult; | |||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | ||||
| import com.ruoyi.platform.service.JupyterService; | import com.ruoyi.platform.service.JupyterService; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | import com.ruoyi.platform.vo.FrameLogPathVo; | ||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||||
| @@ -56,6 +57,13 @@ public class JupyterController extends BaseController { | |||||
| return genericsSuccess(this.jupyterService.stopJupyterService(id)); | return genericsSuccess(this.jupyterService.stopJupyterService(id)); | ||||
| } | } | ||||
| @PostMapping("/getStatus") | |||||
| @ApiOperation("查询jupyter pod状态") | |||||
| @ApiResponse | |||||
| public GenericsAjaxResult<PodStatusVo> getStatus(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception { | |||||
| return genericsSuccess(this.jupyterService.getJupyterStatus(frameLogPathVo)); | |||||
| } | |||||
| @GetMapping(value = "/upload") | @GetMapping(value = "/upload") | ||||
| public AjaxResult upload() throws Exception { | public AjaxResult upload() throws Exception { | ||||
| @@ -4,7 +4,7 @@ import com.ruoyi.common.core.web.controller.BaseController; | |||||
| import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | import com.ruoyi.common.core.web.domain.GenericsAjaxResult; | ||||
| import com.ruoyi.platform.service.TensorBoardService; | import com.ruoyi.platform.service.TensorBoardService; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | import com.ruoyi.platform.vo.FrameLogPathVo; | ||||
| import com.ruoyi.platform.vo.TensorboardStatusVo; | |||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||||
| @@ -37,7 +37,7 @@ public class TensorBoardController extends BaseController { | |||||
| } | } | ||||
| @PostMapping("/getStatus") | @PostMapping("/getStatus") | ||||
| @ApiResponse | @ApiResponse | ||||
| public GenericsAjaxResult<TensorboardStatusVo> getStatus(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception { | |||||
| public GenericsAjaxResult<PodStatusVo> getStatus(@RequestBody FrameLogPathVo frameLogPathVo) throws Exception { | |||||
| return genericsSuccess(tensorBoardService.getTensorBoardStatus(frameLogPathVo)); | return genericsSuccess(tensorBoardService.getTensorBoardStatus(frameLogPathVo)); | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,7 @@ | |||||
| package com.ruoyi.platform.service; | |||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| public interface AimService { | |||||
| String runAim(FrameLogPathVo frameLogPathVo); | |||||
| } | |||||
| @@ -1,6 +1,7 @@ | |||||
| package com.ruoyi.platform.service; | package com.ruoyi.platform.service; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | import com.ruoyi.platform.vo.FrameLogPathVo; | ||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| @@ -14,4 +15,6 @@ public interface JupyterService { | |||||
| String runJupyterService(Integer id); | String runJupyterService(Integer id); | ||||
| String stopJupyterService(Integer id) throws Exception; | String stopJupyterService(Integer id) throws Exception; | ||||
| PodStatusVo getJupyterStatus(FrameLogPathVo frameLogPathVo); | |||||
| } | } | ||||
| @@ -1,12 +1,12 @@ | |||||
| package com.ruoyi.platform.service; | package com.ruoyi.platform.service; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | import com.ruoyi.platform.vo.FrameLogPathVo; | ||||
| import com.ruoyi.platform.vo.TensorboardStatusVo; | |||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| public interface TensorBoardService { | public interface TensorBoardService { | ||||
| TensorboardStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo); | |||||
| PodStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo); | |||||
| /** | /** | ||||
| * 在集群中启动TensorBoard容器,并且返回地址,4小时后销毁 | * 在集群中启动TensorBoard容器,并且返回地址,4小时后销毁 | ||||
| * @param frameLogPathVo | * @param frameLogPathVo | ||||
| @@ -0,0 +1,13 @@ | |||||
| package com.ruoyi.platform.service.impl; | |||||
| import com.ruoyi.platform.service.AimService; | |||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| import org.springframework.stereotype.Service; | |||||
| @Service | |||||
| public class AimServiceImpl implements AimService { | |||||
| @Override | |||||
| public String runAim(FrameLogPathVo frameLogPathVo) { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -30,10 +30,6 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||||
| private DevEnvironmentDao devEnvironmentDao; | private DevEnvironmentDao devEnvironmentDao; | ||||
| @Resource | |||||
| private JupyterService jupyterService; | |||||
| /** | /** | ||||
| * 通过ID查询单条数据 | * 通过ID查询单条数据 | ||||
| * | * | ||||
| @@ -10,9 +10,13 @@ import com.ruoyi.platform.utils.JacksonUtil; | |||||
| import com.ruoyi.platform.utils.K8sClientUtil; | import com.ruoyi.platform.utils.K8sClientUtil; | ||||
| import com.ruoyi.platform.utils.MinioUtil; | import com.ruoyi.platform.utils.MinioUtil; | ||||
| import com.ruoyi.platform.utils.MlflowUtil; | import com.ruoyi.platform.utils.MlflowUtil; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | |||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| import com.ruoyi.system.api.model.LoginUser; | import com.ruoyi.system.api.model.LoginUser; | ||||
| import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim; | import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim; | ||||
| import io.kubernetes.client.openapi.models.V1Pod; | |||||
| import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.context.annotation.Lazy; | |||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||
| @@ -49,6 +53,7 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| private DevEnvironmentDao devEnvironmentDao; | private DevEnvironmentDao devEnvironmentDao; | ||||
| @Resource | @Resource | ||||
| @Lazy | |||||
| private DevEnvironmentService devEnvironmentService; | private DevEnvironmentService devEnvironmentService; | ||||
| @Resource | @Resource | ||||
| @@ -71,6 +76,9 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| @Override | @Override | ||||
| public String runJupyterService(Integer id) { | public String runJupyterService(Integer id) { | ||||
| DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); | DevEnvironment devEnvironment = this.devEnvironmentDao.queryById(id); | ||||
| if(devEnvironment == null){ | |||||
| } | |||||
| String envName = devEnvironment.getName(); | String envName = devEnvironment.getName(); | ||||
| //TODO 设置环境变量 | //TODO 设置环境变量 | ||||
| @@ -103,18 +111,22 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | LoginUser loginUser = SecurityUtils.getLoginUser(); | ||||
| String podName = loginUser.getUsername().toLowerCase() + "-editor-pod"; | String podName = loginUser.getUsername().toLowerCase() + "-editor-pod"; | ||||
| //得到pod | |||||
| V1Pod pod = k8sClientUtil.getNSPodList(namespace, podName); | |||||
| if(pod == null){ | |||||
| return "pod不存在!"; | |||||
| } | |||||
| // 使用 Kubernetes API 删除 Pod | // 使用 Kubernetes API 删除 Pod | ||||
| String deleteResult = k8sClientUtil.deletePod(podName, namespace); | String deleteResult = k8sClientUtil.deletePod(podName, namespace); | ||||
| // 检查 Pod 是否存在 | |||||
| boolean exists = k8sClientUtil.checkPodExists(podName, namespace); | |||||
| if (exists) { | |||||
| throw new Exception("Pod " + podName + " 删除失败"); | |||||
| } | |||||
| return deleteResult + ",编辑器已停止"; | return deleteResult + ",编辑器已停止"; | ||||
| } | } | ||||
| @Override | |||||
| public PodStatusVo getJupyterStatus(FrameLogPathVo frameLogPathVo) { | |||||
| return null; | |||||
| } | |||||
| @Override | @Override | ||||
| public void upload(InputStream inputStream) { | public void upload(InputStream inputStream) { | ||||
| @@ -136,4 +148,5 @@ public class JupyterServiceImpl implements JupyterService { | |||||
| } | } | ||||
| @@ -180,6 +180,8 @@ public class ModelDependencyServiceImpl implements ModelDependencyService { | |||||
| modelVersionDependcyVo.setFileName(modelsVersion.getFileName()); | modelVersionDependcyVo.setFileName(modelsVersion.getFileName()); | ||||
| modelVersionDependcyVo.setFileSize(modelsVersion.getFileSize()); | modelVersionDependcyVo.setFileSize(modelsVersion.getFileSize()); | ||||
| modelVersionDependcyVo.setUrl(modelsVersion.getUrl()); | modelVersionDependcyVo.setUrl(modelsVersion.getUrl()); | ||||
| modelVersionDependcyVo.setCreateBy(modelsVersion.getCreateBy()); | |||||
| modelVersionDependcyVo.setCreateTime(modelsVersion.getCreateTime()); | |||||
| modelDependcyTreeVo.setWorkflowId(experiment.getWorkflowId()); | modelDependcyTreeVo.setWorkflowId(experiment.getWorkflowId()); | ||||
| modelDependcyTreeVo.setModelVersionDependcyVo(modelVersionDependcyVo); | modelDependcyTreeVo.setModelVersionDependcyVo(modelVersionDependcyVo); | ||||
| @@ -7,7 +7,7 @@ import com.ruoyi.platform.domain.PodStatus; | |||||
| import com.ruoyi.platform.service.TensorBoardService; | import com.ruoyi.platform.service.TensorBoardService; | ||||
| import com.ruoyi.platform.utils.K8sClientUtil; | import com.ruoyi.platform.utils.K8sClientUtil; | ||||
| import com.ruoyi.platform.vo.FrameLogPathVo; | import com.ruoyi.platform.vo.FrameLogPathVo; | ||||
| import com.ruoyi.platform.vo.TensorboardStatusVo; | |||||
| import com.ruoyi.platform.vo.PodStatusVo; | |||||
| import com.ruoyi.system.api.model.LoginUser; | import com.ruoyi.system.api.model.LoginUser; | ||||
| import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| @@ -29,9 +29,9 @@ public class TensorBoardServiceImpl implements TensorBoardService { | |||||
| @Resource | @Resource | ||||
| private K8sClientUtil k8sClientUtil; | private K8sClientUtil k8sClientUtil; | ||||
| @Override | @Override | ||||
| public TensorboardStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo){ | |||||
| public PodStatusVo getTensorBoardStatus(FrameLogPathVo frameLogPathVo){ | |||||
| String status = PodStatus.Terminated.getName(); | String status = PodStatus.Terminated.getName(); | ||||
| TensorboardStatusVo tensorboardStatusVo = new TensorboardStatusVo(); | |||||
| PodStatusVo tensorboardStatusVo = new PodStatusVo(); | |||||
| tensorboardStatusVo.setStatus(status); | tensorboardStatusVo.setStatus(status); | ||||
| if (StringUtils.isEmpty(frameLogPathVo.getPath())){ | if (StringUtils.isEmpty(frameLogPathVo.getPath())){ | ||||
| return tensorboardStatusVo; | return tensorboardStatusVo; | ||||
| @@ -218,6 +218,7 @@ public class JacksonUtil { | |||||
| */ | */ | ||||
| public static <T> List<T> parseJSONStr2TList(String jsonStr, Class<T> clazz, String dateFormat) { | public static <T> List<T> parseJSONStr2TList(String jsonStr, Class<T> clazz, String dateFormat) { | ||||
| try { | try { | ||||
| if (StringUtils.isEmpty(jsonStr)) { return new ArrayList<T>(); } | |||||
| ObjectMapper objectMapper = getObjectMapper(dateFormat, false, false, true); | ObjectMapper objectMapper = getObjectMapper(dateFormat, false, false, true); | ||||
| CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz); | CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz); | ||||
| return objectMapper.readValue(jsonStr, listType); | return objectMapper.readValue(jsonStr, listType); | ||||
| @@ -569,12 +569,8 @@ public class K8sClientUtil { | |||||
| V1Pod pod = api.deleteNamespacedPod(podName, namespace, null, null, null, null, null, null); | V1Pod pod = api.deleteNamespacedPod(podName, namespace, null, null, null, null, null, null); | ||||
| return "Pod " + podName + " 删除请求已发送"; | return "Pod " + podName + " 删除请求已发送"; | ||||
| } catch (ApiException e) { | } catch (ApiException e) { | ||||
| if (e.getCode() == 404) { | |||||
| return "Pod " + podName + " 不存在"; | |||||
| } else { | |||||
| log.error("删除pod异常:" + e.getResponseBody(), e); | |||||
| throw e; | |||||
| } | |||||
| log.error("删除pod异常:" + e.getResponseBody(), e); | |||||
| throw e; | |||||
| } | } | ||||
| } | } | ||||
| @@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | import lombok.Data; | ||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| import java.util.Date; | |||||
| @Data | @Data | ||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | ||||
| @@ -45,4 +46,10 @@ public class ModelVersionDependcyVo implements Serializable { | |||||
| @ApiModelProperty(value = "文件大小") | @ApiModelProperty(value = "文件大小") | ||||
| private String fileSize; | private String fileSize; | ||||
| @ApiModelProperty(value = "创建者") | |||||
| private String createBy; | |||||
| @ApiModelProperty(value = "创建时间") | |||||
| private Date createTime; | |||||
| } | } | ||||
| @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; | |||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) | ||||
| public class TensorboardStatusVo implements Serializable { | |||||
| public class PodStatusVo implements Serializable { | |||||
| private String status; | private String status; | ||||
| private String url; | private String url; | ||||
| @@ -25,4 +25,5 @@ public class TensorboardStatusVo implements Serializable { | |||||
| public void setUrl(String url) { | public void setUrl(String url) { | ||||
| this.url = url; | this.url = url; | ||||
| } | } | ||||
| } | } | ||||
| @@ -26,7 +26,7 @@ | |||||
| select | select | ||||
| id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | ||||
| from dev_environment | from dev_environment | ||||
| where id = #{id} | |||||
| where id = #{id} and state = 1 | |||||
| </select> | </select> | ||||
| <!--查询指定行数据--> | <!--查询指定行数据--> | ||||
| @@ -35,6 +35,7 @@ | |||||
| id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | id,name,status,computing_resource,standard,env_variable,image,dataset,model,alt_field1,alt_field2,create_by,create_time,update_by,update_time,state | ||||
| from dev_environment | from dev_environment | ||||
| <where> | <where> | ||||
| state = 1 | |||||
| <if test="devEnvironment.id != null"> | <if test="devEnvironment.id != null"> | ||||
| and id = #{devEnvironment.id} | and id = #{devEnvironment.id} | ||||
| </if> | </if> | ||||
| @@ -93,6 +94,7 @@ | |||||
| select count(1) | select count(1) | ||||
| from dev_environment | from dev_environment | ||||
| <where> | <where> | ||||
| state = 1 | |||||
| <if test="devEnvironment.id != null"> | <if test="devEnvironment.id != null"> | ||||
| and id = #{devEnvironment.id} | and id = #{devEnvironment.id} | ||||
| </if> | </if> | ||||