Skip to content
This repository has been archived by the owner on Jul 5, 2019. It is now read-only.

#11 First work done #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 3 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ resolvers += Resolver.url("scalasbt", new URL("http://scalasbt.artifactoryonline

resolvers += Resolver.file("ivy2-local", new File(Path.userHome.absolutePath + "/.ivy2/local"))(Resolver.ivyStylePatterns)

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.5.4")

addSbtPlugin("play" % "sbt-plugin" % "2.1.1")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")

name := "play2-native-packager-plugin"

Expand All @@ -16,9 +14,9 @@ version := "0.6-SNAPSHOT"

description := "Play2 plugin for producing native system distribution packages"

scalaVersion := "2.9.2"
scalaVersion := "2.10.0"

sbtVersion := "0.12.2"
sbtVersion := "0.13.0"

sbtPlugin := true

Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.12.2
sbt.version=0.13.0
2 changes: 1 addition & 1 deletion project/build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
resolvers += Classpaths.typesafeResolver

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.3.0")
105 changes: 35 additions & 70 deletions src/main/scala/net/kindleit/play2/natpackplugin/NatPackPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,88 +21,53 @@ import sbt.Keys._
import com.typesafe.sbt.packager._
import com.typesafe.sbt.packager.Keys._

/**
* @see https://github.com/sbt/sbt-native-packager/blob/master/src/main/scala/com/typesafe/sbt/packager/universal/UniversalPlugin.scala
*/
object NatPackPlugin extends Plugin with debian.DebianPlugin {

object NatPackKeys extends linux.Keys with debian.DebianKeys {
lazy val debian = TaskKey[File]("deb", "Create the debian package")
lazy val debianPreInst = TaskKey[File]("debian-preinst-file", "Debian pre install maintainer script")
lazy val debianPreRm = TaskKey[File]("debian-prerm-file", "Debian pre remove maintainer script")
lazy val debianPostRm = TaskKey[File]("debian-postrm-file", "Debian post remove maintainer script")
lazy val userName = SettingKey[String]("Unix user to own the extracted package files")
lazy val groupName = SettingKey[String]("Unix group to own the extracted package files")
lazy val configFilePath = SettingKey[String]("Config file path for play application configuration [optional]")
lazy val debianPreInst = TaskKey[File]("debian-preinst-file", "Debian pre install maintainer script")
lazy val debianPreRm = TaskKey[File]("debian-prerm-file", "Debian pre remove maintainer script")
lazy val debianPostRm = TaskKey[File]("debian-postrm-file", "Debian post remove maintainer script")
lazy val userName = SettingKey[String]("Unix user to own the extracted package files")
lazy val groupName = SettingKey[String]("Unix group to own the extracted package files")
lazy val fullName = SettingKey[String]("Will create /usr/share/<fullName> folder")
}
private val npkg = NatPackKeys

import NatPackKeys._

lazy val natPackSettings: Seq[Project.Setting[_]] = linuxSettings ++ debianSettings ++ Seq(
lazy val natPackSettings: Seq[Project.Setting[_]] = Seq(

//evaluate and set defaults
name in Debian <<= normalizedName,
version in Debian <<= version,
maintainer in Debian <<= maintainer,
userName in Debian <<= userName,
groupName in Debian <<= groupName,
description in Debian <<= description,
packageSummary <<= description,
packageSummary in Debian <<= packageSummary,
name in Debian <<= normalizedName,
// To be conform with the sbt-native-packager
fullName in Debian <<= (name, version) apply (_ + "-" + _),
version in Debian <<= version,
maintainer in Debian <<= maintainer,
userName in Debian <<= userName,
groupName in Debian <<= groupName,
description in Debian <<= description,
packageSummary <<= description,
packageSummary in Debian <<= packageSummary,
packageDescription <<= description,
packageDescription in Debian <<= packageDescription,
configFilePath ~= { (cfgPath: String) =>
if (cfgPath.isEmpty) {
Option(System.getProperty("config.file")).getOrElse("")
} else {
cfgPath
}
},

linuxPackageMappings <++=
(baseDirectory, target, normalizedName, npkg.userName, npkg.groupName, packageSummary in Debian,
configFilePath, PlayProject.playPackageEverything, dependencyClasspath in Runtime) map {
(root, target, name, usr, grp, desc, cfg, pkgs, deps) ⇒
val start = target / "start"
val init = target / "initFile"

IO.write(start, startFileContent(cfg))
IO.write(init, initFilecontent(name, desc, usr))

val jarLibs = (pkgs ++ deps.map(_.data)) filter(_.ext == "jar") map { jar ⇒
packageMapping(jar -> "/var/lib/%s/lib/%s".format(name, jar.getName)) withUser(usr) withGroup(grp) withPerms("0644")
}

val appConf = if (!cfg.isEmpty) {
Seq(packageMapping(root / cfg -> "/var/lib/%s/application.conf".format(name)) withUser(usr) withGroup(grp) withPerms("0644"))
} else {
Seq()
}

val confFiles = Seq(
packageMapping(start -> "/var/lib/%s/start".format(name)) withUser(usr) withGroup(grp),
packageMapping(init -> "/etc/init.d/%s".format(name)) withPerms("0754") withConfig(),
packageMapping(root / "README" -> "/var/lib/%s/README".format(name)) withUser(usr) withGroup(grp) withPerms("0644")
)

val otherPkgs = pkgs filter(_.ext != "jar") map { pkg ⇒
packageMapping(pkg -> "/var/lib/%s/%s".format(name, pkg.getName)) withUser(usr) withGroup(grp)
}

jarLibs ++ appConf ++ confFiles ++ otherPkgs
},
npkg.debian <<= (packageBin in Debian, streams) map { (deb, s) ⇒
s.log.info("Package %s ready".format(deb))
s.log.info("If you wish to sign the package as well, run %s:%s".format(Debian, debianSign.key))
deb
}
) ++ inConfig(Debian)( Seq(
npkg.debianPreInst <<= (target, normalizedName, userName, groupName) map debFile3("postinst", postInstContent),
npkg.debianPreRm <<= (target, normalizedName) map debFile1("prerm", preRmContent),
npkg.debianPostRm <<= (target, normalizedName, userName) map debFile2("postrm", postRmContent),
debianExplodedPackage <<= debianExplodedPackage.dependsOn(npkg.debianPreInst, npkg.debianPreRm, npkg.debianPostRm),
debianPackageDependencies ++= Seq("java2-runtime", "daemon"),
debianPackageRecommends += "git"

)) ++
SettingsHelper.makeDeploymentSettings(Debian, packageBin in Debian, "deb")
linuxPackageMappings <++= (target, normalizedName, npkg.userName, packageSummary in Debian) map {
(target, name, usr, desc) ⇒
val init = target / "initFile"
IO.write(init, initFilecontent(name, desc, usr))

Seq(packageMapping(init -> "/etc/init.d/%s".format(name)) withPerms ("0754") withConfig ())

}) ++ inConfig(Debian)(Seq(
npkg.debianPreInst <<= (target, fullName, normalizedName, userName, groupName) map debFile4("postinst", postInstContent),
npkg.debianPreRm <<= (target, normalizedName) map debFile1("prerm", preRmContent),
npkg.debianPostRm <<= (target, fullName, normalizedName, userName) map debFile3("postrm", postRmContent),
debianExplodedPackage <<= debianExplodedPackage.dependsOn(npkg.debianPreInst, npkg.debianPreRm, npkg.debianPostRm),
debianPackageDependencies ++= Seq("java2-runtime", "daemon"),
debianPackageRecommends += "git")) ++
SettingsHelper.makeDeploymentSettings(Debian, packageBin in Debian, "deb")

}
64 changes: 31 additions & 33 deletions src/main/scala/net/kindleit/play2/natpackplugin/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ package object natpackplugin {
import String.format
import sbt._

private[natpackplugin] def postInstContent(name: String, userName: String, groupName: String) = format(
"""#!/bin/sh
private[natpackplugin] def postInstContent(nameAndVersion: String, normalizedName: String, userName: String, groupName: String) = format(
"""#!/bin/sh
# postinst script for %1$s
#
# see: dh_installdeb(1)
Expand All @@ -45,23 +45,25 @@ set -e
case "$1" in
configure)

if ! getent group | grep -q "%3$s"; then
addgroup "%3$s"
if ! getent group | grep -q "%4$s"; then
addgroup "%4$s"
fi

if ! id "%2$s" > /dev/null 2>&1 ; then
adduser --system --home "/var/lib/%1$s" --no-create-home \
--ingroup "%3$s" --disabled-password --shell /bin/bash \
"%2$s"
if ! id "%3$s" > /dev/null 2>&1 ; then
adduser --system --disabled-login --shell /bin/false --no-create-home \
--ingroup "%4$s" --disabled-password "%3$s"
fi

mkdir -p "/var/log/%1$s"
mkdir -p "/var/log/%2$s"

# Create symlink with normalized name
ln -s "/usr/share/%1$s" "/usr/share/%2$s"

# directories needed for jenkins
# we don't do -R because it can take a long time on big installation
chown "%2$s:%3$s" "/var/lib/%1$s" "/var/log/%1$s"
chown "%3$s:%4$s" "/usr/share/%1$s" "/var/log/%2$s"
# we don't do "chmod 750" so that the user can choose the pemission for g and o on their own
chmod u+rwx "/var/lib/%1$s" "/var/log/%1$s"
chmod u+rwx "/usr/share/%1$s" "/var/log/%2$s"
;;

abort-upgrade|abort-remove|abort-deconfigure)
Expand All @@ -76,24 +78,24 @@ esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.

