Skip to content

Commit 724db81

Browse files
committed
SystemD services now source /etc/default/{{app_name}} #737
This change modifies the SystemD template to include the packaged /etc/default environment settings file. Since a sourced SystemD environment file is not the same thing as a bourne shell source script, a different template is used. Those deploying their package to multiple platforms can also specify different /etc/default templates by suffixing `-systemd` to their name, ie: src/templates/etc-default-systemd
1 parent 0ff5b77 commit 724db81

File tree

4 files changed

+71
-17
lines changed

4 files changed

+71
-17
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ project/project
99
log/
1010
target/
1111
.cache
12+
.ensime*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# #####################################
2+
# ##### Environment Configuration #####
3+
# #####################################
4+
5+
# This file is parsed by SystemD. You can modify it to specify environment
6+
# variables for your application. For a description of the format, see `man
7+
# systemd.exec`, section `EnvironmentFile`.
8+
9+
# Available replacements
10+
# ------------------------------------------------
11+
# ${{author}} debian author
12+
# ${{descr}} debian package description
13+
# ${{exec}} startup script name
14+
# ${{chdir}} app directory
15+
# ${{retries}} retries for startup
16+
# ${{retryTimeout}} retry timeout
17+
# ${{app_name}} normalized app name
18+
# ${{daemon_user}} daemon user
19+
# -------------------------------------------------
20+
21+
# Setting JAVA_OPTS
22+
# -----------------
23+
# JAVA_OPTS="-Dpidfile.path=/var/run/${{app_name}}/play.pid"
24+
25+
# Setting PIDFILE
26+
# ---------------
27+
# PIDFILE="/var/run/${{app_name}}/play.pid"

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

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Requires=${{start_facilities}}
55
[Service]
66
Type=simple
77
WorkingDirectory=${{chdir}}
8+
EnvironmentFile=${{env_config}}
89
ExecStart=${{chdir}}/bin/${{exec}}
910
ExecReload=/bin/kill -HUP $MAINPID
1011
Restart=always

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala

+42-17
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ object JavaServerAppPackaging extends AutoPlugin {
3939
/** These settings will be provided by this archetype*/
4040
def javaServerSettings: Seq[Setting[_]] = linuxSettings ++ debianSettings ++ rpmSettings
4141

42-
protected def etcDefaultTemplateSource: java.net.URL = getClass.getResource(ETC_DEFAULT + "-template")
43-
4442
/**
4543
* general settings which apply to all linux server archetypes
4644
*
@@ -59,27 +57,26 @@ object JavaServerAppPackaging extends AutoPlugin {
5957
},
6058
// === etc config mapping ===
6159
bashScriptEnvConfigLocation := Some("/etc/default/" + (packageName in Linux).value),
62-
linuxEtcDefaultTemplate <<= sourceDirectory map { dir =>
63-
val overrideScript = dir / "templates" / ETC_DEFAULT
64-
if (overrideScript.exists) overrideScript.toURI.toURL
65-
else etcDefaultTemplateSource
66-
},
67-
linuxStartScriptName := None,
68-
makeEtcDefault <<= (packageName in Linux, target in Universal, linuxEtcDefaultTemplate, linuxScriptReplacements)
69-
map makeEtcDefaultScript,
70-
linuxPackageMappings <++= (makeEtcDefault, bashScriptEnvConfigLocation) map { (conf, envLocation) =>
71-
val mapping = for (
72-
path <- envLocation;
73-
c <- conf
74-
) yield LinuxPackageMapping(Seq(c -> path), LinuxFileMetaData(Users.Root, Users.Root, "644")).withConfig()
60+
// (serverLoading in Rpm) apply getStartScriptLocation
7561

76-
mapping.toSeq
77-
}
62+
linuxStartScriptName := None
63+
)
7864

65+
/* etcDefaultConfig is dependent on serverLoading (systemd, systemv, etc.),
66+
* and is therefore distro specific. As such, these settings cannot be defined
67+
* generally. */
68+
private val etcDefaultConfig: Seq[Setting[_]] = Seq(
69+
linuxEtcDefaultTemplate <<= (sourceDirectory, serverLoading)
70+
map getEtcTemplateSource,
71+
makeEtcDefault <<= (packageName in Linux, target in Universal, linuxEtcDefaultTemplate, linuxScriptReplacements)
72+
map makeEtcDefaultScript,
73+
linuxPackageMappings <++= (makeEtcDefault, bashScriptEnvConfigLocation) map
74+
etcDefaultMapping
7975
)
8076

8177
def debianSettings: Seq[Setting[_]] = {
8278
import DebianPlugin.Names.{ Preinst, Postinst, Prerm, Postrm }
79+
inConfig(Debian)(etcDefaultConfig) ++
8380
inConfig(Debian)(Seq(
8481
serverLoading := Upstart,
8582
startRunlevels <<= (serverLoading) apply defaultStartRunlevels,
@@ -131,6 +128,7 @@ object JavaServerAppPackaging extends AutoPlugin {
131128

132129
def rpmSettings: Seq[Setting[_]] = {
133130
import RpmPlugin.Names.{ Pre, Post, Preun, Postun }
131+
inConfig(Rpm)(etcDefaultConfig) ++
134132
inConfig(Rpm)(Seq(
135133
serverLoading := SystemV,
136134
startRunlevels <<= (serverLoading) apply defaultStartRunlevels,
@@ -242,6 +240,33 @@ object JavaServerAppPackaging extends AutoPlugin {
242240
}
243241
}
244242

243+
private[this] def getEtcTemplateSource(sourceDirectory: File, loader: ServerLoader): java.net.URL = {
244+
val suffix = loader match {
245+
case Upstart => "-upstart"
246+
case SystemV => "-systemv"
247+
case Systemd => "-systemd"
248+
}
249+
250+
val overrides = List[File](sourceDirectory / "templates" / (ETC_DEFAULT + suffix), sourceDirectory / "templates" / ETC_DEFAULT)
251+
overrides.find(_.exists).map(_.toURI.toURL).getOrElse {
252+
loader match {
253+
case Upstart => getClass.getResource(ETC_DEFAULT + "-template")
254+
case SystemV => getClass.getResource(ETC_DEFAULT + "-template")
255+
case Systemd => getClass.getResource(ETC_DEFAULT + "-systemd-template")
256+
}
257+
}
258+
}
259+
260+
// Used to tell our packager to install our /etc/default/{{appName}} config file.
261+
protected def etcDefaultMapping(conf: Option[File], envLocation: Option[String]): Seq[LinuxPackageMapping] = {
262+
val mapping = for (
263+
path <- envLocation;
264+
c <- conf
265+
) yield LinuxPackageMapping(Seq(c -> path), LinuxFileMetaData(Users.Root, Users.Root, "644")).withConfig()
266+
267+
mapping.toSeq
268+
}
269+
245270
protected def startScriptMapping(name: String, script: Option[File], loader: ServerLoader, scriptDir: String, scriptName: Option[String]): Seq[LinuxPackageMapping] = {
246271
val (path, permissions, isConf) = loader match {
247272
case Upstart => ("/etc/init/" + scriptName.getOrElse(name + ".conf"), "0644", "true")

0 commit comments

Comments
 (0)