Skip to content

Commit 48fbde3

Browse files
rodrigornmuuki88
authored andcommitted
Replace dockerVersion with dockerApiVersion (#1296)
* Add dockerApiVersion validation * Fix typo * Move `dockerApiVersion` to `DockerKeysEx` * Restore previous methods as deprecated for compatibility issues * Update docs * Set `sbtApiVersion` for integration test
1 parent ef57f57 commit 48fbde3

8 files changed

Lines changed: 77 additions & 19 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.typesafe.sbt.packager.docker
2+
3+
import scala.util.matching.Regex
4+
5+
case class DockerApiVersion(major: Int, minor: Int)
6+
7+
object DockerApiVersion {
8+
private val DockerApiVersionPattern: Regex = """^'?([0-9]+)\.([0-9]+)'?$""".r
9+
10+
def parse(version: String): Option[DockerApiVersion] =
11+
Option(version).collect {
12+
case DockerApiVersionPattern(major, minor) => new DockerApiVersion(major.toInt, minor.toInt)
13+
}
14+
}

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

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ object DockerPlugin extends AutoPlugin {
111111
dockerVersion := Try(Process(dockerExecCommand.value ++ Seq("version", "--format", "'{{.Server.Version}}'")).!!).toOption
112112
.map(_.trim)
113113
.flatMap(DockerVersion.parse),
114+
dockerApiVersion := Try(
115+
Process(dockerExecCommand.value ++ Seq("version", "--format", "'{{.Server.APIVersion}}'")).!!
116+
).toOption
117+
.map(_.trim)
118+
.flatMap(DockerApiVersion.parse),
114119
dockerBuildOptions := Seq("--force-rm") ++ dockerAliases.value.flatMap { alias =>
115120
Seq("-t", alias.toString)
116121
},
@@ -243,8 +248,8 @@ object DockerPlugin extends AutoPlugin {
243248
nonEmptyMappings((mappings in Docker).value),
244249
filesExist((mappings in Docker).value),
245250
validateExposedPorts(dockerExposedPorts.value, dockerExposedUdpPorts.value),
246-
validateDockerVersion(dockerVersion.value),
247-
validateDockerPermissionStrategy(dockerPermissionStrategy.value, dockerVersion.value)
251+
validateDockerVersion(dockerApiVersion.value),
252+
validateDockerPermissionStrategy(dockerPermissionStrategy.value, dockerVersion.value, dockerApiVersion.value)
248253
),
249254
dockerPackageMappings := MappingsHelper.contentOf(sourceDirectory.value),
250255
dockerGenerateConfig := {
@@ -638,8 +643,8 @@ object DockerPlugin extends AutoPlugin {
638643
}
639644
}
640645

641-
private[this] def validateDockerVersion(dockerVersion: Option[DockerVersion]): Validation.Validator = () => {
642-
dockerVersion match {
646+
private[this] def validateDockerVersion(dockerApiVersion: Option[DockerApiVersion]): Validation.Validator = () => {
647+
dockerApiVersion match {
643648
case Some(_) => List.empty
644649
case None =>
645650
List(
@@ -649,7 +654,7 @@ object DockerPlugin extends AutoPlugin {
649654
howToFix = """|sbt-native packager tries to parse the `docker version` output. This can fail if
650655
|
651656
| - the output has changed:
652-
| $ docker version --format '{{.Server.Version}}'
657+
| $ docker version --format '{{.Server.APIVersion}}'
653658
|
654659
| - no `docker` executable is available
655660
| $ which docker
@@ -658,52 +663,53 @@ object DockerPlugin extends AutoPlugin {
658663
|
659664
|You can display the parsed docker version in the sbt console with:
660665
|
661-
| sbt:your-project> show dockerVersion
666+
| sbt:your-project> show dockerApiVersion
662667
|
663668
|As a last resort you could hard code the docker version, but it's not recommended!!
664669
|
665-
| import com.typesafe.sbt.packager.docker.DockerVersion
666-
| dockerVersion := Some(DockerVersion(18, 9, 0, Some("ce"))
670+
| import com.typesafe.sbt.packager.docker.DockerApiVersion
671+
| dockerApiVersion := Some(DockerApiVersion(1, 40))
667672
""".stripMargin
668673
)
669674
)
670675
}
671676
}
672677

673678
private[this] def validateDockerPermissionStrategy(strategy: DockerPermissionStrategy,
674-
dockerVersion: Option[DockerVersion]): Validation.Validator =
679+
dockerVersion: Option[DockerVersion],
680+
dockerApiVersion: Option[DockerApiVersion]): Validation.Validator =
675681
() => {
676-
(strategy, dockerVersion) match {
677-
case (DockerPermissionStrategy.MultiStage, Some(ver)) if !DockerSupport.multiStage(ver) =>
682+
(strategy, dockerVersion, dockerApiVersion) match {
683+
case (DockerPermissionStrategy.MultiStage, Some(ver), Some(apiVer)) if !DockerSupport.multiStage(ver, apiVer) =>
678684
List(
679685
ValidationError(
680686
description =
681687
s"The detected Docker version $ver is not compatible with DockerPermissionStrategy.MultiStage",
682688
howToFix =
683689
"""|sbt-native packager tries to parse the `docker version` output.
684-
|To use multi-stage build, upgrade your Docker, pick another strategy, or override dockerVersion:
690+
|To use multi-stage build, upgrade your Docker, pick another strategy, or override dockerApiVersion:
685691
|
686692
| import com.typesafe.sbt.packager.docker.DockerPermissionStrategy
687693
| dockerPermissionStrategy := DockerPermissionStrategy.Run
688694
|
689-
| import com.typesafe.sbt.packager.docker.DockerVersion
690-
| dockerVersion := Some(DockerVersion(18, 9, 0, Some("ce"))
695+
| import com.typesafe.sbt.packager.docker.DockerApiVersion
696+
| dockerApiVersion := Some(DockerApiVersion(1, 40))
691697
""".stripMargin
692698
)
693699
)
694-
case (DockerPermissionStrategy.CopyChown, Some(ver)) if !DockerSupport.chownFlag(ver) =>
700+
case (DockerPermissionStrategy.CopyChown, Some(ver), Some(apiVer)) if !DockerSupport.chownFlag(ver, apiVer) =>
695701
List(
696702
ValidationError(
697703
description =
698704
s"The detected Docker version $ver is not compatible with DockerPermissionStrategy.CopyChown",
699705
howToFix = """|sbt-native packager tries to parse the `docker version` output.
700-
|To use --chown flag, upgrade your Docker, pick another strategy, or override dockerVersion:
706+
|To use --chown flag, upgrade your Docker, pick another strategy, or override dockerApiVersion:
701707
|
702708
| import com.typesafe.sbt.packager.docker.DockerPermissionStrategy
703709
| dockerPermissionStrategy := DockerPermissionStrategy.Run
704710
|
705-
| import com.typesafe.sbt.packager.docker.DockerVersion
706-
| dockerVersion := Some(DockerVersion(18, 9, 0, Some("ce"))
711+
| import com.typesafe.sbt.packager.docker.DockerApiVersion
712+
| dockerApiVersion := Some(DockerApiVersion(1, 40))
707713
""".stripMargin
708714
)
709715
)

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ object DockerSpotifyClientPlugin extends AutoPlugin {
5252

5353
override lazy val projectSettings: Seq[Setting[_]] = inConfig(Docker)(clientSettings)
5454

55-
def clientSettings = Seq(publishLocal := publishLocalDocker.value, dockerVersion := dockerServerVersion.value)
55+
def clientSettings =
56+
Seq(
57+
publishLocal := publishLocalDocker.value,
58+
dockerVersion := dockerServerVersion.value,
59+
dockerApiVersion := dockerServerApiVersion.value
60+
)
5661

5762
def publishLocalDocker: Def.Initialize[Task[Unit]] = Def.task {
5863
val context = stage.value
@@ -71,6 +76,11 @@ object DockerSpotifyClientPlugin extends AutoPlugin {
7176
docker.dockerServerVersion()
7277
}
7378

79+
def dockerServerApiVersion: Def.Initialize[Task[Option[DockerApiVersion]]] = Def.task {
80+
val docker = new DockerClientTask()
81+
docker.dockerServerApiVersion()
82+
}
83+
7484
}
7585

7686
/**
@@ -111,4 +121,9 @@ private class DockerClientTask {
111121
val docker: DockerClient = DefaultDockerClient.fromEnv().build()
112122
DockerVersion.parse(docker.version().version())
113123
}
124+
125+
def dockerServerApiVersion(): Option[DockerApiVersion] = {
126+
val docker: DockerClient = DefaultDockerClient.fromEnv().build()
127+
DockerApiVersion.parse(docker.version().apiVersion())
128+
}
114129
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@ package com.typesafe.sbt.packager.docker
22

33
object DockerSupport {
44

5+
@deprecated
56
def chownFlag(version: DockerVersion): Boolean =
67
(version.major == 17 && version.minor >= 9) || version.major > 17
78

9+
@deprecated
810
def multiStage(version: DockerVersion): Boolean =
911
(version.major == 17 && version.minor >= 5) || version.major > 17
12+
13+
def chownFlag(version: DockerVersion, apiVersion: DockerApiVersion): Boolean =
14+
((version.major == 17 && version.minor >= 9) || version.major > 17) || (apiVersion.major == 1 && apiVersion.minor >= 32)
15+
16+
def multiStage(version: DockerVersion, apiVersion: DockerApiVersion): Boolean =
17+
((version.major == 17 && version.minor >= 5) || version.major > 17) || (apiVersion.major == 1 && apiVersion.minor >= 29)
1018
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ private[packager] trait DockerKeysEx extends DockerKeys {
5656
lazy val dockerChmodType = settingKey[DockerChmodType]("The file permissions for the files copied into Docker image.")
5757
lazy val dockerAdditionalPermissions =
5858
taskKey[Seq[(DockerChmodType, String)]]("Explicit chmod calls to some of the paths.")
59+
val dockerApiVersion = TaskKey[Option[DockerApiVersion]]("dockerApiVersion", "The docker server api version")
5960
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import com.typesafe.sbt.packager.docker._
22

33
dockerVersion := Some(DockerVersion(1, 13, 0, None))
4+
dockerApiVersion := Some(DockerApiVersion(1, 28))

src/sphinx/formats/docker.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ Environment Settings
142142
``dockerVersion``
143143
The docker server version. Used to leverage new docker features while maintaining backwards compatibility.
144144

145+
``dockerApiVersion``
146+
The docker server API version. Used to leverage new docker features while maintaining backwards compatibility.
147+
145148
Publishing Settings
146149
~~~~~~~~~~~~~~~~~~~
147150

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.typesafe.sbt.packager.docker
2+
3+
import org.scalatest._
4+
5+
class DockerApiVersionSpec extends FlatSpec with DiagrammedAssertions {
6+
"DockerApiVersion" should "parse 1.40" in {
7+
val v = DockerApiVersion.parse("1.40")
8+
assert(v == Some(DockerApiVersion(1, 40)))
9+
}
10+
}

0 commit comments

Comments
 (0)