From 0dcd0cb4dabe4892fbf14a4956acee40031e5b40 Mon Sep 17 00:00:00 2001 From: Gary Coady Date: Thu, 24 Apr 2014 10:46:41 +0100 Subject: [PATCH 1/4] Provide task to stage output in a format sufficient to build Docker images. This creates a new docker config, and updates the stage task to create a Dockerfile which can create an image capable of running an application. It works with basic Java applications, and basic Play 2.2 applications. --- .../com/typesafe/sbt/PackagerPlugin.scala | 5 +- .../com/typesafe/sbt/packager/Keys.scala | 3 +- .../sbt/packager/docker/DockerPlugin.scala | 76 +++++++++++++++++++ .../typesafe/sbt/packager/docker/Keys.scala | 22 ++++++ .../sbt/packager/docker/dockerfile.scala | 24 ++++++ src/sbt-test/docker/staging/build.sbt | 7 ++ .../docker/staging/project/plugins.sbt | 1 + .../docker/staging/src/universal/conf/test | 1 + src/sbt-test/docker/staging/test | 4 + 9 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala create mode 100644 src/sbt-test/docker/staging/build.sbt create mode 100644 src/sbt-test/docker/staging/project/plugins.sbt create mode 100644 src/sbt-test/docker/staging/src/universal/conf/test create mode 100644 src/sbt-test/docker/staging/test diff --git a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala index 85021d939..4e2296739 100644 --- a/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/PackagerPlugin.scala @@ -13,6 +13,7 @@ object SbtNativePackager extends Plugin with debian.DebianPlugin with rpm.RpmPlugin with windows.WindowsPlugin + with docker.DockerPlugin with universal.UniversalPlugin with GenericPackageSettings { @@ -24,6 +25,7 @@ object SbtNativePackager extends Plugin debianSettings ++ rpmSettings ++ windowsSettings ++ + dockerSettings ++ universalSettings ++ Seq( // Bad defaults that let us at least not explode users who don't care about native packagers NativePackagerKeys.maintainer := "", @@ -35,6 +37,7 @@ object SbtNativePackager extends Plugin def deploymentSettings = makeDeploymentSettings(Debian, packageBin in Debian, "deb") ++ makeDeploymentSettings(Rpm, packageBin in Rpm, "rpm") ++ makeDeploymentSettings(Windows, packageBin in Windows, "msi") ++ + makeDeploymentSettings(Docker, packageBin in Docker, "tgz") ++ makeDeploymentSettings(Universal, packageBin in Universal, "zip") ++ addPackage(Universal, packageZipTarball in Universal, "tgz") ++ makeDeploymentSettings(UniversalDocs, packageBin in UniversalDocs, "zip") ++ @@ -50,4 +53,4 @@ object SbtNativePackager extends Plugin // TODO - Add a few targets that detect the current OS and build a package for that OS. -} \ No newline at end of file +} diff --git a/src/main/scala/com/typesafe/sbt/packager/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/Keys.scala index 77a505bce..733b02bde 100644 --- a/src/main/scala/com/typesafe/sbt/packager/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/Keys.scala @@ -7,6 +7,7 @@ object Keys extends linux.Keys with debian.DebianKeys with rpm.RpmKeys with windows.WindowsKeys + with docker.DockerKeys with universal.UniversalKeys { // These keys are used by the JavaApp/JavaServer archetypes. @@ -29,4 +30,4 @@ object Keys extends linux.Keys val defaultLinuxInstallLocation = SettingKey[String]("defaultLinuxInstallLocation", "The location where we will install generic linux packages.") val defaultLinuxLogsLocation = SettingKey[String]("defaultLinuxLogsLocation", "The location where application logs will be stored.") val defaultLinuxConfigLocation = SettingKey[String]("defaultLinuxConfigLocation", "The location where application config files will be stored") -} \ No newline at end of file +} diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala new file mode 100644 index 000000000..5ece8c839 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala @@ -0,0 +1,76 @@ +package com.typesafe.sbt +package packager +package docker +import Keys._ +import universal._ +import sbt._ + +import sbt.Keys.cacheDirectory + +trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { + val Docker = config("docker") extend Universal + + private[this] final def makeDockerContent(dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, execName: String) = { + Dockerfile( + Cmd("FROM", dockerBaseImage), + Cmd("MAINTAINER", maintainer), + Cmd("ADD", "files %s" format dockerBaseDirectory), + Cmd("WORKDIR", dockerBaseDirectory), + ExecCmd("RUN", "chown", "-R", daemonUser, "."), + Cmd("USER", daemonUser), + Cmd("ENTRYPOINT", "%s/bin/%s" format (dockerBaseDirectory, execName)), + ExecCmd("CMD") + ).makeContent + } + + private[this] final def setDockerLayout(directoryName: String, mappings: Seq[(java.io.File, String)], dockerFile: java.io.File) = { + def moveMapping(old: (java.io.File, String)) = { + old._1 -> ("%s/%s" format (directoryName, old._2)) + } + + (mappings map moveMapping) :+ (dockerFile -> "Dockerfile") + } + + private[this] final def generateDockerConfig( + dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, normalizedName: String, target: File) = { + val dockerContent = makeDockerContent(dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName) + + val f = target / "Dockerfile" + IO.write(f, dockerContent) + f + } + + def dockerSettings: Seq[Setting[_]] = inConfig(Docker)(Seq( + daemonUser := "daemon", + dockerBaseImage := "dockerfile/java", + dockerBaseDirectory := "/opt/docker", + stagingDirectory <<= (target, normalizedName) { + case (target, normalizedName) => + (target / "docker" / normalizedName) + }, + stage <<= (cacheDirectory, stagingDirectory, mappings) map stageFiles("docker"), + dockerGenerateConfig <<= + (dockerBaseImage, dockerBaseDirectory, maintainer in Docker, daemonUser in Docker, normalizedName in Docker, target in Docker) map { + case (dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName, target) => + generateDockerConfig(dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName, target) + }, + mappings <<= (mappings in Universal, dockerGenerateConfig) map { + case (mappings, dockerfile) => + setDockerLayout("files", mappings, dockerfile) + } + )) + + private[this] def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = { + val cache = cacheDirectory / ("packager-mappings-" + config) + val copies = mappings map { + case (file, path) => file -> (to / path) + } + Sync(cache)(copies) + // Now set scripts to executable using Java's lack of understanding of permissions. + // TODO - Config file user-readable permissions.... + for { + (from, to) <- copies + if from.canExecute + } to.setExecutable(true) + } +} diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala new file mode 100644 index 000000000..17939589a --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala @@ -0,0 +1,22 @@ +package com.typesafe.sbt +package packager +package docker + +import sbt._ + +trait DockerKeys { + val dockerGenerateConfig = TaskKey[File]("docker-generate-config", "Generates configuration file for Docker.") + val dockerBaseImage = SettingKey[String]("dockerBaseImage", "Base image for Dockerfile.") + val dockerBaseDirectory = SettingKey[String]("dockerBaseDirectory", "Base directory in Docker image under which to place files.") +} + +object Keys extends DockerKeys { + def mappings = sbt.Keys.mappings + def daemonUser = linux.Keys.daemonUser + def maintainer = linux.Keys.maintainer + def normalizedName = universal.Keys.normalizedName + def stage = universal.Keys.stage + def stagingDirectory = universal.Keys.stagingDirectory + def target = sbt.Keys.target + def streams = sbt.Keys.streams +} diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala b/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala new file mode 100644 index 000000000..afc76608d --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/docker/dockerfile.scala @@ -0,0 +1,24 @@ +package com.typesafe.sbt +package packager +package docker + +trait CmdLike { + def makeContent: String +} + +case class ExecCmd(cmd: String, args: String*) extends CmdLike { + def makeContent = "%s [%s]\n" format (cmd, args.map('"' + _ + '"').mkString(", ")) +} + +case class Cmd(cmd: String, arg: String) extends CmdLike { + def makeContent = "%s %s\n" format (cmd, arg) +} + +/** Represents dockerfile used by docker when constructing packages. */ +case class Dockerfile(commands: CmdLike*) { + def makeContent: String = { + val sb = new StringBuilder + commands foreach { sb append _.makeContent } + sb toString + } +} diff --git a/src/sbt-test/docker/staging/build.sbt b/src/sbt-test/docker/staging/build.sbt new file mode 100644 index 000000000..8c687dea6 --- /dev/null +++ b/src/sbt-test/docker/staging/build.sbt @@ -0,0 +1,7 @@ +import NativePackagerKeys._ + +packagerSettings + +name := "simple-test" + +version := "0.1.0" diff --git a/src/sbt-test/docker/staging/project/plugins.sbt b/src/sbt-test/docker/staging/project/plugins.sbt new file mode 100644 index 000000000..b53de154c --- /dev/null +++ b/src/sbt-test/docker/staging/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version")) diff --git a/src/sbt-test/docker/staging/src/universal/conf/test b/src/sbt-test/docker/staging/src/universal/conf/test new file mode 100644 index 000000000..ab1006ffd --- /dev/null +++ b/src/sbt-test/docker/staging/src/universal/conf/test @@ -0,0 +1 @@ +# Test configuration to include in zips. diff --git a/src/sbt-test/docker/staging/test b/src/sbt-test/docker/staging/test new file mode 100644 index 000000000..ed1819dda --- /dev/null +++ b/src/sbt-test/docker/staging/test @@ -0,0 +1,4 @@ +# Stage the distribution and ensure files show up. +> show docker:stage +$ exists target/docker/simple-test/Dockerfile +$ exists target/docker/simple-test/files From be2335fc849915bb08aceb3e66f5e477bd94d9af Mon Sep 17 00:00:00 2001 From: Gary Coady Date: Fri, 25 Apr 2014 17:41:28 +0100 Subject: [PATCH 2/4] Updated Docker code. Adds dockerPackageMappings which contains mappings specific to Docker build - defaults to reading from sourceDirectory/docker (overrideable). Builds mappings from dockerPackageMappings and universal:mappings (overrideable). Modifies "docker:stage" command to build a Docker context and Dockerfile from docker:mappings. --- .../sbt/packager/docker/DockerPlugin.scala | 85 +++++++++---------- .../typesafe/sbt/packager/docker/Keys.scala | 12 +-- .../packager/universal/UniversalPlugin.scala | 2 +- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala index 5ece8c839..16a236c76 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala @@ -6,31 +6,24 @@ import universal._ import sbt._ import sbt.Keys.cacheDirectory +import universal.Keys.stage trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { val Docker = config("docker") extend Universal - private[this] final def makeDockerContent(dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, execName: String) = { + private[this] final def makeDockerContent(dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, name: String) = { Dockerfile( Cmd("FROM", dockerBaseImage), Cmd("MAINTAINER", maintainer), - Cmd("ADD", "files %s" format dockerBaseDirectory), - Cmd("WORKDIR", dockerBaseDirectory), - ExecCmd("RUN", "chown", "-R", daemonUser, "."), + Cmd("ADD", "files /"), + Cmd("WORKDIR", "%s/bin" format dockerBaseDirectory), + ExecCmd("RUN", "chown", "-R", daemonUser, ".."), Cmd("USER", daemonUser), - Cmd("ENTRYPOINT", "%s/bin/%s" format (dockerBaseDirectory, execName)), + ExecCmd("ENTRYPOINT", name), ExecCmd("CMD") ).makeContent } - private[this] final def setDockerLayout(directoryName: String, mappings: Seq[(java.io.File, String)], dockerFile: java.io.File) = { - def moveMapping(old: (java.io.File, String)) = { - old._1 -> ("%s/%s" format (directoryName, old._2)) - } - - (mappings map moveMapping) :+ (dockerFile -> "Dockerfile") - } - private[this] final def generateDockerConfig( dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, normalizedName: String, target: File) = { val dockerContent = makeDockerContent(dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName) @@ -40,37 +33,43 @@ trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { f } - def dockerSettings: Seq[Setting[_]] = inConfig(Docker)(Seq( - daemonUser := "daemon", - dockerBaseImage := "dockerfile/java", - dockerBaseDirectory := "/opt/docker", - stagingDirectory <<= (target, normalizedName) { - case (target, normalizedName) => - (target / "docker" / normalizedName) - }, - stage <<= (cacheDirectory, stagingDirectory, mappings) map stageFiles("docker"), - dockerGenerateConfig <<= - (dockerBaseImage, dockerBaseDirectory, maintainer in Docker, daemonUser in Docker, normalizedName in Docker, target in Docker) map { - case (dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName, target) => - generateDockerConfig(dockerBaseImage, dockerBaseDirectory, maintainer, daemonUser, normalizedName, target) - }, - mappings <<= (mappings in Universal, dockerGenerateConfig) map { - case (mappings, dockerfile) => - setDockerLayout("files", mappings, dockerfile) + def mapGenericFilesToDocker: Seq[Setting[_]] = { + def renameDests(from: Seq[(File, String)], dest: String) = { + for { + (f, path) <- from + newPath = "%s/%s" format (dest, path) + } yield (f, newPath) } - )) - private[this] def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = { - val cache = cacheDirectory / ("packager-mappings-" + config) - val copies = mappings map { - case (file, path) => file -> (to / path) - } - Sync(cache)(copies) - // Now set scripts to executable using Java's lack of understanding of permissions. - // TODO - Config file user-readable permissions.... - for { - (from, to) <- copies - if from.canExecute - } to.setExecutable(true) + inConfig(Docker)(Seq( + mappings <<= (mappings in Universal, defaultDockerInstallLocation) map { (mappings, dest) => + renameDests(mappings, dest) + }, + mappings <++= dockerPackageMappings + )) } + + def dockerSettings: Seq[Setting[_]] = Seq( + sourceDirectory in Docker <<= sourceDirectory apply (_ / "docker"), + target in Docker <<= target apply (_ / "docker") + ) ++ mapGenericFilesToDocker ++ inConfig(Docker)(Seq( + daemonUser := "daemon", + dockerBaseImage := "dockerfile/java", + defaultDockerInstallLocation := "/opt/docker", + dockerPackageMappings <<= (sourceDirectory in Docker) map { dir => + MappingsHelper contentOf dir + }, + stage <<= dockerGenerateContext.dependsOn(dockerGenerateConfig), + dockerGenerateContext <<= (cacheDirectory, mappings, target) map { + (cacheDirectory, mappings, t) => + val contextDir = t / "files" + stageFiles("docker")(cacheDirectory, contextDir, mappings) + contextDir + }, + dockerGenerateConfig <<= + (dockerBaseImage, defaultDockerInstallLocation, maintainer in Docker, daemonUser in Docker, normalizedName in Docker, target in Docker) map { + case (dockerBaseImage, baseDirectory, maintainer, daemonUser, normalizedName, target) => + generateDockerConfig(dockerBaseImage, baseDirectory, maintainer, daemonUser, normalizedName, target) + } + )) } diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala index 17939589a..07fa74e94 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala @@ -6,17 +6,17 @@ import sbt._ trait DockerKeys { val dockerGenerateConfig = TaskKey[File]("docker-generate-config", "Generates configuration file for Docker.") + val dockerGenerateContext = TaskKey[Unit]("docker-generate-context", "Generates context directory for Docker.") + val dockerPackageMappings = TaskKey[Seq[(File, String)]]("docker-package-mappings", "Generates location mappings for Docker build.") val dockerBaseImage = SettingKey[String]("dockerBaseImage", "Base image for Dockerfile.") - val dockerBaseDirectory = SettingKey[String]("dockerBaseDirectory", "Base directory in Docker image under which to place files.") + val defaultDockerInstallLocation = SettingKey[String]("defaultDockerInstallLocation", "The location where we will install Docker packages.") } object Keys extends DockerKeys { def mappings = sbt.Keys.mappings + def sourceDirectory = sbt.Keys.sourceDirectory + def target = sbt.Keys.target + def normalizedName = universal.Keys.normalizedName def daemonUser = linux.Keys.daemonUser def maintainer = linux.Keys.maintainer - def normalizedName = universal.Keys.normalizedName - def stage = universal.Keys.stage - def stagingDirectory = universal.Keys.stagingDirectory - def target = sbt.Keys.target - def streams = sbt.Keys.streams } diff --git a/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala index d4714e100..a8deab515 100644 --- a/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala @@ -55,7 +55,7 @@ trait UniversalPlugin extends Plugin { dist } - private[this] def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = { + def stageFiles(config: String)(cacheDirectory: File, to: File, mappings: Seq[(File, String)]): Unit = { val cache = cacheDirectory / ("packager-mappings-" + config) val copies = mappings map { case (file, path) => file -> (to / path) From 832d84a0ee10fc88c8a1549a4bddf718b478df40 Mon Sep 17 00:00:00 2001 From: Gary Coady Date: Fri, 25 Apr 2014 17:54:13 +0100 Subject: [PATCH 3/4] Fix sbt scripted test for Docker --- src/sbt-test/docker/staging/test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sbt-test/docker/staging/test b/src/sbt-test/docker/staging/test index ed1819dda..23231c0b6 100644 --- a/src/sbt-test/docker/staging/test +++ b/src/sbt-test/docker/staging/test @@ -1,4 +1,4 @@ # Stage the distribution and ensure files show up. > show docker:stage -$ exists target/docker/simple-test/Dockerfile -$ exists target/docker/simple-test/files +$ exists target/docker/Dockerfile +$ exists target/docker/files From 666927806592d5a0a4b1d2f5fc357570307b3b47 Mon Sep 17 00:00:00 2001 From: Gary Coady Date: Sat, 10 May 2014 11:59:59 +0100 Subject: [PATCH 4/4] Updated changes for Docker extension to sbt-native-packager - Trait DockerPlugin should not extend DockerKeys - publishArtifact in Docker is false - do not generate POM/etc. - Tasks for stage do not depend on each other. - Change the CWD in the Docker container to install location. - Adding Docker-specific mappings happens outside mapGenericFilesToDocker - Use defaultLinuxInstallLocation instead of defaultDockerInstallLocation - dockerBaseImage is set outside Docker config, easier to override --- .../sbt/packager/docker/DockerPlugin.scala | 28 +++++++++---------- .../typesafe/sbt/packager/docker/Keys.scala | 8 ++++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala index 16a236c76..bbd0827a1 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala @@ -5,10 +5,7 @@ import Keys._ import universal._ import sbt._ -import sbt.Keys.cacheDirectory -import universal.Keys.stage - -trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { +trait DockerPlugin extends Plugin with UniversalPlugin { val Docker = config("docker") extend Universal private[this] final def makeDockerContent(dockerBaseImage: String, dockerBaseDirectory: String, maintainer: String, daemonUser: String, name: String) = { @@ -16,10 +13,10 @@ trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { Cmd("FROM", dockerBaseImage), Cmd("MAINTAINER", maintainer), Cmd("ADD", "files /"), - Cmd("WORKDIR", "%s/bin" format dockerBaseDirectory), - ExecCmd("RUN", "chown", "-R", daemonUser, ".."), + Cmd("WORKDIR", "%s" format dockerBaseDirectory), + ExecCmd("RUN", "chown", "-R", daemonUser, "."), Cmd("USER", daemonUser), - ExecCmd("ENTRYPOINT", name), + ExecCmd("ENTRYPOINT", "bin/%s" format name), ExecCmd("CMD") ).makeContent } @@ -42,24 +39,25 @@ trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { } inConfig(Docker)(Seq( - mappings <<= (mappings in Universal, defaultDockerInstallLocation) map { (mappings, dest) => + mappings <<= (mappings in Universal, defaultLinuxInstallLocation) map { (mappings, dest) => renameDests(mappings, dest) - }, - mappings <++= dockerPackageMappings + } )) } def dockerSettings: Seq[Setting[_]] = Seq( + dockerBaseImage := "dockerfile/java", sourceDirectory in Docker <<= sourceDirectory apply (_ / "docker"), target in Docker <<= target apply (_ / "docker") ) ++ mapGenericFilesToDocker ++ inConfig(Docker)(Seq( daemonUser := "daemon", - dockerBaseImage := "dockerfile/java", - defaultDockerInstallLocation := "/opt/docker", - dockerPackageMappings <<= (sourceDirectory in Docker) map { dir => + publishArtifact := false, + defaultLinuxInstallLocation := "/opt/docker", + dockerPackageMappings <<= (sourceDirectory) map { dir => MappingsHelper contentOf dir }, - stage <<= dockerGenerateContext.dependsOn(dockerGenerateConfig), + mappings <++= dockerPackageMappings, + stage <<= (dockerGenerateConfig, dockerGenerateContext) map { (configFile, contextDir) => () }, dockerGenerateContext <<= (cacheDirectory, mappings, target) map { (cacheDirectory, mappings, t) => val contextDir = t / "files" @@ -67,7 +65,7 @@ trait DockerPlugin extends Plugin with UniversalPlugin with DockerKeys { contextDir }, dockerGenerateConfig <<= - (dockerBaseImage, defaultDockerInstallLocation, maintainer in Docker, daemonUser in Docker, normalizedName in Docker, target in Docker) map { + (dockerBaseImage, defaultLinuxInstallLocation, maintainer, daemonUser, normalizedName, target) map { case (dockerBaseImage, baseDirectory, maintainer, daemonUser, normalizedName, target) => generateDockerConfig(dockerBaseImage, baseDirectory, maintainer, daemonUser, normalizedName, target) } diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala index 07fa74e94..5665e1fd6 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala @@ -6,17 +6,21 @@ import sbt._ trait DockerKeys { val dockerGenerateConfig = TaskKey[File]("docker-generate-config", "Generates configuration file for Docker.") - val dockerGenerateContext = TaskKey[Unit]("docker-generate-context", "Generates context directory for Docker.") + val dockerGenerateContext = TaskKey[File]("docker-generate-context", "Generates context directory for Docker.") val dockerPackageMappings = TaskKey[Seq[(File, String)]]("docker-package-mappings", "Generates location mappings for Docker build.") + val dockerBaseImage = SettingKey[String]("dockerBaseImage", "Base image for Dockerfile.") - val defaultDockerInstallLocation = SettingKey[String]("defaultDockerInstallLocation", "The location where we will install Docker packages.") } object Keys extends DockerKeys { + def cacheDirectory = sbt.Keys.cacheDirectory def mappings = sbt.Keys.mappings + def publishArtifact = sbt.Keys.publishArtifact def sourceDirectory = sbt.Keys.sourceDirectory def target = sbt.Keys.target + def defaultLinuxInstallLocation = packager.Keys.defaultLinuxInstallLocation def normalizedName = universal.Keys.normalizedName + def stage = universal.Keys.stage def daemonUser = linux.Keys.daemonUser def maintainer = linux.Keys.maintainer }