DockerOutput no longer Option[String]
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/Container.scala b/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
index 71872ef..2bd6e0e 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
@@ -78,7 +78,7 @@
* Gets logs for container.
*/
def getLogs()(implicit transid: TransactionId): String = {
- getContainerLogs(containerId) getOrElse ""
+ getContainerLogs(containerId).toOption getOrElse ""
}
/**
@@ -95,7 +95,7 @@
warn(this, s"Retrying to remove container $containerId")
}
unpause() // a paused container cannot be removed
- rmContainer(containerId) match {
+ rmContainer(containerId).toOption match {
case None => remove(tryCount - 1)
case _ => ()
}
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala b/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
index bd438c9..f8b3027 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
@@ -150,7 +150,7 @@
* Lists ALL containers at this docker point with "docker ps -a --no-trunc".
* This could include containers not in this pool at all.
*/
- def listAll()(implicit transid: TransactionId): Array[ContainerState] = listContainers(true)
+ def listAll()(implicit transid: TransactionId): Seq[ContainerState] = listContainers(true)
/**
* Retrieves (possibly create) a container based on the subject and versioned action.
@@ -422,7 +422,7 @@
* 2. Periodically re-populates the container pool with fresh (un-instantiated) nodejs containers.
* 3. Periodically tears down containers that have logically been removed from the system
*/
- private def nannyThread(allContainers: Array[ContainerState]) = new Thread {
+ private def nannyThread(allContainers: Seq[ContainerState]) = new Thread {
override def run {
implicit val tid = TransactionId.invokerWarmup
if (!standalone) killStragglers(allContainers)
@@ -695,7 +695,7 @@
* This is needed for startup and shutdown.
* Concurrent access from clients must be prevented.
*/
- private def killStragglers(allContainers: Array[ContainerState])(implicit transid: TransactionId) = {
+ private def killStragglers(allContainers: Seq[ContainerState])(implicit transid: TransactionId) = {
val candidates = allContainers.filter { case ContainerState(id, image, name) => name.startsWith(actionContainerPrefix) }
info(this, s"Now removing ${candidates.length} leftover containers")
candidates foreach {
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala b/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
index b975676..d8aa0e7 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
@@ -21,6 +21,7 @@
import whisk.common.TransactionId
import whisk.core.entity.ActionLimits
import java.io.File
+import java.io.FileNotFoundException
import scala.util.Try
import scala.language.postfixOps
import whisk.common.LoggingMarkers
@@ -75,17 +76,17 @@
val containerNetwork = Array("--net", network)
val cmd = Array("run") ++ makeEnvVars(env) ++ consulServiceIgnore ++ nameOption ++ cpuArg ++ memoryArg ++
capabilityArg ++ fileHandleLimit ++ processLimit ++ securityOpts ++ containerNetwork ++ Array("-d", image) ++ args
- runDockerCmd(cmd: _*)
+ runDockerCmd(cmd: _*).toOption
}
def killContainer(name: String)(implicit transid: TransactionId): DockerOutput = killContainer(Some(name))
def killContainer(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
- container flatMap { name => runDockerCmd("kill", name) }
+ container.fold(DockerOutput.unavailable)(name => runDockerCmd("kill", name))
}
def getContainerLogs(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
- container flatMap { name => runDockerCmd("logs", name) }
+ container.fold(DockerOutput.unavailable)(name => runDockerCmd("logs", name))
}
def pauseContainer(name: String)(implicit transid: TransactionId): DockerOutput = {
@@ -102,19 +103,19 @@
* Forcefully removes a container, can be used on a running container but not a paused one.
*/
def rmContainer(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
- container flatMap { name => runDockerCmd("rm", "-f", name) }
+ container.fold(DockerOutput.unavailable)(name => runDockerCmd("rm", "-f", name))
}
/*
* List containers (-a if all).
*/
- def listContainers(all: Boolean)(implicit transid: TransactionId): Array[ContainerState] = {
+ def listContainers(all: Boolean)(implicit transid: TransactionId): Seq[ContainerState] = {
val tmp = Array("ps", "--no-trunc")
val cmd = if (all) tmp :+ "-a" else tmp
- runDockerCmd(cmd: _*) map { output =>
- val lines = output.split("\n").drop(1) // skip the header
+ runDockerCmd(cmd: _*).toOption map { output =>
+ val lines = output.split("\n").drop(1).toSeq // skip the header
lines.map(parsePsOutput)
- } getOrElse Array()
+ } getOrElse Seq()
}
def getDockerLogSize(containerId: String, mounted: Boolean)(implicit transid: TransactionId): Long = {
@@ -158,10 +159,8 @@
def getContainerHostAndPort(container: ContainerName)(implicit transid: TransactionId): Option[ContainerAddr] = {
for (
name <- container;
- output <- runDockerCmd("inspect", "--format", "'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'", name)
- ) yield {
- ContainerAddr(output.substring(1, output.length - 1), 8080)
- }
+ output <- runDockerCmd("inspect", "--format", "'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'", name).toOption
+ ) yield ContainerAddr(output.substring(1, output.length - 1), 8080)
}
def runDockerCmd(args: String*)(implicit transid: TransactionId): DockerOutput = runDockerCmd(false, args)
@@ -201,35 +200,43 @@
*/
def runDockerCmd(dockerhost: String, skipLogError: Boolean, args: Seq[String])(implicit transid: TransactionId): DockerOutput = {
val start = transid.started(this, LoggingMarkers.INVOKER_DOCKER_CMD(args(0)))
- getDockerCmd(dockerhost) map { _ ++ args } map {
- SimpleExec.syncRunCmd(_)(transid)
- } map {
- case (stdout, stderr, exitCode) =>
- if (exitCode == 0) {
- transid.finished(this, start)
- Some(stdout.trim)
+
+ try {
+ val fullCmd = getDockerCmd(dockerhost) ++ args
+
+ val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(fullCmd)
+
+ if (exitCode == 0) {
+ transid.finished(this, start)
+ DockerOutput(stdout.trim)
+ } else {
+ if (!skipLogError) {
+ transid.failed(this, start, s"stdout:\n$stdout\nstderr:\n$stderr", ErrorLevel)
} else {
- if (!skipLogError) {
- transid.failed(this, start, s"stdout:\n$stdout\nstderr:\n$stderr", ErrorLevel)
- } else {
- transid.failed(this, start)
- }
- None
+ transid.failed(this, start)
}
- } getOrElse {
- transid.failed(this, start, "docker executable not found", ErrorLevel)
- None
+ DockerOutput.unavailable
+ }
+ } catch {
+ case t: Throwable =>
+ transid.failed(this, start, "error: " + t.getMessage, ErrorLevel)
+ DockerOutput.unavailable
}
}
- private def file(path: String) = Try { new File(path) } filter { _.exists } toOption
+ private def getDockerCmd(dockerhost: String): Seq[String] = {
+ def file(path: String) = Try { new File(path) } filter { _.exists } toOption
- def getDockerCmd(dockerhost: String) = {
val dockerLoc = file("/usr/bin/docker") orElse file("/usr/local/bin/docker")
+
+ val dockerBin = dockerLoc.map(_.toString).getOrElse {
+ throw new FileNotFoundException("Couldn't locate docker binary.")
+ }
+
if (dockerhost == "localhost") {
- dockerLoc map { f => Array(f.toString) }
+ Seq(dockerBin)
} else {
- dockerLoc map { f => Array(f.toString, "--host", s"tcp://$dockerhost") }
+ Seq(dockerBin, "--host", s"tcp://$dockerhost")
}
}
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala b/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
index eaf5a8e..4f8069a 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
@@ -112,7 +112,7 @@
* Tear down the container and retrieve the logs.
*/
def teardown()(implicit transid: TransactionId): String = {
- getContainerLogs(Some(containerName)).getOrElse("none")
+ getContainerLogs(Some(containerName)).toOption.getOrElse("none")
}
/**
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/package.scala b/core/dispatcher/src/main/scala/whisk/core/container/package.scala
index 4161c00..9756a85 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/package.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/package.scala
@@ -87,5 +87,9 @@
type ContainerId = Option[String]
- type DockerOutput = Option[String]
+ final class DockerOutput(val toOption: Option[String]) extends AnyVal
+ object DockerOutput {
+ def apply(content: String) = new DockerOutput(Some(content))
+ def unavailable = new DockerOutput(None)
+ }
}