16.2. Debian packaging#
This chapter describes how software for Univention Corporate Server is packaged in the Debian format. It allows proper dependency handling and guarantees proper tracking of file ownership. Customers can package their own internal software or use the package mechanism to distribute configuration files consistently to different machines.
Software is packaged as a source package, from which one or more binary packages can be created. This is useful to create different packages from the same source package. For example the Samba source package creates multiple binary packages:
one containing the file server
one containing the client commands to access the server
and several other packages containing documentation, libraries, and common files shared between those packages
The directory should be named package_name-version
.
16.2.1. Prerequisites and preparation#
Some packages are required for creating and building packages.
- build-essential
This meta package depends on several other packages like compilers and tools to extract and build source packages. Packages must not declare an explicit dependency on this and its dependent packages.
- devscripts
This package contains additional scripts to modify source package files like for example
debian/changelog
.- dh-make
This program helps to create an initial
debian/
directory, which can be used as a starting point for packaging new software.
These packages must be installed on the development system. If not, missing packages can be installed on the command line using univention-install or through UMC, which is described in the Univention Corporate Server - Manual for users and administrators [2].
16.2.2. dh_make#
dh_make is a tool, which helps creating the initial debian/
directory. It is interactive by default and asks several questions about the
package to be created.
Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch?
[s/i/m/l/k/n]
- s, single binary
A single architecture specific binary package is created from the source package. This is for software which needs to be compiled individually for different CPU architectures like
i386
andamd64
.- i, indep binary
A single architecture-independent binary package is created from the source package. This is for software which runs unmodified on all CPU architectures.
- m, multiple binary
Multiple binary packages are created from the source package, which can be both architecture independent and dependent.
- l, library
Two or more binary packages are created for a compiled library package. The runtime package consists of the shared object file, which is required for running programs using that library. The development package contains the header files and other files, which are only needed when compiling and linking programs on a development system.
- k, kernel module
A single kernel-dependent binary package is created from the source package. Kernel modules need to be compiled for each kernel flavor. dkms should probably be used instead. This type of packages is not described in this manual.
- n, kernel patch
A single kernel-independent package is created from the source package, which contains a patch to be applied against an unpacked Linux kernel source tree. dkms should probably be used instead. This type of packages is not described in this manual.
In Debian, a package normally consists of an upstream software archive, which is
provided by a third party like the Samba team. This collection is extended by a
Debian specific second TAR archive or a patch file, which adds the
debian/
directory and might also modify upstream files for better
integration into a Debian system.
When a source package is built, dpkg-source.1 separates the files
belonging to the packaging process from files belonging to the upstream package.
For this to work, dpkg-source needs the original source either
provided as a TAR archive or a separate directory containing the unpacked
source. If neither of these is found and --native
is not given,
dh_make prints the following warning:
Could not find my-package_1.0.orig.tar.gz
Either specify an alternate file to use with -f,
or add --createorig to create one.
The warning from dh_make states that no pristine upstream archive was
found, which prohibits the creation of the Debian specific patch, since the
Debian packaging tools have no way to separate upstream files from files
specific to Debian packaging. The option --createorig
can be passed to
dh_make to create a .orig.tar.gz
archive before creating the
debian/
directory, if such separation is required.
16.2.3. Debian control files#
The control files in the debian/
directory control the package
creation process. The following sections provide a short description of
these files. A more detailed description is available in the
The Debian GNU/Linux FAQ - Basics of the Debian package management system [4].
Several files will have the .ex
suffix, which mark them as examples. To
activate these files, they must be renamed by stripping this suffix. Otherwise,
the files should be deleted to not clutter up the directory by unused files. In
case a file was deleted and needs to be restored, the original templates can be
found in the /usr/share/debhelper/dh_make/debian/
directory.
The debian/
directory contains some global configuration files, which
can be put into two categories: The files changelog
, control
,
copyright
, rules
are required and control the build process of
all binary packages. Most other files are optional and only affect a single
binary package. Their filename is prefixed with the name of the binary package.
If only a single binary package is build from the source package, this prefix
can be skipped, but it is good practice to always use the prefix.
The following files are required:
changelog
Changes related to packaging, not the upstream package. See debian/changelog below for more information.
compat
The Debhelper tools support different compatibility levels. For UCS-3.x the file must contain a single line with the value
7
. See debhelper.7 for more details.control
Contains control information about the source and all its binary packages. This mostly includes package name and dependency information. See debian/control below for more information.
copyright
This file contains the copyright and license information for all files contained in the package. See debian/copyright below for more information.
rules
This is a
Makefile
style file, which controls the package build process. See debian/rules below for more information.source/format
This file configures how dpkg-source.1 separates the files belonging to the packaging process from files belonging to the upstream package. Historically, the Debian source format
1.0
shipped packages as a TAR file containing the upstream source plus one patch file, which contained all files of thedebian/
sub-directory in addition to all changes to upstream files.The new format
3.0 (quilt)
replaces the patch file with a second TAR archive containing thedebian/
directory. Changes to upstream files are no longer applied as one giant patch, but split into logical changes and applied using a built-in quilt.1.For simple packages, where there is no distinction between upstream and the packaging entity, the
3.0 (native)
format can be used instead, were all files including thedebian/
directory are contained in a single TAR file.
The following files are optional and should be deleted if unused, which helps other developers to concentrate on only the files relevant to the packaging process:
README.Debian
Notes regarding package specific changes and differences to default options, for example compiler options. Will be installed into
/usr/share/doc/package_name/README.Debian
.package.cron.d
Cron tab entries to be installed. See dh_installcron.1 for more details.
package.dirs
List of extra directories to be created. See dh_installdirs.1 for more details. May other dh_ tools automatically create directories themselves, so in most cases this file is unneeded.
package.install
List of files and directories to be copied into the package. This is normally used to partition all files to be installed into separate packages, but can also be used to install arbitrary files into packages. See dh_install.1 for more details.
package.docs
List of documentation files to be installed in
/usr/share/doc/package/
. See dh_installdocs.1 for more details.package.emacsen-install
;package.emacsen-remove
;package.emacsen-startup
Emacs specific files to be installed below
/usr/share/emacs-common/package/
. See dh_installemacsen.1 for more details.package.doc-base*
Control files to install and register extended HTML and PDF documentation. See dh_installdocs.1 for more details.
package.init.d
;package.default
Start-/stop script to manage a system daemon or service. See dh_installinit.1 for more details.
package.manpage.1
;package.manpage.sgml
Manual page for programs, library functions or file formats, either directly in troff or SGML. See dh_installman.1 for more details.
package.menu
Control file to register programs with the Debian menu system. See dh_installmenu.1 for more details.
watch
Control file to specify the download location of this upstream package. This can be used to check for new software versions. See uscan.1 for more details.
package.preinst
;package.postinst
;package.prerm
;package.postrm
Scripts to be executed before and after package installation and removal. See debian/preinst, debian/prerm, debian/postinst, debian/postrm below for more information.
package.maintscript
Control file to simplify the handling of configuration files. See dpkg-maintscript-helper.1 and dh_installdeb.1 for more information.
Other debhelper programs use additional files, which are described in the respective manual pages.
16.2.3.1. debian/control
#
The control
file contains information about the packages and their
dependencies, which are needed by dpkg. The initial control
file created by dh_make looks like this:
Source: testdeb
Section: unknown
Priority: optional
Maintainer: John Doe <user@example.com>
Build-Depends: debhelper (>= 5.0.0)
Standards-Version: 3.7.2
Package: testdeb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description>
<insert long description, indented with spaces>
The first block beginning with Source
describes the source package:
Source
The name of the source package. Must be consistent with the directory name of the package and the information in the
changelog
file.- Section
A category name, which is used to group packages. There are many predefined categories like
libs
,editors
,mail
, but any other string can be used to define a custom group.- Priority
Defines the priority of the package. This information is only used by some tools to create installation DVD. More important packages are put on earlier CD, while less important packages are put on later CD.
essential
Packages are installed by default and dpkg prevents the user from easily removing it.
required
Packages which are necessary for the proper functioning of the system. The package is part of the base installation.
important
Important programs, including those which one would expect to find on any Unix-like system. The package is part of the base installation.
standard
These packages provide a reasonably small but not too limited character-mode system.
optional
Package is not installed by default. This level is recommended for most packages.
extra
This contains all packages that conflict with some other packages.
Maintainer
The name and email address of a person or group responsible for the packaging.
Build-Depends
;Build-Depends-Indep
A list of packages which are required for building the package.
Standards-version
Specifies the Debian Packaging Standards version, which this package is conforming to. This is not used by UCS, but required by Debian.
All further blocks beginning with Package
describes a binary package. For
each binary package one block is required.
Package
The name of the binary package. The name must only consist of lower case letters, digits and dashes. If only a single binary package is built from a source package, the name is usually the same as the source package name.
Architecture
Basically there are two types of packages:
Architecture dependent packages must be build for each architecture like
i386
andamd64
, since binaries created on one architecture do not run on other architectures. A list of architectures can be explicitly given, orany
can be used, which is then automatically replaced by the architecture of the system where the package is built.Architecture independent packages only need to be built once, but can be installed on all architectures. Examples are documentation, scripts and graphics files. They are declared using
all
in the architecture field.
Description
The first line should contain a short description of up to 60 characters, which should describe the purpose of the package sufficiently. A longer description can be given after that, where each line is indented by a single space. An empty line can be inserted by putting a single dot after the leading space.
Most packages are not self-contained but need other packages for proper function. Debian supports different kinds of dependencies.
Depends
A essential dependency on some other packages, which must be already installed and configured before this package is configured.
Recommends
A strong dependency on some other packages, which should normally be co-installed with this package, but can be removed. This is useful for additional software like plug-ins, which extends the functionality of this package, but is not strictly required.
Suggests
A soft dependency on some other packages, which are not installed by default. This is useful for additional software like large add-on packages and documentation, which extends the functionality of this package, but is not strictly required.
Pre-Depends
A strong dependency on some other package, which must be fully operational even before this package is unpacked. This kind of dependency should be used very sparsely. It’s mostly only required for software called from the
.preinst
script.Conflicts
A negative dependency, which prevents the package to be installed while the other package is already installed. This should be used for packages, which contain the same files or use the same resources, for example TCP port numbers.
Provides
This package declares, that it provides the functionality of some other package and can be considered as a replacement for that package.
Replaces
A declaration, that this package overwrites the files contained in some other package. This deactivates the check normally done by dpkg to prevent packages from overwriting files belonging to some other package.
Breaks
A negative dependency, which requests the other package to be upgraded before this package can be installed. This is a lesser form of
Conflicts
.Breaks
is almost always used with a version specification in the formBreaks: package (<< version)
: This forcespackage
to be upgraded to a version greater thanversion
before this package is installed.
In addition to literal package names, debhelper supports a substitution mechanism: Several helper scripts are capable of automatically detecting dependencies, which are stored in variables.
${shlibs:Depends}
dh_shlibdeps automatically determines the shared library used by the programs and libraries of the package and stores the package names providing them in this variable.
${python3:Depends}
dh_python detects similar dependencies for Python modules.
${misc:Depends}
Several Debhelper commands automatically add additional dependencies, which are stored in this variable.
In addition to specifying a single package as a dependency, multiple packages
can be separated by using the pipe symbol (|
). At least one of those
packages must be installed to satisfy the dependency. If none of them is
installed, the first package is chosen as the default.
A package name can be followed by a version constraint enclosed in parenthesis. The following operators are valid:
<<
is less than
<=
is less than or equal to
=
is equal to
>=
is greater than or equal to
>>
is greater than
For example:
Depends: libexample1 (>= ${binary:Version}),
exim4 | mail-transport-agent,
${shlibs:Depends}, ${misc:Depends}
Conflicts: libgg0, libggi1
Recommends: libncurses5 (>> 5.3)
Suggests: libgii0-target-x (= 1:0.8.5-2)
Replaces: vim-python (<< 6.0), vim-tcl (<= 6.0)
Provides: www-browser, news-reader
16.2.3.2. debian/copyright
#
The copyright
file contains copyright and license information. For a
downloaded source package it should include the download location and names of
upstream authors.
This package was debianized by John Doe <max@example.com> on
Mon, 21 Mar 2009 13:46:39 +0100.
It was downloaded from <fill in ftp site>
Copyright:
Upstream Author(s): <put author(s) name and email here>
License:
<Must follow here>
The file does not require any specific format. Debian recommends to use a machine-readable format, but this is not required for UCS. The format is described in Machine-readable debian/copyright file at looks like this:
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Univention GmbH
Upstream-Contact: <package>@univention.de>
Source: https://docs.software-univention.de/
Files: *
Copyright: 2013-2023 Univention GmbH
License: AGPL
16.2.3.3. debian/changelog
#
The changelog
file documents the changes applied to this Debian package.
The initial file created by dh_make only contains a single entry and
looks like this:
testdeb (0.1-1) unstable; urgency=low
* Initial Release.
-- John Doe <user@example.com> Mon, 21 Mar 2013 13:46:39 +0100
For each new package release a new entry must be prepended before all previous entries. The version number needs to be incremented and a descriptive text should be added to describe the change.
The command debchange from the devscripts package can be
used for editing the changelog
file. For example the following command
adds a new version:
dch -i
After that the changelog
file should look like this:
testdeb (0.1-2) unstable; urgency=low
* Add more details.
-- John Doe <user@example.com> Mon, 21 Mar 2013 17:55:47 +0100
testdeb (0.1-1) unstable; urgency=low
* Initial Release.
-- John Doe <user@example.com> Mon, 21 Mar 2013 13:46:39 +0100
The date and timestamp must follow the format described in RFC 2822. debchange automatically inserts and updates the current date. Alternatively date -R can be used on the command line to create the correct format.
For UCS it is best practice to mention the bug ID of the UCS bug tracker (see Bug reporting) to reference additional details of the bug fixed. Other parties are encouraged to devise similar comments, for example URLs to other bug tracking systems.
16.2.3.4. debian/rules
#
The file rules
describes the commands needed to build the package. It
must use the Make syntax The GNU Make manual [5]. It consists of several
rules, which have the following structure:
target: dependencies
command
...
Each rule starts with the target name, which can be a filename or symbolic name. Debian requires the following targets:
clean
This rule must remove all temporary files created during package build and must return the state of all files back to the same state as when the package is freshly extracted.
build
;build-arch
;build-indep
These rules should configure the package and build either all, all architecture dependent or all architecture independent files.
These rules are called without root permissions.
binary
;binary-arch
;binary-indep
These rules should install the package into a temporary staging area. By default this is the directory
debian/tmp/
below the source package root directory. From there files are distributed to individual packages, which are created as the result of these rules.These rules are called with root permissions.
Each command line must be indented with one tabulator character. Each command is
executed in a separate shell, but long command lines can be split over
consecutive lines by terminating each line with a backslash (\
).
Each rule describes a dependency between the target and its dependencies.
make considers a target to be out-of-date, when a file with that name
target
does not exists or when the file is older than one of the files
it depends on. In that case make invokes the given commands to
re-create the target.
In addition to filenames also any other word can be used for target names and in
dependencies. This is most often used to define phony targets, which can be
given on the command line invocation to trigger some tasks. The above mentioned
clean
, build
and binary
targets are examples for that kind of
targets.
dh_make only creates a template for the rules
file. The
initial content looks like this:
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
Since UCS-3.0 the debian/rules
file is greatly simplified by using the
dh sequencer. It is a wrapper around all the different
debhelper tools, which are automatically called in the right order.
Tip
To exactly see which commands are executed when dpkg-buildpackage
builds a package, invoke dh target --no-act
by hand, for example
dh binary --no-act lists all commands to configure, build, install
and create the package.
In most cases it’s sufficient to just provide additional configuration files for
the individual debhelper commands as described in Debian control files.
If this is not sufficient, any debhelper command can be individually
overridden by adding an override target to the rules
file.
For example the following snippet disables the automatic detection of the build system used to build the package and passes additional options:
override_dh_auto_configure:
./setup --prefix=/usr --with-option-foo
Without that explicit override dh_auto_configure would be called,
which normally automatically detects several build systems like
cmake, setup.py, autoconf and others. For these
dh also passes the right options to configure the default prefix
/usr
and use the right compiler flags.
After configuration the package is built and installed to the temporary staging
area in debian/tmp/
. From there dh_install partitions
individual files and directories to binary packages. This is controlled through
the debian/package.install
files.
This file can also be used for simple packages, where no build system is used.
If a path given in the debian/package.install
file is not found below
debian/tmp/
, the path is interpreted as relative to the source package
root directory. This mechanism is sufficient to install simple files, but fails
when files must be renamed or file permissions must be modified.
16.2.3.5. debian/preinst
, debian/prerm
, debian/postinst
, debian/postrm
#
In addition to distributing only files, packages can also be used to run arbitrary commands on installation, upgrades or removal. This is handled by the four Maintainer scripts, which are called before and after files are unpacked or removed:
debian/package.preinst
called before files are unpacked.
debian/package.postinst
called after files are unpacked. Mostly used to (re-)start services after package installation or upgrades.
debian/package.prerm
called before files are removed. Mostly used to stop services before a package is removed or upgraded.
debian/package.postrm
called after files have been removed.
The scripts themselves must be shell scripts, which should contain a
#DEBHELPER#
marker, where the shell script fragments created by the
dh_ programs are inserted. Each script is invoked with several
parameters, from which the script can determine, if the package is freshly
installed, upgraded from a previous version, or removed. The exact arguments are
described in the template files generated by dh_make.
The maintainer scripts can be called multiple times, especially when errors occur. Because of that the scripts should be idempotent, that is they should be written to achieve a consistent state instead of blindly doing the same sequence of commands again and again.
A bad example would be to append some lines to a file on each invocation. The right approach would be to add a check, if that line was already added and only do it otherwise.
Warning
Make sure to handle package upgrades and removal correctly: Both tasks
will invoke any existing scripts prerm
and postrm
, but with
different parameters remove
and upgrade
only.
It is important that all these scripts handle error conditions properly: Maintainer scripts should exit with exit 0 on success and exit 1 on fail, if things go catastrophically wrong.
On the other hand, an exit code unequal to zero usually aborts any package installation, upgrade or removal process. This prevents any automatic package maintenance and usually requires manual intervention of a human administrator. Therefore, it is essential that maintainer scripts handle error conditions properly and are able to recover an inconsistent state.
16.2.4. Building#
Before the first build is started, remove all unused files from the
debian/
directory. This simplifies maintenance of the package and helps
other maintainers to concentrate on only the relevant differences from standard
packages.
The build process is started by invoking the following command:
$ dpkg-buildpackage -us -uc
The options -us
and -uc
disable the PGP signing process of the source
and changes files. This is only needed for Debian packages, were all files must
be cryptographically signed to be uploaded to the Debian infrastructure.
Additionally, the option -b
can be added to restrict the build process to
only build the binary packages. Otherwise a source package will also be created.