2018-10-16 15:35:55 +02:00
|
|
|
/*
|
2019-01-02 18:55:26 +08:00
|
|
|
* Copyright (C) 2018-2019 Lightbend Inc. <https://www.lightbend.com>
|
2018-10-16 15:35:55 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package akka.io.dns
|
|
|
|
|
|
2019-05-24 08:11:50 +02:00
|
|
|
import akka.util.ccompat.JavaConverters._
|
2018-10-16 15:35:55 +02:00
|
|
|
import akka.testkit.AkkaSpec
|
|
|
|
|
import com.spotify.docker.client.DefaultDockerClient
|
2019-02-12 08:06:52 +00:00
|
|
|
import com.spotify.docker.client.DockerClient.{ ListContainersParam, LogsParam }
|
2018-10-16 15:35:55 +02:00
|
|
|
import com.spotify.docker.client.messages.{ ContainerConfig, HostConfig, PortBinding }
|
|
|
|
|
import org.scalatest.concurrent.Eventually
|
|
|
|
|
|
2018-11-05 06:05:16 -08:00
|
|
|
import scala.concurrent.duration._
|
2018-10-16 15:35:55 +02:00
|
|
|
import scala.util.Try
|
|
|
|
|
import scala.util.control.NonFatal
|
|
|
|
|
|
2019-02-09 15:25:39 +01:00
|
|
|
trait DockerBindDnsService extends Eventually { self: AkkaSpec =>
|
2018-10-16 15:35:55 +02:00
|
|
|
val client = DefaultDockerClient.fromEnv().build()
|
|
|
|
|
|
|
|
|
|
val hostPort: Int
|
|
|
|
|
|
|
|
|
|
var id: Option[String] = None
|
|
|
|
|
|
|
|
|
|
def dockerAvailable() = Try(client.ping()).isSuccess
|
|
|
|
|
|
|
|
|
|
override def atStartup(): Unit = {
|
2018-12-05 11:35:10 +00:00
|
|
|
log.info("Running on port port {}", hostPort)
|
2018-10-16 15:35:55 +02:00
|
|
|
self.atStartup()
|
|
|
|
|
|
|
|
|
|
// https://github.com/sameersbn/docker-bind/pull/61
|
|
|
|
|
val image = "raboof/bind:9.11.3-20180713-nochown"
|
|
|
|
|
try {
|
|
|
|
|
client.pull(image)
|
|
|
|
|
} catch {
|
2019-02-09 15:25:39 +01:00
|
|
|
case NonFatal(_) =>
|
2018-10-16 15:35:55 +02:00
|
|
|
log.warning(s"Failed to pull docker image [$image], is docker running?")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-11 10:38:24 +01:00
|
|
|
val containerConfig = ContainerConfig
|
|
|
|
|
.builder()
|
2018-10-16 15:35:55 +02:00
|
|
|
.image(image)
|
|
|
|
|
.env("NO_CHOWN=true")
|
2018-12-05 11:35:10 +00:00
|
|
|
.cmd("-4") // only listen on ipv4
|
2018-10-16 15:35:55 +02:00
|
|
|
.hostConfig(
|
2019-03-11 10:38:24 +01:00
|
|
|
HostConfig
|
|
|
|
|
.builder()
|
2019-03-13 10:56:20 +01:00
|
|
|
.portBindings(Map(
|
|
|
|
|
"53/tcp" -> List(PortBinding.of("", hostPort)).asJava,
|
|
|
|
|
"53/udp" -> List(PortBinding.of("", hostPort)).asJava).asJava)
|
2019-03-11 10:38:24 +01:00
|
|
|
.binds(HostConfig.Bind
|
|
|
|
|
.from(new java.io.File("akka-actor-tests/src/test/bind/").getAbsolutePath)
|
|
|
|
|
.to("/data/bind")
|
|
|
|
|
.build())
|
|
|
|
|
.build())
|
2018-10-16 15:35:55 +02:00
|
|
|
.build()
|
|
|
|
|
|
2019-02-12 08:06:52 +00:00
|
|
|
val containerName = "akka-test-dns-" + getClass.getCanonicalName
|
|
|
|
|
|
2019-03-11 10:38:24 +01:00
|
|
|
client
|
|
|
|
|
.listContainers(ListContainersParam.allContainers())
|
|
|
|
|
.asScala
|
|
|
|
|
.find(_.names().asScala.exists(_.contains(containerName)))
|
|
|
|
|
.foreach(c => {
|
2019-02-14 09:40:15 +00:00
|
|
|
if ("running" == c.state()) {
|
|
|
|
|
client.killContainer(c.id)
|
|
|
|
|
}
|
|
|
|
|
client.removeContainer(c.id)
|
2019-02-12 08:06:52 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
val creation = client.createContainer(containerConfig, containerName)
|
2019-08-14 16:24:11 +02:00
|
|
|
creation.warnings() should be(null).or(have(size(0)))
|
2018-10-16 15:35:55 +02:00
|
|
|
id = Some(creation.id())
|
|
|
|
|
|
|
|
|
|
client.startContainer(creation.id())
|
|
|
|
|
|
2018-11-12 09:11:15 +01:00
|
|
|
eventually(timeout(25.seconds)) {
|
2018-10-16 15:35:55 +02:00
|
|
|
client.logs(creation.id(), LogsParam.stderr()).readFully() should include("all zones loaded")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-20 16:59:46 +00:00
|
|
|
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()))
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-16 15:35:55 +02:00
|
|
|
override def afterTermination(): Unit = {
|
|
|
|
|
self.afterTermination()
|
|
|
|
|
id.foreach(client.killContainer)
|
|
|
|
|
id.foreach(client.removeContainer)
|
|
|
|
|
}
|
|
|
|
|
}
|