Skip to content

Commit 5d11521

Browse files
authored
Fix #754 Add kill timeout to upstart. Add retryTimeout and retries keys (#799)
* Fix #754 Add kill timeout to upstart. Add retryTimeout and retries keys * Add documentation and fixed test
1 parent 8eb636d commit 5d11521

File tree

10 files changed

+75
-49
lines changed

10 files changed

+75
-49
lines changed

src/main/resources/com/typesafe/sbt/packager/archetypes/systemloader/upstart/start-template

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ author "${{author}}"
88
# Stanzas control when and how a process is started and stopped
99
# See a list of stanzas here: http://upstart.ubuntu.com/wiki/Stanzas#respawn
1010

11+
# General settings
12+
kill timeout ${{kill_timeout}}
13+
1114
# When to start the service
1215
start on runlevel ${{start_runlevels}}
1316
${{start_facilities}}

src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemVPlugin.scala

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import com.typesafe.sbt.packager.Keys.{
1313
requiredStartFacilities,
1414
requiredStopFacilities,
1515
startRunlevels,
16-
stopRunlevels
16+
stopRunlevels,
17+
killTimeout,
18+
termTimeout
1719
}
1820
import com.typesafe.sbt.packager.debian.DebianPlugin
1921
import com.typesafe.sbt.packager.rpm.RpmPlugin
@@ -35,6 +37,8 @@ object SystemVPlugin extends AutoPlugin {
3537
requiredStartFacilities := Some("$remote_fs $syslog"),
3638
requiredStopFacilities := Some("$remote_fs $syslog"),
3739
defaultLinuxStartScriptLocation := "/etc/init.d",
40+
termTimeout := 60,
41+
killTimeout := 30,
3842
// add systemloader to mappings and override the isConf setting
3943
linuxPackageMappings ++= startScriptMapping(
4044
linuxStartScriptName.value,

src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderKeys.scala

+5
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@ trait SystemloaderKeys {
88
val stopRunlevels = SettingKey[Option[String]]("stop-runlevels", "Sequence of runlevels on which application will stop")
99
val requiredStartFacilities = SettingKey[Option[String]]("required-start-facilities", "Names of system services that should be provided at application start")
1010
val requiredStopFacilities = SettingKey[Option[String]]("required-stop-facilities", "Names of system services that should be provided at")
11+
val termTimeout = SettingKey[Int]("term-timeout", "Timeout before sigterm on stop")
12+
val killTimeout = SettingKey[Int]("kill-timeout", "Timeout before sigkill on stop (after term)")
13+
val retryTimeout = SettingKey[Int]("retry-timeout", "Timeout between retries in seconds")
14+
val retries = SettingKey[Int]("retries", "Number of retries to start service")
15+
1116
}

src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/SystemloaderPlugin.scala

+28-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import com.typesafe.sbt.packager.Keys.{
1616
requiredStartFacilities,
1717
requiredStopFacilities,
1818
startRunlevels,
19-
stopRunlevels
19+
stopRunlevels,
20+
termTimeout,
21+
killTimeout,
22+
retryTimeout,
23+
retries
2024
}
2125
import com.typesafe.sbt.SbtNativePackager.Universal
2226
import com.typesafe.sbt.packager.archetypes.MaintainerScriptHelper.maintainerScriptsAppend
@@ -44,14 +48,23 @@ object SystemloaderPlugin extends AutoPlugin {
4448
def systemloaderSettings: Seq[Setting[_]] = Seq(
4549
serverLoading := None,
4650
linuxStartScriptName := Some(packageName.value),
51+
// defaults, may be override by concrete systemloader
52+
retries := 0,
53+
retryTimeout := 60,
54+
killTimeout := 5,
55+
termTimeout := 5,
4756
// add loader-functions to script replacements
4857
linuxScriptReplacements += loaderFunctionsReplacement(sourceDirectory.value, serverLoading.value),
4958
linuxScriptReplacements ++= makeStartScriptReplacements(
50-
requiredStartFacilities.value,
51-
requiredStopFacilities.value,
52-
startRunlevels.value,
53-
stopRunlevels.value,
54-
serverLoading.value
59+
requiredStartFacilities = requiredStartFacilities.value,
60+
requiredStopFacilities = requiredStopFacilities.value,
61+
startRunlevels = startRunlevels.value,
62+
stopRunlevels = stopRunlevels.value,
63+
termTimeout = termTimeout.value,
64+
killTimeout = killTimeout.value,
65+
retries = retries.value,
66+
retryTimeout = retryTimeout.value,
67+
loader = serverLoading.value
5568
),
5669
// set the template
5770
linuxStartScriptTemplate := linuxStartScriptUrl(sourceDirectory.value, serverLoading.value),
@@ -117,6 +130,10 @@ object SystemloaderPlugin extends AutoPlugin {
117130
requiredStopFacilities: Option[String],
118131
startRunlevels: Option[String],
119132
stopRunlevels: Option[String],
133+
termTimeout: Int,
134+
killTimeout: Int,
135+
retries: Int,
136+
retryTimeout: Int,
120137
loader: Option[ServerLoader]
121138
): Seq[(String, String)] = {
122139

@@ -129,7 +146,11 @@ object SystemloaderPlugin extends AutoPlugin {
129146
"start_runlevels" -> startRunlevels.getOrElse(""),
130147
"stop_runlevels" -> stopRunlevels.getOrElse(""),
131148
"start_facilities" -> startOn.getOrElse(""),
132-
"stop_facilities" -> stopOn.getOrElse("")
149+
"stop_facilities" -> stopOn.getOrElse(""),
150+
"term_timeout" -> termTimeout.toString,
151+
"kill_timeout" -> killTimeout.toString,
152+
"retries" -> retries.toString,
153+
"retryTimeout" -> retryTimeout.toString
133154
)
134155
}
135156

src/main/scala/com/typesafe/sbt/packager/archetypes/systemloader/UpstartPlugin.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import com.typesafe.sbt.packager.Keys.{
1313
requiredStartFacilities,
1414
requiredStopFacilities,
1515
startRunlevels,
16-
stopRunlevels
16+
stopRunlevels,
17+
killTimeout
1718
}
1819
import com.typesafe.sbt.packager.debian.DebianPlugin
1920
import com.typesafe.sbt.packager.debian.DebianPlugin.autoImport.Debian
@@ -32,12 +33,13 @@ object UpstartPlugin extends AutoPlugin {
3233
def upstartSettings: Seq[Setting[_]] = Seq(
3334
// used by other archetypes to define systemloader dependent behaviour
3435
serverLoading := Some(ServerLoader.Upstart),
35-
// Systemd settings
36+
// Upstart settings
3637
startRunlevels := Some("[2345]"),
3738
stopRunlevels := Some("[016]"),
3839
requiredStartFacilities := None,
3940
requiredStopFacilities := None,
4041
defaultLinuxStartScriptLocation := "/etc/init",
42+
killTimeout := 5,
4143
linuxStartScriptName := Some(packageName.value + ".conf"),
4244
// add systemloader to mappings
4345
linuxPackageMappings ++= startScriptMapping(

src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ trait LinuxKeys {
1717
val linuxPackageMappings = TaskKey[Seq[LinuxPackageMapping]]("linux-package-mappings", "File to install location mappings including owner and privileges.")
1818
val linuxPackageSymlinks = TaskKey[Seq[LinuxSymlink]]("linux-package-symlinks", "Symlinks we should produce in the underlying package.")
1919
val generateManPages = TaskKey[Unit]("generate-man-pages", "Shows all the man files in the current project")
20-
val termTimeout = SettingKey[Int]("term-timeout", "Timeout before sigterm on stop")
21-
val killTimeout = SettingKey[Int]("kill-timeout", "Timeout before sigkill on stop (after term)")
2220

2321
val linuxMakeStartScript = TaskKey[Option[File]]("linuxMakeStartScript", "Creates or discovers the start script used by this project")
2422
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 {
3230
| author - author of this project
3331
| descr - short description
3432
| chdir - execution path of the script
35-
| retries - on fail, how often should a restart be tried
36-
| retryTimeout - pause between retries
3733
| appName - name of application
3834
| appClasspath - application classpath
3935
| appMainClass - main class to start
@@ -43,6 +39,8 @@ trait LinuxKeys {
4339
| daemonGroupGid - daemon group gid
4440
| termTimeout - timeout before sigterm on stop
4541
| killTimeout - timeout before sigkill on stop (after term)
42+
| retries - on fail, how often should a restart be tried
43+
| retryTimeout - pause between retries
4644
""".stripMargin
4745
)
4846

src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala

+13-33
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
package com.typesafe.sbt
2-
package packager
3-
package linux
1+
package com.typesafe.sbt.packager.linux
42

53
import sbt._
64
import sbt.Keys.{ name, normalizedName, mappings, sourceDirectory }
7-
import linux.LinuxPlugin.Users
8-
import packager.Keys._
9-
import packager.archetypes.{ TemplateWriter }
5+
import com.typesafe.sbt.SbtNativePackager.Universal
6+
import com.typesafe.sbt.packager.MappingsHelper
7+
import com.typesafe.sbt.packager.Keys._
8+
import com.typesafe.sbt.packager.universal.UniversalPlugin
9+
import com.typesafe.sbt.packager.archetypes.{ TemplateWriter }
1010
import com.typesafe.sbt.packager.archetypes.systemloader.ServerLoader
11-
import SbtNativePackager.Universal
11+
import LinuxPlugin.Users
1212

1313
/**
1414
* Plugin containing all the generic values used for
@@ -21,7 +21,7 @@ import SbtNativePackager.Universal
2121
*/
2222
object LinuxPlugin extends AutoPlugin {
2323

24-
override def requires = universal.UniversalPlugin
24+
override def requires = UniversalPlugin
2525
override lazy val projectSettings = linuxSettings ++ mapGenericFilesToLinux
2626

2727
object autoImport extends LinuxKeys with LinuxMappingDSL {
@@ -74,8 +74,8 @@ object LinuxPlugin extends AutoPlugin {
7474
stopRunlevels := None,
7575
requiredStartFacilities := None,
7676
requiredStopFacilities := None,
77-
termTimeout := 60,
78-
killTimeout := 30,
77+
termTimeout := 10,
78+
killTimeout := 10,
7979

8080
// Default linux bashscript replacements
8181
linuxScriptReplacements := makeReplacements(
@@ -90,9 +90,7 @@ object LinuxPlugin extends AutoPlugin {
9090
daemonUserUid = (daemonUserUid in Linux).value,
9191
daemonGroup = (daemonGroup in Linux).value,
9292
daemonGroupGid = (daemonGroupGid in Linux).value,
93-
daemonShell = (daemonShell in Linux).value,
94-
termTimeout = (termTimeout in Linux).value,
95-
killTimeout = (killTimeout in Linux).value
93+
daemonShell = (daemonShell in Linux).value
9694
),
9795
linuxScriptReplacements += controlScriptFunctionsReplacement( /* Add key for control-functions */ ),
9896

@@ -146,16 +144,6 @@ object LinuxPlugin extends AutoPlugin {
146144
}
147145
)
148146

149-
/**
150-
*
151-
* @param author -
152-
* @param description - short description
153-
* @param execScript - name of the script in /usr/bin
154-
* @param chdir - execution path of the script
155-
* @param retries - on fail, how often should a restart be tried
156-
* @param retryTimeout - pause between retries
157-
* @return Seq of placeholder>replacement pairs
158-
*/
159147
def makeReplacements(
160148
author: String,
161149
description: String,
@@ -168,29 +156,21 @@ object LinuxPlugin extends AutoPlugin {
168156
daemonUserUid: Option[String],
169157
daemonGroup: String,
170158
daemonGroupGid: Option[String],
171-
daemonShell: String,
172-
retries: Int = 0,
173-
retryTimeout: Int = 60,
174-
termTimeout: Int = 60,
175-
killTimeout: Int = 30
159+
daemonShell: String
176160
): Seq[(String, String)] =
177161
Seq(
178162
"author" -> author,
179163
"descr" -> description,
180164
"exec" -> execScript,
181165
"chdir" -> chdir,
182166
"logdir" -> logdir,
183-
"retries" -> retries.toString,
184-
"retryTimeout" -> retryTimeout.toString,
185167
"app_name" -> appName,
186168
"version" -> version,
187169
"daemon_user" -> daemonUser,
188170
"daemon_user_uid" -> daemonUserUid.getOrElse(""),
189171
"daemon_group" -> daemonGroup,
190172
"daemon_group_gid" -> daemonGroupGid.getOrElse(""),
191-
"daemon_shell" -> daemonShell,
192-
"term_timeout" -> termTimeout.toString,
193-
"kill_timeout" -> killTimeout.toString
173+
"daemon_shell" -> daemonShell
194174
)
195175

196176
/**

src/sbt-test/debian/sysvinit-stoptimeouts-deb/build.sbt

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ requiredStartFacilities := Some("$test-service")
1919

2020
requiredStartFacilities in Debian := Some("$test-deb-service")
2121

22-
termTimeout := 10
22+
termTimeout in Debian := 10
2323

24-
killTimeout := 20
24+
killTimeout in Debian := 20
2525

2626
TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) =>
2727
val header = "#!/bin/sh"

src/sbt-test/debian/upstart-deb-facilities/build.sbt

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ TaskKey[Unit]("check-startup-script") <<= (target, streams) map { (target, out)
2727
assert(script.contains("stop on runlevel [016]"), "script doesn't contain stop on runlevel header\n" + script)
2828
assert(script.contains("start on started [networking]"), "script contains start on started header\n" + script)
2929
assert(script.contains("stop on stopping [networking]"), "script contains stop on stopping header\n" + script)
30+
assert(script.contains("kill timeout 5"), "script doenst't contain kill 'kill timeout 5'\n" + script)
3031
out.log.success("Successfully tested systemV start up script")
3132
()
3233
}

src/sphinx/archetypes/systemloaders.rst

+12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ General Settings
3434
``requiredStopFacilities``
3535
Names of system services that should be provided at application stop
3636

37+
``killTimeout``
38+
Timeout before sigkill on stop (after term)
39+
40+
``termTimeout``
41+
Timeout before sigterm on stop
42+
43+
``retries``
44+
Number of retries to start service"
45+
46+
``retryTimeout``
47+
Timeout between retries in seconds
48+
3749

3850
SystemV
3951
-------

0 commit comments

Comments
 (0)