Procházet zdrojové kódy

feat: 增加git api

370774330@qq.com před 5 roky
rodič
revize
0f265a43b5

+ 6 - 0
api/pom.xml

@@ -25,6 +25,12 @@
 
 
 
 
     <dependencies>
     <dependencies>
+        <!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit -->
+        <dependency>
+            <groupId>org.eclipse.jgit</groupId>
+            <artifactId>org.eclipse.jgit</artifactId>
+            <version>5.9.0.202009080501-r</version>
+        </dependency>
         <dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>

+ 12 - 1
api/src/main/java/seecoder/devcloud/api/ApplicationProperties.java

@@ -33,7 +33,8 @@ public class ApplicationProperties {
 	private K8s k8s = new K8s();
 	private K8s k8s = new K8s();
 	@Valid
 	@Valid
 	private Registry registry = new Registry();
 	private Registry registry = new Registry();
-
+	@Valid
+	private Git git = new Git();
 
 
 	@Data
 	@Data
 	public static class Gitlab {
 	public static class Gitlab {
@@ -128,4 +129,14 @@ public class ApplicationProperties {
 		private String cleanUpTask = "4da7e1e1-2b28-46b5-a080-9d834cc96019";
 		private String cleanUpTask = "4da7e1e1-2b28-46b5-a080-9d834cc96019";
 	}
 	}
 
 
+	@Data
+	public static class Git {
+		@NotEmpty
+		private String username;
+		@NotEmpty
+		private String password;
+	}
+
+
+
 }
 }

+ 9 - 0
api/src/main/java/seecoder/devcloud/api/DevcloudApiAutoConfiguration.java

@@ -1,10 +1,13 @@
 package seecoder.devcloud.api;
 package seecoder.devcloud.api;
 
 
+import org.eclipse.jgit.api.Git;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import seecoder.devcloud.api.docker.DockerApi;
 import seecoder.devcloud.api.docker.DockerApi;
 import seecoder.devcloud.api.docker.impl.DockerApiImpl;
 import seecoder.devcloud.api.docker.impl.DockerApiImpl;
+import seecoder.devcloud.api.git.GitApi;
+import seecoder.devcloud.api.git.impl.GitApiImpl;
 import seecoder.devcloud.api.gitlab.GitlabApi;
 import seecoder.devcloud.api.gitlab.GitlabApi;
 import seecoder.devcloud.api.gitlab.impl.GitlabApiImpl;
 import seecoder.devcloud.api.gitlab.impl.GitlabApiImpl;
 import seecoder.devcloud.api.jenkins.JenkinsApi;
 import seecoder.devcloud.api.jenkins.JenkinsApi;
@@ -33,6 +36,12 @@ public class DevcloudApiAutoConfiguration {
         return new GitlabApiImpl(applicationProperties());
         return new GitlabApiImpl(applicationProperties());
     }
     }
 
 
