In a Play framework (2.3.x) Java project with sbt-native-packager (0.7.x), how can I create customer specific variants of .deb and .rpm packages?
Binary packages (.deb, .zip) are created with generic settings. Some customers require specialties like daemon user names or log locations according to their specifications. I would like to keep the generic packages and their settings as they are and add e.g. a new configuration with a few overrides so that I would get the variant with activator customer:packageBin
.
What I have tried so far is to create a new SBT configuration which extend
s the Debian
configuration of sbt-native-packager and thus to my limited understanding should inherit its settings and tasks. Then I’d like to be able to set e.g. daemonUser in Customer := "custom"
, but otherwise use the existing Debian settings.
My build.sbt
for a sample Play-Java project (activator new
› play-java
):
import NativePackagerKeys._
name := """play-java"""
version := "1.0-SNAPSHOT"
lazy val Customer = config("customer") extend(Debian)
lazy val root = (project in file("."))
.enablePlugins(PlayJava)
.configs(Customer)
.settings( inConfig(Customer)(packagerSettings) : _*)
scalaVersion := "2.11.1"
libraryDependencies ++= Seq(
javaJdbc,
javaEbean,
cache,
javaWs
)
maintainer := "Me"
packageSummary := "Example project"
packageDescription in Debian := "Longer description"
daemonUser in Customer := "custom-user"
As you can see I can now set e.g. daemonUser in Customer
. In the Play console I can see that it is correctly applied with inspect customer:daemonUser
. I can create a .deb package with activator customer:packageBin
. But the package is almost empty and does not contain the application:
$ dpkg-deb -c target/play-java_1.0-SNAPSHOT_all.deb
drwxr-xr-x root/root 0 2014-10-06 22:08 ./
drwxr-xr-x root/root 0 2014-10-06 22:08 ./usr/
drwxr-xr-x root/root 0 2014-10-06 22:08 ./usr/share/
drwxr-xr-x root/root 0 2014-10-06 22:08 ./usr/share/play-java/
drwxr-xr-x root/root 0 2014-10-06 22:08 ./universal/
drwxr-xr-x root/root 0 2014-10-06 22:08 ./universal/tmp/
drwxr-xr-x root/root 0 2014-10-06 22:08 ./universal/tmp/bin/
-rw-r--r-- root/root 64 2014-10-06 22:08 ./universal/tmp/bin/debianprerm
-rw-r--r-- root/root 137 2014-10-06 22:08 ./universal/tmp/bin/debianpostinst
lrwxrwxrwx root/root 0 2014-10-06 22:08 ./usr/share/play-java/logs -> /var/log/play-java
Are additional configurations per customer the way to go or does it not work the way I imagined?
Is there a different way to achive what I need, e.g. with sub-projects?
I’ve solved my problem with a different approach:
The customer name has to be provided as system property. Inside build.sbt
I have if-then-elses wherever a customer needs a special setting.
build.sbt:
val customer = sys.props.get("customer") getOrElse ""
daemonUser in Linux := {
customer match {
case "customerA" => "custom-user"
case _ => (daemonUser in Linux).value
}
}
Then start the build with activator -Dcustomer=customerA debian:package-bin
.
Advantages:
build.sbt
. The if-then-elses are easy to read and it is clear what is going on.Disadvantages:
I’m happy so far, but if someone comes along with a better idea I’d still like to hear it.