From 39d2480a8c4e7862166ef05c41887a22392a59b3 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Fri, 3 Feb 2023 17:42:15 +0000 Subject: [PATCH] Create home directory for daemon users in LinuxPlugin --- .../mima-filters/1.3.15.backward.excludes | 6 ++++- .../archetypes/java_server/rpm/pre-template | 2 +- .../sbt/packager/debian/postinst-template | 2 +- .../sbt/packager/linux/control-functions | 4 ++- .../typesafe/sbt/packager/linux/Keys.scala | 2 ++ .../sbt/packager/linux/LinuxPlugin.scala | 4 +++ src/sbt-test/debian/daemon-user-deb/build.sbt | 2 +- .../debian/daemon-user-homedir-deb/build.sbt | 26 +++++++++++++++++++ .../project/plugins.sbt | 1 + .../debian/daemon-user-homedir-deb/test | 10 +++++++ src/sphinx/archetypes/cheatsheet.rst | 1 + src/sphinx/archetypes/java_server/index.rst | 3 +++ 12 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/sbt-test/debian/daemon-user-homedir-deb/build.sbt create mode 100644 src/sbt-test/debian/daemon-user-homedir-deb/project/plugins.sbt create mode 100644 src/sbt-test/debian/daemon-user-homedir-deb/test diff --git a/src/main/mima-filters/1.3.15.backward.excludes b/src/main/mima-filters/1.3.15.backward.excludes index 6ce6f586d..2042df3a5 100644 --- a/src/main/mima-filters/1.3.15.backward.excludes +++ b/src/main/mima-filters/1.3.15.backward.excludes @@ -74,4 +74,8 @@ ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.do ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.ExecCmd.apply") ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.CombinedCmd.apply") ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.Cmd.apply") -ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.DockerPlugin.publishDocker") \ No newline at end of file +ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.docker.DockerPlugin.publishDocker") + +ProblemFilters.exclude[ReversedMissingMethodProblem]("com.typesafe.sbt.packager.linux.LinuxKeys.com$typesafe$sbt$packager$linux$LinuxKeys$_setter_$daemonHome_=") +ProblemFilters.exclude[ReversedMissingMethodProblem]("com.typesafe.sbt.packager.linux.LinuxKeys.daemonHome") +ProblemFilters.exclude[DirectMissingMethodProblem]("com.typesafe.sbt.packager.linux.LinuxPlugin.makeReplacements") diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template index 088b148f9..abc133f8e 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/pre-template @@ -7,7 +7,7 @@ then # Adding system user/group : ${{daemon_user}} and ${{daemon_group}} addGroup ${{daemon_group}} "${{daemon_group_gid}}" - addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} user-daemon" "${{daemon_shell}}" + addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} user-daemon" "${{daemon_shell}}" "${{daemon_home}}" fi if [ -e /etc/sysconfig/${{app_name}} ] ; diff --git a/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template b/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template index 30b7aa9a4..e88763086 100644 --- a/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template +++ b/src/main/resources/com/typesafe/sbt/packager/debian/postinst-template @@ -2,6 +2,6 @@ ${{header}} ${{control-functions}} addGroup ${{daemon_group}} "${{daemon_group_gid}}" -addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} daemon-user" "${{daemon_shell}}" +addUser ${{daemon_user}} "${{daemon_user_uid}}" ${{daemon_group}} "${{app_name}} daemon-user" "${{daemon_shell}}" "${{daemon_home}}" ${{chown-paths}} diff --git a/src/main/resources/com/typesafe/sbt/packager/linux/control-functions b/src/main/resources/com/typesafe/sbt/packager/linux/control-functions index e18114728..634f1371c 100644 --- a/src/main/resources/com/typesafe/sbt/packager/linux/control-functions +++ b/src/main/resources/com/typesafe/sbt/packager/linux/control-functions @@ -8,6 +8,7 @@ # $3 = group # $4 = description # $5 = shell (defaults to /bin/false) +# $6 = home directory (defaults to /var/lib/$user) addUser() { user="$1" if [ -z "$user" ]; then @@ -23,10 +24,11 @@ addUser() { group=${3:-$user} descr=${4:-No description} shell=${5:-/bin/false} + homedir=${6:-/var/lib/$user} if ! getent passwd | grep -q "^$user:"; then echo "Creating system user: $user in $group with $descr and shell $shell" - useradd $uid_flags --gid $group -r --shell $shell -c "$descr" $user + useradd $uid_flags --gid $group -r --shell $shell -c "$descr" -d "$homedir" -m $user fi } diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala index 25511af53..d58ad8fa6 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala @@ -18,6 +18,8 @@ trait LinuxKeys { SettingKey[Option[String]]("daemon-group-gid", "GID of daemonGroup") val daemonShell = SettingKey[String]("daemon-shell", "Shell provided for the daemon user") + val daemonHome = + SettingKey[String]("daemon-home", "Home directory provided for the daemon user") val fileDescriptorLimit = SettingKey[Option[String]]( "file-descriptor-limit", "Maximum number of open file descriptors for the spawned application" diff --git a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala index f2c92fe38..f335fef91 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala @@ -68,6 +68,7 @@ object LinuxPlugin extends AutoPlugin { daemonGroup in Linux := daemonGroup.value, daemonGroupGid in Linux := None, daemonShell in Linux := "/bin/false", + daemonHome in Linux := s"/var/lib/${(daemonUser in Linux).value}", defaultLinuxInstallLocation := "/usr/share", defaultLinuxLogsLocation := "/var/log", defaultLinuxConfigLocation := "/etc", @@ -93,6 +94,7 @@ object LinuxPlugin extends AutoPlugin { daemonGroup = (daemonGroup in Linux).value, daemonGroupGid = (daemonGroupGid in Linux).value, daemonShell = (daemonShell in Linux).value, + daemonHome = (daemonHome in Linux).value, fileDescriptorLimit = (fileDescriptorLimit in Linux).value ), linuxScriptReplacements += controlScriptFunctionsReplacement( /* Add key for control-functions */ ), @@ -162,6 +164,7 @@ object LinuxPlugin extends AutoPlugin { daemonGroup: String, daemonGroupGid: Option[String], daemonShell: String, + daemonHome: String, fileDescriptorLimit: Option[String] ): Seq[(String, String)] = Seq( @@ -177,6 +180,7 @@ object LinuxPlugin extends AutoPlugin { "daemon_group" -> daemonGroup, "daemon_group_gid" -> daemonGroupGid.getOrElse(""), "daemon_shell" -> daemonShell, + "daemon_home" -> daemonHome, "file_descriptor_limit" -> fileDescriptorLimit.getOrElse("") ) diff --git a/src/sbt-test/debian/daemon-user-deb/build.sbt b/src/sbt-test/debian/daemon-user-deb/build.sbt index efd7d188b..ec95086d8 100644 --- a/src/sbt-test/debian/daemon-user-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-deb/build.sbt @@ -19,7 +19,7 @@ TaskKey[Unit]("checkControlFiles") := { val postrm = IO.read(debian / "postrm") assert(postinst contains """addGroup daemongroup """"", "postinst misses addgroup for daemongroup: " + postinst) assert( - postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/false"""", + postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/false" "/var/lib/daemonuser""", "postinst misses useradd for daemonuser: " + postinst ) assert( diff --git a/src/sbt-test/debian/daemon-user-homedir-deb/build.sbt b/src/sbt-test/debian/daemon-user-homedir-deb/build.sbt new file mode 100644 index 000000000..3d458c453 --- /dev/null +++ b/src/sbt-test/debian/daemon-user-homedir-deb/build.sbt @@ -0,0 +1,26 @@ +enablePlugins(JavaServerAppPackaging) + +daemonUser in Linux := "daemonuser" +daemonGroup in Linux := "daemongroup" +daemonHome in Linux := "/var/lib/customdaemonhome" + +mainClass in Compile := Some("empty") + +name := "debian-test" +version := "0.1.0" +maintainer := "Josh Suereth " + +packageSummary := "Test debian package" +packageDescription := """A fun package description of our software, + with multiple lines.""" + +TaskKey[Unit]("checkControlFiles") := { + val debian = target.value / "debian-test-0.1.0" / "DEBIAN" + val postinst = IO.read(debian / "postinst") + val postrm = IO.read(debian / "postrm") + assert( + postinst contains """addUser daemonuser "" daemongroup "debian-test daemon-user" "/bin/false" "/var/lib/customdaemonhome"""", + "postinst misses useradd for daemonuser with custom home directory: " + postinst + ) + () +} diff --git a/src/sbt-test/debian/daemon-user-homedir-deb/project/plugins.sbt b/src/sbt-test/debian/daemon-user-homedir-deb/project/plugins.sbt new file mode 100644 index 000000000..218f1a27d --- /dev/null +++ b/src/sbt-test/debian/daemon-user-homedir-deb/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.github.sbt" % "sbt-native-packager" % sys.props("project.version")) diff --git a/src/sbt-test/debian/daemon-user-homedir-deb/test b/src/sbt-test/debian/daemon-user-homedir-deb/test new file mode 100644 index 000000000..003fb4e70 --- /dev/null +++ b/src/sbt-test/debian/daemon-user-homedir-deb/test @@ -0,0 +1,10 @@ +# Run the debian packaging. +> debian:packageBin +$ exists target/debian-test_0.1.0_all.deb + +# Check defaults +$ exists target/debian-test-0.1.0/DEBIAN/prerm +$ exists target/debian-test-0.1.0/DEBIAN/postinst + +# Check files for defaults +> checkControlFiles diff --git a/src/sphinx/archetypes/cheatsheet.rst b/src/sphinx/archetypes/cheatsheet.rst index c364bfd19..6647c5097 100644 --- a/src/sphinx/archetypes/cheatsheet.rst +++ b/src/sphinx/archetypes/cheatsheet.rst @@ -217,6 +217,7 @@ You can use ``${{variable_name}}`` to reference variables when writing your scri * ``daemon_group`` - The group of the user that the service should run as; defined by ``Linux / daemonGroup``. * ``daemon_group_gid`` - The group ID of the group of the user that the service should run as; defined by ``Linux / daemonGroupGid``. * ``daemon_shell`` - The shell of the user that the service should run as; defined by ``Linux / daemonShell``. +* ``daemon_home`` - The home directory of the user that the service should run as; defined by ``Linux / daemonHome``. * ``term_timeout`` - The timeout for the service to respond to a TERM signal; defined by ``Linux / termTimeout``, defaults to ``60``. * ``kill_timeout`` - The timeout for the service to respond to a KILL signal; defined by ``Linux / killTimeout``, defaults to ``30``. * ``start_facilities`` - Intended for the ``Required-Start:`` line in the ``INIT INFO`` block. Its value is automatically generated with respect to the chosen system loader. diff --git a/src/sphinx/archetypes/java_server/index.rst b/src/sphinx/archetypes/java_server/index.rst index 15337e632..2a2ff43bc 100644 --- a/src/sphinx/archetypes/java_server/index.rst +++ b/src/sphinx/archetypes/java_server/index.rst @@ -54,6 +54,9 @@ have sensible defaults. ``daemonShell`` Shell provided for the daemon user + ``daemonHome`` + Home directory provided for the daemon user + ``daemonStdoutLogFile`` Filename stdout/stderr of application daemon. Now it's supported only in SystemV