+    @Bean
+    @ConditionalOnBean(ApplicationProperties.class)
+    public GitApi gitApi(){
+        return new GitApiImpl(applicationProperties());
+    }
+
     @Bean
     @Bean
     @ConditionalOnBean(ApplicationProperties.class)
     @ConditionalOnBean(ApplicationProperties.class)
     public K8sApiConfiguration k8sApiConfiguration(){
     public K8sApiConfiguration k8sApiConfiguration(){

+ 8 - 0
api/src/main/java/seecoder/devcloud/api/git/GitApi.java

@@ -0,0 +1,8 @@
+package seecoder.devcloud.api.git;
+
+import org.eclipse.jgit.api.Git;
+
+public interface GitApi {
+
+    Git clone(String repoUrl, String directory) throws Exception;
+}

+ 33 - 0
api/src/main/java/seecoder/devcloud/api/git/impl/GitApiImpl.java

@@ -0,0 +1,33 @@
+package seecoder.devcloud.api.git.impl;
+
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import seecoder.devcloud.api.ApplicationProperties;
+import seecoder.devcloud.api.git.GitApi;
+
+import java.io.File;
+
+@Component
+public class GitApiImpl implements GitApi {
+
+    private CredentialsProvider credentialsProvider;
+
+    @Autowired
+    public GitApiImpl(ApplicationProperties properties) {
+        ApplicationProperties.Git gitProperties = properties.getGit();
+        credentialsProvider = new UsernamePasswordCredentialsProvider(gitProperties.getUsername(), gitProperties.getPassword());
+    }
+
+    @Override
+    public Git clone(String repoUrl, String directory) throws Exception {
+        Git git = Git.cloneRepository()
+                .setCredentialsProvider(credentialsProvider)
+                .setURI(repoUrl)
+                .setDirectory(new File(directory)).call();
+        return git;
+    }
+}

+ 165 - 45
core/src/main/java/seecoder/devcloud/core/pipeline/handler/DockerImageBuildHandler.java

@@ -1,48 +1,168 @@
-package seecoder.devcloud.core.pipeline.handler;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.FileUtils;
-import seecoder.devcloud.api.docker.DockerApi;
-import seecoder.devcloud.common.util.SpringUtil;
-import seecoder.devcloud.core.pipeline.Context;
-import seecoder.devcloud.core.pipeline.Handler;
-
-import java.io.*;
-import java.nio.file.Files;
-
-/**
- * @author PuHong Weng
- * @date 2021/1/18
- * @description: docker镜像构建
- */
-@Slf4j
-public class DockerImageBuildHandler extends AbstractHandler {
-
-    private static final String TEMP_PREFIX = "SEECODER-DEVCLOUD-";
-
-    public DockerApi dockerApi;
-
-    public DockerImageBuildHandler(){
-        dockerApi = SpringUtil.getBean(DockerApi.class);
-    }
-
-    @Override
-    public void process(Context context){
-//        File tempDir = null;
+//package seecoder.devcloud.core.pipeline.handler;
+//
+//import com.spotify.docker.client.ProgressHandler;
+//import com.spotify.docker.client.exceptions.DockerException;
+//import com.spotify.docker.client.messages.ProgressMessage;
+//import io.kubernetes.client.openapi.models.*;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.io.FileUtils;
+//import org.apache.commons.lang.StringUtils;
+//import org.eclipse.jgit.api.Git;
+//import org.eclipse.jgit.api.ResetCommand;
+//import org.springframework.util.CollectionUtils;
+//import seecoder.devcloud.api.ApplicationProperties;
+//import seecoder.devcloud.api.docker.DockerApi;
+//import seecoder.devcloud.api.git.GitApi;
+//import seecoder.devcloud.api.gitlab.GitlabApi;
+//import seecoder.devcloud.common.exceptions.Asserts;
+//import seecoder.devcloud.common.util.SpringUtil;
+//import seecoder.devcloud.core.pipeline.Context;
+//import seecoder.devcloud.core.pipeline.Handler;
+//
+//import java.io.*;
+//import java.nio.file.Files;
+//import java.nio.file.Path;
+//import java.nio.file.Paths;
+//import java.time.LocalDateTime;
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @author PuHong Weng
+// * @date 2021/1/18
+// * @description: docker镜像构建
+// */
+//@Slf4j
+//public class DockerImageBuildHandler extends AbstractHandler {
+//
+//    private static final String TEMP_PREFIX = "SEECODER-DEVCLOUD-";
+//
+//    public DockerApi dockerApi;
+//
+//    public GitlabApi gitlabApi;
+//
+//    public GitApi gitApi;
+//
+//    public DockerImageBuildHandler() {
+//        gitlabApi = SpringUtil.getBean(GitlabApi.class);
+//        dockerApi = SpringUtil.getBean(DockerApi.class);
+//        gitApi = SpringUtil.getBean(GitApi.class);
+//    }
+//
+//    @Override
+//    public void process(Context context) {
 //        try {
 //        try {
-//            tempDir = Files.createTempDirectory(TEMP_PREFIX).toFile();
-//            //
-//            File dockerFile = new File(tempDir, "Dockerfile");
-//            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dockerFile)))) {
-//                writer.write(question.getQuestionType().getHelper().dockerFile(question.getName()));
+//            String imageName = context.getGroupName() + "-" + context.getProjectName();
+//            String repoUrl = context.getConfigs().get("repoUrl");
+//
+//
+//            // 1. 有git从git拿到地址进行镜像构建构建并push
+//            try {
+//                Path directory = Files.createTempDirectory("seecoder-devcloud-");
+//                Git git = gitApi.clone(repoUrl, directory.toString());
+//                if (Files.exists(Paths.get(directory.toString(), "Dockerfile"))) {
+//                    git.reset().setMode(ResetCommand.ResetType.HARD).setRef(result.getBuildTypeValue()).call();
+//                    String imageTag = String.valueOf(new Date().getTime());
+//                    StringBuilder sb = new StringBuilder();
+//                    final int DEFAULT_BUFFER_LENGTH = 200;
+//                    final long MAX_BUFFER_SIZE = 1 << 18;
+//                    dockerApi.buildAndPush(directory.toString(), "seecoder-paas-" + labelValue, imageTag, new ProgressHandler() {
+//                        @Override
+//                        public void progress(ProgressMessage message) throws DockerException {
+//                            String value = message.stream();
+//                            if (value == null) {
+//                                value = "";
+//                            }
+//                            if (!StringUtils.isEmpty(message.error())) {
+//                                value += "\n" + message.error();
+//                            }
+//                            sb.append(value);
+//                            if (sb.length() > DEFAULT_BUFFER_LENGTH) {
+//                                result.setBuildOutput(result.getBuildOutput() + sb.toString());
+//                                if (result.getBuildOutput().length() > MAX_BUFFER_SIZE) {
+//                                    result.setBuildOutput(result.getBuildOutput().substring((int) (result.getBuildOutput().length() - MAX_BUFFER_SIZE)));
+//                                }
+//                                sb.setLength(0);
+//                                environmentDAO.save(result);
+//                            }
+//                        }
+//                    });
+//                    if (sb.length() > 0) {
+//                        result.setBuildOutput(result.getBuildOutput() + sb.toString());
+//                    }
+//                    imageName = applicationProperties.getK8s().getImageRegistry() + "/seecoder-paas-" + labelValue + ":" + imageTag;
+//                    result.setBuildStatus(BuildStatus.SUCCESS);
+//                    result.setDeployStatus(DeployStatus.DEPLOYING);
+//                    result.setDeployStartTime(LocalDateTime.now());
+//                    result.setImage(imageName);
+//                    environmentDAO.save(result);
+//                } else {
+//                    result.setBuildStatus(BuildStatus.FAIL);
+//                    result.setBuildOutput("找不到构建文件Dockerfile!");
+//                    environmentDAO.save(result);
+//                    throw new ServiceException("102", "找不到构建文件Dockerfile!");
+//                }
+//            } catch (Exception e) {
+//                result.setBuildStatus(BuildStatus.FAIL);
+//                if (!e.getLocalizedMessage().contains("Could not acquire image ID or digest following build")) {
+//                    result.setBuildOutput(e.getLocalizedMessage());
+//                }
+//                environmentDAO.save(result);
+//                LoggerUtil.error(logger, e, "构建失败!gitUrl={}, branchOrCommit={}", application.getGitUrl(), result.getBuildTypeValue());
+//                return;
 //            }
 //            }
-//            //dockerApi.build(tempDir.getAbsolutePath(), question.getImageName(), question.getImageTag());
-//        } catch (IOException e){
-//            e.printStackTrace();
-//            log.error("镜像构建失败, 产生IO错误, {}", e.getMessage());
-//        } finally {
-//            FileUtils.deleteDirectory(tempDir);
+//        } else if (result.getBuildType() == BuildType.FROM_IMAGE) {
+//            result.setBuildStatus(BuildStatus.SUCCESS);
+//            result.setBuildOutput("镜像构建无需部署");
+//            result.setDeployStatus(DeployStatus.DEPLOYING);
+//            result.setDeployStartTime(LocalDateTime.now());
+//            result.setImage(imageName);
+//            environmentDAO.save(result);
 //        }
 //        }
-    }
-
-}
+//
+//        String[] ports = (configContent.getServicePort() == null ? "" : configContent.getServicePort()).split(",");
+//        if (!StringUtils.isEmpty(configContent.getHostPrefix())) {
+//            for (String port : ports) {
+//                // ingress
+//                List<Ingress> ingresses = ingressApi.getByCondition(K8sObjectRequest.builder()
+//                        .name(labelValue + "-" + port)
+//                        .namespace(deploymentNamespace).labels(labelsMap).build());
+//                Ingress ingress = new Ingress();
+//                ingress.setNamespace(deploymentNamespace);
+//                ingress.setName(labelValue + "-" + port);
+//                ingress.setLabels(labelsMap);
+//                if (configContent.getIngressAnnotations() != null && configContent.getIngressAnnotations().get(port) != null) {
+//                    ingress.setAnnotations(configContent.getIngressAnnotations().get(port));
+//                }
+//                String ingressHost = configContent.getHostPrefix() + "-" + port + "." + deploymentHost;
+//                if (configContent.getIngressPort() != null) {
+//                    if (port.equals(configContent.getIngressPort())) {
+//                        ingressHost = configContent.getHostPrefix() + "." + deploymentHost;
+//                    }
+//                } else {
+//                    if (ports.length == 1 || port.equals("80")) {
+//                        ingressHost = configContent.getHostPrefix() + "." + deploymentHost;
+//                    }
+//                }
+//                ingress.setAnnotation(Ingress.REWRITE_ANNOTATION, Ingress.DEFAULT_REWRITE_PATH);
+//                ingress.setHttpRules(Collections.singletonList(
+//                        Ingress.IngressRule.builder().host(ingressHost).ruleValues(
+//                                Collections.singleton(Ingress.IngressPath.builder()
+//                                        .path("/")
+//                                        .serviceName(labelValue)
+//                                        .port(Integer.parseInt(port))
+//                                        .build())
+//                        ).build()
+//                ));
+//                if (CollectionUtils.isEmpty(ingresses) || ingresses.size() != 1) {
+//                    ingressApi.create(ingress);
+//                } else {
+//                    ingressApi.update(ingress);
+//                }
+//            }
+//        }
+//
+//        return;
+//    }
+//}
+//

+ 12 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sPVCHandler.java

@@ -0,0 +1,12 @@
+package seecoder.devcloud.core.pipeline.handler;
+
+import lombok.Data;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description: 创建K8s 持久卷声明
+ */
+@Data
+public class K8sPVCHandler {
+}