Apport is the software that handles bug crashes in Ubuntu. Whenever you want to report a bug in Ubuntu, apport collects data about that package, attach it to the bug report and send it to Launchpad.
Hooks are scripts written in python that help apport to collect specific data about a package. In this post, I’ll show how to write one, specifically an apport hook for the MPD package which includes the user configuration file. There are some links that you have to read to get a better understanding of what hooks are, and how to write them, those links will be at the end of this post.
If you want to write a hook for a package that doesn’t have a hook but need it, then you can report a bug similar to this one: https://bugs.launchpad.net/bugs/947551
First off, we need to get the source of the package:
bzr branch ubuntu:mpd ; bzr branch mpd fix-missing-hook ; cd fix-missing-hook
And we’re ready to start. In this example, th eMPD user configuration file is stored at ~/.mpdconf. Everytime we write a hook, we *must* ensure that we keep the user data safe. That means that if the configuration file contains passwords, they *must* kept away from the public. Fortunately for this example I found a snippet that replaces passwords strings in files (link at the end). I just had to modified it to fit my needs and add some little things to it. Here’s the apport hook to include MPD user configuration file:
apport package hook for Music Player Deamon
Author: Ronny Cardona
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. See http://www.gnu.org/copyleft/gpl.html for
the full text of the license.
from apport.hookutils import *
# Reference for this function: http://pastebin.ubuntu.com/263396/
def _my_files(report, filename, keyname):
if not (os.path.exists(filename)):
key = keyname
report[key] = “”
for line in read_file(filename).split(‘\n’):
if ‘password’ in line.split(‘”‘):
line = “%s \”@@APPORTREPLACED@@\” ” % (line.split(‘”‘))
report[key] += line + ‘\n’
_my_files(report, os.path.expanduser(‘~/.mpdconf’), ‘UserMpdConf’)
As you can see, the script was initially released under GPL3+, BUT! MPD uses GPL2+ which means that it’s incompatible with the software license. The best solution is to always release the hooks under the same licence as the software the hook was written for, in this example GPL2+.
After the script is ready and copied to /usr/share/apport/package-hooks it *must* be tested to check that it works like expected:
This will call apport which will call then the hooks for the specific package, if you can see in attached files the user configuration file (or whatever file you wanted to include), then the script works like it should do.
So, the script is ready and working, just left to package it. Here comes the interesting part. Apport hooks *must* be included in the debian/ directory, named source_package.py. That means that MPD hook must be named as source_mpd.py and then put it inside the debian/ directory.
Now, we can edit mpd.install file to point out where our script will be allocated after installation. That destination is at /usr/share/apport/package-hooks/. So, we append a line like this one:
That is all we need to do when writing a simple apport hook. We haven’t change code outside debian/ dir, so we’re ready to write the changelog entry:
And here we can specify our changes:
mpd (0.16.5-1ubuntu4) precise; urgency=low
– Added apport hook to include user configuration file. (LP: #947551)
– Ronny Cardona Wed, 07 Mar 2012 18:03:12 -0600
Then, commit the change:
And build the package:
bzr builddeb -S
pbuilder-dist precise build ../*.dsc
We install the package and test it. And check the hook destination directory to verify that it was installed in it’s respective directory. We also verify (one more time) if the hook is called when apport is launched =)
Push the branch to LP:
bzr push lp:~rcart/ubuntu/precise/mpd/fix-947551
Then propose for merge