Skip to content

Commit

Permalink
Add Dockerfile.customInstruction method to be able to use Dockerfile …
Browse files Browse the repository at this point in the history
…instructions not implemented in the DSL
  • Loading branch information
marcuslonnberg committed Mar 7, 2022
1 parent e3bb90d commit 4a5963e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 4 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@ docker / dockerfile := NativeDockerfile(file("subdirectory") / "Dockerfile")

Have a look at [DockerfileExamples](examples/DockerfileExamples.scala) for different ways of defining a Dockerfile.

#### Missing Dockerfile instructions

Dockerfile instructions that are missing from the sbt-docker DSL can still be used by calling the `.customInstruction(instructionName, arguments)` method.
Example:
```scala
new Dockerfile {
customInstruction("FROM", "openjdk AS stage1")
run("build")

customInstruction("FROM", "openjdk AS stage2")
customInstruction("COPY", "--from=stage1 /path/to/file /path/to/file")
customInstruction("STOPSIGNAL", "SIGQUIT")

entryPoint("application")
}
```

### Building an image

To build an image use the `docker` task.
Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/sbtdocker/DockerfileCommands.scala
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,20 @@ trait DockerfileCommands {
def healthCheckShell(commands: String*): T = healthCheckShell(commands)

def healthCheckNone(): T = addInstruction(HealthCheckNone)

/**
* Adds a custom Dockerfile instruction that is not currently supported by this DSL.
*
* @example
* {{{
* // Copy in a multi-stage Dockerfile
* // Equivalent to: "COPY --from=stage1 /path/to/file /path/to/file"
* customInstruction("COPY", "--from=stage1 /path/to/file /path/to/file")
*
* // Onbuild instruction can be represented as:
* // ONBUILD RUN /usr/local/bin/python-build --dir /app/src
* customInstruction("ONBUILD", "RUN /usr/local/bin/python-build --dir /app/src")
* }}}
*/
def customInstruction(instructionName: String, arguments: String): T = addInstruction(Raw(instructionName, arguments))
}
7 changes: 5 additions & 2 deletions src/test/scala/sbtdocker/DockerfileLikeSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class DockerfileLikeSuite extends AnyFunSuite with Matchers {
.exec(Seq("cmd", "arg"), interval = Some(20.seconds), timeout = Some(10.seconds), startPeriod = Some(1.second), retries = Some(3)),
HealthCheck
.shell(Seq("cmd", "arg"), interval = Some(20.seconds), timeout = Some(10.seconds), startPeriod = Some(1.second), retries = Some(3)),
HealthCheck.none
HealthCheck.none,
Raw("COPY", "--from=stage1 /path/to/file /path/to/file")
)

test("Instructions string is in correct order and matches instructions") {
Expand Down Expand Up @@ -62,7 +63,8 @@ class DockerfileLikeSuite extends AnyFunSuite with Matchers {
|ONBUILD RUN ["echo", "123"]
|HEALTHCHECK --interval=20s --timeout=10s --start-period=1s --retries=3 CMD ["cmd", "arg"]
|HEALTHCHECK --interval=20s --timeout=10s --start-period=1s --retries=3 CMD cmd arg
|HEALTHCHECK NONE""".stripMargin
|HEALTHCHECK NONE
|COPY --from=stage1 /path/to/file /path/to/file""".stripMargin
}

def staged(dockerfile: immutable.Dockerfile): StagedDockerfile = {
Expand Down Expand Up @@ -118,6 +120,7 @@ class DockerfileLikeSuite extends AnyFunSuite with Matchers {
retries = Some(3)
)
.healthCheckNone()
.customInstruction("COPY", "--from=stage1 /path/to/file /path/to/file")

withMethods shouldEqual predefined
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/scala/sbtdocker/InstructionsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,12 @@ class InstructionsSpec extends AnyFlatSpec with Matchers {
"""LABEL com.example.bar="foo" com.example.bor="boz""""
Label("foo=bar").toString shouldEqual "LABEL foo=bar"
}

"Raw" should "create a correct string" in {
Raw(
"ONBUILD",
"RUN /usr/local/bin/python-build --dir /app/src"
).toString shouldEqual "ONBUILD RUN /usr/local/bin/python-build --dir /app/src"
Raw("COPY", "--from=stage1 /path/to/file /path/to/file").toString shouldEqual "COPY --from=stage1 /path/to/file /path/to/file"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class ImmutableDockerfileSpec extends AnyFlatSpec with Matchers {
retries = Some(3)
)
.healthCheckNone()
.customInstruction("COPY", "--from=stage1 /path/to/file /path/to/file")

val instructions = Seq(
From("image"),
Expand Down Expand Up @@ -108,7 +109,8 @@ class ImmutableDockerfileSpec extends AnyFlatSpec with Matchers {
startPeriod = Some(1.second),
retries = Some(3)
),
HealthCheckNone
HealthCheckNone,
Raw("COPY", "--from=stage1 /path/to/file /path/to/file")
)

dockerfile.instructions should contain theSameElementsInOrderAs instructions
Expand Down
4 changes: 3 additions & 1 deletion src/test/scala/sbtdocker/mutable/MutableDockerfileSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class MutableDockerfileSpec extends AnyFlatSpec with Matchers {
retries = Some(3)
)
healthCheckNone()
customInstruction("COPY", "--from=stage1 /path/to/file /path/to/file")
}

val instructions = Seq(
Expand Down Expand Up @@ -107,7 +108,8 @@ class MutableDockerfileSpec extends AnyFlatSpec with Matchers {
startPeriod = Some(1.second),
retries = Some(3)
),
HealthCheckNone
HealthCheckNone,
Raw("COPY", "--from=stage1 /path/to/file /path/to/file")
)

dockerfile.instructions should contain theSameElementsInOrderAs instructions
Expand Down

0 comments on commit 4a5963e

Please sign in to comment.