Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 'dockerBuild{Command, Options}' and renaming 'dockerTag' #854

Merged
merged 1 commit into from
Aug 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main/scala/com/typesafe/sbt/packager/docker/DockerAlias.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.typesafe.sbt.packager.docker

/**
* This class represents a Docker alias.
* It generates a string in the form of {{{[REGISTRY_HOST/][USERNAME/]NAME[:TAG]}}},
* e.g. ''my-registry.com:1234/my-user/my-service:1.0.0'' or just ''my-service:1.0.0''.
* @param registryHost Optional hostname of the registry (including port if applicable)
* @param username Optional username or other qualifier
* @param name Name of the image, e.g. the artifact name
* @param tag Optional tag for the image, e.g. the version
*/
case class DockerAlias(registryHost: Option[String], username: Option[String], name: String, tag: Option[String]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little documentation for this class and the public fields would be helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

protected val untagged = registryHost.map(_ + "/").getOrElse("") + username.map(_ + "/").getOrElse("") + name

/** Tag with (optional) given version */
val versioned = untagged + tag.map(":" + _).getOrElse("")
/** Tag with version 'latest' */
val latest = s"$untagged:latest"
}
46 changes: 21 additions & 25 deletions src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ object DockerPlugin extends AutoPlugin {

object autoImport extends DockerKeys {
val Docker = config("docker")

val DockerAlias = com.typesafe.sbt.packager.docker.DockerAlias
}

import autoImport._
Expand All @@ -74,10 +76,17 @@ object DockerPlugin extends AutoPlugin {
dockerExposedPorts := Seq(),
dockerExposedVolumes := Seq(),
dockerRepository := None,
dockerTag := dockerRepository.value.map(_ + "/").getOrElse("") + packageName.value + ":" + version.value,
dockerAlias := DockerAlias(dockerRepository.value, None, packageName.value, Some(version.value)),
dockerUpdateLatest := false,
dockerEntrypoint := Seq("bin/%s" format executableScriptName.value),
dockerCmd := Seq(),
dockerBuildOptions := Seq("--force-rm") ++ Seq("-t", dockerAlias.value.versioned) ++ (
if (dockerUpdateLatest.value)
Seq("-t", dockerAlias.value.latest)
else
Seq()
),
dockerBuildCommand := Seq("docker", "build") ++ dockerBuildOptions.value ++ Seq("."),
dockerCommands := {
val dockerBaseDirectory = (defaultLinuxInstallLocation in Docker).value
val user = (daemonUser in Docker).value
Expand Down Expand Up @@ -106,16 +115,16 @@ object DockerPlugin extends AutoPlugin {
mappings ++= Seq(dockerGenerateConfig.value) pair relativeTo(target.value),
name := name.value,
packageName := packageName.value,
publishLocal <<= (stage, dockerTag, dockerUpdateLatest, streams) map {
(context, target, updateLatest, s) =>
publishLocalDocker(context, target, updateLatest, s.log)
publishLocal <<= (stage, dockerAlias, dockerBuildCommand, streams) map {
(context, alias, buildCommand, s) =>
publishLocalDocker(context, buildCommand, s.log)
s.log.info(s"Built image $alias")
},
publish <<= (publishLocal, dockerTag, dockerUpdateLatest, streams) map {
(_, target, updateLatest, s) =>
publishDocker(target, s.log)
publish <<= (publishLocal, dockerAlias, dockerUpdateLatest, streams) map {
(_, alias, updateLatest, s) =>
publishDocker(alias.versioned, s.log)
if (updateLatest) {
val name = target.substring(0, target.lastIndexOf(":")) + ":latest"
publishDocker(name, s.log)
publishDocker(alias.latest, s.log)
}
},
sourceDirectory := sourceDirectory.value / "docker",
Expand Down Expand Up @@ -283,27 +292,14 @@ object DockerPlugin extends AutoPlugin {
}
}

def publishLocalDocker(context: File, tag: String, latest: Boolean, log: Logger): Unit = {
val cmd = Seq("docker", "build", "--force-rm", "-t", tag, ".")

log.debug("Executing Native " + cmd.mkString(" "))
def publishLocalDocker(context: File, buildCommand: Seq[String], log: Logger): Unit = {
log.debug("Executing Native " + buildCommand.mkString(" "))
log.debug("Working directory " + context.toString)

val ret = Process(cmd, context) ! publishLocalLogger(log)
val ret = Process(buildCommand, context) ! publishLocalLogger(log)

if (ret != 0)
throw new RuntimeException("Nonzero exit value: " + ret)
else
log.info("Built image " + tag)

if (latest) {
val name = tag.substring(0, tag.lastIndexOf(":")) + ":latest"
val latestCmd = Seq("docker", "tag", tag, name)
Process(latestCmd).! match {
case 0 => log.info("Update Latest from image " + tag)
case n => sys.error("Failed to run docker tag")
}
}
}

def publishDocker(tag: String, log: Logger): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ object DockerSpotifyClientPlugin extends AutoPlugin {

def publishLocalDocker = Def.task {
val context = stage.value
val tag = dockerTag.value
val tag = dockerAlias.value.versioned
val latest = dockerUpdateLatest.value
val log = streams.value.log

Expand Down
4 changes: 3 additions & 1 deletion src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ trait DockerKeys {
val dockerExposedPorts = SettingKey[Seq[Int]]("dockerExposedPorts", "Ports exposed by Docker image")
val dockerExposedVolumes = SettingKey[Seq[String]]("dockerExposedVolumes", "Volumes exposed by Docker image")
val dockerRepository = SettingKey[Option[String]]("dockerRepository", "Repository for published Docker image")
val dockerTag = SettingKey[String]("dockerTag", "Docker tag for the built image")
val dockerAlias = SettingKey[DockerAlias]("dockerAlias", "Docker alias for the built image")
val dockerUpdateLatest = SettingKey[Boolean]("dockerUpdateLatest", "Set to update latest tag")
val dockerEntrypoint = SettingKey[Seq[String]]("dockerEntrypoint", "Entrypoint arguments passed in exec form")
val dockerCmd = SettingKey[Seq[String]]("dockerCmd", "Docker CMD. Used together with dockerEntrypoint. Arguments passed in exec form")
val dockerBuildOptions = SettingKey[Seq[String]]("dockerBuildOptions", "Options used for the Docker build")
val dockerBuildCommand = SettingKey[Seq[String]]("dockerBuildCommand", "Command for building the Docker image")

val dockerCommands = TaskKey[Seq[CmdLike]]("dockerCommands", "List of docker commands that form the Dockerfile")
}
Expand Down
7 changes: 7 additions & 0 deletions src/sbt-test/docker/alias/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enablePlugins(JavaAppPackaging)

name := "docker-alias-test"

version := "0.1.0"

dockerAlias := DockerAlias(None, None, "docker-alias-test", Some("0.1.0"))
3 changes: 3 additions & 0 deletions src/sbt-test/docker/alias/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Stage the distribution and ensure files show up.
> docker:publishLocal
$ exec bash -c 'docker run docker-alias-test:0.1.0 | grep -q "Hello world"'
9 changes: 9 additions & 0 deletions src/sbt-test/docker/build-command/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
enablePlugins(JavaAppPackaging)

name := "docker-build-command-test"

version := "0.1.0"

import NativePackagerHelper._
mappings in Docker ++= directory("src/main/resources/docker-test")
dockerBuildCommand := Seq("docker", "build", "-t", "docker-build-command-test:0.1.0", "docker-test/")
1 change: 1 addition & 0 deletions src/sbt-test/docker/build-command/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM busybox

CMD ["echo", "docker build command override test"]
3 changes: 3 additions & 0 deletions src/sbt-test/docker/build-command/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Stage the distribution and ensure files show up.
> docker:publishLocal
$ exec bash -c 'docker run docker-build-command-test:0.1.0 | grep -q "docker build command override test"'
7 changes: 7 additions & 0 deletions src/sbt-test/docker/build-options/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enablePlugins(JavaAppPackaging)

name := "docker-build-options-test"

version := "0.1.0"

dockerBuildOptions := dockerBuildOptions.value ++ Seq("-t", "docker-build-options-test:0.1.0-random-tag")
1 change: 1 addition & 0 deletions src/sbt-test/docker/build-options/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
3 changes: 3 additions & 0 deletions src/sbt-test/docker/build-options/src/main/scala/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object Main extends App {
println("Hello world")
}
4 changes: 4 additions & 0 deletions src/sbt-test/docker/build-options/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Stage the distribution and ensure files show up.
> docker:publishLocal
$ exec bash -c 'docker run docker-build-options-test:0.1.0 | grep -q "Hello world"'
$ exec bash -c 'docker run docker-build-options-test:0.1.0-random-tag | grep -q "Hello world"'
7 changes: 0 additions & 7 deletions src/sbt-test/docker/tag/build.sbt

This file was deleted.

3 changes: 0 additions & 3 deletions src/sbt-test/docker/tag/test

This file was deleted.

15 changes: 12 additions & 3 deletions src/sphinx/formats/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,18 @@ Publishing Settings
``dockerUpdateLatest``
The flag to automatic update the latest tag when the ``docker:publish`` task is run. Default value is ``FALSE``.

``dockerTag``
The tag to be used during build for the resulting image.
Defaults to ``[dockerRepository]/[name]:[version]``.
``dockerAlias``
The alias to be used for tagging the resulting image of the Docker build.
The type of the setting key is ``DockerAlias`.
Defaults to ``[dockerRepository/][name]:[version]``.

``dockerBuildOptions``
Overrides the default Docker build options.
Defaults to ``Seq("--force-rm", "-t", "[dockerAlias]")``. This default is expanded if ``dockerUpdateLatest`` is set to true.

``dockerBuildCommand``
Overrides the default Docker build command.
Defaults to ``Seq("docker", "build", "[dockerBuildOptions]", ".")``.

Tasks
-----
Expand Down