if [ -x "/etc/init.d/%1$s" ]; then
update-rc.d "%1$s" defaults >/dev/null
invoke-rc.d "%1$s" start || exit $?
if [ -x "/etc/init.d/%2$s" ]; then
update-rc.d "%2$s" defaults >/dev/null
invoke-rc.d "%2$s" start || exit $?
fi

exit 0
""", name, userName, groupName)
""", nameAndVersion, normalizedName, userName, groupName)

private[natpackplugin] def postRmContent(name: String, userName: String) = format(
"""#!/bin/sh
private[natpackplugin] def postRmContent(nameAndVersion: String, normalizedName: String, userName: String) = format(
"""#!/bin/sh

set -e

case "$1" in
purge)
userdel "%2$s" || true
rm -rf "/var/lib/%1$s" "/var/log/%1$s" \
"/var/run/%1$s"
userdel "%3$s" || true
rm -rf "/usr/share/%1$s" "/usr/share/%2$s" "/var/log/%2$s" \
"/var/run/%2$s"
;;

remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
Expand All @@ -106,31 +108,24 @@ case "$1" in
esac

if [ "$1" = "purge" ] ; then
update-rc.d "%1$s" remove >/dev/null
update-rc.d "%2$s" remove >/dev/null
fi

exit 0
""", name, userName)
""", nameAndVersion, normalizedName, userName)

