Replacing deprecated docker-client with docker-java (#922)
* Replacing deprecated docker-client with docker-java. * Addressing feedback. * Awaiting for image pull. --------- Co-authored-by: Samuele Resca <sr7@ad.datcon.co.uk>
This commit is contained in:
parent
3f8be563b9
commit
b7be586e77
2 changed files with 104 additions and 51 deletions
|
|
@ -18,23 +18,43 @@ import scala.util.Try
|
|||
import scala.util.control.NonFatal
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import com.spotify.docker.client.DefaultDockerClient
|
||||
import com.spotify.docker.client.DockerClient.{ ListContainersParam, LogsParam }
|
||||
import com.spotify.docker.client.messages.{ ContainerConfig, HostConfig, PortBinding }
|
||||
import com.github.dockerjava.core.DockerClientConfig
|
||||
import com.github.dockerjava.api.model.HostConfig;
|
||||
import com.github.dockerjava.core.DefaultDockerClientConfig
|
||||
import com.github.dockerjava.api.model.Frame;
|
||||
import com.github.dockerjava.api.async.ResultCallback;
|
||||
import org.scalatest.concurrent.Eventually
|
||||
|
||||
import org.apache.pekko
|
||||
import pekko.testkit.PekkoSpec
|
||||
import pekko.util.ccompat.JavaConverters._
|
||||
import com.github.dockerjava.api.DockerClient
|
||||
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient
|
||||
import com.github.dockerjava.api.command.CreateContainerCmd
|
||||
import com.github.dockerjava.api.model.PortBinding
|
||||
import com.github.dockerjava.api.model.Container
|
||||
import com.github.dockerjava.api.model.Volume
|
||||
import com.github.dockerjava.core.DockerClientImpl
|
||||
import com.github.dockerjava.api.model.Bind
|
||||
|
||||
abstract class DockerBindDnsService(config: Config) extends PekkoSpec(config) with Eventually {
|
||||
val client = DefaultDockerClient.fromEnv().build()
|
||||
|
||||
val dockerConfig: DockerClientConfig = DefaultDockerClientConfig
|
||||
.createDefaultConfigBuilder()
|
||||
.build();
|
||||
|
||||
val httpClient: ApacheDockerHttpClient = new ApacheDockerHttpClient.Builder()
|
||||
.dockerHost(dockerConfig.getDockerHost())
|
||||
.sslConfig(dockerConfig.getSSLConfig())
|
||||
.build();
|
||||
|
||||
val client: DockerClient = DockerClientImpl.getInstance(dockerConfig, httpClient);
|
||||
|
||||
val hostPort: Int
|
||||
|
||||
var id: Option[String] = None
|
||||
|
||||
def dockerAvailable() = Try(client.ping()).isSuccess
|
||||
def dockerAvailable() = Try(client.pingCmd().exec()).isSuccess
|
||||
|
||||
override def atStartup(): Unit = {
|
||||
log.info("Running on port port {}", hostPort)
|
||||
|
|
@ -43,64 +63,100 @@ abstract class DockerBindDnsService(config: Config) extends PekkoSpec(config) wi
|
|||
// https://github.com/sameersbn/docker-bind/pull/61
|
||||
val image = "raboof/bind:9.11.3-20180713-nochown"
|
||||
try {
|
||||
client.pull(image)
|
||||
client
|
||||
.pullImageCmd(image)
|
||||
.start()
|
||||
.awaitCompletion()
|
||||
} catch {
|
||||
case NonFatal(_) =>
|
||||
log.warning(s"Failed to pull docker image [$image], is docker running?")
|
||||
return
|
||||
}
|
||||
|
||||
val containerConfig = ContainerConfig
|
||||
.builder()
|
||||
.image(image)
|
||||
.env("NO_CHOWN=true")
|
||||
.cmd("-4") // only listen on ipv4
|
||||
.hostConfig(
|
||||
HostConfig
|
||||
.builder()
|
||||
.portBindings(Map(
|
||||
"53/tcp" -> List(PortBinding.of("", hostPort)).asJava,
|
||||
"53/udp" -> List(PortBinding.of("", hostPort)).asJava).asJava)
|
||||
.binds(HostConfig.Bind
|
||||
.from(new java.io.File("actor-tests/src/test/bind/").getAbsolutePath)
|
||||
.to("/data/bind")
|
||||
.build())
|
||||
.build())
|
||||
.build()
|
||||
|
||||
val containerName = "pekko-test-dns-" + getClass.getCanonicalName
|
||||
|
||||
val containerCommand: CreateContainerCmd = client
|
||||
.createContainerCmd(image)
|
||||
.withName(containerName)
|
||||
.withEnv("NO_CHOWN=true")
|
||||
.withCmd("-4")
|
||||
.withHostConfig(
|
||||
HostConfig.newHostConfig()
|
||||
.withPortBindings(
|
||||
PortBinding.parse(s"$hostPort:53/tcp"),
|
||||
PortBinding.parse(s"$hostPort:53/udp"))
|
||||
.withBinds(new Bind(new java.io.File("actor-tests/src/test/bind/").getAbsolutePath,
|
||||
new Volume("/data/bind"))))
|
||||
|
||||
client
|
||||
.listContainers(ListContainersParam.allContainers())
|
||||
.listContainersCmd()
|
||||
.exec()
|
||||
.asScala
|
||||
.find(_.names().asScala.exists(_.contains(containerName)))
|
||||
.foreach(c => {
|
||||
if ("running" == c.state()) {
|
||||
client.killContainer(c.id)
|
||||
.find((c: Container) => c.getNames().exists(_.contains(containerName)))
|
||||
.foreach((c: Container) => {
|
||||
if ("running" == c.getState()) {
|
||||
client.killContainerCmd(c.getId()).exec()
|
||||
}
|
||||
client.removeContainer(c.id)
|
||||
client.removeContainerCmd(c.getId()).exec()
|
||||
})
|
||||
|
||||
val creation = client.createContainer(containerConfig, containerName)
|
||||
if (creation.warnings() != null)
|
||||
creation.warnings() should have(size(0))
|
||||
id = Some(creation.id())
|
||||
val creation = containerCommand.exec()
|
||||
if (creation.getWarnings() != null)
|
||||
creation.getWarnings() should have(size(0))
|
||||
id = Some(creation.getId())
|
||||
|
||||
client.startContainer(creation.id())
|
||||
client.startContainerCmd(creation.getId()).exec()
|
||||
val reader = new StringBuilderLogReader
|
||||
|
||||
eventually(timeout(25.seconds)) {
|
||||
client.logs(creation.id(), LogsParam.stderr()).readFully() should include("all zones loaded")
|
||||
client
|
||||
.logContainerCmd(creation.getId())
|
||||
.withStdErr(true)
|
||||
.exec(reader)
|
||||
|
||||
reader.toString should include("all zones loaded")
|
||||
}
|
||||
}
|
||||
|
||||
def dumpNameserverLogs(): Unit = {
|
||||
id.foreach(id => log.info("Nameserver std out: {} ", client.logs(id, LogsParam.stdout()).readFully()))
|
||||
id.foreach(id => log.info("Nameserver std err: {} ", client.logs(id, LogsParam.stderr()).readFully()))
|
||||
id.foreach(id => {
|
||||
val reader = new StringBuilderLogReader
|
||||
client
|
||||
.logContainerCmd(id)
|
||||
.withStdOut(true)
|
||||
.exec(reader)
|
||||
.awaitCompletion()
|
||||
|
||||
log.info("Nameserver std out: {} ", reader.toString())
|
||||
})
|
||||
id.foreach(id => {
|
||||
val reader = new StringBuilderLogReader
|
||||
client
|
||||
.logContainerCmd(id)
|
||||
.withStdErr(true)
|
||||
.exec(reader)
|
||||
.awaitCompletion()
|
||||
log.info("Nameserver std err: {} ", reader.toString())
|
||||
})
|
||||
}
|
||||
|
||||
override def afterTermination(): Unit = {
|
||||
super.afterTermination()
|
||||
id.foreach(client.killContainer)
|
||||
id.foreach(client.removeContainer)
|
||||
id.foreach(id => client.killContainerCmd(id).exec())
|
||||
id.foreach(id => client.removeContainerCmd(id).exec())
|
||||
|
||||
client.close()
|
||||
}
|
||||
}
|
||||
|
||||
class StringBuilderLogReader extends ResultCallback.Adapter[Frame] {
|
||||
|
||||
lazy val builder: StringBuilder = new StringBuilder
|
||||
|
||||
override def onNext(item: Frame): Unit = {
|
||||
builder.append(new String(item.getPayload))
|
||||
super.onNext(item)
|
||||
}
|
||||
|
||||
override def toString(): String = builder.toString()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,9 +167,11 @@ object Dependencies {
|
|||
// in-memory filesystem for file related tests
|
||||
val jimfs = "com.google.jimfs" % "jimfs" % "1.3.0" % Test
|
||||
|
||||
// docker utils
|
||||
val dockerClient = ("com.spotify" % "docker-client" % "8.16.0" % Test)
|
||||
.exclude("org.bouncycastle", "bcpkix-jdk15on")
|
||||
val dockerClient = Def.setting {
|
||||
Seq(
|
||||
"com.github.docker-java" % "docker-java-core" % "3.3.4" % Test,
|
||||
"com.github.docker-java" % "docker-java-transport-httpclient5" % "3.3.4" % Test)
|
||||
}
|
||||
|
||||
val jackson = Def.setting {
|
||||
Seq(
|
||||
|
|
@ -250,18 +252,13 @@ object Dependencies {
|
|||
TestDependencies.scalatest.value,
|
||||
TestDependencies.scalatestJUnit.value,
|
||||
TestDependencies.scalatestScalaCheck.value,
|
||||
TestDependencies.bcpkix, // to force TestDependencies.dockerClient to use safe version of this lib
|
||||
TestDependencies.commonsCodec,
|
||||
TestDependencies.commonsCompress, // to force TestDependencies.dockerClient to use safe version of this lib
|
||||
TestDependencies.commonsIo, // to force TestDependencies.dockerClient to use safe version of this lib
|
||||
TestDependencies.commonsMath,
|
||||
TestDependencies.httpClient, // to force TestDependencies.dockerClient to use safe version of this lib
|
||||
TestDependencies.jimfs,
|
||||
TestDependencies.dockerClient,
|
||||
Provided.activation // dockerClient needs javax.activation.DataSource in JDK 11+
|
||||
) ++ {
|
||||
TestDependencies.jimfs) ++ {
|
||||
// TestDependencies.dockerClient bring in older versions of libs that have CVEs
|
||||
TestDependencies.jackson.value
|
||||
} ++ {
|
||||
TestDependencies.dockerClient.value
|
||||
}
|
||||
|
||||
val actorTestkitTyped = l ++= Seq(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue