diff --git a/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template index 4d7d946d1..9301f7d7e 100644 --- a/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template +++ b/src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template @@ -8,6 +8,9 @@ author "${{author}}" # Stanzas control when and how a process is started and stopped # See a list of stanzas here: http://upstart.ubuntu.com/wiki/Stanzas#respawn +# General settings +kill timeout ${{kill_timeout}} + # When to start the service start on runlevel ${{start_runlevels}} ${{start_facilities}} 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 index c87a0be1b..f681fe431 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala @@ -13,7 +13,9 @@ import com.typesafe.sbt.packager.Keys.{ requiredStartFacilities, requiredStopFacilities, startRunlevels, - stopRunlevels + stopRunlevels, + killTimeout, + termTimeout } import com.typesafe.sbt.packager.debian.DebianPlugin import com.typesafe.sbt.packager.rpm.RpmPlugin @@ -35,6 +37,8 @@ object SystemVPlugin extends AutoPlugin { requiredStartFacilities := Some("$remote_fs $syslog"), requiredStopFacilities := Some("$remote_fs $syslog"), defaultLinuxStartScriptLocation := "/etc/init.d", + termTimeout := 60, + killTimeout := 30, // add systemloader to mappings and override the isConf setting linuxPackageMappings ++= startScriptMapping( linuxStartScriptName.value, 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 index c2286c741..58752673f 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala @@ -8,4 +8,9 @@ trait SystemloaderKeys { 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") + 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 retryTimeout = SettingKey[Int]("retry-timeout", "Timeout between retries in seconds") + val retries = SettingKey[Int]("retries", "Number of retries to start service") + } \ 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 index 0865be221..1ae9e61a3 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala @@ -16,7 +16,11 @@ import com.typesafe.sbt.packager.Keys.{ requiredStartFacilities, requiredStopFacilities, startRunlevels, - stopRunlevels + stopRunlevels, + termTimeout, + killTimeout, + retryTimeout, + retries } import com.typesafe.sbt.SbtNativePackager.Universal import com.typesafe.sbt.packager.archetypes.MaintainerScriptHelper.maintainerScriptsAppend @@ -44,14 +48,23 @@ object SystemloaderPlugin extends AutoPlugin { def systemloaderSettings: Seq[Setting[_]] = Seq( serverLoading := None, linuxStartScriptName := Some(packageName.value), + // defaults, may be override by concrete systemloader + retries := 0, + retryTimeout := 60, + killTimeout := 5, + termTimeout := 5, // add loader-functions to script replacements linuxScriptReplacements += loaderFunctionsReplacement(sourceDirectory.value, serverLoading.value), linuxScriptReplacements ++= makeStartScriptReplacements( - requiredStartFacilities.value, - requiredStopFacilities.value, - startRunlevels.value, - stopRunlevels.value, - serverLoading.value + requiredStartFacilities = requiredStartFacilities.value, + requiredStopFacilities = requiredStopFacilities.value, + startRunlevels = startRunlevels.value, + stopRunlevels = stopRunlevels.value, + termTimeout = termTimeout.value, + killTimeout = killTimeout.value, + retries = retries.value, + retryTimeout = retryTimeout.value, + loader = serverLoading.value ), // set the template linuxStartScriptTemplate := linuxStartScriptUrl(sourceDirectory.value, serverLoading.value), @@ -117,6 +130,10 @@ object SystemloaderPlugin extends AutoPlugin { requiredStopFacilities: Option[String], startRunlevels: Option[String], stopRunlevels: Option[String], + termTimeout: Int, + killTimeout: Int, + retries: Int, + retryTimeout: Int, loader: Option[ServerLoader] ): Seq[(String, String)] = { @@ -129,7 +146,11 @@ object SystemloaderPlugin extends AutoPlugin { "start_runlevels" -> startRunlevels.getOrElse(""), "stop_runlevels" -> stopRunlevels.getOrElse(""), "start_facilities" -> startOn.getOrElse(""), - "stop_facilities" -> stopOn.getOrElse("") + "stop_facilities" -> stopOn.getOrElse(""), + "term_timeout" -> termTimeout.toString, + "kill_timeout" -> killTimeout.toString, + "retries" -> retries.toString, + "retryTimeout" -> retryTimeout.toString ) } 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 index 9a181a3e0..788213fe3 100644 --- a/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala @@ -13,7 +13,8 @@ import com.typesafe.sbt.packager.Keys.{ requiredStartFacilities, requiredStopFacilities, startRunlevels, - stopRunlevels + stopRunlevels, + killTimeout } import com.typesafe.sbt.packager.debian.DebianPlugin import com.typesafe.sbt.packager.debian.DebianPlugin.autoImport.Debian @@ -32,12 +33,13 @@ object UpstartPlugin extends AutoPlugin { def upstartSettings: Seq[Setting[_]] = Seq( // used by other archetypes to define systemloader dependent behaviour serverLoading := Some(ServerLoader.Upstart), - // Systemd settings + // Upstart settings startRunlevels := Some("[2345]"), stopRunlevels := Some("[016]"), requiredStartFacilities := None, requiredStopFacilities := None, defaultLinuxStartScriptLocation := "/etc/init", + killTimeout := 5, linuxStartScriptName := Some(packageName.value + ".conf"), // add systemloader to mappings linuxPackageMappings ++= startScriptMapping( 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 ebae8c9ab..e179128c9 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala @@ -17,8 +17,6 @@ trait LinuxKeys { 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]]("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") @@ -32,8 +30,6 @@ trait LinuxKeys { | author - author of this project | descr - short description | chdir - execution path of the script - | retries - on fail, how often should a restart be tried - | retryTimeout - pause between retries | appName - name of application | appClasspath - application classpath | appMainClass - main class to start @@ -43,6 +39,8 @@ trait LinuxKeys { | daemonGroupGid - daemon group gid | termTimeout - timeout before sigterm on stop | killTimeout - timeout before sigkill on stop (after term) + | retries - on fail, how often should a restart be tried + | retryTimeout - pause between retries """.stripMargin ) 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 fbfc6ff67..6b3b446fe 100644 --- a/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala @@ -1,14 +1,14 @@ -package com.typesafe.sbt -package packager -package linux +package com.typesafe.sbt.packager.linux import sbt._ import sbt.Keys.{ name, normalizedName, mappings, sourceDirectory } -import linux.LinuxPlugin.Users -import packager.Keys._ -import packager.archetypes.{ TemplateWriter } +import com.typesafe.sbt.SbtNativePackager.Universal +import com.typesafe.sbt.packager.MappingsHelper +import com.typesafe.sbt.packager.Keys._ +import com.typesafe.sbt.packager.universal.UniversalPlugin +import com.typesafe.sbt.packager.archetypes.{ TemplateWriter } import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader -import SbtNativePackager.Universal +import LinuxPlugin.Users /** * Plugin containing all the generic values used for @@ -21,7 +21,7 @@ import SbtNativePackager.Universal */ object LinuxPlugin extends AutoPlugin { - override def requires = universal.UniversalPlugin + override def requires = UniversalPlugin override lazy val projectSettings = linuxSettings ++ mapGenericFilesToLinux object autoImport extends LinuxKeys with LinuxMappingDSL { @@ -74,8 +74,8 @@ object LinuxPlugin extends AutoPlugin { stopRunlevels := None, requiredStartFacilities := None, requiredStopFacilities := None, - termTimeout := 60, - killTimeout := 30, + termTimeout := 10, + killTimeout := 10, // Default linux bashscript replacements linuxScriptReplacements := makeReplacements( @@ -90,9 +90,7 @@ object LinuxPlugin extends AutoPlugin { daemonUserUid = (daemonUserUid in Linux).value, daemonGroup = (daemonGroup in Linux).value, daemonGroupGid = (daemonGroupGid in Linux).value, - daemonShell = (daemonShell in Linux).value, - termTimeout = (termTimeout in Linux).value, - killTimeout = (killTimeout in Linux).value + daemonShell = (daemonShell in Linux).value ), linuxScriptReplacements += controlScriptFunctionsReplacement( /* Add key for control-functions */ ), @@ -146,16 +144,6 @@ object LinuxPlugin extends AutoPlugin { } ) - /** - * - * @param author - - * @param description - short description - * @param execScript - name of the script in /usr/bin - * @param chdir - execution path of the script - * @param retries - on fail, how often should a restart be tried - * @param retryTimeout - pause between retries - * @return Seq of placeholder>replacement pairs - */ def makeReplacements( author: String, description: String, @@ -168,11 +156,7 @@ object LinuxPlugin extends AutoPlugin { daemonUserUid: Option[String], daemonGroup: String, daemonGroupGid: Option[String], - daemonShell: String, - retries: Int = 0, - retryTimeout: Int = 60, - termTimeout: Int = 60, - killTimeout: Int = 30 + daemonShell: String ): Seq[(String, String)] = Seq( "author" -> author, @@ -180,17 +164,13 @@ object LinuxPlugin extends AutoPlugin { "exec" -> execScript, "chdir" -> chdir, "logdir" -> logdir, - "retries" -> retries.toString, - "retryTimeout" -> retryTimeout.toString, "app_name" -> appName, "version" -> version, "daemon_user" -> daemonUser, "daemon_user_uid" -> daemonUserUid.getOrElse(""), "daemon_group" -> daemonGroup, "daemon_group_gid" -> daemonGroupGid.getOrElse(""), - "daemon_shell" -> daemonShell, - "term_timeout" -> termTimeout.toString, - "kill_timeout" -> killTimeout.toString + "daemon_shell" -> daemonShell ) /** diff --git a/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt b/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt index e00bb8391..4d85c3ad7 100644 --- a/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt +++ b/src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt @@ -19,9 +19,9 @@ requiredStartFacilities := Some("$test-service") requiredStartFacilities in Debian := Some("$test-deb-service") -termTimeout := 10 +termTimeout in Debian := 10 -killTimeout := 20 +killTimeout in Debian := 20 TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) => val header = "#!/bin/sh" diff --git a/src/sbt-test/debian/upstart-deb-facilities/build.sbt b/src/sbt-test/debian/upstart-deb-facilities/build.sbt index 174475ca3..fcfc0e98f 100644 --- a/src/sbt-test/debian/upstart-deb-facilities/build.sbt +++ b/src/sbt-test/debian/upstart-deb-facilities/build.sbt @@ -27,6 +27,7 @@ TaskKey[Unit]("check-startup-script") <<= (target, streams) map { (target, out) assert(script.contains("stop on runlevel [016]"), "script doesn't contain stop on runlevel header\n" + script) assert(script.contains("start on started [networking]"), "script contains start on started header\n" + script) assert(script.contains("stop on stopping [networking]"), "script contains stop on stopping header\n" + script) + assert(script.contains("kill timeout 5"), "script doenst't contain kill 'kill timeout 5'\n" + script) out.log.success("Successfully tested systemV start up script") () } \ No newline at end of file diff --git a/src/sphinx/archetypes/systemloaders.rst b/src/sphinx/archetypes/systemloaders.rst index 597def891..29b8f0436 100644 --- a/src/sphinx/archetypes/systemloaders.rst +++ b/src/sphinx/archetypes/systemloaders.rst @@ -34,6 +34,18 @@ General Settings ``requiredStopFacilities`` Names of system services that should be provided at application stop + ``killTimeout`` + Timeout before sigkill on stop (after term) + + ``termTimeout`` + Timeout before sigterm on stop + + ``retries`` + Number of retries to start service" + + ``retryTimeout`` + Timeout between retries in seconds + SystemV -------