From 0a6be58f7402c5ef44d7d1d84c83076ffe2e191a Mon Sep 17 00:00:00 2001 From: Nepomuk Seiler Date: Sun, 22 May 2016 19:22:33 +0200 Subject: [PATCH] Extract Systemloaders into AutoPlugins (#785) * Add systemd plugin. Idea on how to configure systemloaders * First intermediate step. Systemd emits debian and rpm maintainerScripts * Created Plugins for all loaders. Now write tests * Start fixing debian tests * Add systemloader replacements * More tests fixed * Fixed debian tests and started with rpm tests * RPM and Debian are now working * Fix setarch-rpm test * Fixing some codacy issues * Remove systemd extra settings * Add documentation --- .../java_server/debian/postinst-template | 11 - .../java_server/debian/postrm-template | 10 - .../java_server/debian/preinst-template | 10 - .../java_server/debian/prerm-template | 12 -- .../archetypes/java_server/rpm/post-template | 9 - .../java_server/rpm/postun-template | 6 - .../archetypes/java_server/rpm/preun-template | 8 - .../systemloader/systemd/loader-functions | 0 .../systemloader/systemd/start-template | 0 .../systemloader/systemv/loader-functions | 0 .../systemv/start-debian-template | 0 .../systemloader/systemv/start-rpm-template | 0 .../systemloader/upstart/loader-functions | 0 .../systemloader/upstart/start-template | 0 .../com/typesafe/sbt/packager/Keys.scala | 1 + .../archetypes/JavaServerApplication.scala | 194 +++--------------- .../archetypes/JavaServerBashScript.scala | 4 +- .../archetypes/MaintainerScriptHelper.scala | 28 ++- .../packager/archetypes/TemplateWriter.scala | 2 + .../{ => systemloader}/ServerLoader.scala | 5 +- .../systemloader/SystemVPlugin.scala | 66 ++++++ .../systemloader/SystemdPlugin.scala | 56 +++++ .../systemloader/SystemloaderKeys.scala | 11 + .../systemloader/SystemloaderPlugin.scala | 135 ++++++++++++ .../systemloader/UpstartPlugin.scala | 51 +++++ .../archetypes/systemloader/package.scala | 67 ++++++ .../sbt/packager/debian/DebianPlugin.scala | 33 ++- .../typesafe/sbt/packager/linux/Keys.scala | 10 +- .../sbt/packager/linux/LinuxPlugin.scala | 3 +- .../sbt/packager/rpm/RpmMetadata.scala | 28 ++- .../typesafe/sbt/packager/rpm/RpmPlugin.scala | 32 ++- .../debian/daemon-group-gid-deb/build.sbt | 11 +- src/sbt-test/debian/daemon-user-deb/build.sbt | 8 - src/sbt-test/debian/daemon-user-deb/test | 2 - .../debian/daemon-user-shell-deb/build.sbt | 9 - .../debian/daemon-user-uid-deb/build.sbt | 9 - src/sbt-test/debian/daemon-user-uid-deb/test | 2 +- .../debian/java-app-archetype/build.sbt | 2 +- src/sbt-test/debian/log-directory/build.sbt | 4 - src/sbt-test/debian/log-directory/test | 4 - .../debian/override-control-files/build.sbt | 4 +- .../debian/override-etc-default/build.sbt | 6 +- .../debian/override-start-script/build.sbt | 12 +- .../{debian => systemloader}/systemv | 0 .../{debian => systemloader}/upstart | 0 src/sbt-test/debian/systemd-deb/build.sbt | 9 +- src/sbt-test/debian/systemd-deb/test | 3 + src/sbt-test/debian/sysvinit-deb/build.sbt | 6 +- .../sysvinit-stoptimeouts-deb/build.sbt | 6 +- .../test-executableScriptName/build.sbt | 2 +- .../debian/upstart-deb-facilities/build.sbt | 6 +- src/sbt-test/debian/upstart-deb/build.sbt | 12 +- src/sbt-test/rpm/path-override-rpm/build.sbt | 9 +- .../rpm/scriptlets-override-rpm/build.sbt | 9 +- src/sbt-test/rpm/setarch-rpm/build.sbt | 14 +- src/sbt-test/rpm/systemd-rpm/build.sbt | 12 +- src/sbt-test/rpm/sysvinit-rpm/build.sbt | 10 +- .../rpm/test-executableScriptName/build.sbt | 2 +- src/sbt-test/rpm/test-packageName/build.sbt | 2 +- src/sphinx/archetypes/akka_app.rst | 47 ----- src/sphinx/archetypes/index.rst | 2 +- .../archetypes/java_server/customize.rst | 100 +-------- src/sphinx/archetypes/java_server/index.rst | 37 +--- src/sphinx/archetypes/systemloaders.rst | 135 ++++++++++++ test-project-simple/build.sbt | 2 +- 65 files changed, 668 insertions(+), 622 deletions(-) delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template delete mode 100644 src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preun-template rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/systemd/loader-functions (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/systemd/start-template (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/systemv/loader-functions (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/systemv/start-debian-template (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/systemv/start-rpm-template (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/upstart/loader-functions (100%) rename src/main/resources/com/typesafe/sbt/packager/archetypes/{java_server => }/systemloader/upstart/start-template (100%) rename src/main/scala/com/typesafe/sbt/packager/archetypes/{ => systemloader}/ServerLoader.scala (77%) create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemdPlugin.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala create mode 100644 src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/package.scala rename src/sbt-test/debian/override-start-script/src/templates/{debian => systemloader}/systemv (100%) rename src/sbt-test/debian/override-start-script/src/templates/{debian => systemloader}/upstart (100%) delete mode 100644 src/sphinx/archetypes/akka_app.rst create mode 100644 src/sphinx/archetypes/systemloaders.rst diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template deleted file mode 100644 index 11d2412a5..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postinst-template +++ /dev/null @@ -1,11 +0,0 @@ -# ------------------------------------------------------------------------------------ -# ____ _ _ _ -# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ -# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ -# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ -# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| -# |___/|_| -# ------------------------------------------------------------------------------------ - -${{loader-functions}} -startService ${{app_name}} || echo "${{app_name}} could not be registered or started" diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template deleted file mode 100644 index d63a46751..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/postrm-template +++ /dev/null @@ -1,10 +0,0 @@ -# ------------------------------------------------------------------------------------ -# ____ _ _ _ -# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ -# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ -# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ -# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| -# |___/|_| -# ------------------------------------------------------------------------------------ - -# empty \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template deleted file mode 100644 index d63a46751..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/preinst-template +++ /dev/null @@ -1,10 +0,0 @@ -# ------------------------------------------------------------------------------------ -# ____ _ _ _ -# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ -# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ -# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ -# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| -# |___/|_| -# ------------------------------------------------------------------------------------ - -# empty \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template deleted file mode 100644 index b4e318141..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/debian/prerm-template +++ /dev/null @@ -1,12 +0,0 @@ -# ------------------------------------------------------------------------------------ -# ____ _ _ _ -# / ___| ___ _ ____ _____ _ __ / \ _ __ ___| |__ ___| |_ _ _ _ __ ___ -# \___ \ / _ \ '__\ \ / / _ \ '__| / _ \ | '__/ __| '_ \ / _ \ __| | | | '_ \ / _ \ -# ___) | __/ | \ V / __/ | / ___ \| | | (__| | | | __/ |_| |_| | |_) | __/ -# |____/ \___|_| \_/ \___|_| /_/ \_\_| \___|_| |_|\___|\__|\__, | .__/ \___| -# |___/|_| -# ------------------------------------------------------------------------------------ - -${{loader-functions}} - -stopService ${{app_name}} || echo "${{app_name}} wasn't even running!" \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template deleted file mode 100644 index 63b0e4ccc..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/post-template +++ /dev/null @@ -1,9 +0,0 @@ -${{loader-functions}} - -# Scriptlet syntax: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Syntax -# $1 == 1 is first installation and $1 == 2 is upgrade - -if [ $1 -eq 1 ] ; -then - startService ${{app_name}} || echo "Could not start ${{app_name}}" -fi \ No newline at end of file diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postun-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postun-template index cb3bacb78..730050157 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postun-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/postun-template @@ -1,5 +1,4 @@ ${{control-functions}} -${{loader-functions}} # Removing system user/group : ${{daemon_user}} and ${{daemon_group}} @@ -18,9 +17,4 @@ then then echo "Deleting system group: ${{daemon_group}}" deleteGroup ${{daemon_group}} - fi -else - restartService ${{app_name}} || echo "Failed to try-restart ${{app_name}}" fi - - diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preun-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preun-template deleted file mode 100644 index 4157a5886..000000000 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/rpm/preun-template +++ /dev/null @@ -1,8 +0,0 @@ -${{loader-functions}} - -# Scriptlet syntax: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Syntax -# $1 == 1 is upgrade and $1 == 0 is uninstall -if [ $1 -eq 0 ] ; -then - stopService ${{app_name}} || echo "Could not stop ${{app_name}}" -fi diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemd/loader-functions b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemd/loader-functions similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemd/loader-functions rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemd/loader-functions diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemd/start-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemd/start-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemd/start-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemd/start-template diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/loader-functions b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/loader-functions similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/loader-functions rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/loader-functions diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-debian-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/start-debian-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-debian-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/start-debian-template diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-rpm-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/start-rpm-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/systemv/start-rpm-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/systemv/start-rpm-template diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/upstart/loader-functions b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/loader-functions similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/upstart/loader-functions rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/loader-functions diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/upstart/start-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template similarity index 100% rename from src/main/resources/com/typesafe/sbt/packager/archetypes/java_server/systemloader/upstart/start-template rename to src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template diff --git a/src/main/scala/com/typesafe/sbt/packager/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/Keys.scala index c18d5fd05..3e09b964b 100644 --- a/src/main/scala/com/typesafe/sbt/packager/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/Keys.scala @@ -49,3 +49,4 @@ object Keys extends NativePackagerKeys with rpm.RpmKeys with archetypes.JavaAppKeys with archetypes.JavaServerAppKeys + with archetypes.systemloader.SystemloaderKeys diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala index ad2552e18..5a64c049a 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala @@ -1,27 +1,22 @@ -package com.typesafe.sbt -package packager -package archetypes +package com.typesafe.sbt.packager.archetypes import sbt._ import sbt.Keys.{ target, mainClass, sourceDirectory, streams, javaOptions, run } -import SbtNativePackager.{ Debian, Rpm, Universal } -import packager.Keys.{ packageName, maintainerScripts, daemonStdoutLogFile } -import linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin } -import linux.LinuxPlugin.autoImport._ -import debian.DebianPlugin -import debian.DebianPlugin.autoImport.{ debianMakePreinstScript, debianMakePostinstScript, debianMakePrermScript, debianMakePostrmScript } -import rpm.RpmPlugin -import rpm.RpmPlugin.autoImport.{ rpmPre, rpmPost, rpmPostun, rpmPreun, rpmScriptsDirectory, rpmDaemonLogFile, RpmConstants } -import JavaAppPackaging.autoImport.{ bashScriptConfigLocation, bashScriptEnvConfigLocation } +import com.typesafe.sbt.SbtNativePackager.{ Debian, Rpm, Universal, Linux } +import com.typesafe.sbt.packager.Keys._ +import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin } +import com.typesafe.sbt.packager.linux.LinuxPlugin.autoImport.packageTemplateMapping +import com.typesafe.sbt.packager.debian.DebianPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin.autoImport.RpmConstants +import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader /** - * This class contains the default settings for creating and deploying an archetypical Java application. - * A Java application archetype is defined as a project that has a main method and is run by placing - * all of its JAR files on the classpath and calling that main method. + * == Java Server App Packaging == * - * This doesn't create the best of distributions, but it can simplify the distribution of code. + * Provides configuration for running an application on a server. * - * **NOTE: EXPERIMENTAL** This currently only supports debian upstart scripts. + * @see [[http://sbt-native-packager.readthedocs.io/en/latest/archetypes/java_server/index.html]] */ object JavaServerAppPackaging extends AutoPlugin { import ServerLoader._ @@ -74,7 +69,7 @@ object JavaServerAppPackaging extends AutoPlugin { private[this] val etcDefaultConfig: Seq[Setting[_]] = Seq( linuxEtcDefaultTemplate := getEtcTemplateSource( sourceDirectory.value, - serverLoading.value), + (serverLoading ?? None).value), makeEtcDefault := makeEtcDefaultScript( packageName.value, (target in Universal).value, @@ -89,33 +84,10 @@ object JavaServerAppPackaging extends AutoPlugin { import DebianPlugin.Names.{ Preinst, Postinst, Prerm, Postrm } inConfig(Debian)(etcDefaultConfig) ++ inConfig(Debian)(Seq( - serverLoading := Upstart, - startRunlevels <<= (serverLoading) apply defaultStartRunlevels, - stopRunlevels <<= (serverLoading) apply defaultStopRunlevels, - requiredStartFacilities <<= (serverLoading) apply defaultFacilities, - requiredStopFacilities <<= (serverLoading) apply defaultFacilities, - // === Startscript creation === - linuxScriptReplacements <++= (requiredStartFacilities, requiredStopFacilities, startRunlevels, stopRunlevels, serverLoading) apply - makeStartScriptReplacements, - linuxScriptReplacements += JavaServerLoaderScript.loaderFunctionsReplacement(serverLoading.value, ARCHETYPE), + // === Extra replacements === linuxScriptReplacements ++= bashScriptEnvConfigLocation.value.map(ENV_CONFIG_REPLACEMENT -> _).toSeq, linuxScriptReplacements += Names.DaemonStdoutLogFileReplacement -> daemonStdoutLogFile.value.getOrElse(""), - linuxStartScriptTemplate <<= (serverLoading in Debian, sourceDirectory) map { (loader, srcDir) => - JavaServerLoaderScript( - script = defaultTemplateName(loader, Debian), - loader = loader, - archetype = ARCHETYPE, - template = overrideTemplate(srcDir, loader, Debian) - ) - }, - defaultLinuxStartScriptLocation <<= serverLoading apply getStartScriptLocation, - linuxMakeStartScript in Debian <<= (linuxStartScriptTemplate in Debian, - linuxScriptReplacements in Debian, - target in Universal, - serverLoading in Debian) map makeStartScript, - linuxPackageMappings <++= (packageName, linuxMakeStartScript, serverLoading, defaultLinuxStartScriptLocation, linuxStartScriptName) map startScriptMapping, - // === Maintainer scripts === maintainerScripts := { val scripts = (maintainerScripts in Debian).value @@ -123,10 +95,10 @@ object JavaServerAppPackaging extends AutoPlugin { val contentOf = getScriptContent(Debian, replacements) _ scripts ++ Map( - Preinst -> (scripts.getOrElse(Preinst, Nil) :+ contentOf(Preinst)), - Postinst -> (scripts.getOrElse(Postinst, Nil) :+ contentOf(Postinst)), - Prerm -> (scripts.getOrElse(Prerm, Nil) :+ contentOf(Prerm)), - Postrm -> (scripts.getOrElse(Postrm, Nil) :+ contentOf(Postrm)) + Preinst -> (scripts.getOrElse(Preinst, Nil) ++ contentOf(Preinst)), + Postinst -> (scripts.getOrElse(Postinst, Nil) ++ contentOf(Postinst)), + Prerm -> (scripts.getOrElse(Prerm, Nil) ++ contentOf(Prerm)), + Postrm -> (scripts.getOrElse(Postrm, Nil) ++ contentOf(Postrm)) ) } )) ++ Seq( @@ -142,14 +114,7 @@ object JavaServerAppPackaging extends AutoPlugin { import RpmPlugin.Names.{ Pre, Post, Preun, Postun } inConfig(Rpm)(etcDefaultConfig) ++ inConfig(Rpm)(Seq( - serverLoading := SystemV, - startRunlevels <<= (serverLoading) apply defaultStartRunlevels, - stopRunlevels in Rpm <<= (serverLoading) apply defaultStopRunlevels, - requiredStartFacilities in Rpm <<= (serverLoading) apply defaultFacilities, - requiredStopFacilities in Rpm <<= (serverLoading) apply defaultFacilities, - linuxScriptReplacements <++= (requiredStartFacilities, requiredStopFacilities, startRunlevels, stopRunlevels, serverLoading) apply - makeStartScriptReplacements, - linuxScriptReplacements += JavaServerLoaderScript.loaderFunctionsReplacement(serverLoading.value, ARCHETYPE), + // === Extra replacements === linuxScriptReplacements ++= bashScriptEnvConfigLocation.value.map(ENV_CONFIG_REPLACEMENT -> _).toSeq, linuxScriptReplacements += Names.DaemonStdoutLogFileReplacement -> daemonStdoutLogFile.value.getOrElse(""), @@ -163,24 +128,6 @@ object JavaServerAppPackaging extends AutoPlugin { daemonUserUid in Rpm <<= daemonUserUid in Linux, daemonGroup in Rpm <<= daemonGroup in Linux, daemonGroupGid in Rpm <<= daemonGroupGid in Linux, - // === Startscript creation === - linuxStartScriptTemplate <<= (serverLoading in Rpm, sourceDirectory) map { (loader, srcDir) => - JavaServerLoaderScript( - script = defaultTemplateName(loader, Rpm), - loader = loader, - archetype = ARCHETYPE, - template = overrideTemplate(srcDir, loader, Rpm) - ) - }, - linuxMakeStartScript in Rpm <<= (linuxStartScriptTemplate in Rpm, - linuxScriptReplacements in Rpm, - target in Universal, - serverLoading in Rpm) map makeStartScript, - - defaultLinuxStartScriptLocation in Rpm <<= (serverLoading in Rpm) apply getStartScriptLocation, - linuxStartScriptName in Rpm <<= linuxStartScriptName in Linux, - linuxPackageMappings in Rpm <++= (packageName in Rpm, linuxMakeStartScript in Rpm, serverLoading in Rpm, defaultLinuxStartScriptLocation in Rpm, linuxStartScriptName in Rpm) map startScriptMapping, - // == Maintainer scripts === maintainerScripts in Rpm := rpmScriptletContents(rpmScriptsDirectory.value, (maintainerScripts in Rpm).value, (linuxScriptReplacements in Rpm).value) ) @@ -190,67 +137,6 @@ object JavaServerAppPackaging extends AutoPlugin { /* ============ Helper Methods ============== */ /* ========================================== */ - private[this] def defaultTemplateName(loader: ServerLoader, config: Configuration): String = (loader, config.name) match { - // SystemV has two different start scripts - case (SystemV, name) => s"start-$name-template" - case _ => "start-template" - } - - private[this] def overrideTemplate(sourceDirectory: File, loader: ServerLoader, config: Configuration): Option[File] = { - Option(sourceDirectory / "templates" / config.name / loader.toString.toLowerCase) - } - - private[this] def makeStartScriptReplacements( - requiredStartFacilities: Option[String], - requiredStopFacilities: Option[String], - startRunlevels: Option[String], - stopRunlevels: Option[String], - loader: ServerLoader): Seq[(String, String)] = { - - // Upstart cannot handle empty values - val (startOn, stopOn) = loader match { - case Upstart => (requiredStartFacilities.map("start on started " + _), requiredStopFacilities.map("stop on stopping " + _)) - case _ => (requiredStartFacilities, requiredStopFacilities) - } - Seq( - "start_runlevels" -> startRunlevels.getOrElse(""), - "stop_runlevels" -> stopRunlevels.getOrElse(""), - "start_facilities" -> startOn.getOrElse(""), - "stop_facilities" -> stopOn.getOrElse("") - ) - } - - private[this] def defaultFacilities(loader: ServerLoader): Option[String] = { - Option(loader match { - case SystemV => "$remote_fs $syslog" - case Upstart => null - case Systemd => "network.target" - }) - } - - private[this] def defaultStartRunlevels(loader: ServerLoader): Option[String] = { - Option(loader match { - case SystemV => "2 3 4 5" - case Upstart => "[2345]" - case Systemd => null - }) - } - - private[this] def defaultStopRunlevels(loader: ServerLoader): Option[String] = { - Option(loader match { - case SystemV => "0 1 6" - case Upstart => "[016]" - case Systemd => null - }) - } - - private[this] def getStartScriptLocation(loader: ServerLoader): String = { - loader match { - case Upstart => "/etc/init/" - case SystemV => "/etc/init.d/" - case Systemd => "/usr/lib/systemd/system/" - } - } /* Find the template source for the given Server loading scheme, with cascading fallback * If the serverLoader scheme is SystemD, then searches for files in this order: @@ -261,16 +147,13 @@ object JavaServerAppPackaging extends AutoPlugin { * - src/templates/etc-default * - Provided template */ - - private[this] def getEtcTemplateSource(sourceDirectory: File, loader: ServerLoader): java.net.URL = { - val (suffix, default) = loader match { - case Upstart => - ("-upstart", getClass.getResource(ETC_DEFAULT + "-template")) - case SystemV => - ("-systemv", getClass.getResource(ETC_DEFAULT + "-template")) - case Systemd => - ("-systemd", getClass.getResource(ETC_DEFAULT + "-systemd-template")) - } + private[this] def getEtcTemplateSource(sourceDirectory: File, loader: Option[ServerLoader]): java.net.URL = { + val defaultTemplate = getClass.getResource(ETC_DEFAULT + "-template") + val (suffix, default) = loader.map { + case Upstart => ("-upstart", defaultTemplate) + case SystemV => ("-systemv", defaultTemplate) + case Systemd => ("-systemd", getClass.getResource(ETC_DEFAULT + "-systemd-template")) + }.getOrElse(("", defaultTemplate)) val overrides = List[File]( sourceDirectory / "templates" / (ETC_DEFAULT + suffix), @@ -291,35 +174,16 @@ object JavaServerAppPackaging extends AutoPlugin { mapping.toSeq } - protected def startScriptMapping(name: String, script: Option[File], loader: ServerLoader, scriptDir: String, scriptName: Option[String]): Seq[LinuxPackageMapping] = { - val (path, permissions, isConf) = loader match { - case Upstart => ("/etc/init/" + scriptName.getOrElse(name + ".conf"), "0644", "true") - case SystemV => ("/etc/init.d/" + scriptName.getOrElse(name), "0755", "false") - case Systemd => ("/usr/lib/systemd/system/" + scriptName.getOrElse(name + ".service"), "0644", "true") - } - for { - s <- script.toSeq - } yield LinuxPackageMapping(Seq(s -> path), LinuxFileMetaData(Users.Root, Users.Root, permissions, isConf)) - } - - protected def makeStartScript(template: URL, replacements: Seq[(String, String)], tmpDir: File, loader: ServerLoader): Option[File] = { - val scriptBits = TemplateWriter generateScript (template, replacements) - val script = tmpDir / "tmp" / "bin" / s"$loader-init" - IO.write(script, scriptBits) - Some(script) - } - /** + * Loads an available script from the native-packager source if available. * * @param config for which plugin (Debian, Rpm) * @param replacements for the placeholders * @param scriptName that should be loaded * @return script lines */ - private[this] def getScriptContent(config: Configuration, replacements: Seq[(String, String)])(scriptName: String): String = { - JavaServerBashScript(scriptName, ARCHETYPE, config, replacements) getOrElse { - sys.error(s"Couldn't load [$scriptName] for config [${config.name}] in archetype [$ARCHETYPE]") - } + private[this] def getScriptContent(config: Configuration, replacements: Seq[(String, String)])(scriptName: String): Seq[String] = { + JavaServerBashScript(scriptName, ARCHETYPE, config, replacements).toSeq } /** diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala index e305fea8a..f5bbe1bd6 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerBashScript.scala @@ -1,7 +1,7 @@ package com.typesafe.sbt.packager.archetypes import sbt._ -import com.typesafe.sbt.packager.archetypes.ServerLoader._ +import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader._ /** * Loads scripts from the resource path that are associated with @@ -65,7 +65,7 @@ object JavaServerLoaderScript { } /** - * Loads the [[ServerLoader]] specific "functions" resource, + * Loads the [[com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader]] specific "functions" resource, * replaces all placeholders and returns the resolved string. * * The functions script resides in "[archetype]/[loader]/functions" diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala index 5bce9bfe9..49d360881 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/MaintainerScriptHelper.scala @@ -41,19 +41,37 @@ trait MaintainerScriptHelper { * import RpmConstants._ * maintainerScripts in Rpm := maintainerScriptsAppend((maintainerScripts in Rpm).value)( * Pretrans -> "echo 'hello, world'", - * Post -> s"echo 'installing ${(packageName in Rpm).value}'" + * Post -> "echo 'installing " + (packageName in Rpm).value + "'" + * ) + * }}} + * + * @example Adding content from a string and use script replacements + * {{{ + * import DebianConstants._ + * maintainerScripts in Rpm := maintainerScriptsAppend( + * (maintainerScripts in Debian).value, + * (linuxScriptReplacements in Debian).value + * )( + * Preinst -> "echo 'hello, world'", + * Postinst -> s"echo 'installing ${(packageName in Debian).value}'" * ) * }}} * * * @param current maintainer scripts + * @param replacements (e.g. (linuxScriptReplacements in Debian).value) * @param scripts scriptName -> scriptContent pairs * @return maintainerScripts with appended `scripts` * @see [[maintainerScriptsAppendFromFile]] */ - def maintainerScriptsAppend(current: Map[String, Seq[String]] = Map.empty)(scripts: (String, String)*): Map[String, Seq[String]] = { + def maintainerScriptsAppend( + current: Map[String, Seq[String]] = Map.empty, + replacements: Seq[(String, String)] = Nil)(scripts: (String, String)*): Map[String, Seq[String]] = { val appended = scripts.map { - case (key, script) => key -> (current.getOrElse(key, Seq.empty) :+ script) + case (key, script) => key -> TemplateWriter.generateScriptFromLines( + (current.getOrElse(key, Seq.empty) :+ script), + replacements + ) }.toMap current ++ appended } @@ -85,4 +103,6 @@ trait MaintainerScriptHelper { current ++ appended } -} \ No newline at end of file +} + +object MaintainerScriptHelper extends MaintainerScriptHelper \ No newline at end of file diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala index 53047f138..8a06263ad 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/TemplateWriter.scala @@ -21,6 +21,8 @@ package com.typesafe.sbt.packager.archetypes * val replacements = Seq("name" -> "your-app", "custom" -> "1") * TemplateWriter.generateScript(template, replacements, "\r\n", TemplateWriter.batFriendlyKeySurround) * }}} + * + * TODO move out of archetypes package */ object TemplateWriter { def defaultCharset: java.nio.charset.Charset = java.nio.charset.Charset.forName("UTF-8") diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/ServerLoader.scala similarity index 77% rename from src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala rename to src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/ServerLoader.scala index d6728a47b..37baccd67 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/ServerLoader.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/ServerLoader.scala @@ -1,7 +1,4 @@ -package com.typesafe.sbt.packager.archetypes - -import java.io.File -import java.net.URL +package com.typesafe.sbt.packager.archetypes.systemloader /** * Stores the available types of server loaders. diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala new file mode 100644 index 000000000..27251b3e0 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala @@ -0,0 +1,66 @@ +package com.typesafe.sbt.packager.archetypes.systemloader + +import sbt._ +import sbt.Keys.{ target, sourceDirectory } +import com.typesafe.sbt.SbtNativePackager.{ Debian, Rpm } +import com.typesafe.sbt.packager.Keys.{ + serverLoading, + linuxStartScriptTemplate, + linuxMakeStartScript, + linuxPackageMappings, + linuxStartScriptName, + defaultLinuxStartScriptLocation, + requiredStartFacilities, + requiredStopFacilities, + startRunlevels, + stopRunlevels +} +import com.typesafe.sbt.packager.debian.DebianPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin + +object SystemVPlugin extends AutoPlugin { + + override def requires = SystemloaderPlugin + + override def projectSettings: Seq[Setting[_]] = + inConfig(Debian)(systemVSettings) ++ debianSettings ++ + inConfig(Rpm)(systemVSettings) ++ rpmSettings + + def systemVSettings: Seq[Setting[_]] = Seq( + // used by other archetypes to define systemloader dependent behaviour + serverLoading := Some(ServerLoader.SystemV), + // Systemd settings + startRunlevels := Some("2 3 4 5"), + stopRunlevels := Some("0 1 6"), + requiredStartFacilities := Some("$remote_fs $syslog"), + requiredStopFacilities := Some("$remote_fs $syslog"), + defaultLinuxStartScriptLocation := "/etc/init.d", + // add systemloader to mappings and override the isConf setting + linuxPackageMappings ++= startScriptMapping( + linuxStartScriptName.value, + linuxMakeStartScript.value, + defaultLinuxStartScriptLocation.value, + isConf = false + ) + ) + + + def debianSettings: Seq[Setting[_]] = inConfig(Debian)(Seq( + // set the template + linuxStartScriptTemplate := linuxStartScriptUrl( + (sourceDirectory in Compile).value, + serverLoading.value, + "start-debian-template" + ) + )) + + def rpmSettings: Seq[Setting[_]] = inConfig(Rpm)(Seq( + // set the template + linuxStartScriptTemplate := linuxStartScriptUrl( + (sourceDirectory in Compile).value, + serverLoading.value, + "start-rpm-template" + ) + )) + +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemdPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemdPlugin.scala new file mode 100644 index 000000000..2fd11ab15 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemdPlugin.scala @@ -0,0 +1,56 @@ +package com.typesafe.sbt.packager.archetypes.systemloader + +import sbt._ +import sbt.Keys.{ target, sourceDirectory } +import com.typesafe.sbt.packager.Keys.{ + maintainerScripts, + packageName, + linuxStartScriptName, + linuxStartScriptTemplate, + linuxMakeStartScript, + linuxScriptReplacements, + linuxPackageMappings, + defaultLinuxStartScriptLocation, + serverLoading, + startRunlevels, + stopRunlevels, + requiredStartFacilities, + requiredStopFacilities +} +import com.typesafe.sbt.SbtNativePackager.{ Debian, Rpm, Universal, Linux } +import com.typesafe.sbt.packager.archetypes.MaintainerScriptHelper.maintainerScriptsAppend +import com.typesafe.sbt.packager.debian.DebianPlugin +import com.typesafe.sbt.packager.debian.DebianPlugin.autoImport.DebianConstants +import com.typesafe.sbt.packager.rpm.RpmPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin.autoImport.RpmConstants + +import java.nio.file.{ Paths, Files } + +object SystemdPlugin extends AutoPlugin { + + override def requires = SystemloaderPlugin + + override def projectSettings: Seq[Setting[_]] = + inConfig(Debian)(systemdSettings) ++ inConfig(Rpm)(systemdSettings) + + def systemdSettings: Seq[Setting[_]] = Seq( + // used by other archetypes to define systemloader dependent behaviour + serverLoading := Some(ServerLoader.Systemd), + // Systemd settings + startRunlevels := None, + stopRunlevels := None, + requiredStartFacilities := Some("network.target"), + requiredStopFacilities := Some("network.target"), + defaultLinuxStartScriptLocation := "/usr/lib/systemd/system", + linuxStartScriptName := Some(packageName.value + ".service"), + // add systemloader to mappings + linuxPackageMappings ++= startScriptMapping( + linuxStartScriptName.value, + linuxMakeStartScript.value, + defaultLinuxStartScriptLocation.value, + isConf = true + ) + ) + + +} diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala new file mode 100644 index 000000000..c2286c741 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala @@ -0,0 +1,11 @@ +package com.typesafe.sbt.packager.archetypes.systemloader + +import sbt._ + +trait SystemloaderKeys { + val serverLoading = SettingKey[Option[ServerLoader.ServerLoader]]("server-loader", "Loading system to be used for application start script") + val startRunlevels = SettingKey[Option[String]]("start-runlevels", "Sequence of runlevels on which application will start up") + val stopRunlevels = SettingKey[Option[String]]("stop-runlevels", "Sequence of runlevels on which application will stop") + val requiredStartFacilities = SettingKey[Option[String]]("required-start-facilities", "Names of system services that should be provided at application start") + val requiredStopFacilities = SettingKey[Option[String]]("required-stop-facilities", "Names of system services that should be provided at") +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala new file mode 100644 index 000000000..bea4cd6d6 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala @@ -0,0 +1,135 @@ +package com.typesafe.sbt.packager.archetypes.systemloader + +import sbt._ +import sbt.Keys.{ sourceDirectory, target } +import com.typesafe.sbt.SbtNativePackager.{ Debian, Rpm } +import com.typesafe.sbt.packager.Keys.{ + packageName, + maintainerScripts, + defaultLinuxStartScriptLocation, + linuxMakeStartScript, + linuxStartScriptTemplate, + linuxScriptReplacements, + linuxStartScriptName, + linuxPackageMappings, + serverLoading, + requiredStartFacilities, + requiredStopFacilities, + startRunlevels, + stopRunlevels +} +import com.typesafe.sbt.SbtNativePackager.Universal +import com.typesafe.sbt.packager.archetypes.MaintainerScriptHelper.maintainerScriptsAppend +import com.typesafe.sbt.packager.debian.DebianPlugin +import com.typesafe.sbt.packager.debian.DebianPlugin.autoImport.DebianConstants +import com.typesafe.sbt.packager.rpm.RpmPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin.autoImport.RpmConstants +import ServerLoader.{ ServerLoader, Upstart } + +/** + * General settings for all systemloader plugins. + */ +object SystemloaderPlugin extends AutoPlugin { + + override def requires = DebianPlugin && RpmPlugin + + object autoImport extends SystemloaderKeys { + val ServerLoader = com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader + } + + override def projectSettings: Seq[Setting[_]] = + inConfig(Debian)(systemloaderSettings) ++ debianSettings ++ + inConfig(Rpm)(systemloaderSettings) ++ rpmSettings + + def systemloaderSettings: Seq[Setting[_]] = Seq( + serverLoading := None, + linuxStartScriptName := Some(packageName.value), + // add loader-functions to script replacements + linuxScriptReplacements += loaderFunctionsReplacement(sourceDirectory.value, serverLoading.value), + linuxScriptReplacements ++= makeStartScriptReplacements( + requiredStartFacilities.value, + requiredStopFacilities.value, + startRunlevels.value, + stopRunlevels.value, + serverLoading.value + ), + // set the template + linuxStartScriptTemplate := linuxStartScriptUrl(sourceDirectory.value, serverLoading.value), + // define task to generate the systemloader script + linuxMakeStartScript := makeStartScript( + linuxStartScriptTemplate.value, + linuxScriptReplacements.value, + (target in Universal).value, + defaultLinuxStartScriptLocation.value, + linuxStartScriptName.value.getOrElse(sys.error("`linuxStartScriptName` is not defined")) + ) + ) + + def debianSettings: Seq[Setting[_]] = inConfig(Debian)(Seq( + // add automatic service start/stop + maintainerScripts := maintainerScriptsAppend( + maintainerScripts.value, + linuxScriptReplacements.value + )( + DebianConstants.Postinst -> s"""|# ${serverLoading.value} support + |$${{loader-functions}} + |startService $${{app_name}} || echo "$${{app_name}} could not be registered or started" + |""".stripMargin, + DebianConstants.Prerm -> s"""|# ${serverLoading.value} support + |$${{loader-functions}} + |stopService $${{app_name}} || echo "$${{app_name}} wasn't even running!" + |""".stripMargin + )) + ) + + def rpmSettings: Seq[Setting[_]] = inConfig(Rpm)(Seq( + // add automatic service start/stop + maintainerScripts in Rpm := maintainerScriptsAppend( + maintainerScripts.value, + linuxScriptReplacements.value + )( + RpmConstants.Post -> s"""|# ${serverLoading.value} support + |$${{loader-functions}} + |# Scriptlet syntax: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Syntax + |# $$1 == 1 is first installation and $$1 == 2 is upgrade + |if [ $$1 -eq 1 ] ; + |then + | startService $${{app_name}} || echo "Could not start $${{app_name}}" + |fi + |""".stripMargin, + RpmConstants.Postun -> s"""|# ${serverLoading.value} support + |if [ $$1 -ge 1 ] + | restartService $${{app_name}} || echo "Failed to try-restart $${{app_name}}" + |fi + |""".stripMargin, + RpmConstants.Preun -> s"""|# ${serverLoading.value} support + |$${{loader-functions}} + |if [ $$1 -eq 0 ] ; + |then + | stopService $${{app_name}} || echo "Could not stop $${{app_name}}" + |fi + |""".stripMargin + )) + ) + + private[this] def makeStartScriptReplacements( + requiredStartFacilities: Option[String], + requiredStopFacilities: Option[String], + startRunlevels: Option[String], + stopRunlevels: Option[String], + loader: Option[ServerLoader]): Seq[(String, String)] = { + + // Upstart cannot handle empty values + val (startOn, stopOn) = loader match { + case Some(Upstart) => (requiredStartFacilities.map("start on started " + _), requiredStopFacilities.map("stop on stopping " + _)) + case _ => (requiredStartFacilities, requiredStopFacilities) + } + Seq( + "start_runlevels" -> startRunlevels.getOrElse(""), + "stop_runlevels" -> stopRunlevels.getOrElse(""), + "start_facilities" -> startOn.getOrElse(""), + "stop_facilities" -> stopOn.getOrElse("") + ) + } + +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala new file mode 100644 index 000000000..9a181a3e0 --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala @@ -0,0 +1,51 @@ +package com.typesafe.sbt.packager.archetypes.systemloader + +import sbt._ +import sbt.Keys.{ target, sourceDirectory } +import com.typesafe.sbt.packager.Keys.{ + packageName, + serverLoading, + linuxStartScriptName, + linuxStartScriptTemplate, + linuxMakeStartScript, + linuxPackageMappings, + defaultLinuxStartScriptLocation, + requiredStartFacilities, + requiredStopFacilities, + startRunlevels, + stopRunlevels +} +import com.typesafe.sbt.packager.debian.DebianPlugin +import com.typesafe.sbt.packager.debian.DebianPlugin.autoImport.Debian +import com.typesafe.sbt.packager.rpm.RpmPlugin +import com.typesafe.sbt.packager.rpm.RpmPlugin.autoImport.Rpm + +import java.nio.file.{ Paths, Files } + +object UpstartPlugin extends AutoPlugin { + + override def requires = SystemloaderPlugin + + override def projectSettings: Seq[Setting[_]] = + inConfig(Debian)(upstartSettings) ++ inConfig(Rpm)(upstartSettings) + + def upstartSettings: Seq[Setting[_]] = Seq( + // used by other archetypes to define systemloader dependent behaviour + serverLoading := Some(ServerLoader.Upstart), + // Systemd settings + startRunlevels := Some("[2345]"), + stopRunlevels := Some("[016]"), + requiredStartFacilities := None, + requiredStopFacilities := None, + defaultLinuxStartScriptLocation := "/etc/init", + linuxStartScriptName := Some(packageName.value + ".conf"), + // add systemloader to mappings + linuxPackageMappings ++= startScriptMapping( + linuxStartScriptName.value, + linuxMakeStartScript.value, + defaultLinuxStartScriptLocation.value, + isConf = true + ) + ) + +} diff --git a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/package.scala b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/package.scala new file mode 100644 index 000000000..ab0c157ae --- /dev/null +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/package.scala @@ -0,0 +1,67 @@ +package com.typesafe.sbt.packager.archetypes + +import sbt._ +import java.io.File +import java.net.URL + +import com.typesafe.sbt.packager.linux._ +import com.typesafe.sbt.packager.linux.LinuxPlugin.Users + +import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader._ + +package object systemloader { + + private val LOADER_FUNCTIONS = "loader-functions" + + def linuxStartScriptUrl(sourceDirectory: File, loaderOpt: Option[ServerLoader], name: String = "start-template"): URL = { + val loader = loaderOpt.getOrElse( + sys.error("No serverLoader defined. Enable a systemloader, e.g. with `enablePlugins(UpstartPlugin)`") + ) + overrideFromFile(sourceDirectory, loader, name) + .getOrElse(getClass getResource in(loader, name)) + } + + def loaderFunctionsReplacement(sourceDirectory: File, loaderOpt: Option[ServerLoader]): (String, String) = { + val replacement = for { + loader <- loaderOpt + source <- overrideFromFile(sourceDirectory, loader, LOADER_FUNCTIONS) + .orElse(Option(getClass getResource in(loader, LOADER_FUNCTIONS))) + } yield LOADER_FUNCTIONS -> TemplateWriter.generateScript(source, Nil) + + replacement.getOrElse(sys.error(s"Loader functions could not be loaded for ${loaderOpt}")) + } + + def makeStartScript(template: URL, replacements: Seq[(String, String)], target: File, path: String, name: String): Option[File] = { + val scriptBits = TemplateWriter generateScript (template, replacements) + val script = target / "tmp" / path / name + IO.write(script, scriptBits) + Some(script) + } + + /** + * Create the linuxPackageMapping for the systemloader start-script/conffile + * @param scriptName - optional name from `linuxStartScriptName.value` + * @param script - file with contents from ` linuxMakeStartScript.value` + * @param location - target destination from `defaultLinuxStartScriptLocation.value` + * @param isConf - if the start script should be registered as a config file + */ + def startScriptMapping( + scriptName: Option[String], script: Option[File], location: String, isConf: Boolean): Seq[LinuxPackageMapping] = { + val name = scriptName.getOrElse( + sys.error("""No linuxStartScriptName defined. Add `linuxStartScriptName in := Some("name.service")""") + ) + val path = location + "/" + name + val perms = if (isConf) "0644" else "0755" + for { + s <- script.toSeq + } yield LinuxPackageMapping(Seq(s -> path), LinuxFileMetaData(Users.Root, Users.Root, perms, isConf.toString)) + } + + private def in(loader: ServerLoader, name: String): String = loader.toString + "/" + name + + private def overrideFromFile(sourceDirectory: File, loader: ServerLoader, name: String): Option[URL] = { + Option(sourceDirectory / "templates" / "systemloader" / loader.toString) + .filter(_.exists) + .map(_.toURI.toURL) + } +} \ No newline at end of file diff --git a/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala index 5d5d724f7..b5eaca4e7 100644 --- a/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/debian/DebianPlugin.scala @@ -11,7 +11,6 @@ import linux.LinuxPlugin.autoImport.{ linuxScriptReplacements, linuxPackageMappings, linuxPackageSymlinks, - serverLoading, daemonShell } import linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink } @@ -110,39 +109,39 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { debianChangelog := None, /* === new debian scripts implementation */ - maintainerScripts in Debian := { + maintainerScripts in Debian := { val replacements = (linuxScriptReplacements in Debian).value val scripts = Map( - Names.Prerm -> defaultMaintainerScript(Names.Prerm).toSeq.flatten, - Names.Preinst -> defaultMaintainerScript(Names.Preinst).toSeq.flatten, - Names.Postinst -> defaultMaintainerScript(Names.Postinst).toSeq.flatten, - Names.Postrm -> defaultMaintainerScript(Names.Postrm).toSeq.flatten + Names.Prerm -> defaultMaintainerScript(Names.Prerm).toSeq.flatten, + Names.Preinst -> defaultMaintainerScript(Names.Preinst).toSeq.flatten, + Names.Postinst -> defaultMaintainerScript(Names.Postinst).toSeq.flatten, + Names.Postrm -> defaultMaintainerScript(Names.Postrm).toSeq.flatten ) // this is for legacy purposes to keep old behaviour // --- legacy starts def readContent(scriptFiles: Seq[(File, String)]): Map[String, Seq[String]] = scriptFiles.map { - case (scriptFile, scriptName) => scriptName -> IO.readLines(scriptFile) + case (scriptFile, scriptName) => scriptName -> IO.readLines(scriptFile) }.toMap val userProvided = readContent(Seq( - debianMakePreinstScript.value.map(script => script -> Names.Preinst), - debianMakePostinstScript.value.map(script => script -> Names.Postinst), - debianMakePrermScript.value.map(script => script -> Names.Prerm), - debianMakePostrmScript.value.map(script => script -> Names.Postrm) + debianMakePreinstScript.value.map(script => script -> Names.Preinst), + debianMakePostinstScript.value.map(script => script -> Names.Postinst), + debianMakePrermScript.value.map(script => script -> Names.Prerm), + debianMakePostrmScript.value.map(script => script -> Names.Postrm) ).flatten) // these things get appended. Don't check for nonexisting keys as they are already in the default scripts map val appendedScripts = scripts.map { - case (scriptName, content) => scriptName -> (content ++ userProvided.getOrElse(scriptName, Nil)) + case (scriptName, content) => scriptName -> (content ++ userProvided.getOrElse(scriptName, Nil)) } // override and merge with the user defined scripts. Will change in the future val controlScriptsDir = debianControlScriptsDirectory.value val overridenScripts = scripts ++ readContent(Seq( - scriptMapping(Names.Prerm, debianMakePrermScript.value, controlScriptsDir), - scriptMapping(Names.Preinst, debianMakePreinstScript.value, controlScriptsDir), - scriptMapping(Names.Postinst, debianMakePostinstScript.value, controlScriptsDir), - scriptMapping(Names.Postrm, debianMakePostrmScript.value, controlScriptsDir) + scriptMapping(Names.Prerm, debianMakePrermScript.value, controlScriptsDir), + scriptMapping(Names.Preinst, debianMakePreinstScript.value, controlScriptsDir), + scriptMapping(Names.Postinst, debianMakePostinstScript.value, controlScriptsDir), + scriptMapping(Names.Postrm, debianMakePostrmScript.value, controlScriptsDir) ).flatten) // --- legacy ends @@ -151,7 +150,7 @@ object DebianPlugin extends AutoPlugin with DebianNativePackaging { // apply all replacements content.mapValues { lines => - TemplateWriter.generateScriptFromLines(lines, replacements) + TemplateWriter.generateScriptFromLines(lines, replacements) } }, debianMaintainerScripts := generateDebianMaintainerScripts( 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 1cc87af40..ebae8c9ab 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala @@ -3,7 +3,7 @@ package packager package linux import sbt._ -import com.typesafe.sbt.packager.archetypes.ServerLoader.ServerLoader +import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader /** Linux packaging generic build targets. */ trait LinuxKeys { @@ -13,18 +13,14 @@ trait LinuxKeys { val daemonGroup = SettingKey[String]("daemon-group", "Group to start application daemon") val daemonGroupGid = SettingKey[Option[String]]("daemon-group-gid", "GID of daemonGroup") val daemonShell = SettingKey[String]("daemon-shell", "Shell provided for the daemon user") - val serverLoading = SettingKey[ServerLoader]("server-loader", "Loading system to be used for application start script") - val startRunlevels = SettingKey[Option[String]]("start-runlevels", "Sequence of runlevels on which application will start up") - val stopRunlevels = SettingKey[Option[String]]("stop-runlevels", "Sequence of runlevels on which application will stop") - val requiredStartFacilities = SettingKey[Option[String]]("required-start-facilities", "Names of system services that should be provided at application start") - val requiredStopFacilities = SettingKey[Option[String]]("required-stop-facilities", "Names of system services that should be provided at application stop") + val linuxPackageMappings = TaskKey[Seq[LinuxPackageMapping]]("linux-package-mappings", "File to install location mappings including owner and privileges.") val linuxPackageSymlinks = TaskKey[Seq[LinuxSymlink]]("linux-package-symlinks", "Symlinks we should produce in the underlying package.") val generateManPages = TaskKey[Unit]("generate-man-pages", "Shows all the man files in the current project") val termTimeout = SettingKey[Int]("term-timeout", "Timeout before sigterm on stop") val killTimeout = SettingKey[Int]("kill-timeout", "Timeout before sigkill on stop (after term)") - val linuxMakeStartScript = TaskKey[Option[File]]("makeStartScript", "Creates or discovers the start script used by this project") + val linuxMakeStartScript = TaskKey[Option[File]]("linuxMakeStartScript", "Creates or discovers the start script used by this project") val linuxStartScriptTemplate = TaskKey[URL]("linuxStartScriptTemplate", "The location of the template start script file we use for debian (upstart or init.d") val linuxStartScriptName = SettingKey[Option[String]]("linuxStartScriptName", "The name of the start script for debian (primary useful for systemd)") val linuxEtcDefaultTemplate = TaskKey[URL]("linuxEtcDefaultTemplate", "The location of the /etc/default/ template script.") 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 d6c3743e8..6a539c284 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala @@ -6,7 +6,8 @@ import sbt._ import sbt.Keys.{ name, normalizedName, mappings, sourceDirectory } import linux.LinuxPlugin.Users import packager.Keys._ -import packager.archetypes.{ ServerLoader, TemplateWriter } +import packager.archetypes.{ TemplateWriter } +import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader import SbtNativePackager.Universal /** diff --git a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala index eff210cfd..6b0c438e5 100644 --- a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala +++ b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmMetadata.scala @@ -5,6 +5,7 @@ package rpm import sbt._ import com.typesafe.sbt.packager.linux.{ LinuxPlugin, LinuxPackageMapping, LinuxFileMetaData, LinuxSymlink } import com.typesafe.sbt.packager.rpm.RpmPlugin.Names._ +import com.typesafe.sbt.packager.archetypes.TemplateWriter import java.io.File case class RpmMetadata( @@ -108,15 +109,24 @@ case class RpmScripts( object RpmScripts { - def fromMaintainerScripts(maintainerScripts: Map[String, Seq[String]] = Map()): RpmScripts = RpmScripts( - pretrans = maintainerScripts.get(Pretrans).map(_.mkString("\n")), - pre = maintainerScripts.get(Pre).map(_.mkString("\n")), - post = maintainerScripts.get(Post).map(_.mkString("\n")), - verifyscript = maintainerScripts.get(Verifyscript).map(_.mkString("\n")), - posttrans = maintainerScripts.get(Posttrans).map(_.mkString("\n")), - preun = maintainerScripts.get(Preun).map(_.mkString("\n")), - postun = maintainerScripts.get(Postun).map(_.mkString("\n")) - ) + def fromMaintainerScripts( + maintainerScripts: Map[String, Seq[String]], + replacements: Seq[(String, String)]): RpmScripts = { + val toContent = toContentWith(replacements) _ + RpmScripts( + pretrans = maintainerScripts.get(Pretrans).map(toContent), + pre = maintainerScripts.get(Pre).map(toContent), + post = maintainerScripts.get(Post).map(toContent), + verifyscript = maintainerScripts.get(Verifyscript).map(toContent), + posttrans = maintainerScripts.get(Posttrans).map(toContent), + preun = maintainerScripts.get(Preun).map(toContent), + postun = maintainerScripts.get(Postun).map(toContent) + ) + } + + // insert replacements + private def toContentWith(replacements: Seq[(String, String)])(lines: Seq[String]): String = + TemplateWriter.generateScriptFromLines(lines, replacements).mkString("\n") } diff --git a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala index 7aabae10e..6adf7d02d 100644 --- a/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/rpm/RpmPlugin.scala @@ -1,15 +1,13 @@ -package com.typesafe.sbt -package packager -package rpm +package com.typesafe.sbt.packager.rpm import sbt._ -import linux._ +import sbt.Keys.{ name, version, sourceDirectory, target, packageBin, streams } import java.nio.charset.Charset -import SbtNativePackager.Linux -import sbt.Keys.{ name, version, sourceDirectory, target, packageBin, streams } -import linux.LinuxPlugin.autoImport.{ linuxPackageMappings, linuxPackageSymlinks, serverLoading, packageArchitecture } -import packager.Keys._ +import com.typesafe.sbt.SbtNativePackager.Linux +import com.typesafe.sbt.packager.SettingsHelper +import com.typesafe.sbt.packager.Keys._ +import com.typesafe.sbt.packager.linux._ /** * Plugin containing all generic values used for packaging rpms. @@ -108,16 +106,16 @@ object RpmPlugin extends AutoPlugin { rpmDependencies <<= (rpmProvides, rpmRequirements, rpmPrerequisites, rpmObsoletes, rpmConflicts) apply RpmDependencies, maintainerScripts := { - val scripts = maintainerScripts.value - if (rpmBrpJavaRepackJars.value) { - val pre = scripts.getOrElse(Names.Pre, Nil) - val scriptBits = IO.readStream(RpmPlugin.osPostInstallMacro.openStream, Charset forName "UTF-8") - scripts + (Names.Pre -> (pre :+ scriptBits)) - } else { - scripts - } + val scripts = maintainerScripts.value + if (rpmBrpJavaRepackJars.value) { + val pre = scripts.getOrElse(Names.Pre, Nil) + val scriptBits = IO.readStream(RpmPlugin.osPostInstallMacro.openStream, Charset forName "UTF-8") + scripts + (Names.Pre -> (pre :+ scriptBits)) + } else { + scripts + } }, - rpmScripts := RpmScripts.fromMaintainerScripts(maintainerScripts.value), + rpmScripts := RpmScripts.fromMaintainerScripts(maintainerScripts.value, linuxScriptReplacements.value), rpmSpecConfig <<= (rpmMetadata, rpmDescription, rpmDependencies, rpmSetarch, rpmScripts, linuxPackageMappings, linuxPackageSymlinks, defaultLinuxInstallLocation) map RpmSpec, packageBin <<= (rpmSpecConfig, target, streams) map { (spec, dir, s) => diff --git a/src/sbt-test/debian/daemon-group-gid-deb/build.sbt b/src/sbt-test/debian/daemon-group-gid-deb/build.sbt index cea79f827..09a17809c 100644 --- a/src/sbt-test/debian/daemon-group-gid-deb/build.sbt +++ b/src/sbt-test/debian/daemon-group-gid-deb/build.sbt @@ -1,25 +1,16 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.Upstart +enablePlugins(JavaServerAppPackaging, UpstartPlugin) daemonUser in Linux := "daemonuser" - daemonGroup in Linux := "daemongroup" - daemonGroupGid in Linux := Some("25000") 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.""" diff --git a/src/sbt-test/debian/daemon-user-deb/build.sbt b/src/sbt-test/debian/daemon-user-deb/build.sbt index 57f6b3ddb..6408ffaec 100644 --- a/src/sbt-test/debian/daemon-user-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-deb/build.sbt @@ -1,23 +1,15 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - enablePlugins(JavaServerAppPackaging) -serverLoading in Debian := ServerLoader.Upstart - daemonUser in Linux := "daemonuser" - daemonGroup in Linux := "daemongroup" 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.""" diff --git a/src/sbt-test/debian/daemon-user-deb/test b/src/sbt-test/debian/daemon-user-deb/test index 967f7a260..b59d4d6be 100644 --- a/src/sbt-test/debian/daemon-user-deb/test +++ b/src/sbt-test/debian/daemon-user-deb/test @@ -2,8 +2,6 @@ > debian:package-bin $ exists target/debian-test_0.1.0_all.deb -$ exists target/debian-test-0.1.0/etc -$ exists target/debian-test-0.1.0/etc/init/debian-test.conf # Check defaults $ exists target/debian-test-0.1.0/DEBIAN/prerm $ exists target/debian-test-0.1.0/DEBIAN/postinst diff --git a/src/sbt-test/debian/daemon-user-shell-deb/build.sbt b/src/sbt-test/debian/daemon-user-shell-deb/build.sbt index 4678554ca..7a2727685 100644 --- a/src/sbt-test/debian/daemon-user-shell-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-shell-deb/build.sbt @@ -1,25 +1,16 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - enablePlugins(JavaServerAppPackaging) -serverLoading in Debian := ServerLoader.Upstart - daemonUser in Linux := "daemonuser" - daemonGroup in Linux := "daemongroup" - daemonShell in Linux := "/bin/bash" 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.""" diff --git a/src/sbt-test/debian/daemon-user-uid-deb/build.sbt b/src/sbt-test/debian/daemon-user-uid-deb/build.sbt index b3fa52df9..89c9fa503 100644 --- a/src/sbt-test/debian/daemon-user-uid-deb/build.sbt +++ b/src/sbt-test/debian/daemon-user-uid-deb/build.sbt @@ -1,25 +1,16 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - enablePlugins(JavaServerAppPackaging) -serverLoading in Debian := ServerLoader.Upstart - daemonUser in Linux := "daemonuser" - daemonUserUid in Linux := Some("20000") - daemonGroup in Linux := "daemongroup" 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.""" diff --git a/src/sbt-test/debian/daemon-user-uid-deb/test b/src/sbt-test/debian/daemon-user-uid-deb/test index 967f7a260..2aaab684c 100644 --- a/src/sbt-test/debian/daemon-user-uid-deb/test +++ b/src/sbt-test/debian/daemon-user-uid-deb/test @@ -3,7 +3,7 @@ $ exists target/debian-test_0.1.0_all.deb $ exists target/debian-test-0.1.0/etc -$ exists target/debian-test-0.1.0/etc/init/debian-test.conf + # Check defaults $ exists target/debian-test-0.1.0/DEBIAN/prerm $ exists target/debian-test-0.1.0/DEBIAN/postinst diff --git a/src/sbt-test/debian/java-app-archetype/build.sbt b/src/sbt-test/debian/java-app-archetype/build.sbt index e0e6e65f7..95957b0cc 100644 --- a/src/sbt-test/debian/java-app-archetype/build.sbt +++ b/src/sbt-test/debian/java-app-archetype/build.sbt @@ -1,4 +1,4 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaAppPackaging) name := "debian-test" diff --git a/src/sbt-test/debian/log-directory/build.sbt b/src/sbt-test/debian/log-directory/build.sbt index bd7191f31..8d26f0db4 100644 --- a/src/sbt-test/debian/log-directory/build.sbt +++ b/src/sbt-test/debian/log-directory/build.sbt @@ -1,9 +1,5 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - enablePlugins(JavaServerAppPackaging) -serverLoading in Debian := ServerLoader.Upstart - daemonUser in Debian := "root" mainClass in Compile := Some("empty") diff --git a/src/sbt-test/debian/log-directory/test b/src/sbt-test/debian/log-directory/test index d885bb403..8fc5d14f9 100644 --- a/src/sbt-test/debian/log-directory/test +++ b/src/sbt-test/debian/log-directory/test @@ -2,10 +2,6 @@ > debian:package-bin $ exists target/debian-test_0.1.0_all.deb -$ exists target/debian-test-0.1.0/etc -$ exists target/debian-test-0.1.0/etc/default/debian-test -$ exists target/debian-test-0.1.0/etc/init/debian-test.conf - # Check defaults $ exists target/debian-test-0.1.0/DEBIAN/prerm $ exists target/debian-test-0.1.0/DEBIAN/postinst diff --git a/src/sbt-test/debian/override-control-files/build.sbt b/src/sbt-test/debian/override-control-files/build.sbt index db535c08c..2eb9aabae 100644 --- a/src/sbt-test/debian/override-control-files/build.sbt +++ b/src/sbt-test/debian/override-control-files/build.sbt @@ -1,6 +1,4 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, UpstartPlugin) mainClass in Compile := Some("empty") diff --git a/src/sbt-test/debian/override-etc-default/build.sbt b/src/sbt-test/debian/override-etc-default/build.sbt index f1f98cc97..d18120e48 100644 --- a/src/sbt-test/debian/override-etc-default/build.sbt +++ b/src/sbt-test/debian/override-etc-default/build.sbt @@ -1,8 +1,4 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging, JDebPackaging) - -serverLoading in Debian := ServerLoader.Upstart +enablePlugins(JavaServerAppPackaging, JDebPackaging, UpstartPlugin) // TODO change this after #437 is fixed daemonUser in Linux := "root" diff --git a/src/sbt-test/debian/override-start-script/build.sbt b/src/sbt-test/debian/override-start-script/build.sbt index f416fe4c1..d7315a20e 100644 --- a/src/sbt-test/debian/override-start-script/build.sbt +++ b/src/sbt-test/debian/override-start-script/build.sbt @@ -1,26 +1,16 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging, JDebPackaging) - -serverLoading in Debian := ServerLoader.Upstart +enablePlugins(JavaServerAppPackaging, JDebPackaging, UpstartPlugin) // TODO change this after #437 is fixed daemonUser in Linux := "root" - daemonGroup in Linux := "app-group" mainClass in Compile := Some("empty") name := "debian-test" - -name in Debian := "debian-test" - version := "0.1.0" - maintainer := "Josh Suereth " packageSummary := "Test debian package" - packageDescription := """A fun package description of our software, with multiple lines.""" diff --git a/src/sbt-test/debian/override-start-script/src/templates/debian/systemv b/src/sbt-test/debian/override-start-script/src/templates/systemloader/systemv similarity index 100% rename from src/sbt-test/debian/override-start-script/src/templates/debian/systemv rename to src/sbt-test/debian/override-start-script/src/templates/systemloader/systemv diff --git a/src/sbt-test/debian/override-start-script/src/templates/debian/upstart b/src/sbt-test/debian/override-start-script/src/templates/systemloader/upstart similarity index 100% rename from src/sbt-test/debian/override-start-script/src/templates/debian/upstart rename to src/sbt-test/debian/override-start-script/src/templates/systemloader/upstart diff --git a/src/sbt-test/debian/systemd-deb/build.sbt b/src/sbt-test/debian/systemd-deb/build.sbt index 3fedacb24..00f4c2d76 100644 --- a/src/sbt-test/debian/systemd-deb/build.sbt +++ b/src/sbt-test/debian/systemd-deb/build.sbt @@ -1,17 +1,10 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.Systemd +enablePlugins(JavaServerAppPackaging, SystemdPlugin) name := "debian-test" - version := "0.1.0" - maintainer := "Alexey Kardapoltsev " packageSummary := "Test debian package" - packageDescription := """A fun package description of our software, with multiple lines.""" diff --git a/src/sbt-test/debian/systemd-deb/test b/src/sbt-test/debian/systemd-deb/test index 0dd84aabf..ab3996982 100644 --- a/src/sbt-test/debian/systemd-deb/test +++ b/src/sbt-test/debian/systemd-deb/test @@ -3,6 +3,9 @@ $ exists target/debian-test_0.1.0_all.deb $ exists target/debian-test-0.1.0/usr/lib/systemd/system/debian-test.service +> show debian:serverLoader +> show debian:linuxStartScriptTemplate +> plugins > check-startup-script > check-etc-default \ No newline at end of file diff --git a/src/sbt-test/debian/sysvinit-deb/build.sbt b/src/sbt-test/debian/sysvinit-deb/build.sbt index 4d24d045a..05dcea761 100644 --- a/src/sbt-test/debian/sysvinit-deb/build.sbt +++ b/src/sbt-test/debian/sysvinit-deb/build.sbt @@ -1,8 +1,4 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.SystemV +enablePlugins(JavaServerAppPackaging, SystemVPlugin) daemonUser in Debian := "root" diff --git a/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt b/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt index d9f5c1e80..e00bb8391 100644 --- a/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt +++ b/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt @@ -1,8 +1,4 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.SystemV +enablePlugins(JavaServerAppPackaging, SystemVPlugin) daemonUser in Debian := "root" diff --git a/src/sbt-test/debian/test-executableScriptName/build.sbt b/src/sbt-test/debian/test-executableScriptName/build.sbt index d2ac73a2d..e4c1441f3 100644 --- a/src/sbt-test/debian/test-executableScriptName/build.sbt +++ b/src/sbt-test/debian/test-executableScriptName/build.sbt @@ -1,4 +1,4 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, UpstartPlugin) name := "debian-test" diff --git a/src/sbt-test/debian/upstart-deb-facilities/build.sbt b/src/sbt-test/debian/upstart-deb-facilities/build.sbt index 8b7b14855..174475ca3 100644 --- a/src/sbt-test/debian/upstart-deb-facilities/build.sbt +++ b/src/sbt-test/debian/upstart-deb-facilities/build.sbt @@ -1,8 +1,4 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.Upstart +enablePlugins(JavaServerAppPackaging, UpstartPlugin) daemonUser in Debian := "root" diff --git a/src/sbt-test/debian/upstart-deb/build.sbt b/src/sbt-test/debian/upstart-deb/build.sbt index aae4b2a96..1bab90afa 100644 --- a/src/sbt-test/debian/upstart-deb/build.sbt +++ b/src/sbt-test/debian/upstart-deb/build.sbt @@ -1,26 +1,16 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader - -enablePlugins(JavaServerAppPackaging) - -serverLoading in Debian := ServerLoader.Upstart +enablePlugins(JavaServerAppPackaging, UpstartPlugin) // TODO change this after #437 is fixed daemonUser in Linux := "root" - daemonGroup in Linux := "app-group" mainClass in Compile := Some("empty") name := "debian-test" - -name in Debian := "debian-test" - version := "0.1.0" maintainer := "Josh Suereth " - packageSummary := "Test debian package" - packageDescription := """A fun package description of our software, with multiple lines.""" diff --git a/src/sbt-test/rpm/path-override-rpm/build.sbt b/src/sbt-test/rpm/path-override-rpm/build.sbt index fa82d5435..7142d9f86 100644 --- a/src/sbt-test/rpm/path-override-rpm/build.sbt +++ b/src/sbt-test/rpm/path-override-rpm/build.sbt @@ -1,9 +1,7 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, SystemVPlugin) name := "rpm-test" - version := "0.1.0" - maintainer := "Josh Suereth " packageSummary := "Test rpm package" @@ -14,17 +12,12 @@ packageDescription := """A fun package description of our software, with multiple lines.""" rpmRelease := "1" - rpmVendor := "typesafe" - rpmUrl := Some("http://github.com/sbt/sbt-native-packager") - rpmLicense := Some("BSD") - rpmGroup := Some("test-group") defaultLinuxInstallLocation := "/opt/test" - defaultLinuxLogsLocation := "/opt/test/log" TaskKey[Unit]("unzip") <<= (baseDirectory, packageBin in Rpm, streams) map { (baseDir, rpmFile, streams) => diff --git a/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt b/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt index aa68c95a1..7c65548af 100644 --- a/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt +++ b/src/sbt-test/rpm/scriptlets-override-rpm/build.sbt @@ -1,22 +1,15 @@ -// only works with java_server archetype -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, SystemVPlugin) name := "rpm-test" - version := "0.1.0" - maintainer := "Josh Suereth " packageSummary := "Test rpm package" - packageDescription := "Description" rpmRelease := "1" - rpmVendor := "typesafe" - rpmUrl := Some("http://github.com/sbt/sbt-native-packager") - rpmLicense := Some("BSD") mainClass in (Compile, run) := Some("com.example.MainApp") diff --git a/src/sbt-test/rpm/setarch-rpm/build.sbt b/src/sbt-test/rpm/setarch-rpm/build.sbt index 1448c3d6e..4db53c066 100644 --- a/src/sbt-test/rpm/setarch-rpm/build.sbt +++ b/src/sbt-test/rpm/setarch-rpm/build.sbt @@ -1,28 +1,20 @@ import com.typesafe.sbt.packager.linux.LinuxPackageMapping -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaAppPackaging) name := "rpm-test" - version := "0.1.0" - maintainer := "David Pennell " packageSummary := "Test rpm package" - packageName in Linux := "rpm-package" - packageDescription := """A fun package description of our software, with multiple lines.""" rpmRelease := "1" - rpmVendor := "typesafe" - rpmUrl := Some("http://github.com/sbt/sbt-native-packager") - rpmLicense := Some("BSD") - packageArchitecture in Rpm:= "i386" rpmSetarch := Some("i386") @@ -37,10 +29,6 @@ TaskKey[Unit]("check-spec-file") <<= (target, streams) map { (target, out) => out.log.success(spec) assert(spec contains "%attr(0644,root,root) /usr/share/rpm-package/lib/rpm-test.rpm-test-0.1.0.jar", "Wrong installation path\n" + spec) assert(spec contains "%attr(0755,root,root) /usr/share/rpm-package/libexec/hello-32bit", "Wrong 32-bit exe installation path\n" + spec) - assert(spec contains "%attr(0755,root,root) /etc/init.d/rpm-package", "Wrong /etc/init.d path\n" + spec) - assert(spec contains "%config %attr(644,root,root) /etc/default/rpm-package", "Wrong /etc default file\n" + spec) - assert(spec contains "%dir %attr(755,rpm-package,rpm-package) /var/log/rpm-package", "Wrong logging dir path\n" + spec) - assert(spec contains "%dir %attr(755,rpm-package,rpm-package) /var/run/rpm-package", "Wrong /var/run dir path\n" + spec) out.log.success("Successfully tested rpm-package file") () } diff --git a/src/sbt-test/rpm/systemd-rpm/build.sbt b/src/sbt-test/rpm/systemd-rpm/build.sbt index e25786502..175fa7720 100644 --- a/src/sbt-test/rpm/systemd-rpm/build.sbt +++ b/src/sbt-test/rpm/systemd-rpm/build.sbt @@ -1,26 +1,17 @@ -import com.typesafe.sbt.packager.archetypes.ServerLoader +enablePlugins(JavaServerAppPackaging, SystemdPlugin) -enablePlugins(JavaServerAppPackaging) - -serverLoading in Rpm := ServerLoader.Systemd name := "rpm-test" - version := "0.1.0" - maintainer := "Alexey Kardapoltsev " packageSummary := "Test rpm package" - packageDescription := """A fun package description of our software, with multiple lines.""" rpmRelease := "1" - rpmVendor := "typesafe" - rpmUrl := Some("http://github.com/sbt/sbt-native-packager") - rpmLicense := Some("BSD") requiredStartFacilities in Rpm := Some("serviceA.service") @@ -41,6 +32,7 @@ TaskKey[Unit]("checkStartupScript") <<= (target, streams) map { (target, out) => TaskKey[Unit]("checkSpecFile") <<= (target, streams) map { (target, out) => val spec = IO.read(target / "rpm" / "SPECS" / "rpm-test.spec") + println(spec) assert(spec contains """ |# diff --git a/src/sbt-test/rpm/sysvinit-rpm/build.sbt b/src/sbt-test/rpm/sysvinit-rpm/build.sbt index f3a58e100..e641daf5b 100644 --- a/src/sbt-test/rpm/sysvinit-rpm/build.sbt +++ b/src/sbt-test/rpm/sysvinit-rpm/build.sbt @@ -1,25 +1,17 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, SystemVPlugin) name := "rpm-test" - version := "0.1.0" - maintainer := "Josh Suereth " packageSummary := "Test rpm package" - packageDescription := "Description" rpmRelease := "1" - rpmVendor := "typesafe" - rpmUrl := Some("http://github.com/sbt/sbt-native-packager") - rpmLicense := Some("BSD") - rpmGroup := Some("test-group") - rpmDaemonLogFile := "test.log" mainClass in (Compile, run) := Some("com.example.MainApp") diff --git a/src/sbt-test/rpm/test-executableScriptName/build.sbt b/src/sbt-test/rpm/test-executableScriptName/build.sbt index c69bbd988..ed9e18c46 100644 --- a/src/sbt-test/rpm/test-executableScriptName/build.sbt +++ b/src/sbt-test/rpm/test-executableScriptName/build.sbt @@ -1,4 +1,4 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, SystemVPlugin) name := "rpm-test" diff --git a/src/sbt-test/rpm/test-packageName/build.sbt b/src/sbt-test/rpm/test-packageName/build.sbt index 4009a6d9a..4252d0cad 100644 --- a/src/sbt-test/rpm/test-packageName/build.sbt +++ b/src/sbt-test/rpm/test-packageName/build.sbt @@ -1,4 +1,4 @@ -enablePlugins(JavaServerAppPackaging) +enablePlugins(JavaServerAppPackaging, SystemVPlugin) name := "rpm-test" diff --git a/src/sphinx/archetypes/akka_app.rst b/src/sphinx/archetypes/akka_app.rst deleted file mode 100644 index 1ae3b5f7e..000000000 --- a/src/sphinx/archetypes/akka_app.rst +++ /dev/null @@ -1,47 +0,0 @@ -.. _akka-app-plugin: - -Akka Microkernel -################ - -.. danger:: - The **Akka Microkernel Archetype** is deprecated in favor of the more - general and better maintained :ref:`java-app-plugin`. - - -An Akka microkernel application is similar to a Java Command Line application. Instead of running the classic ``mainClass``, -an Akka microkernel application instantiates and runs a subclass of -`Bootable `_ . A minimal example -could look like this - -.. code-block:: scala - - class HelloKernel extends Bootable { - val system = ActorSystem("hellokernel") - - def startup = { - // HelloActor and Start case object must of course be defined - system.actorOf(Props[HelloActor]) ! Start - } - - def shutdown = { - system.terminate() - } - } - -The *bash/bat* script that starts up the Akka application is copied from the Akka distribution. - -To use this archetype in your build, add the following to your ``build.sbt``: - -.. code-block:: scala - - packageArchetype.akka_application - - name := "A-package-friendly-name" - - mainClass in Compile := Some("HelloKernel") - -For more information take a look at the akka docs - -* `Akka microkernel `_ -* `akka.kernel.Main source `_ -* `akka.kernel.Bootable docs `_ diff --git a/src/sphinx/archetypes/index.rst b/src/sphinx/archetypes/index.rst index 8c20fe667..9a016f122 100644 --- a/src/sphinx/archetypes/index.rst +++ b/src/sphinx/archetypes/index.rst @@ -15,6 +15,6 @@ of them for usage. Java Command Line Application Java Server Application - Akka App [DEPRECATED] + Systemloaders Configuration Archetypes An archetype cheatsheet diff --git a/src/sphinx/archetypes/java_server/customize.rst b/src/sphinx/archetypes/java_server/customize.rst index 495d2aec2..8f34a8340 100644 --- a/src/sphinx/archetypes/java_server/customize.rst +++ b/src/sphinx/archetypes/java_server/customize.rst @@ -67,103 +67,11 @@ Windows Configuration Support planned. -Service Manager Configuration -============================= +Systemloader Configuration +========================== -It is possible to change the default Service Manager for a given platform by specifying a ``ServerLoader``. To use -Upstart for an Rpm package simply: - -.. code-block:: scala - - import com.typesafe.sbt.packager.archetypes.ServerLoader - - serverLoading in Rpm := ServerLoader.Upstart - - -*As a side note Fedora/RHEL/Centos family of linux specifies* ``Default requiretty`` *in its* ``/etc/sudoers`` -*file. This prevents the default Upstart script from working correctly as it uses sudo to run the application -as the* ``daemonUser`` *. Simply disable requiretty to use Upstart or modify the Upstart template.* - -Customize Start Script ----------------------- - -Sbt Native Packager leverages templating to customize various start/stop scripts and pre/post install tasks. -As an example, to alter the ``loader-functions`` which manage the specific start and stop process commands -for SystemLoaders you can to the ``linuxScriptReplacements`` map: - -.. code-block:: scala - - import com.typesafe.sbt.packager.archetypes.TemplateWriter - - linuxScriptReplacements += { - val functions = sourceDirectory.value / "templates" / "custom-loader-functions" - // Nil == replacements. If you want to replace stuff in your script put them in this Seq[(String,String)] - "loader-functions" -> TemplateWriter.generateScript(functions.toURL, Nil) - } - -which will add the following resource file to use start/stop instead of initctl in the post install script: - -.. code-block:: bash - - startService() { - app_name=$1 - start $app_name - } - - stopService() { - app_name=$1 - stop $app_name - } - -The :doc:`debian ` and :doc:`redhat ` pages have further information on overriding -distribution specific actions. - -Override Start Script ------------------------------------------------ - -It's also possible to override the entire script/configuration for your service manager. -Create a file ``src/templates/$format/$loader`` and it will be used instead. - -Possible values: - -* ``$format`` - ``debian`` or ``rpm`` -* ``$loader`` - ``upstart``, ``systemv`` or ``systemd`` - -**Syntax** - -You can use ``${{variable_name}}`` to reference variables when writing your script. The default set of variables is: - -* ``descr`` - The description of the server. -* ``author`` - The configured author name. -* ``exec`` - The script/binary to execute when starting the server -* ``chdir`` - The working directory for the server. -* ``retries`` - The number of times to retry starting the server. -* ``retryTimeout`` - The amount of time to wait before trying to run the server. -* ``app_name`` - The name of the application (linux friendly) -* ``app_main_class`` - The main class / entry point of the application. -* ``app_classpath`` - The (ordered) classpath of the application. -* ``daemon_user`` - The user that the server should run as. - - -SystemD Support ---------------- - -There is also experimental SystemD support for Fedora release 20 (Heisenbug). You can use the ```Systemd``` server loader: - -.. code-block:: scala - - import com.typesafe.sbt.packager.archetypes.ServerLoader - - serverLoading in Rpm := ServerLoader.Systemd - -There is only partial systemd support in Ubuntu 14.04 LTS which prevents sbt-native-packager systemd from working correctly on -Ubuntu. Ubuntu 15.04 is the first version that switched to Systemd and the default Upstart won't work. Switch to Systemd with - -.. code-block:: scala - - import com.typesafe.sbt.packager.archetypes.ServerLoader - - serverLoading in Debian := ServerLoader.Systemd +See the :ref:`systemloaders` documentation on how to add a systemloader (e.g. SystemV, Systemd or Upstart) to your +package. Package Lifecycle Configuration =============================== diff --git a/src/sphinx/archetypes/java_server/index.rst b/src/sphinx/archetypes/java_server/index.rst index 47cfd86c6..725e83997 100644 --- a/src/sphinx/archetypes/java_server/index.rst +++ b/src/sphinx/archetypes/java_server/index.rst @@ -16,12 +16,11 @@ Features The *JavaServerAppPackaging* archetype depends on the :ref:`java-app-plugin` and adds the following features -* install/uninstall services +* daemon user/group support * default mappings for server applications * ``/var/log/`` is symlinked from ``/logs`` * ``/var/run/`` owned by ``daemonUser`` -* Creates a start script in for the configured system loader (SystemV, Upstart or SystemD) - +* ``etc-default`` support Usage ===== @@ -32,6 +31,8 @@ Usage Everything else works the same way as the :ref:`java-app-plugin`. +.. tip:: If you want your application to be registered as a service enable a :ref:`systemloaders` plugin. + Settings & Tasks ================ @@ -53,21 +54,6 @@ have sensible defaults. ``daemonShell`` Shell provided for the daemon user - ``serverLoading`` - Loading system to be used for application start script (SystemV, Upstart, Systemd) - - ``startRunlevels`` - Sequence of runlevels on which application will start up - - ``stopRunlevels`` - Sequence of runlevels on which application will stop - - ``requiredStartFacilities`` - Names of system services that should be provided at application start - - ``requiredStopFacilities`` - Names of system services that should be provided at application stop - ``daemonStdoutLogFile`` Filename stdout/stderr of application daemon. Now it's supported only in SystemV @@ -98,21 +84,6 @@ this `native packager discussion`_. If you want to change something in this predefined structure read more about it in the :doc:`linux section `. -Service Managers -================ - -Platforms are tied to both package managers (Rpm, Debian) and Service Managers (System V, Upstart, SystemD). By -default the native packager will configure a service manager to run the daemon process. The default configurations are: - -+---------------+--------------------+ -| Package Format| Service Manager | -+===============+====================+ -| Debian | Upstart (Default) | -+---------------+--------------------+ -| Rpm | SystemV (Default) | -+---------------+--------------------+ - -See the :ref:`server-app-customize` section on how to change these. .. _server-app-customize: diff --git a/src/sphinx/archetypes/systemloaders.rst b/src/sphinx/archetypes/systemloaders.rst new file mode 100644 index 000000000..597def891 --- /dev/null +++ b/src/sphinx/archetypes/systemloaders.rst @@ -0,0 +1,135 @@ +.. _systemloaders: + +Systemloaders +============= + +SBT native packager provides support for different systemloaders in order to register your application as a service on +your target system, start it automatically and provide systemloader specific configuration. + +.. tip:: You can use systemloaders with the :ref:`java-app-plugin` or the :ref:`java-server-plugin`! + +Overview +-------- + +There is a generic ``SystemloaderPlugin`` which configures default settings and requires necessary plugins. It gets +triggered automatically, when you enable a specific systemloader plugin. If you want to implement your own loader, +you should require the ``SystemloaderPlugin``. + +General Settings +~~~~~~~~~~~~~~~~ + + ``serverLoading`` + Loading system to be used for application start script (SystemV, Upstart, Systemd). + This setting can be used to trigger systemloader specific behaviour in your build. + + ``startRunlevels`` + Sequence of runlevels on which application will start up + + ``stopRunlevels`` + Sequence of runlevels on which application will stop + + ``requiredStartFacilities`` + Names of system services that should be provided at application start + + ``requiredStopFacilities`` + Names of system services that should be provided at application stop + + +SystemV +------- + +Native packager provides different SysV scripts for ``rpm`` (CentOS, RHEL, Fedora) and ``debian`` (Debian, Ubuntu) +package based systems. Enable SystemV with: + +.. code-block:: scala + + enablePlugins(SystemVPlugin) + +The :ref:`java-server-plugin` provides a ``daemonStdoutLogFile`` setting, that you can use to redirect the systemV +output into a file. + +Systemd +------- + +In order to enable Systemd add this plugin: + +.. code-block:: scala + + enablePlugins(SystemdPlugin) + +Upstart +------- + +SystemV alternative developed by `Ubuntu `_. Native packager adds support for rpm as well, +but we recommend using Systemd if possible. + +.. code-block:: scala + + enablePlugins(UpstartPlugin) + +*As a side note Fedora/RHEL/Centos family of linux specifies* ``Default requiretty`` *in its* ``/etc/sudoers`` +*file. This prevents the default Upstart script from working correctly as it uses sudo to run the application +as the* ``daemonUser`` *. Simply disable requiretty to use Upstart or modify the Upstart template.* + +Customization +------------- + +Customize Start Script +~~~~~~~~~~~~~~~~~~~~~~ + +Sbt Native Packager leverages templating to customize various start/stop scripts and pre/post install tasks. +As an example, to alter the ``loader-functions`` which manage the specific start and stop process commands +for SystemLoaders you can to the ``linuxScriptReplacements`` map: + +.. code-block:: scala + + import com.typesafe.sbt.packager.archetypes.TemplateWriter + + linuxScriptReplacements += { + val functions = sourceDirectory.value / "templates" / "custom-loader-functions" + // Nil == replacements. If you want to replace stuff in your script put them in this Seq[(String,String)] + "loader-functions" -> TemplateWriter.generateScript(functions.toURL, Nil) + } + +which will add the following resource file to use start/stop instead of initctl in the post install script: + +.. code-block:: bash + + startService() { + app_name=$1 + start $app_name + } + + stopService() { + app_name=$1 + stop $app_name + } + +The :doc:`debian ` and :doc:`redhat ` pages have further information on overriding +distribution specific actions. + +Override Start Script +~~~~~~~~~~~~~~~~~~~~~ + +It's also possible to override the entire script/configuration for your service manager. +Create a file ``src/templates/systemloader/$loader`` and it will be used instead. + +Possible values: + +* ``$loader`` - ``upstart``, ``systemv`` or ``systemd`` + +**Syntax** + +You can use ``${{variable_name}}`` to reference variables when writing your script. The default set of variables is: + +* ``descr`` - The description of the server. +* ``author`` - The configured author name. +* ``exec`` - The script/binary to execute when starting the server +* ``chdir`` - The working directory for the server. +* ``retries`` - The number of times to retry starting the server. +* ``retryTimeout`` - The amount of time to wait before trying to run the server. +* ``app_name`` - The name of the application (linux friendly) +* ``app_main_class`` - The main class / entry point of the application. +* ``app_classpath`` - The (ordered) classpath of the application. +* ``daemon_user`` - The user that the server should run as. +* ``daemon_log_file`` - Absolute path to daemon log file. diff --git a/test-project-simple/build.sbt b/test-project-simple/build.sbt index dad5343b7..21662de31 100644 --- a/test-project-simple/build.sbt +++ b/test-project-simple/build.sbt @@ -6,7 +6,7 @@ libraryDependencies ++= Seq( mainClass in Compile := Some("ExampleApp") -enablePlugins(JavaServerAppPackaging, JDebPackaging) +enablePlugins(JavaServerAppPackaging, JDebPackaging, SystemdPlugin) maintainer := "Josh Suereth " packageSummary := "Minimal Native Packager"