PylonsHQ.

Layout: Fixed-width

Creating a Debian package from your Pylons project

Unknown macro: {metadata-list}
Name Creating a Debian package from your Pylons project
Space Pylons CookBook
Section Deployment
Page Creating a Debian package from your Pylons project
Version 1.0
Status Draft
Reviewed False
Author(s) Christoph Haas
Consider using easy_install

There is some controversy on how to install and maintain Python modules on Debian systems. Naturally on Debian you install software using apt-get because it allows you to install dependent packages automatically and remove them again later. Python provides another way of installing modules called easy_install that intends to provide similar features and conflicts with Debian's package management. While Debian developers prefer the Debian way Python developers seems to prefer using easy_install in a sandbox (that is described at James Gardner's article about sandboxing Pylons installations). This article deals with creating Pylons application the Debian way.

Eggs versus Debian packages

When you want to deploy your Pylons project you typically create an egg file from it that other people can install. This is made easy through the power of easy_install. It installs all necessary files and even downloads packages it needs to run automatically. On Debian systems this approach is problematic though. Debian GNU/Linux is a Linux distribution that has a good software package management system. The package management typically knows about every file in your file system. You can install packages and remove packages without leaving cruft. A package installs other packages it needs to run just like easy_install but has more sophisticated features. The package management cannot work correctly if you install software without telling it. So using easy_install to install Python modules on Debian will quickly lead to chaos on your system. There is a Debian package called "python-pylons". Imagine what happens if you you easy_install to download and install the Pylons package. You would get two installations of Pylons on your system that conflict. You cannot even remove the easy_install'ed software properly because there is not yet such a feature. In the worst case you will need to reinstall your system soon.

A quick comparison...

Debian packages

  • Can be installed from the central Debian repositories
  • "stable" branch: Debian developers provide security patches automatically
  • "unstable" (daily) branch: Debian developers provide up-to-date packages (well, mostly)
  • Can be removed properly
  • Can download and install dependent packages
  • installation is system-wide so security patches will be applied for all applications automatically
  • installation is system-wide so all applications need to use the installed version of a package (different applications must not depend on different versions of the packages being installed)
  • Not all Python packages are up-to-date (or even present) in Debian

easy_install / CheeseShop / eggs

  • Installs Python packages the way they are meant to be installed
  • You get up-to-date packages
  • Dependent packages are downloaded and installed automatically
  • You cannot deinstall a package
  • Debian's package management has no notion of per-user installed Python packages (think: security patches)

Conclusion

As you see there is no perfect solution for this dilemma. But whatever you do you must not mix apt-get installed packages with easy_install installed packages. So your options are:

  • Install only Debian packages and don't ever use easy_install. Not even to install into /usr/local. This is the Debian way. You will then be limited to packages that already in Debian and need to create your own Debian packages for Python software that has not yet been debianized (although that is simpler than it may sound).
  • Ignore the Debian package management system and install all Python packages through easy_install. This is nearly impossible because a lot of system tools require Python and certain Python packages so you cannot avoid using the apt-get system for some packages. This is not really an option.
  • Run Python in a controlled environment (called a "sandbox") so that packages installed through easy_install don't conflict with what apt-get installed. You cannot update a sandbox easily though and every application needs its own sandbox. And your applications need to use the Python installation in the sandbox.

So besides the sandboxing approach I told you at the top there is a way to turn your Pylon project into a proper Debian package that you can install and remove on any Debian system.

Debianize a Pylons project

Packaging crash course

