Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Started refactoring of archetypes templates #131

Merged
merged 4 commits into from
Jan 22, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
service ${{app_name}} stop || echo "${{app_name}} wasn't even running!"
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,67 @@ import java.net.URL
object JavaAppStartScript {

import ServerLoader._
import com.typesafe.sbt.packager.debian.DebianPlugin.Names._
val startScript = "start"

protected def upstartTemplateSource: URL = getClass.getResource("upstart-template")
protected def sysvinitTemplateSource: URL = getClass.getResource("sysvinit-template")
protected def postinstTemplateSource: URL = getClass.getResource("postinst-template")
protected def postinstSysvinitTemplateSource: URL = getClass.getResource("postinst-sysvinit-template")
protected def postrmSysvinitTemplateSource: URL = getClass.getResource("postrm-sysvinit-template")
protected def preremTemplateSource: URL = getClass.getResource("prerem-template")


def defaultStartScriptTemplate(loader: ServerLoader, defaultLocation: File): URL =
if(defaultLocation.exists) defaultLocation.toURI.toURL
else loader match {
case Upstart => upstartTemplateSource
case SystemV => sysvinitTemplateSource
}
private val upstartScripts = Seq(startScript, Postinst, Prerm)
private val systemvScripts = Seq(startScript, Postinst, Prerm, Postrm)

/**
* Generating the URL to the startScript template.
* 1. Looking in defaultLocation
* 2. Using default fallback
*
* @param loader - used, when no file in the defaultLocation
* @param defaultLocation - use if exists
*/
def defaultStartScriptTemplate(loader: ServerLoader, defaultLocation: File): URL =
if (defaultLocation.exists) defaultLocation.toURI.toURL
else templateUrl(startScript, loader) getOrElse sys.error("Default startscript not available for loader: " + loader)

def generatePrerm(appName: String, template: java.net.URL = preremTemplateSource): String =
TemplateWriter.generateScript(template, Seq("app_name" -> appName))

/**
* Generating the start script depending on the serverLoader.
*
* @param loader - which startup system
* @param replacements - default replacements
* @param template - if specified, it will override the default one
*/
def generateStartScript(
loader: ServerLoader,
replacements: Seq[(String, String)],
template: Option[URL] = None): Option[String] = generateTemplate(startScript, loader, replacements, template)

def generatePostrm(appName: String, loader: ServerLoader, template: Option[java.net.URL] = None): Option[String] =
(template, loader) match {
case (Some(template), _) => Option(TemplateWriter.generateScript(template, Seq("app_name" -> appName)))
case (_, SystemV) =>
Option(TemplateWriter.generateScript(postrmSysvinitTemplateSource, Seq("app_name" -> appName)))
case (_, _) => None
}
/**
*
* @param templateName - DebianPlugin.Names for maintainer scripts and "start"
* @param loader - which startup system
* @param replacements - default replacements
* @param template - if specified, it will override the default one
*/
def generateTemplate(
templateName: String,
loader: ServerLoader,
replacements: Seq[(String, String)],
template: Option[URL] = None): Option[String] = {

// use template orElse search for a default
val url = templateUrl(templateName, loader, template)

def generatePostinst(appName: String, loader: ServerLoader, template: Option[java.net.URL] = None): String =
(template, loader) match {
// User has overriden the default.
case (Some(template), _) => TemplateWriter.generateScript(template, Seq("app_name" -> appName))
case (_, Upstart) =>
TemplateWriter.generateScript(postinstTemplateSource, Seq("app_name" -> appName))
case (_, SystemV) =>
TemplateWriter.generateScript(postinstSysvinitTemplateSource, Seq("app_name" -> appName))
// if an url was found, create the script
url map { template =>
TemplateWriter generateScript (template, replacements)
}
}

def templateUrl(templateName: String, loader: ServerLoader, template: Option[URL] = None): Option[URL] = template orElse {
Option(loader match {
case Upstart if (upstartScripts contains templateName) =>
getClass getResource ("upstart/" + templateName + "-template")
case SystemV if (systemvScripts contains templateName) =>
getClass getResource ("systemv/" + templateName + "-template")
case _ => null
})
}

/**
*
Expand Down Expand Up @@ -82,11 +103,9 @@ object JavaAppStartScript {
"app_name" -> appName,
"app_main_class" -> appMainClass,
"app_classpath" -> appClasspath,
"daemon_user" -> daemonUser
)
"daemon_user" -> daemonUser)
}


object ServerLoader extends Enumeration {
type ServerLoader = Value
val Upstart, SystemV = Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import sbt._
import sbt.Keys.{ target, mainClass, normalizedName, sourceDirectory }
import SbtNativePackager._
import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping, LinuxSymlink, LinuxPlugin }
import com.typesafe.sbt.packager.debian.DebianPlugin

/**
* This class contains the default settings for creating and deploying an archetypical Java application.
Expand All @@ -20,6 +21,7 @@ import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping,
object JavaServerAppPackaging {
import ServerLoader._
import LinuxPlugin.Users
import DebianPlugin.Names.{ Preinst, Postinst, Prerm, Postrm }

def settings: Seq[Setting[_]] = JavaAppPackaging.settings ++ debianSettings
protected def etcDefaultTemplateSource: java.net.URL = getClass.getResource("etc-default-template")
Expand All @@ -29,7 +31,7 @@ object JavaServerAppPackaging {
serverLoading := Upstart,
daemonUser := Users.Root,
// This one is begging for sbt 0.13 syntax...
debianStartScriptReplacements <<= (
debianScriptReplacements <<= (
maintainer in Debian, packageSummary in Debian, serverLoading in Debian, daemonUser in Debian, normalizedName,
sbt.Keys.version, defaultLinuxInstallLocation, mainClass in Compile, scriptClasspath)
map { (author, descr, loader, daemonUser, name, version, installLocation, mainClass, cp) =>
Expand All @@ -47,21 +49,15 @@ object JavaServerAppPackaging {
daemonUser = daemonUser)
},
// TODO - Default locations shouldn't be so hacky.

// === Startscript creation ===
linuxStartScriptTemplate in Debian <<= (serverLoading in Debian, sourceDirectory) map { (loader, dir) =>
JavaAppStartScript.defaultStartScriptTemplate(loader, dir / "templates" / "start")
},
debianMakeStartScript <<= (debianStartScriptReplacements, normalizedName, target in Universal, linuxStartScriptTemplate in Debian)
map makeDebianStartScript,
linuxEtcDefaultTemplate in Debian <<= sourceDirectory map { dir =>
val overrideScript = dir / "templates" / "etc-default"
if(overrideScript.exists) overrideScript.toURI.toURL
else etcDefaultTemplateSource
},
debianMakeEtcDefault <<= (normalizedName, target in Universal, serverLoading in Debian, linuxEtcDefaultTemplate in Debian)
map makeEtcDefaultScript,
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName) map { (conf, name) =>
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name))).withConfig()).toSeq
},
debianMakeStartScript <<= (target in Universal, serverLoading in Debian, debianScriptReplacements, linuxStartScriptTemplate in Debian)
map { (tmpDir, loader, replacements, template) =>
makeDebianMaintainerScript(JavaAppStartScript.startScript, Some(template))(tmpDir, loader, replacements)
},
linuxPackageMappings in Debian <++= (debianMakeStartScript, normalizedName, serverLoading in Debian)
map { (script, name, loader) =>
val (path, permissions) = loader match {
Expand All @@ -72,7 +68,21 @@ object JavaServerAppPackaging {
s <- script.toSeq
} yield LinuxPackageMapping(Seq(s -> path)).withPerms(permissions).withConfig()
},

// === etc config mapping ===
linuxEtcDefaultTemplate in Debian <<= sourceDirectory map { dir =>
val overrideScript = dir / "templates" / "etc-default"
if (overrideScript.exists) overrideScript.toURI.toURL
else etcDefaultTemplateSource
},
debianMakeEtcDefault <<= (normalizedName, target in Universal, serverLoading in Debian, linuxEtcDefaultTemplate in Debian)
map makeEtcDefaultScript,
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName) map { (conf, name) =>
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name))).withConfig()).toSeq
},
// TODO should we specify daemonGroup in configs?

// === logging directory mapping ===
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxLogsLocation, target in Debian, daemonUser in Debian) map {
(name, logsDir, target, user) =>
// create empty var/log directory
Expand All @@ -83,45 +93,22 @@ object JavaServerAppPackaging {
linuxPackageSymlinks in Debian <+= (normalizedName, defaultLinuxInstallLocation) map {
(name, install) => LinuxSymlink(install + "/" + name + "/logs", "/var/log/" + name)
},
// TODO - only make these if the upstart config exists...
debianMakePrermScript <<= (normalizedName, target in Universal) map makeDebianPrermScript,
debianMakePostrmScript <<= (normalizedName, target in Universal, serverLoading in Debian) map makeDebianPostrmScript,
debianMakePostinstScript <<= (normalizedName, target in Universal, serverLoading in Debian) map makeDebianPostinstScript)

private def makeDebianStartScript(
replacements: Seq[(String, String)], name: String, tmpDir: File, template: URL): Option[File] =
if (replacements.isEmpty) None
else {
val scriptBits = TemplateWriter.generateScript(template, replacements)
val script = tmpDir / "tmp" / "init" / name
IO.write(script, scriptBits)
Some(script)
}
// === Maintainer scripts ===
debianMakePreinstScript <<= (target in Universal, serverLoading in Debian, debianScriptReplacements) map makeDebianMaintainerScript(Preinst),
debianMakePostinstScript <<= (target in Universal, serverLoading in Debian, debianScriptReplacements) map makeDebianMaintainerScript(Postinst),
debianMakePrermScript <<= (target in Universal, serverLoading in Debian, debianScriptReplacements) map makeDebianMaintainerScript(Prerm),
debianMakePostrmScript <<= (target in Universal, serverLoading in Debian, debianScriptReplacements) map makeDebianMaintainerScript(Postrm))

protected def makeDebianPrermScript(name: String, tmpDir: File): Option[File] = {
val scriptBits = JavaAppStartScript.generatePrerm(name)
val script = tmpDir / "tmp" / "bin" / "debian-prerm"
IO.write(script, scriptBits)
Some(script)
}

protected def makeDebianPostrmScript(name: String, tmpDir: File, loader: ServerLoader): Option[File] = {
JavaAppStartScript.generatePostrm(name, loader) match {
case Some(scriptBits) =>
val script = tmpDir / "tmp" / "bin" / "debian-postrm"
IO.write(script, scriptBits)
Some(script)
case None => None
protected def makeDebianMaintainerScript(scriptName: String, template: Option[URL] = None)(
tmpDir: File, loader: ServerLoader, replacements: Seq[(String, String)]): Option[File] = {
JavaAppStartScript.generateTemplate(scriptName, loader, replacements, template) map { scriptBits =>
val script = tmpDir / "tmp" / "bin" / ("debian-" + scriptName)
IO.write(script, scriptBits)
script
}
}

protected def makeDebianPostinstScript(name: String, tmpDir: File, loader: ServerLoader): Option[File] = {
val scriptBits = JavaAppStartScript.generatePostinst(name, loader)
val script = tmpDir / "tmp" / "bin" / "debian-postinst"
IO.write(script, scriptBits)
Some(script)
}

protected def makeEtcDefaultScript(name: String, tmpDir: File, loader: ServerLoader, source: java.net.URL): Option[File] = {
loader match {
case Upstart => None
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ trait DebianKeys {
""".stripMargin)

val debianMakeStartScript = TaskKey[Option[File]]("makeStartScript", "Creates or discovers the start script used by this project")
val debianStartScriptReplacements = TaskKey[Seq[(String, String)]]("upstartScriptReplacements",
val debianScriptReplacements = TaskKey[Seq[(String, String)]]("upstartScriptReplacements",
"""|Replacements of template parameters used in the upstart script.
| Default supported templates:
| execScript - name of the script in /usr/bin
Expand Down