Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy existing Git repository into container #24

Merged
merged 7 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

import java.io.IOException;
import java.net.URI;
Expand All @@ -18,17 +19,17 @@
private static final String GIT_PASSWORD_KEY = "GIT_PASSWORD";
private static DockerImageName DEFAULT_DOCKER_IMAGE_NAME = DockerImageName.parse("rockstorm/git-server");
private String gitRepoName = "testRepo";
private String pathToExistingRepo;
private SshIdentity sshClientIdentity;
private SshHostKey hostKey;

/**
*
* @param dockerImageName - name of the docker image
*/
public GitServerContainer(DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(DEFAULT_DOCKER_IMAGE_NAME);
if ("2.38".compareTo(dockerImageName.getVersionPart()) <= 0 ) {
if ("2.38".compareTo(dockerImageName.getVersionPart()) <= 0) {
waitingFor(Wait.forLogMessage(".*Container configuration completed.*", 1)).addExposedPorts(22);
} else {
withExposedPorts(22);
Expand All @@ -38,8 +39,9 @@

/**
* Override the default git password.
*
* <p>
* Default password is 12345
*
* @param password - git password
* @return instance of the git server container
*/
Expand All @@ -51,7 +53,7 @@

/**
* Override the default git repository name.
*
* <p>
* Default name is "testRepo"
*
* @param gitRepoName - name of the git repository that is created by default
Expand All @@ -69,10 +71,10 @@
*/
public GitServerContainer withSshKeyAuth() {
try {
sshClientIdentity = new SshIdentity(
this.getClass().getClassLoader().getResourceAsStream("id_client").readAllBytes(),
this.getClass().getClassLoader().getResourceAsStream("id_client.pub").readAllBytes(),
new byte[0]);
sshClientIdentity = new SshIdentity(
this.getClass().getClassLoader().getResourceAsStream("id_client").readAllBytes(),
this.getClass().getClassLoader().getResourceAsStream("id_client.pub").readAllBytes(),
new byte[0]);

withClasspathResourceMapping("id_client.pub", "/home/git/.ssh/authorized_keys", BindMode.READ_ONLY);
withClasspathResourceMapping("sshd_config", "/etc/ssh/sshd_config", BindMode.READ_ONLY);
Expand All @@ -84,37 +86,66 @@
return this;
}

/**
* Copy an existing git repository to the container.
* <p>
* The git repository is copied to the container and the git repository is initialized as bare repository.
*
* @param pathtoExistingRepo - path to the existing git repository. The path is relative to the project root.
* @return instance of the git server container
*/
public GitServerContainer withCopyExistingGitRepoToContainer(String pathtoExistingRepo) {
this.pathToExistingRepo = pathtoExistingRepo;
return this;
}

/**
* Return the SSH URI for git repo.
*
* @return SSH URI
*/
public URI getGitRepoURIAsSSH() {

return URI.create("ssh://git@"+ getHost() + ":" + getMappedPort(22) + "/srv/git/" + gitRepoName + ".git");
return URI.create("ssh://git@" + getHost() + ":" + getMappedPort(22) + "/srv/git/" + gitRepoName + ".git");
}

@Override
protected void containerIsStarted(InspectContainerResponse containerInfo) {
super.containerIsStarted(containerInfo);
try {
String gitRepoPath = String.format("/srv/git/%s.git", gitRepoName);
execInContainer("mkdir", "-p", gitRepoPath);
execInContainer("git", "init", "--bare", gitRepoPath);
execInContainer("chown", "-R", "git:git", "/srv");
configureGitRepository();
collectHostKeyInformation();
}

private void collectHostKeyInformation() {
try {
ExecResult result = execInContainer("cat", "/etc/ssh/ssh_host_ecdsa_key.pub");
String[] catResult = result.getStdout().split(" ");
hostKey = new SshHostKey(getHost(), Base64.getDecoder().decode(catResult[1]));
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Could not collect host key information", e);

Check warning on line 125 in src/main/java/com/github/sparsick/testcontainers/gitserver/GitServerContainer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/github/sparsick/testcontainers/gitserver/GitServerContainer.java#L124-L125

Added lines #L124 - L125 were not covered by tests
}
}

private void configureGitRepository() {
try {
String gitRepoPath = String.format("/srv/git/%s.git", gitRepoName);
if (pathToExistingRepo != null) {
copyFileToContainer(MountableFile.forHostPath(pathToExistingRepo + "/.git"), gitRepoPath);
execInContainer("git", "config", "--bool", "core.bare", "true", gitRepoPath);
execInContainer("chown", "-R", "git:git", "/srv");
} else {
execInContainer("mkdir", "-p", gitRepoPath);
execInContainer("git", "init", "--bare", gitRepoPath);
execInContainer("chown", "-R", "git:git", "/srv");
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
throw new RuntimeException("Configure Git repository failed",e);

Check warning on line 142 in src/main/java/com/github/sparsick/testcontainers/gitserver/GitServerContainer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/github/sparsick/testcontainers/gitserver/GitServerContainer.java#L142

Added line #L142 was not covered by tests
}
}

/**
* Return the Git Password that was set with the method {@code withGitPassword}.
*
* <p>
* If no password was set, the default "12345" is returned.
*
* @return the git password
Expand All @@ -126,7 +157,7 @@

/**
* Return the identity information for public key authentication.
*
* <p>
* If {@code withSshKeyAuth} was not called, then it returns null.
*
* @return identity information for a public key authentication
Expand All @@ -143,4 +174,5 @@
public SshHostKey getHostKey() {
return hostKey;
}

}
Loading
Loading