(The complete documentation about creating Debian packages is located at http://www.debian.org/doc/debian-policy/.)

To create a Debian package you can call the debuild tool. It looks up certain information in a subdirectory called "debian/" and creates a Debian package with a ".deb" suffix. To get the necessary tools to create a Debian package please install the _devscripts_ package: *aptitude install devscripts*

These files are important in the debian/ directory:

  • debian/control
    Contains information about dependencies on other Debian packages, the name of the package, the description, the name of the maintainer and to which section it belongs.
  • debian/copyright
    A text file describing the licensing terms of your project.
  • debian/changelog
    Everytime a new Debian package of some software is release the changelog file gets a new entry documenting the changes the package maintainer made. The newest entry in the changelog also sets the version number of the package.
  • debian/docs
    A text file containing a list of documentary files that get installed into /usr/share/doc/$PACKAGE/ later.
  • debian/compat
    A text file containing just one number. This is the version number of the debhelper tools that are used to build the package. Because most Debian packages are built in a similar way the debhelpers are shell tools for everyday tasks like installing init.d scripts, installing documentation or moving files around. Currently we are at version '5'.
  • debian/pycompat
    Python modules in Debian are built in special ways. This version number described the compatibility version which is currently '2'.
  • debian/$PACKAGE.init
    An init.d script that is copied to /etc/init.d/$PACKAGE during installation and that is used to start/stop the Pylons web server.
  • debian/rules
    A program/shell script/Makefile that is run with different arguments to build the actual Debian package. It unpacks the egg, adds certain control information and in the end creates - among other files - a *.deb file.

If everything works you can run "debuild" and create the Debian package. I recommend the options "-uc -us" for most users which skips PGP-signing the package. It is a mandatory process for official Debian packages though so that only registered Debian developers may upload packages into the distribution.

Automatically adding the debian/ directory

To aid in adding these control files I have written a Python script that checks a few marginal conditions (trying to help you fix these issues) and creates a Debian package. If all goes well you can run "debuild -uc -us" afterwards and get your Debian package. The script is available at http://workaround.org/pylons but you should also find a copy attached to this wiki page.

Details on the installed package:

  • the ini file that contains the setting that the system administrator will want to customize is at /etc/default/$PROJECT-production.ini
  • as the /usr/share/doc/$PROJECT/README.Debian states after customizing the ini file you must run "paster setup-app /etc/default/$PROJECT-production.ini"
  • the init.d script is copied to /etc/init.d/$PROJECT and will start the project automatically during system startup
  • the "data" directory points to /var/cache/pylons-$PROJECT (this is where cached pages and session information is stored). This directory is owned by the "www-data" user.
  • the log file is written to /var/log/$PROJECT.log (there is currently no logrotate cleaning up the log - this has still to be done)

Note: while the package is probably suitable for installing it in a production environment it is not suited to be uploaded directly into the Debian distribution. Mainly because it is a so called _native_ package (there is no orig.tar.gz and a patch file but all the project is contained in one .deb file). Consider digging deeper into Debian package maintenance if you like that or contain the debian-mentors mailing list on lists.debian.org.

Kudos

  • Piotr Ozarowski (maintainer of several Pylons-related Debian packages)
  • James Gardner (who documented how to sandbox a Pylons application which also works well on Debian)
  • other people on the pylons-discuss mailing list adding valuable opinions and snippets

Labels

debian debian Delete
deploy deploy Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Mar 17, 2007

    Jon Rosebaugh says:

    Why does the list for Eggs say "You cannot deinstall a package"? It's easy to de...

    Why does the list for Eggs say "You cannot deinstall a package"? It's easy to deinstall a package; type 'easy_install -m SomePackage' and then delete the egg.

    1. Apr 02, 2007

      Christoph Haas says:

      I don't really consider the "-m" switch a clean way. Quote from http://peak.tele...

      I don't really consider the "-m" switch a clean way. Quote from http://peak.telecommunity.com/DevCenter/EasyInstall#uninstalling-packages:

      ---------
      If you want to delete the currently installed version of a package (or all versions of a package), you should first run:

      easy_install -m PackageName

      This will ensure that Python doesn't continue to search for a package you're planning to remove. After you've done this, you can safely delete the .egg files or directories, along with any scripts you wish to remove.
      ---------

      I don't want to search for egg files and directories manually. And when I last tested that I had a lot of clutter in my /usr/local/* that didn't get purged. On Debian when you "purge" something there should be no trace of it any more.

      1. Apr 16, 2007

        Jon Rosebaugh says:

        Maybe it's not a clean way. But it is a way to deinstall a package. The list say...

        Maybe it's not a clean way. But it is a way to deinstall a package. The list says "You cannot deinstall a package". The list, therefore, is incorrect.

        1. Oct 03

          Rich Pixley says:

          -m doesn't remove packages.  It simply prepares packages to be removed....

          -m doesn't remove packages.  It simply prepares packages to be removed.  You still need something else, perhaps just "ls" and "rm" to actually find them and remove them.

          And you still have a problem with any modules which were depending in that module.

          "rm -rf /" will also remove packages.  :).  But most people would probably find that to be an inferior process.

  2. Apr 29, 2008

    Peter says:

    Thanks for taking the time to jot all this down, saved me time which I'm gratefu...

    Thanks for taking the time to jot all this down, saved me time which I'm grateful to use elsewhere.

    Kudos

  3. Feb 04, 2009

    Kevin Baker says:

    Here is my logrotate script. I just dropped it into /etc/logrotate.d/ Note my ...

    Here is my logrotate script.

    I just dropped it into /etc/logrotate.d/

    Note my pylons startup script is at "/etc/init.d/pylons" and my pid file for startup is in "/var/run/paster.pid"

    /var/log/pylons/pylons.log

    Unknown macro: { daily missingok rotate 360 compress delaycompress notifempty create 640 root adm sharedscripts postrotate if [ -f /var/run/paster.pid]; then /etc/init.d/pylons restart > /dev/null fi endscript }
  4. Feb 04, 2009

    Kevin Baker says:

    It looks like the form hosed my script... trying again. /var/log/pylons/pylons....

    It looks like the form hosed my script... trying again.

    /var/log/pylons/pylons.log {
            daily
            missingok
            rotate 360
            compress
            delaycompress
            notifempty
            create 640 root adm
            sharedscripts
            postrotate
                    if [ -f /var/run/paster.pid]; then
                            /etc/init.d/pylons restart > /dev/null
                    fi
            endscript
    }


  5. Oct 03

    Rich Pixley says:

    Thank you for this. I keep thinking that if setuptools can produce rpms, then i...

    Thank you for this.

    I keep thinking that if setuptools can produce rpms, then it should be capable of producing debs. That would also induce the deb production process into python modules that weren't specifically set up to be debs, which would be extremely useful.

  6. Oct 04

    Rich Pixley says:

    Also, for the comparison, debian's apt format can list installed packages and ve...

    Also, for the comparison, debian's apt format can list installed packages and versions. I haven't yet found a way to do that through the easy_install interface. (Yes, you can root around inside the format, but if I do that programmatically, then my code will break when the format changes.)

    Too, debian can and does support multiple versions of the same package - they just don't support arbitrary combinations. It's common for them to support different major versions of things like libc, java[56], gcc, firefox, etc.

    And... if we're going to include virtualenv and friends as a possible solution to the package removal problem for python, then we also need to look at things like virtualbox, (http://www.virtualbox.org), qemu, (http://www.qemu.org), and vmware, (http://vware.org), which are each capable of producing a recursive instance of a debian/ubuntu system running on a debian/ubuntu system. This also essentially allows for per-user installed debian packages. Heck, even chroot or scratchbox can be used to produce recursive environments for per-user installed debians.

    I see only three features in favor of easy_install. They overlap. And I don't consider them to be sufficiently compelling.

    1. easy_install packages are operating system independent. You can build one on linux and install it on macosx, freebsd, eg. Debians can't do that and for an interpreted system, that's very useful. (Would not be particularly useful for, say,

    2. In part because of #1, the definitive place to look for additional python modules is pypi. While debian has an equivalent, it's not useful for freebsd nor macosx.

    3. distutils/setuptools does seem to be ubiquitous. Not only is there an obvious place to look, (pypi), but pretty much all python packages I've seen include a setup.py. I think that argues in favor of extending distutils or setuptools to produce debians.


Powered by Pylons - Contact Administrators