Debian Plugin¶
The debian package specification is very robust and powerful. If you wish to do any advanced features, it’s best to understand how the underlying packaging system works. Debian Binary Package Building HOWTO by Chr. Clemens Lee is an excellent tutorial.
SBT Native Packager provides two ways to build debian packages:
- A native implementation, where you need
dpkg-deb
installed, or - A java, platform independent approach with jdeb.
By default the native implementation is activated.
Note
The debian plugin depends on the Linux Plugin.
Requirements¶
If you use the native debian package implementation you need the following applications installed:
- dpkg-deb
- dpkg-sig
- dpkg-genchanges
- lintian
- fakeroot
Build¶
sbt debian:packageBin
Required Settings¶
A debian package needs some mandatory settings to be valid. Make sure you have these settings in your build:
name := "Debian Example"
version := "1.0"
maintainer := "Max Smith <max.smith@yourcompany.io>"
packageSummary := "Hello World Debian Package"
packageDescription := """A fun package description of our software,
with multiple lines."""
It’s not exactly mandatory, but still highly recommended to add relevant JRE dependency, for example:
debianPackageDependencies := Seq("java8-runtime-headless")
Enable the debian plugin to activate the native package implementation.
enablePlugins(DebianPlugin)
JRE Dependencies¶
By default, a Debian package would have no dependencies, even for the Java Runtime Environment (JRE). A startup script will seek JRE in several popular locations, and, JRE is not found, the following message would be displayed:
No java installations was detected.
Please go to http://www.java.com/getjava/ and download
To build a Debian package that integrates properly with Debian
repository environment, i.e. depends on a package that provides JRE,
one needs to specify JRE dependency using
debianPackageDependencies
. Debian (Ubuntu and compatible
distributions as well) provides two families of virtual packages to do
that:
javaN-runtime
- Regular (full) JRE packages, with GUI support. Use this for applications requiring AWT/Swing support, OpenGL, sound, etc.
javaN-runtime-headless
- Minimal JRE packages without GUI support, useful for server installation to avoid pulling large set of X.org-related packages. Use this for console-only applications, services, networked / web applications, etc.
N
in javaN
should be replaced with minimal JRE version
required by the packaged application. It usually depends on a Scala
version used:
- Scala 2.11.x or earlier requires Java 6
- Scala 2.12.x requires Java 8
Note that these are virtual packages, which are provided by a set of
real packages. This means, for example, while installing a .deb
package that depends on java6-runtime-headless
:
- If end-user has no suitable JRE installed, it would automatically
pull and install some “sane default” package which provides thing
functionality (typically, it would be
openjdk-8-jre-headless
). - If end-user does not like default suggested JRE for some reason, it’s possible to install any alternative implementation.
- If end-user has some existing JRE installation that is sufficient to
play that role (for example,
openjdk-9-jre
, which provides, along others,java8-runtime-headless
too), it would be used.
This dependency works equally well with both free/libre OpenJDK packages supplied by Debian, and non-free JDKs supplied by Oracle and packaged as .deb using make-jpkg utility from Debian’s java-package.
Native packaging¶
Since JARs are by default already compressed, DebianPlugin disables additional compression of the debian package contents.
To compress the debian package, override debianNativeBuildOptions with options for dpkg-deb.
debianNativeBuildOptions in Debian := Nil // dpkg-deb's default compression (currently xz)
debianNativeBuildOptions in Debian := Seq("-Zgzip", "-z3") // gzip compression at level 3
Note that commit cee091c released in 1.1.1 disables package re-compression by default. While this works great with tools such as apt and dpkg, un-compressed package installation is bugged in python-apt 8.8 series. This bug prevents installation of the generated debian package in the following configuration:
- installation using python-apt module, used by Ansible and SaltStack for example,
- being on python-apt 8.8 series that’s on Debian Wheezy and perhaps older
It will fail with an error message like:
E: This is not a valid DEB archive, it has no 'data.tar.gz', 'data.tar.bz2' or 'data.tar.lzma' member
Solutions include:
- upgrading to Debian Jessie,
- upgrading python-apt, note that no official backport is known
- re-enabling package re-compression in sbt-native-packager, by overridding debianNativeBuildOptions as described above.
Java based packaging¶
If you want to use the java based implementation, enable the following plugin:
enablePlugins(JDebPackaging)
and this to your plugins.sbt
:
libraryDependencies += "org.vafer" % "jdeb" % "1.3" artifacts (Artifact("jdeb", "jar", "jar"))
JDeb is a provided dependency. You have to explicitly add it on your own. It brings a lot of dependencies that could slow your build times. This is the reason the dependency is marked as provided.
Configurations¶
Settings and Tasks inherited from parent plugins can be scoped with Debian
.
linuxPackageMappings in Debian := linuxPackageMappings.value
Settings¶
Debian requires the following specific settings:
name in Debian
- The name of the package for debian (if different from general linux name).
version in Debian
- The debian-friendly version of the package. Should be of the form
x.y.z-build-aa
.debianPackageConflicts in Debian
- The list of debian packages that this package conflicts with.
debianPackageDependencies in Debian
- The list of debian packages that this package depends on.
debianPackageProvides in Debian
- The list of debian packages that are provided by this package.
debianPackageRecommends in Debian
- The list of debian packages that are recommended to be installed with this package.
linuxPackageMappings in Debian
- Debian requires a
/usr/share/doc/{package name}/changelog.gz
file that describes the version changes in this package. These should be appended to the base linux versions.maintainerScripts in Debian
(debianMaintainerScripts
)- DEPRECATED use
maintainerScripts in Debian
instead. These are the packaging scripts themselves used bydpkg-deb
to build your debian. These scripts are used when installing/uninstalling a debian, like prerm, postinstall, etc. These scripts are placed in theDEBIAN
file when building. Some of these files can be autogenerated, for example when using a package archetype, like server_application. However, any autogenerated file can be overridden by placing your own files in thesrc/debian/DEBIAN
directory.changelog in Debian
- This is the changelog used by
dpkg-genchanges
to create the .changes file. This will allow you to upload the debian package to a mirror.
Tasks¶
The Debian support grants the following commands:
debian:package-bin
- Generates the
.deb
package for this project.debian:lintian
- Generates the
.deb
file and runs thelintian
command to look for issues in the package. Useful for debugging.debian:gen-changes
- Generates the
.changes
, and therefore the.deb
package for this project.
Customize¶
This section contains examples of how you can customize your debian build.
Customizing Debian Metadata¶
A Debian package provides metadata, which includes dependencies and recommendations. This example adds a dependency on java and recommends a git installation.
debianPackageDependencies in Debian ++= Seq("java2-runtime", "bash (>= 2.05a-11)")
debianPackageRecommends in Debian += "git"
Hook Actions into the Debian Package Lifecycle¶
To hook into the debian package lifecycle (https://wiki.debian.org/MaintainerScripts) you
can add preinst
, postinst
, prerm
and/or postrm
scripts. Just place them into
src/debian/DEBIAN
. Or you can do it programmatically in your build.sbt
. This example adds actions to preinst
and postinst
:
import DebianConstants._
maintainerScripts in Debian := maintainerScriptsAppend((maintainerScripts in Debian).value)(
Preinst -> "echo 'hello, world'",
Postinst -> s"echo 'installed ${(packageName in Debian).value}'"
)
The helper methods can be found in MaintainerScriptHelper Scaladocs.
If you use the JavaServerAppPackaging
there are predefined postinst
and
preinst
files, which start/stop the application on install/remove calls. Existing
maintainer scripts will be extended not overridden.
Use a Different Castle Directory for your Control Scripts¶
Your control scripts are in a different castle.. directory? No problem.
debianControlScriptsDirectory <<= (sourceDirectory) apply (_ / "deb" / "control")