// Script to run before removing the package. (stops the service)
private[natpackplugin] def preRmContent(initName: String) = format(
"""#!/bin/sh
"""#!/bin/sh
set -e
if [ -x "/etc/init.d/%1$s" ]; then
invoke-rc.d "%1$s" stop || exit $?
fi
""", initName)

//local Play start file
private[natpackplugin] def startFileContent(config: String) = format(
"""#!/usr/bin/env sh

exec java $* -cp "`dirname $0`/lib/*" %s play.core.server.NettyServer `dirname $0` $@
""", if (config.isEmpty()) "" else "-Dconfig.file=`dirname $0`/application.conf")

// /etc/init.d init script
private[natpackplugin] def initFilecontent(id: String, desc: String, user: String) = format(
"""#!/bin/bash
"""#!/bin/bash
# "/etc/init.d/%1$s"
# debian-compatible %1$s startup script.
# Original version by: Amelia A Lewis <[email protected]>
Expand Down Expand Up @@ -236,7 +231,7 @@ do_start()

# --user in daemon doesn't prepare environment variables like HOME, USER, LOGNAME or USERNAME,
# so we let su do so for us now
$SU -l $USER --shell=/bin/bash -c "$DAEMON $DAEMON_ARGS -- /var/lib/%1$s/start $PLAY_ARGS" || return 2
$SU -l $USER --shell=/bin/bash -c "$DAEMON $DAEMON_ARGS -- /usr/bin/%1$s $PLAY_ARGS" || return 2
}


Expand Down Expand Up @@ -379,7 +374,7 @@ exit 0
private[natpackplugin] def chmod(file: File, perms: String): Unit =
Process(Seq("chmod", perms, file.getAbsolutePath)).! match {
case 0 ⇒ ()
case n ⇒ sys.error("Error running chmod %s %s" format(perms, file))
case n ⇒ sys.error("Error running chmod %s %s" format (perms, file))
}

private[natpackplugin] def debFile(name: String, content: => String)(dir: File) = {
Expand All @@ -398,4 +393,7 @@ exit 0
private[natpackplugin] def debFile3[T, U, V](name: String, content: (T, U, V) => String)(dir: File, t: T, u: U, v: V) =
debFile(name, content(t, u, v))(dir)

private[natpackplugin] def debFile4[T, U, V, W](name: String, content: (T, U, V, W) => String)(dir: File, t: T, u: U, v: V, w: W) =
debFile(name, content(t, u, v, w))(dir)

}