Skip to content

Commit fecf78c

Browse files
committed
Add support for --chown flag for ADD/COPY Docker commands
Closes sbt#1029
1 parent 8d4ad99 commit fecf78c

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala

+27-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import com.typesafe.sbt.SbtNativePackager.Universal
1313
import com.typesafe.sbt.packager.Compat._
1414
import com.typesafe.sbt.packager.{MappingsHelper, Stager}
1515

16+
import scala.sys.process.Process
17+
import scala.util.Try
18+
1619
/**
1720
* == Docker Plugin ==
1821
*
@@ -80,6 +83,9 @@ object DockerPlugin extends AutoPlugin {
8083
dockerEntrypoint := Seq("bin/%s" format executableScriptName.value),
8184
dockerCmd := Seq(),
8285
dockerExecCommand := Seq("docker"),
86+
dockerVersion := Try(Process(dockerExecCommand.value ++ Seq("version --format '{{.Server.Version}}'")).!!)
87+
.toOption.map(_.trim)
88+
.flatMap(DockerVersion.parse),
8389
dockerBuildOptions := Seq("--force-rm") ++ Seq("-t", dockerAlias.value.versioned) ++ (
8490
if (dockerUpdateLatest.value)
8591
Seq("-t", dockerAlias.value.latest)
@@ -96,7 +102,7 @@ object DockerPlugin extends AutoPlugin {
96102
val generalCommands = makeFrom(dockerBaseImage.value) +: makeMaintainer((maintainer in Docker).value).toSeq
97103

98104
generalCommands ++
99-
Seq(makeWorkdir(dockerBaseDirectory), makeAdd(dockerBaseDirectory), makeChown(user, group, "." :: Nil)) ++
105+
Seq(makeWorkdir(dockerBaseDirectory)) ++ makeAdd(dockerVersion.value, dockerBaseDirectory, user, group) ++
100106
dockerLabels.value.map(makeLabel) ++
101107
makeExposePorts(dockerExposedPorts.value, dockerExposedUdpPorts.value) ++
102108
makeVolumes(dockerExposedVolumes.value, user, group) ++
@@ -179,18 +185,34 @@ object DockerPlugin extends AutoPlugin {
179185
Cmd("WORKDIR", dockerBaseDirectory)
180186

181187
/**
182-
* @param dockerBaseDirectory, the installation directory
188+
* @param dockerVersion
189+
* @param dockerBaseDirectory the installation directory
190+
* @param daemonUser
191+
* @param daemonGroup
183192
* @return ADD command adding all files inside the installation directory
184193
*/
185-
private final def makeAdd(dockerBaseDirectory: String): CmdLike = {
194+
private final def makeAdd(dockerVersion: Option[DockerVersion], dockerBaseDirectory: String,
195+
daemonUser: String, daemonGroup: String): Seq[CmdLike] = {
186196

187197
/**
188198
* This is the file path of the file in the Docker image, and does not depend on the OS where the image
189199
* is being built. This means that it needs to be the Unix file separator even when the image is built
190200
* on e.g. Windows systems.
191201
*/
192202
val files = dockerBaseDirectory.split(UnixSeparatorChar)(1)
193-
Cmd("ADD", s"$files /$files")
203+
204+
dockerVersion match {
205+
case Some(DockerVersion(major, minor, _, _)) if major >= 17 && minor >= 9 =>
206+
Seq(
207+
Cmd("ADD", s"--chown=$daemonUser:$daemonGroup $files /$files")
208+
)
209+
210+
case _ =>
211+
Seq(
212+
Cmd("ADD", s"$files /$files"),
213+
makeChown(daemonUser, daemonGroup, "." :: Nil)
214+
)
215+
}
194216
}
195217

196218
/**
@@ -278,7 +300,7 @@ object DockerPlugin extends AutoPlugin {
278300
}
279301

280302
/**
281-
* uses the `mappings in Unversial` to generate the
303+
* uses the `mappings in Universal` to generate the
282304
* `mappings in Docker`.
283305
*/
284306
def mapGenericFilesToDocker: Seq[Setting[_]] = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.typesafe.sbt.packager.docker
2+
3+
import scala.util.matching.Regex
4+
5+
6+
case class DockerVersion(major: Int, minor: Int, patch: Int, release: Option[String])
7+
8+
object DockerVersion {
9+
private val DockerVersionPattern: Regex = "^'([0-9]+).([0-9]+).([0-9]+)-?([-a-z]+)?'$".r
10+
11+
def parse(version: String): Option[DockerVersion] = {
12+
Option(version).collect {
13+
case DockerVersionPattern(major, minor, patch, release) =>
14+
new DockerVersion(major.toInt, minor.toInt, patch.toInt, Option(release))
15+
}
16+
}
17+
}

src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ trait DockerKeys {
2929
"Docker CMD. Used together with dockerEntrypoint. Arguments passed in exec form"
3030
)
3131
val dockerExecCommand = SettingKey[Seq[String]]("dockerExecCommand", "The shell command used to exec Docker")
32+
val dockerVersion = SettingKey[Option[DockerVersion]]("dockerVersion", "The docker server version")
3233
val dockerBuildOptions = SettingKey[Seq[String]]("dockerBuildOptions", "Options used for the Docker build")
3334
val dockerBuildCommand = SettingKey[Seq[String]]("dockerBuildCommand", "Command for building the Docker image")
3435
val dockerLabels = SettingKey[Map[String, String]]("dockerLabels", "Labels applied to the Docker image")

0 commit comments

Comments
 (0)