| @@ -63,7 +63,7 @@ public class DevEnvironment implements Serializable { | |||
| /** | |||
| * 备用字段2 | |||
| */ | |||
| private String altField2; | |||
| private String codePath; | |||
| /** | |||
| * 创建者 | |||
| */ | |||
| @@ -1,18 +1,23 @@ | |||
| package com.ruoyi.platform.service.impl; | |||
| import cn.hutool.core.util.ObjectUtil; | |||
| import com.ruoyi.common.core.utils.DateUtils; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| import com.ruoyi.platform.domain.CodeConfig; | |||
| import com.ruoyi.platform.domain.DevEnvironment; | |||
| import com.ruoyi.platform.domain.PodStatus; | |||
| import com.ruoyi.platform.mapper.DevEnvironmentDao; | |||
| import com.ruoyi.platform.service.DevEnvironmentService; | |||
| import com.ruoyi.platform.service.JupyterService; | |||
| import com.ruoyi.platform.service.ResourceOccupyService; | |||
| import com.ruoyi.platform.service.*; | |||
| import com.ruoyi.platform.utils.DVCUtils; | |||
| import com.ruoyi.platform.utils.JacksonUtil; | |||
| import com.ruoyi.platform.vo.DevEnvironmentVo; | |||
| import com.ruoyi.platform.vo.GitProjectVo; | |||
| import com.ruoyi.platform.vo.PodStatusVo; | |||
| import com.ruoyi.system.api.constant.Constant; | |||
| import com.ruoyi.system.api.model.LoginUser; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.context.annotation.Lazy; | |||
| import org.springframework.data.domain.Page; | |||
| import org.springframework.data.domain.PageImpl; | |||
| @@ -23,6 +28,9 @@ import org.springframework.transaction.annotation.Transactional; | |||
| import javax.annotation.Resource; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import static com.ruoyi.common.security.utils.SecurityUtils.decrypt; | |||
| /** | |||
| * (DevEnvironment)表服务实现类 | |||
| @@ -30,6 +38,7 @@ import java.util.List; | |||
| * @author Xidaray | |||
| * @since 2024-06-03 15:17:37 | |||
| */ | |||
| @Slf4j | |||
| @Service("devEnvironmentService") | |||
| public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||
| @Resource | |||
| @@ -38,9 +47,19 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||
| @Resource | |||
| @Lazy | |||
| private JupyterService jupyterService; | |||
| @Resource | |||
| private ResourceOccupyService resourceOccupyService; | |||
| @Resource | |||
| private DVCUtils dvcUtils; | |||
| @Value("${git.localPath}") | |||
| String localPathlocal; | |||
| @Resource | |||
| private CodeConfigService codeConfigService; | |||
| /** | |||
| * 通过ID查询单条数据 | |||
| * | |||
| @@ -101,6 +120,7 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||
| //插入预备,此时不需要判断版本重复 | |||
| DevEnvironment devEnvironment = new DevEnvironment(); | |||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||
| String localPath = cloneCode(devEnvironmentVo.getCodeConfigId()); | |||
| devEnvironment.setName(devEnvironmentVo.getName()); | |||
| //状态先设为未知 | |||
| devEnvironment.setStatus(Constant.Unknown); | |||
| @@ -120,6 +140,7 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||
| devEnvironment.setUpdateTime(new Date()); | |||
| devEnvironment.setCreateTime(new Date()); | |||
| devEnvironment.setState(Constant.State_valid); | |||
| devEnvironment.setCodePath(localPath); | |||
| this.devEnvironmentDao.insert(devEnvironment); | |||
| return devEnvironment; | |||
| } | |||
| @@ -174,4 +195,35 @@ public class DevEnvironmentServiceImpl implements DevEnvironmentService { | |||
| resourceOccupyService.deleteTaskState(Constant.TaskType_Dev, Long.valueOf(id), null); | |||
| return this.devEnvironmentDao.update(devEnvironment) > 0 ? "删除成功" : "删除失败"; | |||
| } | |||
| /** | |||
| * 保存代码数据并返回保存路径 | |||
| * @param codeConfigId | |||
| * @return | |||
| */ | |||
| private String cloneCode(Long codeConfigId) { | |||
| String localPath = null; | |||
| try { | |||
| CodeConfig codeConfig = codeConfigService.queryById(codeConfigId); | |||
| if (ObjectUtil.isEmpty(codeConfig)) { | |||
| log.info("[returnCodeConfig error,codeConfigId={}]", codeConfigId); | |||
| return localPath; | |||
| } | |||
| LoginUser loginUser = SecurityUtils.getLoginUser(); | |||
| String gitLinkUsername = loginUser.getSysUser().getUserName(); | |||
| String ci4sUsername = Boolean.TRUE.equals(codeConfig.getIsPublic()) ? Constant.Item_Public : loginUser.getUsername(); | |||
| String gitLinkPassword = decrypt(loginUser.getSysUser().getOriginPassword()); | |||
| String repositoryName = ci4sUsername + "_code_" + DateUtils.dateTimeNow(); | |||
| String relatePath = ci4sUsername + "/code/" + repositoryName + "/" + codeConfig.getGitBranch(); | |||
| localPath = localPathlocal + relatePath; | |||
| dvcUtils.gitClone(localPath, codeConfig.getGitUrl(), codeConfig.getGitBranch(), gitLinkUsername, gitLinkPassword); | |||
| } catch (Exception e) { | |||
| log.error("[returnCodeConfig error,codeConfigId={}]", codeConfigId); | |||
| } | |||
| return localPath; | |||
| } | |||
| } | |||
| @@ -105,7 +105,7 @@ public class JupyterServiceImpl implements JupyterService { | |||
| // 调用修改后的 createPod 方法,传入额外的参数 | |||
| // Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, pvc, devEnvironment, minioPvcName, datasetPath, modelPath); | |||
| Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, null, devEnvironment, minioPvcName, datasetPath, modelPath); | |||
| Integer podPort = k8sClientUtil.createConfiguredPod(podName, namespace, port, mountPath, null, devEnvironment, minioPvcName, datasetPath, modelPath,devEnvironment.getCodePath()); | |||
| String url = masterIp + ":" + podPort; | |||
| redisService.setCacheObject(podName, masterIp + ":" + podPort); | |||
| devEnvironment.setStatus(Constant.Pending); | |||
| @@ -1,5 +1,6 @@ | |||
| package com.ruoyi.platform.service.impl; | |||
| import cn.hutool.core.util.StrUtil; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| @@ -1325,10 +1326,10 @@ public class ModelsServiceImpl implements ModelsService { | |||
| } | |||
| if (modelTopicName != null && modelTopic.equals(modelTopicName)) { | |||
| if (StringUtils.isNotEmpty(modelTagName) && !modelTagName.toLowerCase().equals(modelTag)) { | |||
| if (StrUtil.containsAnyIgnoreCase(modelTagName,modelTag)) { | |||
| continue; | |||
| } | |||
| if (StringUtils.isNotEmpty(modelTypeName) && !modelTypeName.toLowerCase().equals(modelType)) { | |||
| if (StrUtil.containsAnyIgnoreCase(modelTypeName,modelType)) { | |||
| continue; | |||
| } | |||
| newModelVo.setModelTag(modelTagName); | |||
| @@ -1,5 +1,6 @@ | |||
| package com.ruoyi.platform.service.impl; | |||
| import cn.hutool.core.util.StrUtil; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.ruoyi.common.core.utils.DateUtils; | |||
| import com.ruoyi.common.security.utils.SecurityUtils; | |||
| @@ -34,7 +35,6 @@ import java.nio.file.Files; | |||
| import java.nio.file.Path; | |||
| import java.nio.file.Paths; | |||
| import java.util.*; | |||
| import java.util.concurrent.CompletableFuture; | |||
| import java.util.stream.Collectors; | |||
| import java.util.zip.ZipEntry; | |||
| import java.util.zip.ZipOutputStream; | |||
| @@ -666,10 +666,10 @@ public class NewDatasetServiceImpl implements NewDatasetService { | |||
| } | |||
| if (datasetTopic.equals(datasetTopicName)) { | |||
| if (StringUtils.isNotEmpty(datasetTagName) && !datasetTagName.toLowerCase().equals(datasetTag)) { | |||
| if (StrUtil.containsAnyIgnoreCase(datasetTagName,datasetTag)) { | |||
| continue; | |||
| } | |||
| if (StringUtils.isNotEmpty(datasetTypeName) && !datasetTypeName.toLowerCase().equals(datasetType)) { | |||
| if (StrUtil.containsAnyIgnoreCase(datasetTypeName,datasetType)) { | |||
| continue; | |||
| } | |||
| newDatasetVo.setDataTag(datasetTagName); | |||
| @@ -73,10 +73,10 @@ public class K8sClientUtil { | |||
| this.http = http; | |||
| this.token = token; | |||
| try { | |||
| // this.apiClient = new ClientBuilder(). | |||
| // setBasePath(http).setVerifyingSsl(false). | |||
| // setAuthentication(new AccessTokenAuthentication(token)).build(); | |||
| this.apiClient = Config.fromCluster(); | |||
| this.apiClient = new ClientBuilder(). | |||
| setBasePath(http).setVerifyingSsl(false). | |||
| setAuthentication(new AccessTokenAuthentication(token)).build(); | |||
| // this.apiClient = Config.fromCluster(); | |||
| } catch (Exception e) { | |||
| log.error("构建K8s-Client异常", e); | |||
| throw new RuntimeException("构建K8s-Client异常"); | |||
| @@ -436,7 +436,7 @@ public class K8sClientUtil { | |||
| } | |||
| // 创建配置好的Pod | |||
| public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, DevEnvironment devEnvironment, String dataPvcName, String datasetPath, String modelPath) throws IOException { | |||
| public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, DevEnvironment devEnvironment, String dataPvcName, String datasetPath, String modelPath,String codePath) throws IOException { | |||
| //设置选择节点,pod反亲和性 | |||
| Map<String, String> selector = new LinkedHashMap<>(); | |||
| @@ -512,7 +512,10 @@ public class K8sClientUtil { | |||
| if (StringUtils.isNotEmpty(modelPath)) { | |||
| volumeMounts.add(new V1VolumeMount().name("data").mountPath("/opt/model").subPath(modelPath).readOnly(true)); | |||
| } | |||
| if (StringUtils.isNotEmpty(datasetPath) || StringUtils.isNotEmpty(modelPath)) { | |||
| if (StringUtils.isNotEmpty(modelPath)) { | |||
| volumeMounts.add(new V1VolumeMount().name("data").mountPath("/opt/code").subPath(modelPath).readOnly(true)); | |||
| } | |||
| if (StringUtils.isNotEmpty(datasetPath) || StringUtils.isNotEmpty(modelPath) || StringUtils.isNotEmpty(codePath)) { | |||
| volumes.add(new V1Volume().name("data").hostPath(new V1HostPathVolumeSource().path(hostPath).type("DirectoryOrCreate"))); | |||
| } | |||
| @@ -31,6 +31,11 @@ public class DevEnvironmentVo implements Serializable { | |||
| * 环境变量 | |||
| */ | |||
| private String envVariable; | |||
| /** | |||
| * 代码配置ID | |||
| */ | |||
| private Long codeConfigId; | |||
| /** | |||
| * 所用镜像 | |||
| */ | |||
| @@ -46,8 +46,8 @@ | |||
| <if test="devEnvironment.url != null and devEnvironment.url != ''"> | |||
| and url = #{devEnvironment.url} | |||
| </if> | |||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||
| and alt_field2 = #{devEnvironment.altField2} | |||
| <if test="devEnvironment.codePath != null and devEnvironment.codePath != ''"> | |||
| and alt_field2 = #{devEnvironment.codePath} | |||
| </if> | |||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||
| and create_by = #{devEnvironment.createBy} | |||
| @@ -105,8 +105,8 @@ | |||
| <if test="devEnvironment.url != null and devEnvironment.url != ''"> | |||
| and url = #{devEnvironment.url} | |||
| </if> | |||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||
| and alt_field2 = #{devEnvironment.altField2} | |||
| <if test="devEnvironment.codePath != null and devEnvironment.codePath != ''"> | |||
| and alt_field2 = #{devEnvironment.codePath} | |||
| </if> | |||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||
| and create_by = #{devEnvironment.createBy} | |||
| @@ -143,7 +143,7 @@ | |||
| #{devEnvironment.dataset}, | |||
| #{devEnvironment.model}, | |||
| #{devEnvironment.url}, | |||
| #{devEnvironment.altField2}, | |||
| #{devEnvironment.codePath}, | |||
| #{devEnvironment.createBy}, | |||
| #{devEnvironment.createTime}, | |||
| #{devEnvironment.updateBy}, | |||
| @@ -186,8 +186,8 @@ | |||
| <if test="devEnvironment.url != null and devEnvironment.url != ''"> | |||
| url = #{devEnvironment.url}, | |||
| </if> | |||
| <if test="devEnvironment.altField2 != null and devEnvironment.altField2 != ''"> | |||
| alt_field2 = #{devEnvironment.altField2}, | |||
| <if test="devEnvironment.codePath != null and devEnvironment.codePath != ''"> | |||
| alt_field2 = #{devEnvironment.codePath}, | |||
| </if> | |||
| <if test="devEnvironment.createBy != null and devEnvironment.createBy != ''"> | |||
| create_by = #{devEnvironment.createBy}, | |||