From 89d605056ac166daec6a0ecbf7c75fdf420f7515 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 8 Feb 2019 17:00:06 -0500 Subject: [PATCH 1/2] Run chmod +x explicitly in stage0 Using sbt-native-packager 1.3.17 with OpenShift, I still ran into some permission issues and needed to call chmod +x explicitly in the container. This will emit chmod +x for all bash scripts that was generated. --- .../docker/DockerPermissionStrategy.scala | 14 ++++++++ .../sbt/packager/docker/DockerPlugin.scala | 33 +++++++++++++++---- .../typesafe/sbt/packager/docker/Keys.scala | 2 ++ .../docker/file-permission/Main.scala | 5 +++ src/sbt-test/docker/file-permission/build.sbt | 3 ++ src/sphinx/formats/docker.rst | 21 +++++++++--- 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/sbt-test/docker/file-permission/Main.scala diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala index 837bc9271..7313baed5 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala @@ -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. @@ -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. */ diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala index b489cb148..125f37532 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala @@ -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 + 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 @@ -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" @@ -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() } @@ -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 => @@ -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 @@ -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: _*) /** diff --git a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala index 1966d7fb5..0c516a051 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/Keys.scala @@ -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.") } diff --git a/src/sbt-test/docker/file-permission/Main.scala b/src/sbt-test/docker/file-permission/Main.scala new file mode 100644 index 000000000..995292067 --- /dev/null +++ b/src/sbt-test/docker/file-permission/Main.scala @@ -0,0 +1,5 @@ +package example + +object Main extends App { + println("hello") +} diff --git a/src/sbt-test/docker/file-permission/build.sbt b/src/sbt-test/docker/file-permission/build.sbt index aba07e026..1364a2992 100644 --- a/src/sbt-test/docker/file-permission/build.sbt +++ b/src/sbt-test/docker/file-permission/build.sbt @@ -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 @@ -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) @@ -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 diff --git a/src/sphinx/formats/docker.rst b/src/sphinx/formats/docker.rst index 0b8b97fbc..98d6834d1 100644 --- a/src/sphinx/formats/docker.rst +++ b/src/sphinx/formats/docker.rst @@ -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``. + ``dockerVersion`` The docker server version. Used to leverage new docker features while maintaining backwards compatibility. @@ -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 @@ -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 ~~~~~~~~~~~~~~~~~ From 3f720ad9a375ab753a4c046916261796d29df23c Mon Sep 17 00:00:00 2001 From: Nepomuk Seiler Date: Tue, 12 Feb 2019 09:42:39 +0100 Subject: [PATCH 2/2] Add full default permission type --- src/sphinx/formats/docker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sphinx/formats/docker.rst b/src/sphinx/formats/docker.rst index 98d6834d1..ae79c3a1a 100644 --- a/src/sphinx/formats/docker.rst +++ b/src/sphinx/formats/docker.rst @@ -136,7 +136,7 @@ Environment Settings * ``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``. + 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.