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

Run chmod +x explicitly in stage0 #1201

Merged
merged 2 commits into from
Feb 12, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ sealed trait DockerChmodType {
}
object DockerChmodType {

/**
* Gives read permission to users and groups.
*/
case object UserGroupRead extends DockerChmodType {
def argument: String = "u=r,g=r"
}

/**
* Gives read permission to users and groups.
* Gives execute permission to users and groups, if +x flag is on for any.
Expand All @@ -61,6 +68,13 @@ object DockerChmodType {
def argument: String = "u=rwX,g=rwX"
}

/**
* Gives +x permission to users and groups.
*/
case object UserGroupPlusExecute extends DockerChmodType {
def argument: String = "u+x,g+x"
}

/**
* Copies user file mode bits to group file mode bits.
*/
Expand Down
33 changes: 27 additions & 6 deletions src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ object DockerPlugin extends AutoPlugin {
},
dockerRmiCommand := dockerExecCommand.value ++ Seq("rmi"),
dockerBuildCommand := dockerExecCommand.value ++ Seq("build") ++ dockerBuildOptions.value ++ Seq("."),
dockerAdditionalPermissions := {
val scripts = makeBashScripts.value
Copy link
Contributor

@muuki88 muuki88 Feb 28, 2019

Choose a reason for hiding this comment

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

I overlooked that. This causes a circular dependency between JavaAppPackaging and the DockerPlugin, which produces a bug reported in #1205

val ms = (mappings in Docker).value
scripts flatMap {
case (script, _) =>
ms collect {
case (k, v) if k == script => DockerChmodType.UserGroupPlusExecute -> v
}
}
},
dockerCommands := {
val strategy = dockerPermissionStrategy.value
val dockerBaseDirectory = (defaultLinuxInstallLocation in Docker).value
Expand All @@ -116,6 +126,7 @@ object DockerPlugin extends AutoPlugin {
val group = (daemonGroup in Docker).value
val gidOpt = (daemonGroupGid in Docker).value
val base = dockerBaseImage.value
val addPerms = dockerAdditionalPermissions.value

val generalCommands = makeFrom(base) +: makeMaintainer((maintainer in Docker).value).toSeq
val stage0name = "stage0"
Expand All @@ -126,9 +137,10 @@ object DockerPlugin extends AutoPlugin {
makeWorkdir(dockerBaseDirectory),
makeCopy(dockerBaseDirectory),
makeUser("root"),
makeChmod(dockerChmodType.value, Seq(dockerBaseDirectory)),
DockerStageBreak
)
makeChmodRecursive(dockerChmodType.value, Seq(dockerBaseDirectory))
) ++
(addPerms map { case (tpe, v) => makeChmod(tpe, Seq(v)) }) ++
Seq(DockerStageBreak)
case _ => Seq()
}

Expand All @@ -142,7 +154,8 @@ object DockerPlugin extends AutoPlugin {
case DockerPermissionStrategy.MultiStage =>
Seq(makeCopyFrom(dockerBaseDirectory, stage0name, user, group))
case DockerPermissionStrategy.Run =>
Seq(makeCopy(dockerBaseDirectory), makeChmod(dockerChmodType.value, Seq(dockerBaseDirectory)))
Seq(makeCopy(dockerBaseDirectory), makeChmodRecursive(dockerChmodType.value, Seq(dockerBaseDirectory))) ++
(addPerms map { case (tpe, v) => makeChmod(tpe, Seq(v)) })
case DockerPermissionStrategy.CopyChown =>
Seq(makeCopyChown(dockerBaseDirectory, user, group))
case DockerPermissionStrategy.None =>
Expand All @@ -156,6 +169,8 @@ object DockerPlugin extends AutoPlugin {
case Some(uid) => makeUser(uid)
case _ => makeUser(user)
}) ++
// Use this to debug permissions
// Seq(ExecCmd("RUN", Seq("ls", "-l", "/opt/docker/bin/"): _*)) ++
Seq(makeEntrypoint(dockerEntrypoint.value), makeCmd(dockerCmd.value))

stage0 ++ stage1
Expand Down Expand Up @@ -321,9 +336,15 @@ object DockerPlugin extends AutoPlugin {
ExecCmd("RUN", Seq("chown", "-R", s"$daemonUser:$daemonGroup") ++ directories: _*)

/**
* @return chown command, owning the installation directory with the daemonuser
* @return chmod command
*/
private final def makeChmod(chmodType: DockerChmodType, files: Seq[String]): CmdLike =
ExecCmd("RUN", Seq("chmod", chmodType.argument) ++ files: _*)

/**
* @return chmod command recursively
*/
private final def makeChmod(chmodType: DockerChmodType, directories: Seq[String]): CmdLike =
private final def makeChmodRecursive(chmodType: DockerChmodType, directories: Seq[String]): CmdLike =
ExecCmd("RUN", Seq("chmod", "-R", chmodType.argument) ++ directories: _*)

/**
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ trait DockerKeys {
private[packager] trait DockerKeysEx extends DockerKeys {
lazy val dockerPermissionStrategy = settingKey[DockerPermissionStrategy]("The strategy to change file permissions.")
lazy val dockerChmodType = settingKey[DockerChmodType]("The file permissions for the files copied into Docker image.")
lazy val dockerAdditionalPermissions =
taskKey[Seq[(DockerChmodType, String)]]("Explicit chmod calls to some of the paths.")
}
5 changes: 5 additions & 0 deletions src/sbt-test/docker/file-permission/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package example

object Main extends App {
println("hello")
}
3 changes: 3 additions & 0 deletions src/sbt-test/docker/file-permission/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ lazy val root = (project in file("."))
|COPY opt /opt
|USER root
|RUN ["chmod", "-R", "u=rX,g=rX", "/opt/docker"]
|RUN ["chmod", "u+x,g+x", "/opt/docker/bin/file-permission-test"]
|
|FROM fabric8/java-centos-openjdk8-jdk
|USER root
Expand Down Expand Up @@ -53,6 +54,7 @@ lazy val root = (project in file("."))
|WORKDIR /opt/docker
|COPY opt /opt
|RUN ["chmod", "-R", "u=rX,g=rX", "/opt/docker"]
|RUN ["chmod", "u+x,g+x", "/opt/docker/bin/file-permission-test"]
|USER 1001
|ENTRYPOINT ["/opt/docker/bin/file-permission-test"]
|CMD []""".stripMargin.linesIterator.toList)
Expand All @@ -79,6 +81,7 @@ lazy val root = (project in file("."))
|COPY opt /opt
|USER root
|RUN ["chmod", "-R", "u=rwX,g=rwX", "/opt/docker"]
|RUN ["chmod", "u+x,g+x", "/opt/docker/bin/file-permission-test"]
|
|FROM fabric8/java-centos-openjdk8-jdk
|USER root
Expand Down
21 changes: 17 additions & 4 deletions src/sphinx/formats/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,16 @@ Environment Settings
``dockerChmodType``
The file permissions for the files copied into Docker image when ``MultiStage`` or ``Run`` strategy is used.

* ``DockerChmodType.UserGroupReadExecute`` (default): chmod -R u=rX,g=rX
* ``DockerChmodType.UserGroupWriteExecute``: chmod -R u=rwX,g=rwX
* ``DockerChmodType.SyncGroupToUser``: chmod -R g=u
* ``DockerChmodType.UserGroupReadExecute`` (default): chmod u=rX,g=rX
* ``DockerChmodType.UserGroupRead``: chmod u=r,g=r
* ``DockerChmodType.UserGroupWriteExecute``: chmod u=rwX,g=rwX
* ``DockerChmodType.SyncGroupToUser``: chmod g=u
* ``DockerChmodType.UserGroupPlusExecute``: chmod u+x,g+x (This is for ``dockerAdditionalPermissions``)
* ``DockerChmodType.Custom``: Custom argument provided by the user.

``dockerAdditionalPermissions``
Additional permissions typically used to give ``chmod +x`` rights for the executable files. By default generated Bash scripts are given ``DockerChmodType.UserGroupPlusExecute``.

``dockerVersion``
The docker server version. Used to leverage new docker features while maintaining backwards compatibility.

Expand Down Expand Up @@ -271,6 +276,14 @@ If you want to make the working directory writable by the running process, here'

dockerChmodType := DockerChmodType.UserGroupWriteExecute

By default, the shell scripts generated by SBT Native Packager are given ``chmod +x`` rights. Here's the setting to do so for other files:

.. code-block:: scala

import com.typesafe.sbt.packager.docker.DockerChmodType

dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/opt/docker/bin/hello")

If you don't want SBT Native Packager to change the file permissions at all here's a strategy you can choose:

.. code-block:: scala
Expand All @@ -280,7 +293,7 @@ If you don't want SBT Native Packager to change the file permissions at all here
dockerPermissionStrategy := DockerPermissionStrategy.None

This will inherit the file mode bits set in your machine. Given that Kubernetes implementations like OpenShift will use an arbitrary user,
remember to set both the user bits and group bits when running `chmod` yourself.
remember to set both the user bits and group bits when running ``chmod`` yourself.

Custom Dockerfile
~~~~~~~~~~~~~~~~~
Expand Down