Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
Feat: add git prebuilt-tasks
Browse files Browse the repository at this point in the history
This commit addressed a new way to clone and archive git repositories
inside Parodos.

The main objective for these tasks is to implement work on top of
Move2kube.

Signed-off-by: Eloy Coto <eloy.coto@acalustra.com>
  • Loading branch information
eloycoto committed May 8, 2023
1 parent 390e10e commit 24fc1d4
Show file tree
Hide file tree
Showing 6 changed files with 513 additions and 0 deletions.
35 changes: 35 additions & 0 deletions prebuilt-tasks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<jira-rest-client.version>5.2.4</jira-rest-client.version>
<attlasian-fugue.version>2.6.1</attlasian-fugue.version>
<org.json.version>20230227</org.json.version>
<jgit-version>6.5.0.202303070854-r</jgit-version>
</properties>

<repositories>
Expand Down Expand Up @@ -95,5 +96,39 @@
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${jgit-version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>${jgit-version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.gpg.bc</artifactId>
<version>${jgit-version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.archive</artifactId>
<version>${jgit-version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.redhat.parodos.tasks.git;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.redhat.parodos.workflow.parameter.WorkParameter;
import com.redhat.parodos.workflow.parameter.WorkParameterType;
import com.redhat.parodos.workflow.task.BaseWorkFlowTask;
import com.redhat.parodos.workflows.work.DefaultWorkReport;
import com.redhat.parodos.workflows.work.WorkContext;
import com.redhat.parodos.workflows.work.WorkReport;
import com.redhat.parodos.workflows.work.WorkStatus;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.ArchiveCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.archive.ZipFormat;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

@Slf4j
@AllArgsConstructor
public class GitArchiveTask extends BaseWorkFlowTask {

@Override
public @NonNull List<WorkParameter> getWorkFlowTaskParameters() {
return List.of(WorkParameter.builder().key(GitUtils.getGitRepoPath()).type(WorkParameterType.TEXT)
.optional(true).description("path where the git repo is located").build());
}

@Override
public WorkReport execute(WorkContext workContext) {
String path = GitUtils.getRepoPath(workContext);
if (Strings.isNullOrEmpty(path)) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new IllegalArgumentException("The path parameter cannot be null or empty"));
}
Repository repo = null;
try {
repo = getRepo(path);
Path archivePath = archive(repo);
workContext.put(GitUtils.getContextArchivePath(), archivePath.toAbsolutePath().toString());
}
catch (FileNotFoundException | GitAPIException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("Cannot archive the repository:" + e));
}
catch (IOException e) {
// This is the catch for Repository clone call or archive, we don't really
// know.
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("No repository at " + path + " Error:" + e.getMessage()));
}
catch (Exception e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("Cannot archive the repository:" + e));
}
finally {
if (repo != null) {
repo.close();
}
}

return new DefaultWorkReport(WorkStatus.COMPLETED, workContext, null);
}

private Repository getRepo(String path) throws IOException {
Path gitDir = Paths.get(path);
return new FileRepositoryBuilder().setGitDir(gitDir.toFile()).build();
}

private Path archive(Repository repo) throws FileNotFoundException, IOException, GitAPIException {

// Create a Git instance
Git git = new Git(repo);
ArchiveCommand.registerFormat("zip", new ZipFormat());

// Create a ZipFormat instance
String tmpdir = Files.createTempDir().getAbsolutePath();
Path zipFile = Paths.get(tmpdir + "/output.zip");

try (FileOutputStream out = new FileOutputStream(zipFile.toAbsolutePath().toString())) {
git.archive().setTree(repo.resolve("HEAD")).setFormat("zip").setOutputStream(out).call();
}
finally {
git.close();
}
return zipFile;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.redhat.parodos.tasks.git;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

import com.redhat.parodos.workflow.context.WorkContextDelegate;
import com.redhat.parodos.workflow.exception.MissingParameterException;
import com.redhat.parodos.workflow.parameter.WorkParameter;
import com.redhat.parodos.workflow.parameter.WorkParameterType;
import com.redhat.parodos.workflow.task.BaseWorkFlowTask;
import com.redhat.parodos.workflows.work.DefaultWorkReport;
import com.redhat.parodos.workflows.work.WorkContext;
import com.redhat.parodos.workflows.work.WorkReport;
import com.redhat.parodos.workflows.work.WorkStatus;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;

@AllArgsConstructor
@Slf4j
public class GitCloneTask extends BaseWorkFlowTask {

@Override
public @NonNull List<WorkParameter> getWorkFlowTaskParameters() {
return List.of(
WorkParameter.builder().key(GitUtils.getUri()).type(WorkParameterType.TEXT).optional(false)
.description("Url to clone from").build(),
WorkParameter.builder().key(GitUtils.getBranch()).type(WorkParameterType.TEXT).optional(true)
.description("Branch to clone from, default main").build(),
WorkParameter.builder().key("credentials").type(WorkParameterType.TEXT).optional(false)
.description("Git credential").build());
}

@Override
public WorkReport execute(WorkContext workContext) {
String gitUri = null;
String destination = null;
String gitBranch = null;

try {
gitUri = WorkContextDelegate.getRequiredValueFromRequestParams(workContext, GitUtils.getUri());
gitBranch = WorkContextDelegate.getOptionalValueFromRequestParams(workContext, GitUtils.getBranch(),
"main");
destination = cloneRepo(gitUri, gitBranch);
}
catch (MissingParameterException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext, e);
}
catch (TransportException e) {
log.debug("Cannot connect to repository server '{}' error: {}", gitUri, e.getMessage());
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("cannot connect to the repository server"));
}
catch (InvalidRemoteException e) {
log.debug("remote repository server '{}' is not available, error: {}", gitUri, e.getMessage());
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("Remote repository " + gitUri + " is not available"));
}
catch (IOException | GitAPIException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("cannot clone repository, error: " + e.getMessage()));
}

workContext.put(GitUtils.getContextUri(), gitUri);
workContext.put(GitUtils.getContextDestination(), destination);
workContext.put(GitUtils.getContextBranch(), gitBranch);
return new DefaultWorkReport(WorkStatus.COMPLETED, workContext, null);
}

private String cloneRepo(String gitUri, String gitBranch)
throws InvalidRemoteException, TransportException, IOException, GitAPIException {
String tmpDir = Files.createTempDirectory("GitTaskClone").toAbsolutePath().toString();
Git.cloneRepository().setURI(gitUri).setBranch("refs/heads/" + gitBranch).setDirectory(new File(tmpDir)).call();
return tmpDir;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.redhat.parodos.tasks.git;

import com.redhat.parodos.workflow.context.WorkContextDelegate;
import com.redhat.parodos.workflows.work.WorkContext;
import lombok.Getter;

public abstract class GitUtils {

private GitUtils() {
}

@Getter
static final String gitRepoPath = "path";

@Getter
static final String uri = "uri";

@Getter
static final String branch = "branch";

@Getter
static final String ContextUri = "gitUri";

@Getter
static final String ContextBranch = "gitBranch";

@Getter
static final String contextDestination = "gitDestination";

@Getter
static final String contextArchivePath = "gitArchivePath";

public static String getRepoPath(WorkContext workContext) {
var dest = workContext.get(contextDestination);
if (dest == null) {
return WorkContextDelegate.getOptionalValueFromRequestParams(workContext, getGitRepoPath(), "");
}
return WorkContextDelegate.getOptionalValueFromRequestParams(workContext, getGitRepoPath(), dest.toString());
}

}
Loading

0 comments on commit 24fc1d4

Please sign in to comment.