diff --git a/src/main/kotlin/com/atlassian/performance/tools/sshubuntu/api/SshUbuntuContainer.kt b/src/main/kotlin/com/atlassian/performance/tools/sshubuntu/api/SshUbuntuContainer.kt index b9ab136..3c81497 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/sshubuntu/api/SshUbuntuContainer.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/sshubuntu/api/SshUbuntuContainer.kt @@ -1,10 +1,11 @@ package com.atlassian.performance.tools.sshubuntu.api -import com.atlassian.performance.tools.sshubuntu.SshUbuntuProperties import org.testcontainers.containers.GenericContainer import org.testcontainers.containers.wait.strategy.Wait +import org.testcontainers.images.builder.ImageFromDockerfile import org.testcontainers.utility.MountableFile import java.io.File +import java.util.concurrent.Future import java.util.function.Consumer class SshUbuntuContainer( @@ -17,8 +18,11 @@ class SshUbuntuContainer( } fun start(): SshUbuntu { - val version = SshUbuntuProperties().version - val ubuntu: GenericContainer<*> = GenericContainerImpl("atlassian/ssh-ubuntu:$version") + return start("bionic") + } + + fun start(ubuntuCodeName: String): SshUbuntu { + val ubuntu: GenericContainer<*> = GenericContainerImpl(getImage(ubuntuCodeName)) .withExposedPorts(SSH_PORT) .waitingFor(Wait.forListeningPort()) containerCustomization.accept(ubuntu) @@ -49,6 +53,17 @@ class SshUbuntuContainer( } } + private fun getImage(baseImage: String): Future { + if (baseImage[0].isDigit()) { + throw IllegalArgumentException("Only ubuntu codenames (e.g. focal) are supported, got: $baseImage") + } + val dockerfile = javaClass.getResource("/image/Dockerfile").readText() + .replace("UBUNTU_CODENAME", baseImage) + return ImageFromDockerfile("ssh-ubuntu-$baseImage", false) + .withFileFromClasspath("authorized_keys", "image/authorized_keys") + .withFileFromString("Dockerfile", dockerfile) + } + private fun getHostSshPort(ubuntuContainer: GenericContainer<*>) = ubuntuContainer.getMappedPort(SSH_PORT) @@ -59,7 +74,7 @@ class SshUbuntuContainer( * https://github.com/testcontainers/testcontainers-java/issues/318 * The class is a workaround for the problem. */ - private class GenericContainerImpl(dockerImageName: String) : GenericContainer(dockerImageName) { + private class GenericContainerImpl(imageName: Future) : GenericContainer(imageName) { override fun getLivenessCheckPortNumbers(): Set { return setOf(getMappedPort(SSH_PORT)) } diff --git a/src/main/resources/image/Dockerfile b/src/main/resources/image/Dockerfile new file mode 100644 index 0000000..e6b4a3a --- /dev/null +++ b/src/main/resources/image/Dockerfile @@ -0,0 +1,25 @@ +FROM ubuntu:UBUNTU_CODENAME + +RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt UBUNTU_CODENAME main restricted universe multiverse\n" > /etc/apt/sources.list +RUN apt-get update +RUN apt-get -y upgrade + +RUN apt-get install --no-install-recommends -y openssh-server ca-certificates + +RUN echo 'root:root' |chpasswd + +RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config + +RUN mkdir /root/.ssh + +RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + + +COPY authorized_keys /root/.ssh/ + +RUN mkdir /var/run/sshd + +EXPOSE 22 + +CMD ["/usr/sbin/sshd", "-D"] diff --git a/src/main/resources/image/authorized_keys b/src/main/resources/image/authorized_keys new file mode 100644 index 0000000..5e0e241 --- /dev/null +++ b/src/main/resources/image/authorized_keys @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzks4zFoVaXPHzTuvkWeX8pEt55bsS+q/TuFphQE+7Cl/GADElYz4ie81scl0M0tVE7SFx79wwTMPmVFB0kA5PqNOYIfDaqvLjGWhaUkIwj68Ld+OKDoOGH8kv6BdBeVv/GRKJwypXzJ9VhL2VmD4taMRc/R5GB7QITzJTXnxvk20SKPqRl8j8vF2fw2DGANy+pGbUoM7i3w9r39S3ngL9X91sKP1YFyqn0dBnQMdAU5zNAvmIjo6PGto74/J439TZiAO8Jz2NzMlsUC140rqwNdGj4taxgZQDe32z1n4YQvLTZVXShFgVRlts4kwX0mSpNTWwxWUMwyviIlMsz5hl root@2e859decf826 \ No newline at end of file diff --git a/src/test/kotlin/com/atlassian/performance/tools/sshubuntu/api/ssh/SshUbuntuTest.kt b/src/test/kotlin/com/atlassian/performance/tools/sshubuntu/api/ssh/SshUbuntuTest.kt index b07c3db..716281f 100644 --- a/src/test/kotlin/com/atlassian/performance/tools/sshubuntu/api/ssh/SshUbuntuTest.kt +++ b/src/test/kotlin/com/atlassian/performance/tools/sshubuntu/api/ssh/SshUbuntuTest.kt @@ -22,7 +22,7 @@ class SshUbuntuTest { @Test fun shouldInstallPackagesFast() { - SshUbuntuContainer().start().use { sshUbuntu -> + SshUbuntuContainer().start("bionic").use { sshUbuntu -> Ssh(with(sshUbuntu.ssh) { SshHost( ipAddress = ipAddress, @@ -32,7 +32,7 @@ class SshUbuntuTest { ) }).newConnection().use { connection -> connection.execute("apt-get update") - connection.execute("export DEBIAN_FRONTEND=noninteractive; apt-get install gnupg2 -y -qq", Duration.ofSeconds(15)) + connection.execute("export DEBIAN_FRONTEND=noninteractive; apt-get install wget -y -q", Duration.ofSeconds(15)) } } } @@ -41,7 +41,7 @@ class SshUbuntuTest { cmd: String, timeout: Duration = Duration.ofSeconds(30) ): SshConnection.SshResult { - SshUbuntuContainer().start().use { sshUbuntu -> + SshUbuntuContainer().start("bionic").use { sshUbuntu -> Ssh(with(sshUbuntu.ssh) { SshHost( ipAddress = ipAddress, @@ -62,7 +62,7 @@ class SshUbuntuTest { container.addExposedPort(additionalPort) } - SshUbuntuContainer(customization).start().use { sshUbuntu -> + SshUbuntuContainer(customization).start("bionic").use { sshUbuntu -> val ip = sshUbuntu.container.getContainerIpAddress() val port = sshUbuntu.container.getMappedPort(additionalPort) Socket(ip, port).close() @@ -75,7 +75,7 @@ class SshUbuntuTest { container.setPrivilegedMode(true) } - val privileged = SshUbuntuContainer(customization).start().use { sshUbuntu -> + val privileged = SshUbuntuContainer(customization).start("bionic").use { sshUbuntu -> sshUbuntu.container.isPrivilegedMode() }