Creating packages for a Launchpad PPA (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Wed, 30 May 2012

Creating packages for a Launchpad PPA

In a previous article I wrote about how to use stdeb to turn a Python script into source and binary Debian/Ubuntu packages.

You can distribute a .deb file that people can download and install; but it's a lot easier for people to install if you set up a repository, so they can get automatic updates from you. If you're targeting Ubuntu, the best way to do that is to set up a Launchpad Personal Package Archive, or PPA.

Create your PPA

First, create your PPA. If you don't have a Launchpad account yet, create one, add a GPG key, and sign the Code of Conduct. Then log in to your account and click on Create a new PPA.

You'll have to pick a name and a display name for your PPA. The default is "ppa", and many people leave personal PPAs as that. You might want to give it a display name of yourname-ppa or something similar if it's for a collection of stuff; or you're only going to use it for software related to one program or package, name it accordingly.

Ubuntu requires nonstandard paths

When you're creating your package with stdeb, if you're ultimately targeting a PPA, you'll only need the souce dsc package, not the binary deb. But as you'll see, you'll need to rebuild it to make Launchpad happy.

If you're intending to go through the Developer.ubuntu.com process, there are specific requirements for version numbering and tarball naming -- see "Packaging" in the App Review Board Guidelines. Your app will also need to install unusual locations -- in particular, any files it installs, including the script itself, need to be in /opt/extras.ubuntu.com/<packagename> instead of a more standard location.

How the user is supposed to run these apps (run a script to add each of /opt/extras.ubuntu.com/* to your path?) is not clear to me; I'm not sure this app review thing has been fully thought out. In any case, you may need to massage your setup.py accordingly, and keep a separate version around for when you're creating the Ubuntu version of your app.

There are also apparently some problems loading translation files for an app in /opt/extras.ubuntu.com which may require some changes to your Python code.

Prepare and sign your package

Okay, now comes the silly part. You know that source .dsc package you just made? Now you have to unpack it and "build" it before you can upload it. That's partly because you have to sign it with your GPG key -- stdeb apparently can't do the signing step.

Normally, you'd sign a package with debsign deb_dist/packagename_version.changes (then type your GPG passphrase when prompted). Unfortunately, that sort of signing doesn't work here. If you used stdeb's bdist_deb to generate both binary and source packages, the .changes file it generates will contain both source and binary and Launchpad will reject it. If you used sdist_dsc to generate only the source package, then you don't have a .changes file to sign and submit to Launchpad. So here's how you can make a signed, source-only .changes file Launchpad will accept.

Since this will extract all your files again, I suggest doing this in a temporary directory to make it easier to clean up afterward:

$ mkdir tmp
$ cd tmp
$ dpkg-source -x ../deb_dist/packagename_version.dsc
$ cd packagename_version

Now is a good time to take a look at the deb_dist/packagename_version/debian/changelog that stdeb created, and make sure it got the right version and OS codename for the Ubuntu release you're targeting -- oneiric, precise, quantal or whatever. stdeb's default is "unstable" (Debian) so you'll probably need to change it. You can cross-check this information in the deb_dist/packagename_version.changes file, which is the file you'll actually be uploading to the PPA.

Finally, build and sign your source package:

$ debuild -S -sa
  [type your GPG passphrase when prompted, twice]
$ dput ppa:yourppa ../packagename_version_source.changes

Upload the package

Finally, it's time to upload the package:

$ dput ppa:your-ppa-name deb_dist/packagename_version.changes

This will give you some output and eventually probably tell you Successfully uploaded packages. It's lying -- it may have failed. Watch your inbox for messages. If Launchpad rejects your changes, you should get an email fairly quickly.

If Launchpad accepts the changes, you'll get an Accepted email. Great! But don't celebrate quite yet. Launchpad still has to build your package before it can be installed. If you try to add your PPA now, you'll get a 404.

Wait for Launchpad to build

You might as well add your repository now so you can install from it once it's ready:

$ sudo add-apt-repository ppa:your-ppa-name

But don't apt-get update yet! if you try that too soon, you'll get a 404, or an Ign meaning that the repository exists but there are no packages in it for your architecture. It might be as long as a few hours before Launchpad builds your package.

To keep track of this, go to your Launchpad PPA page (something like https://launchpad.net/~yourname/+archive/ppa) and look under PPA Statistics for something like "1 package waiting to build". Click on that link, then in the page that comes up, click on the link like i386 build of pkgname version in ubuntu precise RELEASE. That should give you a time estimate.

Wondering why it's being built for i386 when Python should be arch independent? Worry not -- that's just the architecture that's doing the building. Once it's built, your package should install anywhere.

Once the Launchpad build page finally says the package is built, it's finally safe to run the usual apt-get update.

Add your key

But when you apt-get update you may get an error like this:

The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 16126D3A3E5C1192

Obviously you have your own public key, so what's up? You have to import the key from Ubuntu's keyserver, and then export it into apt-key, before apt can use it -- even if it's your own key.

For this, you need the last 8 digits given in the NO PUBKEY message. Take those 8 digits and run these two commands:

gpg --keyserver keyserver.ubuntu.com --recv 3E5C1192
gpg --export --armor 3E5C1192 | sudo apt-key add -

I'm told that apt-add-repository is supposed to add the key automatically, but it didn't for me. Maybe it will if you wait until after your package is built before calling apt-add-repository.

Now if you apt-get update, you should see no errors. Finally, you can apt-get install pkgname. Congratulations! You have a working PPA package.

Tags: , ,
[ 13:34 May 30, 2012    More programming | permalink to this entry | ]

Comments via Disqus:

blog comments powered by Disqus