Creating Debian Packages
This document describes the decisions made in packaging and descrbes the steps taken.
For the purpose of this discussion, we'll consider the build directory to be at ~/build.
Bazaar
$ sudo aptitude install bzr
If you are creating a new project, then make a directory for the project and put it under version control. For example:
$ bzr init ihris-qualify-debian
Since you are probably dealing with code already under version control, you can just check it out. For example, to check out the my build scripts for the i2ce project from Launchpad:
$ bzr co lp:~hexmode/i2ce/debian-dev i2ce-debian $ ls i2ce-debian
bzr-builddeb
$ sudo aptitude install bzr-builddeb
The build scripts are kept separate repository and kept under version control. To enable this (and keep the number of revision control systems in use to a minimum), I use bzr-builddeb to build packages directly from the bzr repository.
This package generation tool can keep the debian directory under revision control. If you look at my debian repositories, you'll see that the repositories are the contents of the debian directory. During the build process, bzr-builddeb merges the directory with the pristine source tree and performs all build operations there.
bzr-builddeb uses several configuration files to control its operation. The only one we're concerned with here is the default.conf file under the .bzr-builddeb directory. This stores the defaults for this package. The contents of ~/build/i2ce-debian/.bzr-debbuild/default.conf:
[BUILDDEB] merge = True export-upstream = http://bazaar.launchpad.net/%7Eintrahealth%2Binformatics/i2ce/main/
The first line just confirms that this is a bzr-builddeb configuration package.
The second line (merge = True) tells bzr-builddeb to merge this directory (in this case, ~/build/i2ce-debian with the the upstream source.
The third line (export-upstream = …) gives the location of the original source in Bazaar to check out.
Running bzr builddeb from within the i2ce-debian directory will create a ~/build/build-area/i2ce-2.0 directory, check out the code from Launchpad, put the contents of the current directory in the debian subdirectory, and build the package. After the package is built, the ~/build/build-area/i2ce-2.0 directory will be removed.
dpatch
dpatch is a patch management system that I used to alter the pristine configuration files so that they would work in the Debian packages.
Patches are stored in the patches sub-directory and are applied in the order listed in the 00list file in that directory.
To apply all the patches, the command dpatch apply-all is executed. To remove all patches (i.e. in a “clean” operation), use the command dpatch deapply-all. To create a new patch, see “Creating dpatch scriptlets” in the dpatch man page.
dbconfig-common
dbconfig-common is used to set up the database structure for the i2ce. If there is any need to provide initial database data for other packages, this package should be used to handle the installation.
To setup a database, two things must be done. First, the database data must be provided. Second, the dbconfig-common post-installation hooks must be called.
The SQL data is provided during the package building process by putting an SQL file at /usr/share/dbconfig-common/data/package/install/mysql. PostgreSQL setup can be done in a similar way.
Important: Since dbconfig-common creates a database as well as a user for the application, do not perform these steps in your database setup.
In the post-installation script, a few environment variables are set to tell dbconfig-common where to place the templates it produces and then the dbconfig-common hooks are called. These hooks take care of collecting and assigning passords; creating the user and database for the application; and loading the data into the database.
ucf
Configuration files are managed with ucf (Update Configuration File).
This tool provides a way to udate configuration files so that user's changes are preserved. ucf is called from the post-installation scripts to copy over a new configuration file. If changes are detected that cannot easily be merged, the administrator performing the installtion will be prompted to confirm the update.
In the iHRIS packages, files managed with ucf are /etc/i2ce/I2CE_config.inc.php, /etc/i2ce/ihris_config.inc.php, /etc/apache2/conf.d/ihris-manage.conf, and the like.
Files and Directories in the Debian directory
The debian directories under Bazaar contain several identically named files. Here I describe the purpose of each file. To learn more about the process of creating a Debian package, see the Debian New Maintainers' Guide
.bzr
Bazaar stores all information about files under version control in this directory. I won't bother talking about the specifics of what is in here since it isn't related to the build process. Just don't delete it if you plan to use bzr-builddeb
.bzr-builddeb/default.conf
The contents of this file were explained in the [#bzr-builddeb bzr-builddeb] section.
rules
This is a makefile that controls the creating of a package. It has five mandatory targets (clean, binary, binary-arch, binary-indep, and build).
Since we're using dpatch, I've added patch and unpatch targets that build and clean depend on.
patch: patch-stamp patch-stamp: dpatch apply-all -v dpatch cat-all > patch-stamp unpatch: dpatch deapply-all rm -rf patch-stamp debian/patched
PHP-based packages don't really need that much “build” effort, so most of the action happens in the install target (used by the mandatory binary target) where files are re-arranged into something resembling the Filesystem Hierarchy Standard (fhs). As of this writing, for example, the i2ce package contains the following instructions:
install -d -m 755 -o root -g admin $(DESTDIR)/usr/share/ihris install -d -m 755 -o root -g admin $(DESTDIR)/usr/share/ihris/lib install -d -m 755 -o root -g admin $(DESTDIR)/etc/$(PACKAGE) install -d -m 755 -o root -g admin $(SQL_DIR) install -m 444 -o root -g admin \ lib/*.php $(DESTDIR)/usr/share/ihris/lib install -m 444 -o root -g admin I2CE_config.inc.php \ $(DESTDIR)/usr/share/ihris/ install -m 444 -o root -g admin I2CE_structure.sql $(SQL_DIR)/mysql;
changelog
This is just a description of the changes to the package itself. Since it has a very specific format, use dch or Emacs' debian-changelog-mode to create new entries.
compat
(I'm not sure what this is. I believe it contains the version number the build scripts look at to make sure they build the package properly.)
control
The packages that can be produces from this debian directory as well as the description, architecture, build-dependencies and install-dependencies are listed in the file.
For example, the control file for i2ce looks like this:
Source: i2ce Section: web Priority: extra Maintainer: Mark A. Hershberger <mhershberger@intrahealth.org> Build-Depends: debhelper (>= 5), dpatch Standards-Version: 3.7.2 Package: i2ce Architecture: all Pre-Depends: ucf Depends: ${shlibs:Depends}, ${misc:Depends}, php-i18nv2, php-mdb2-driver-mysql, php-text-password, dbconfig-common Description: database-driven software for forms IntraHealth Informatics Core Engine (I2CE) is a set of classes for handling database-driven HTML forms with templates and database abstraction. It is the core programming engine for the iHRIS Suite of software.
The first stanza describes the source package and build depends. Items like Section and Maintainer will be applied to the later binary package stanza's.
Since each of the packages (at present) creates only one debian package, there is only a single Package stanza. If a source tree can produce multiple packages, then more stanzas will be placed here. Of course, the packaging becomes more complex, but since the IntraHealth packages don't use this, I've not covered it here.
copyright
Every Debian package must contain a copyright file so that users can easily find the license on the package. Since we're using the GPLv3, we can just make a reference to it. For an example of a more complex copyright file, see virtualbox-ose's copyright file in Ubuntu.
patches
The patches directory contains the patches for dpatch. The contents are described in the [#dpatch dpatch] section above.
config
This is a script that is included in the binary package and executed to take care of the configuration step of package installation. The only IntraHealth package that includes a config script is the i2ce package. i2ce uses this script to call the configuration hooks for dbcommon-config.
postinst
This script is included in the binary package and executed after the files from the package have been put in place. Any final setup takes place here. For example, i2ce uses this script to set some environment variables and then call the dbconfig-common postinst hooks:
dbc_generate_include=php:/etc/i2ce/i2ce.php.inc dbc_generate_include_owner=www-data dbc_generate_include_perms=0400 dbc_dbtypes=mysql . /usr/share/debconf/confmodule . /usr/share/dbconfig-common/dpkg/postinst dbc_go i2ce $@
Any files that are under the control of ucf ([#ucf see above]) are handled here. i2ce installs its configuration file here:
ucf /usr/share/ihris/I2CE_config.inc.php /etc/i2ce/I2CE_config.inc.php
postrm
postrm is executed after the package has been removed. In the case of i2ce, dbconfig-common recommends deleting the files it generates during removal.
README.Debian
This contains any notes the packager may wish to include. Don't just copy a README file as the packaging usually includes this.