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..1a9defcbf 100644 --- a/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala +++ b/src/main/scala/com/typesafe/sbt/packager/docker/DockerPermissionStrategy.scala @@ -44,6 +44,12 @@ sealed trait DockerChmodType { def argument: String } 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. @@ -61,6 +67,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..dbaf5c4c0 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,15 @@ 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 +125,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 +136,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 +153,11 @@ 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 => @@ -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..bbbb4e766 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,5 @@ 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..97a506866 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