From ffd7a065d2b41f9295ef5516923eebcea3893487 Mon Sep 17 00:00:00 2001 From: Viktor Taranenko Date: Sun, 9 Jul 2017 09:40:13 +0100 Subject: [PATCH] hostconfig with tmpfs --- .../com/whisk/docker/DockerContainer.scala | 9 ++++- .../whisk/docker/DockerContainerManager.scala | 7 ++-- .../impl/dockerjava/DockerJavaExecutor.scala | 40 +++++++++---------- .../SpotifyDockerCommandExecutor.scala | 13 +++--- .../docker/DockerElasticsearchService.scala | 8 ++-- .../com/whisk/docker/DockerNeo4jService.scala | 8 ++-- .../whisk/docker/DockerPostgresService.scala | 28 +++++++------ 7 files changed, 63 insertions(+), 50 deletions(-) diff --git a/core/src/main/scala/com/whisk/docker/DockerContainer.scala b/core/src/main/scala/com/whisk/docker/DockerContainer.scala index 772cb59..d366891 100644 --- a/core/src/main/scala/com/whisk/docker/DockerContainer.scala +++ b/core/src/main/scala/com/whisk/docker/DockerContainer.scala @@ -10,6 +10,10 @@ case class LogLineReceiver(withErr: Boolean, f: String => Unit) case class DockerPortMapping(hostPort: Option[Int] = None, address: String = "0.0.0.0") +case class HostConfig( + tmpfs: Option[Map[String, String]] = None +) + case class DockerContainer(image: String, name: Option[String] = None, command: Option[Seq[String]] = None, @@ -24,7 +28,8 @@ case class DockerContainer(image: String, volumeMappings: Seq[VolumeMapping] = Seq.empty, logLineReceiver: Option[LogLineReceiver] = None, user: Option[String] = None, - hostname: Option[String] = None) { + hostname: Option[String] = None, + hostConfig: Option[HostConfig] = None) { def withCommand(cmd: String*) = copy(command = Some(cmd)) @@ -54,4 +59,6 @@ case class DockerContainer(image: String, def withUser(user: String) = copy(user = Some(user)) def withHostname(hostname: String) = copy(hostname = Some(hostname)) + + def withHostConfig(hostConfig: HostConfig) = copy(hostConfig = Some(hostConfig)) } diff --git a/core/src/main/scala/com/whisk/docker/DockerContainerManager.scala b/core/src/main/scala/com/whisk/docker/DockerContainerManager.scala index 1b6bada..d67694a 100644 --- a/core/src/main/scala/com/whisk/docker/DockerContainerManager.scala +++ b/core/src/main/scala/com/whisk/docker/DockerContainerManager.scala @@ -41,8 +41,8 @@ class DockerContainerManager(containers: Seq[DockerContainer], executor: DockerC @tailrec def initGraph(graph: ContainerDependencyGraph, - previousInits: Future[Seq[DockerContainerState]] = Future.successful(Seq.empty) - ): Future[Seq[DockerContainerState]] = { + previousInits: Future[Seq[DockerContainerState]] = Future.successful(Seq.empty)) + : Future[Seq[DockerContainerState]] = { val initializedContainers = previousInits.flatMap { prev => Future.traverse(graph.containers.map(dockerStatesMap))(_.init()).map(prev ++ _) } @@ -50,7 +50,8 @@ class DockerContainerManager(containers: Seq[DockerContainer], executor: DockerC graph.dependants match { case None => initializedContainers case Some(dependants) => - val readyInits: Future[Seq[Future[Boolean]]] = initializedContainers.map(_.map(state => state.isReady())) + val readyInits: Future[Seq[Future[Boolean]]] = + initializedContainers.map(_.map(state => state.isReady())) val simplifiedReadyInits: Future[Seq[Boolean]] = readyInits.flatMap(Future.sequence(_)) Await.result(simplifiedReadyInits, containerStartTimeout) initGraph(dependants, initializedContainers) diff --git a/impl/docker-java/src/main/scala/com/whisk/docker/impl/dockerjava/DockerJavaExecutor.scala b/impl/docker-java/src/main/scala/com/whisk/docker/impl/dockerjava/DockerJavaExecutor.scala index f14bfd0..5dce17f 100644 --- a/impl/docker-java/src/main/scala/com/whisk/docker/impl/dockerjava/DockerJavaExecutor.scala +++ b/impl/docker-java/src/main/scala/com/whisk/docker/impl/dockerjava/DockerJavaExecutor.scala @@ -24,8 +24,28 @@ class DockerJavaExecutor(override val host: String, client: DockerClient) } val baseCmd = { + val hostConfig = new com.github.dockerjava.api.model.HostConfig() + hostConfig + .withOption(spec.networkMode)({ case (config, value) => config.withNetworkMode(value) }) + .withPortBindings(spec.bindPorts.foldLeft(new Ports()) { + case (ps, (guestPort, DockerPortMapping(Some(hostPort), address))) => + ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.bindPort(hostPort)) + ps + case (ps, (guestPort, DockerPortMapping(None, address))) => + ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.empty()) + ps + }) + .withLinks( + new Links(spec.links.map { + case ContainerLink(container, alias) => + new Link(container.name.get, alias) + }: _*) + ) + .withBinds(new Binds(volumeToBind.map(_._2): _*)) + val tmpCmd = client .createContainerCmd(spec.image) + .withHostConfig(hostConfig) .withPortSpecs(spec.bindPorts .map({ case (guestPort, DockerPortMapping(Some(hostPort), address)) => @@ -37,27 +57,7 @@ class DockerJavaExecutor(override val host: String, client: DockerClient) .withTty(spec.tty) .withStdinOpen(spec.stdinOpen) .withEnv(spec.env: _*) - .withOption(spec.networkMode) { - case (config, networkMode) => config.withNetworkMode(networkMode) - } - .withPortBindings( - spec.bindPorts.foldLeft(new Ports()) { - case (ps, (guestPort, DockerPortMapping(Some(hostPort), address))) => - ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.bindPort(hostPort)) - ps - case (ps, (guestPort, DockerPortMapping(None, address))) => - ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.empty()) - ps - } - ) - .withLinks( - spec.links.map { - case ContainerLink(container, alias) => - new Link(container.name.get, alias) - }.asJava - ) .withVolumes(volumeToBind.map(_._1): _*) - .withBinds(volumeToBind.map(_._2): _*) .withOption(spec.user) { case (config, user) => config.withUser(user) } .withOption(spec.hostname) { case (config, hostName) => config.withHostName(hostName) } diff --git a/impl/spotify/src/main/scala/com/whisk/docker/impl/spotify/SpotifyDockerCommandExecutor.scala b/impl/spotify/src/main/scala/com/whisk/docker/impl/spotify/SpotifyDockerCommandExecutor.scala index c36dd11..589bd70 100644 --- a/impl/spotify/src/main/scala/com/whisk/docker/impl/spotify/SpotifyDockerCommandExecutor.scala +++ b/impl/spotify/src/main/scala/com/whisk/docker/impl/spotify/SpotifyDockerCommandExecutor.scala @@ -28,14 +28,14 @@ class SpotifyDockerCommandExecutor(override val host: String, client: DockerClie case (guestPort, DockerPortMapping(None, address)) => guestPort.toString -> Collections.singletonList(PortBinding.randomPort(address)) } - val binds: Seq[String] = spec.volumeMappings.map{ - volumeMapping => - val rw = if(volumeMapping.rw) ":rw" else "" - volumeMapping.host + ":" + volumeMapping.container + rw + val binds: Seq[String] = spec.volumeMappings.map { volumeMapping => + val rw = if (volumeMapping.rw) ":rw" else "" + volumeMapping.host + ":" + volumeMapping.container + rw } val hostConfig = { - val hostConfigBase = HostConfig.builder().portBindings(portBindings.asJava).binds(binds.asJava) + val hostConfigBase = + HostConfig.builder().portBindings(portBindings.asJava).binds(binds.asJava) val links = spec.links.map { case ContainerLink(container, alias) => s"${container.name.get}:$alias" @@ -47,6 +47,9 @@ class SpotifyDockerCommandExecutor(override val host: String, client: DockerClie .withOption(spec.networkMode) { case (config, networkMode) => config.networkMode(networkMode) } + .withOption(spec.hostConfig.flatMap(_.tmpfs)) { + case (config, value) => config.tmpfs(value.asJava) + } .build() } diff --git a/samples/src/main/scala/com/whisk/docker/DockerElasticsearchService.scala b/samples/src/main/scala/com/whisk/docker/DockerElasticsearchService.scala index f71784d..bef2c92 100644 --- a/samples/src/main/scala/com/whisk/docker/DockerElasticsearchService.scala +++ b/samples/src/main/scala/com/whisk/docker/DockerElasticsearchService.scala @@ -10,10 +10,10 @@ trait DockerElasticsearchService extends DockerKit { val elasticsearchContainer = DockerContainer("elasticsearch:1.7.1") .withPorts(DefaultElasticsearchHttpPort -> None, DefaultElasticsearchClientPort -> None) .withReadyChecker( - DockerReadyChecker - .HttpResponseCode(DefaultElasticsearchHttpPort, "/") - .within(100.millis) - .looped(20, 1250.millis) + DockerReadyChecker + .HttpResponseCode(DefaultElasticsearchHttpPort, "/") + .within(100.millis) + .looped(20, 1250.millis) ) abstract override def dockerContainers: List[DockerContainer] = diff --git a/samples/src/main/scala/com/whisk/docker/DockerNeo4jService.scala b/samples/src/main/scala/com/whisk/docker/DockerNeo4jService.scala index a2c32f3..8990495 100644 --- a/samples/src/main/scala/com/whisk/docker/DockerNeo4jService.scala +++ b/samples/src/main/scala/com/whisk/docker/DockerNeo4jService.scala @@ -10,10 +10,10 @@ trait DockerNeo4jService extends DockerKit { .withPorts(DefaultNeo4jHttpPort -> None) .withEnv("NEO4J_AUTH=none") .withReadyChecker( - DockerReadyChecker - .HttpResponseCode(DefaultNeo4jHttpPort, "/db/data/") - .within(100.millis) - .looped(20, 1250.millis) + DockerReadyChecker + .HttpResponseCode(DefaultNeo4jHttpPort, "/db/data/") + .within(100.millis) + .looped(20, 1250.millis) ) abstract override def dockerContainers: List[DockerContainer] = diff --git a/samples/src/main/scala/com/whisk/docker/DockerPostgresService.scala b/samples/src/main/scala/com/whisk/docker/DockerPostgresService.scala index 817a4b1..6b8996a 100644 --- a/samples/src/main/scala/com/whisk/docker/DockerPostgresService.scala +++ b/samples/src/main/scala/com/whisk/docker/DockerPostgresService.scala @@ -16,23 +16,25 @@ trait DockerPostgresService extends DockerKit { .withPorts((PostgresAdvertisedPort, Some(PostgresExposedPort))) .withEnv(s"POSTGRES_USER=$PostgresUser", s"POSTGRES_PASSWORD=$PostgresPassword") .withReadyChecker( - new PostgresReadyChecker(PostgresUser, PostgresPassword, Some(PostgresExposedPort)).looped(15, 1.second) + new PostgresReadyChecker(PostgresUser, PostgresPassword, Some(PostgresExposedPort)) + .looped(15, 1.second) ) abstract override def dockerContainers: List[DockerContainer] = postgresContainer :: super.dockerContainers } -class PostgresReadyChecker(user: String, password: String, port: Option[Int] = None) extends DockerReadyChecker { +class PostgresReadyChecker(user: String, password: String, port: Option[Int] = None) + extends DockerReadyChecker { - override def apply(container: DockerContainerState)(implicit docker: DockerCommandExecutor, ec: ExecutionContext) = - container.getPorts().map(ports => - Try { - Class.forName("org.postgresql.Driver") - val url = s"jdbc:postgresql://${docker.host}:${port.getOrElse(ports.values.head)}/" - Option(DriverManager.getConnection(url, user, password)) - .map(_.close) - .isDefined - }.getOrElse(false) - ) -} \ No newline at end of file + override def apply(container: DockerContainerState)(implicit docker: DockerCommandExecutor, + ec: ExecutionContext) = + container + .getPorts() + .map(ports => + Try { + Class.forName("org.postgresql.Driver") + val url = s"jdbc:postgresql://${docker.host}:${port.getOrElse(ports.values.head)}/" + Option(DriverManager.getConnection(url, user, password)).map(_.close).isDefined + }.getOrElse(false)) +}