Skip to content

Commit 6b24f98

Browse files
committed
Merge branch 'master' of github.com:whisklabs/docker-it-scala
2 parents d132200 + a53e644 commit 6b24f98

File tree

6 files changed

+90
-50
lines changed

6 files changed

+90
-50
lines changed

config/src/main/scala/com/whisk/docker/config/DockerTypesafeConfig.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.whisk.docker.config
22

33
import com.whisk.docker.impl.dockerjava.DockerKitDockerJava
4-
import com.whisk.docker.{DockerContainer, DockerPortMapping, DockerReadyChecker, VolumeMapping}
4+
import com.whisk.docker.{DockerContainer, DockerPortMapping, DockerReadyChecker, HostConfig, VolumeMapping}
55

66
import scala.concurrent.duration._
77

@@ -46,10 +46,13 @@ object DockerTypesafeConfig extends DockerKitDockerJava {
4646
case class DockerConfig(`image-name`: String,
4747
`container-name`: Option[String],
4848
command: Option[Seq[String]],
49+
entrypoint: Option[Seq[String]],
4950
`environmental-variables`: Seq[String] = Seq.empty,
5051
`port-maps`: Option[Map[String, DockerConfigPortMap]],
5152
`ready-checker`: Option[DockerConfigReadyChecker],
52-
`volume-maps`: Seq[VolumeMapping] = Seq.empty) {
53+
`volume-maps`: Seq[VolumeMapping] = Seq.empty,
54+
memory: Option[Long],
55+
`memory-reservation`: Option[Long]) {
5356

5457
def toDockerContainer(): DockerContainer = {
5558
val bindPorts = `port-maps`.fold(EmptyPortBindings) { _.values.map(_.asTuple).toMap } mapValues {
@@ -59,14 +62,21 @@ object DockerTypesafeConfig extends DockerKitDockerJava {
5962

6063
val readyChecker = `ready-checker`.fold[DockerReadyChecker](AlwaysReady) { _.toReadyChecker }
6164

65+
val hostConfig = HostConfig(
66+
memory = memory,
67+
memoryReservation = `memory-reservation`
68+
)
69+
6270
DockerContainer(
6371
image = `image-name`,
6472
name = `container-name`,
6573
command = command,
74+
entrypoint = entrypoint,
6675
bindPorts = bindPorts,
6776
env = `environmental-variables`,
6877
readyChecker = readyChecker,
69-
volumeMappings = `volume-maps`
78+
volumeMappings = `volume-maps`,
79+
hostConfig = Some(hostConfig)
7080
)
7181
}
7282
}

config/src/test/resources/application.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ docker {
8383

8484
elasticsearch {
8585
image-name = "elasticsearch:1.7.1"
86+
entrypoint = [ "my", "custom", "entrypoint" ]
87+
memory = 536870912 # 512MB
88+
memory-reservation = 268435456 # 256MB
8689
ready-checker {
8790
http-response-code {
8891
port = 9200

config/src/test/scala/com/whisk/docker/config/test/DockerConfigSpec.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.whisk.docker.config.test
22

3-
import com.whisk.docker.{DockerContainer, DockerReadyChecker, VolumeMapping}
3+
import com.whisk.docker.{DockerContainer, DockerReadyChecker, HostConfig, VolumeMapping}
44
import com.whisk.docker.config.DockerKitConfig
55
import org.scalatest._
66

@@ -38,7 +38,9 @@ class DockerConfigSpec extends FlatSpec with Matchers with DockerKitConfig {
3838
configureDockerContainer("docker.mongodb") shouldBe mongodbExpected
3939

4040
val elasticExpected = DockerContainer("elasticsearch:1.7.1")
41+
.withEntrypoint("my", "custom", "entrypoint")
4142
.withPorts(9200 -> None, 9300 -> None)
43+
.withHostConfig(HostConfig(memory = Some(536870912), memoryReservation = Some(268435456)))
4244
.withReadyChecker(
4345
DockerReadyChecker
4446
.HttpResponseCode(9200, "/")

core/src/main/scala/com/whisk/docker/DockerContainer.scala

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,25 @@ case class LogLineReceiver(withErr: Boolean, f: String => Unit)
1111
case class DockerPortMapping(hostPort: Option[Int] = None, address: String = "0.0.0.0")
1212

1313
case class HostConfig(
14-
tmpfs: Option[Map[String, String]] = None
14+
15+
tmpfs: Option[Map[String, String]] = None,
16+
17+
/**
18+
* the hard limit on memory usage (in bytes)
19+
*/
20+
memory: Option[Long] = None,
21+
22+
/**
23+
* the soft limit on memory usage (in bytes)
24+
*/
25+
memoryReservation: Option[Long] = None
26+
1527
)
1628

1729
case class DockerContainer(image: String,
1830
name: Option[String] = None,
1931
command: Option[Seq[String]] = None,
32+
entrypoint: Option[Seq[String]] = None,
2033
bindPorts: Map[Int, DockerPortMapping] = Map.empty,
2134
tty: Boolean = false,
2235
stdinOpen: Boolean = false,
@@ -33,6 +46,8 @@ case class DockerContainer(image: String,
3346

3447
def withCommand(cmd: String*) = copy(command = Some(cmd))
3548

49+
def withEntrypoint(entrypoint: String*) = copy(entrypoint = Some(entrypoint))
50+
3651
def withPorts(ps: (Int, Option[Int])*) =
3752
copy(bindPorts = ps.toMap.mapValues(hostPort => DockerPortMapping(hostPort)))
3853

@@ -61,4 +76,5 @@ case class DockerContainer(image: String,
6176
def withHostname(hostname: String) = copy(hostname = Some(hostname))
6277

6378
def withHostConfig(hostConfig: HostConfig) = copy(hostConfig = Some(hostConfig))
79+
6480
}

impl/docker-java/src/main/scala/com/whisk/docker/impl/dockerjava/DockerJavaExecutor.scala

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,48 +23,51 @@ class DockerJavaExecutor(override val host: String, client: DockerClient)
2323
(volume, new Bind(mapping.host, volume, AccessMode.fromBoolean(mapping.rw)))
2424
}
2525

26-
val baseCmd = {
27-
val hostConfig = new com.github.dockerjava.api.model.HostConfig()
28-
hostConfig
29-
.withOption(spec.networkMode)({ case (config, value) => config.withNetworkMode(value) })
30-
.withPortBindings(spec.bindPorts.foldLeft(new Ports()) {
31-
case (ps, (guestPort, DockerPortMapping(Some(hostPort), address))) =>
32-
ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.bindPort(hostPort))
33-
ps
34-
case (ps, (guestPort, DockerPortMapping(None, address))) =>
35-
ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.empty())
36-
ps
26+
val hostConfig = new com.github.dockerjava.api.model.HostConfig()
27+
.withOption(spec.networkMode)({ case (config, value) => config.withNetworkMode(value) })
28+
.withPortBindings(spec.bindPorts.foldLeft(new Ports()) {
29+
case (ps, (guestPort, DockerPortMapping(Some(hostPort), address))) =>
30+
ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.bindPort(hostPort))
31+
ps
32+
case (ps, (guestPort, DockerPortMapping(None, address))) =>
33+
ps.bind(ExposedPort.tcp(guestPort), Ports.Binding.empty())
34+
ps
35+
})
36+
.withLinks(
37+
new Links(spec.links.map {
38+
case ContainerLink(container, alias) =>
39+
new Link(container.name.get, alias)
40+
}: _*)
41+
)
42+
.withBinds(new Binds(volumeToBind.map(_._2): _*))
43+
.withOption(spec.hostConfig.flatMap(_.memory)) {
44+
case (config, memory) => config.withMemory(memory)
45+
}
46+
.withOption(spec.hostConfig.flatMap(_.memoryReservation)) {
47+
case (config, memoryReservation) => config.withMemoryReservation(memoryReservation)
48+
}
49+
50+
val cmd = client
51+
.createContainerCmd(spec.image)
52+
.withHostConfig(hostConfig)
53+
.withPortSpecs(spec.bindPorts
54+
.map({
55+
case (guestPort, DockerPortMapping(Some(hostPort), address)) =>
56+
s"$address:$hostPort:$guestPort"
57+
case (guestPort, DockerPortMapping(None, address)) => s"$address::$guestPort"
3758
})
38-
.withLinks(
39-
new Links(spec.links.map {
40-
case ContainerLink(container, alias) =>
41-
new Link(container.name.get, alias)
42-
}: _*)
43-
)
44-
.withBinds(new Binds(volumeToBind.map(_._2): _*))
45-
46-
val tmpCmd = client
47-
.createContainerCmd(spec.image)
48-
.withHostConfig(hostConfig)
49-
.withPortSpecs(spec.bindPorts
50-
.map({
51-
case (guestPort, DockerPortMapping(Some(hostPort), address)) =>
52-
s"$address:$hostPort:$guestPort"
53-
case (guestPort, DockerPortMapping(None, address)) => s"$address::$guestPort"
54-
})
55-
.toSeq: _*)
56-
.withExposedPorts(spec.bindPorts.keys.map(ExposedPort.tcp).toSeq: _*)
57-
.withTty(spec.tty)
58-
.withStdinOpen(spec.stdinOpen)
59-
.withEnv(spec.env: _*)
60-
.withVolumes(volumeToBind.map(_._1): _*)
61-
.withOption(spec.user) { case (config, user) => config.withUser(user) }
62-
.withOption(spec.hostname) { case (config, hostName) => config.withHostName(hostName) }
63-
64-
spec.name.map(tmpCmd.withName).getOrElse(tmpCmd)
65-
}
59+
.toSeq: _*)
60+
.withExposedPorts(spec.bindPorts.keys.map(ExposedPort.tcp).toSeq: _*)
61+
.withTty(spec.tty)
62+
.withStdinOpen(spec.stdinOpen)
63+
.withEnv(spec.env: _*)
64+
.withVolumes(volumeToBind.map(_._1): _*)
65+
.withOption(spec.user) { case (config, user) => config.withUser(user) }
66+
.withOption(spec.hostname) { case (config, hostName) => config.withHostName(hostName) }
67+
.withOption(spec.name) { case (config, name) => config.withName(name) }
68+
.withOption(spec.command) { case (config, c) => config.withCmd(c: _*) }
69+
.withOption(spec.entrypoint) { case (config, entrypoint) => config.withEntrypoint(entrypoint: _*) }
6670

67-
val cmd = spec.command.fold(baseCmd)(c => baseCmd.withCmd(c: _*))
6871
Future(cmd.exec()).map { resp =>
6972
if (resp.getId != null && resp.getId != "") {
7073
resp.getId

impl/spotify/src/main/scala/com/whisk/docker/impl/spotify/SpotifyDockerCommandExecutor.scala

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import com.spotify.docker.client.exceptions.ContainerNotFoundException
1212
import com.spotify.docker.client.messages.{
1313
ContainerConfig,
1414
HostConfig,
15-
PortBinding,
16-
AttachedNetwork
15+
PortBinding
1716
}
1817
import com.spotify.docker.client.{DockerClient, LogMessage}
1918
import com.whisk.docker._
@@ -55,10 +54,16 @@ class SpotifyDockerCommandExecutor(override val host: String, client: DockerClie
5554
.withOption(spec.hostConfig.flatMap(_.tmpfs)) {
5655
case (config, value) => config.tmpfs(value.asJava)
5756
}
57+
.withOption(spec.hostConfig.flatMap(_.memory)) {
58+
case (config, memory) => config.memory(memory)
59+
}
60+
.withOption(spec.hostConfig.flatMap(_.memoryReservation)) {
61+
case (config, reservation) => config.memoryReservation(reservation)
62+
}
5863
.build()
5964
}
6065

61-
val builder = ContainerConfig
66+
val containerConfig = ContainerConfig
6267
.builder()
6368
.image(spec.image)
6469
.hostConfig(hostConfig)
@@ -68,8 +73,9 @@ class SpotifyDockerCommandExecutor(override val host: String, client: DockerClie
6873
.env(spec.env: _*)
6974
.withOption(spec.user) { case (config, user) => config.user(user) }
7075
.withOption(spec.hostname) { case (config, hostname) => config.hostname(hostname) }
71-
72-
val containerConfig = spec.command.fold(builder)(c => builder.cmd(c: _*)).build()
76+
.withOption(spec.command) { case (config, command) => config.cmd(command: _*) }
77+
.withOption(spec.entrypoint) { case (config, entrypoint) => config.entrypoint(entrypoint: _*) }
78+
.build()
7379

7480
val creation = Future(
7581
spec.name.fold(client.createContainer(containerConfig))(

0 commit comments

Comments
 (0)