Skip to content

Commit

Permalink
feat: deploy Docker registry on Kubernetes
Browse files Browse the repository at this point in the history
  • Loading branch information
manusa committed Mar 22, 2023
1 parent 3e7451a commit b4b772d
Showing 1 changed file with 53 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.eclipse.jkube.integrationtests.cli.CliUtils;
import org.eclipse.jkube.integrationtests.jupiter.api.DockerRegistry;
import org.eclipse.jkube.integrationtests.jupiter.api.DockerRegistryHost;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
Expand All @@ -30,35 +29,40 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.stream.Stream;

import static org.eclipse.jkube.integrationtests.cli.CliUtils.isWindows;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

public class RegistryExtension implements HasKubernetesClient, BeforeAllCallback, BeforeEachCallback, AfterAllCallback {

private static final Logger log = LoggerFactory.getLogger(RegistryExtension.class);

private static final String K8S_RESOURCE_NAME = "docker-registry";

@Override
public void beforeAll(ExtensionContext context) throws Exception {
final var annotation = context.getRequiredTestClass().getAnnotation(DockerRegistry.class);
CliUtils.runCommand("docker rm -f " + getName(annotation));
log.debug(() -> "Starting Docker Registry Extension");
final CliUtils.CliResult dockerRegistry;
final RegistryInfo dockerRegistry;
if (isWindows()) {
dockerRegistry = startWindowsDockerRegistry(annotation);
} else {
dockerRegistry = startRegularDockerRegistry(annotation);
dockerRegistry = startKubernetesDockerRegistry(context);
}
assertThat(dockerRegistry.getOutput(), dockerRegistry.getExitCode(), Matchers.equalTo(0));
assertThat(dockerRegistry.assertionContext, dockerRegistry.host, notNullValue());
getStore(context).put(RegistryInfo.class, dockerRegistry);
log.debug(() -> "Docker Registry started successfully");
}

@Override
public void beforeEach(ExtensionContext context) throws Exception {
final var annotation = context.getRequiredTestClass().getAnnotation(DockerRegistry.class);
final var registryInfo = getStore(context).get(RegistryInfo.class, RegistryInfo.class);
for (Field f : context.getRequiredTestClass().getDeclaredFields()) {
if (f.isAnnotationPresent(DockerRegistryHost.class) && f.getType() == String.class) {
setFieldValue(f, context.getRequiredTestInstance(), getDockerHost() + ":" + annotation.port());
setFieldValue(f, context.getRequiredTestInstance(), registryInfo.host + ":" + registryInfo.port);
}
}
}
Expand All @@ -67,22 +71,47 @@ public void beforeEach(ExtensionContext context) throws Exception {
public void afterAll(ExtensionContext context) throws Exception {
log.debug(() -> "Closing Docker Registry");
CliUtils.runCommand("docker stop " + getName(context.getRequiredTestClass().getAnnotation(DockerRegistry.class)));
if (!isWindows()) {
deleteKubernetesDockerRegistry(context);
}
}

private void deleteKubernetesDockerRegistry(ExtensionContext context) {
final var client = getClient(context);
Stream.of(
client.pods().withName(K8S_RESOURCE_NAME),
client.services().withName(K8S_RESOURCE_NAME)
).forEach(r -> r.withGracePeriod(0L).delete());
}

private static CliUtils.CliResult startRegularDockerRegistry(DockerRegistry dockerRegistry) throws IOException, InterruptedException {
log.debug(() -> "Starting standard Docker Registry");
return CliUtils.runCommand("docker run --rm -d -p " + dockerRegistry.port() +":5000 --name " +
getName(dockerRegistry) + " registry:2");
private RegistryInfo startKubernetesDockerRegistry(ExtensionContext context) throws IOException, InterruptedException {
deleteKubernetesDockerRegistry(context);
final var client = getClient(context);
final var ip = CliUtils.runCommand("minikube ip").getOutput().trim();
final var dockerRegistry = client.run().withName(K8S_RESOURCE_NAME).withImage("registry:2")
.withNewRunConfig()
.addToLabels("app", K8S_RESOURCE_NAME).addToLabels("group", "jkube-it").done();
final var service = client.services().resource(new ServiceBuilder()
.withNewMetadata().withName(K8S_RESOURCE_NAME)
.addToLabels("app", K8S_RESOURCE_NAME).addToLabels("group", "jkube-it").endMetadata()
.withNewSpec().withType("NodePort").withSelector(dockerRegistry.getMetadata().getLabels())
.addNewPort().withName("http").withPort(5000).withTargetPort(new IntOrString(5000)).endPort().endSpec()
.build()).serverSideApply();
return new RegistryInfo(ip, service.getSpec().getPorts().get(0).getNodePort(), null);
}

private static CliUtils.CliResult startWindowsDockerRegistry(DockerRegistry dockerRegistry) throws IOException, InterruptedException {
private static RegistryInfo startWindowsDockerRegistry(DockerRegistry dockerRegistry) throws IOException, InterruptedException {
log.debug(() -> "Starting Windows specific Docker Registry");
final var registry = new File("C:\\registry");
if (!registry.exists() && !registry.mkdirs()) {
throw new IllegalStateException("Directory C:\\registry cannot be created");
}
return CliUtils.runCommand("docker run --rm -d -p " + dockerRegistry.port() +":5000 --name " +
final var result = CliUtils.runCommand("docker run --rm -d -p " + dockerRegistry.port() +":5000 --name " +
getName(dockerRegistry) + " -v C:\\registry:C:\\registry marcnuri/docker-registry-windows:ltsc2022");
if (result.getExitCode() != 0) {
return new RegistryInfo(null, -1, result.getOutput());
}
return new RegistryInfo(getDockerHost(), dockerRegistry.port(), result.getOutput());
}

private static String getName(DockerRegistry dockerRegistry) {
Expand All @@ -98,4 +127,16 @@ private static String getDockerHost() {
.replaceAll(":\\d+$", "");
}
}

private static final class RegistryInfo {
private final String host;
private final int port;
private final String assertionContext;

public RegistryInfo(String host, int port, String assertionContext) {
this.host = host;
this.port = port;
this.assertionContext = assertionContext;
}
}
}

0 comments on commit b4b772d

Please sign in to comment.