View: HTML | Text | PS | PDF | RTF | Wiki | DocBook | DocBook Inline | changelog | about this header Circle Jeff Boweron  
Configuring a Simple Launchpad PPA

Configuring a Simple Launchpad PPA

This document describes how to setup a simple Launchpad PPA for your projects.


Table of Contents
1. What is a PPA? (and why do I want one?)
1.1. How is a PPA different from a .DEB file?
2. Configure Launchpad
2.1. Sign up for a Launchpad Account
2.2. Create and Publish GPG/PGP Keys
2.3. Sign the Code of Conduct
2.4. Create Your PPA
2.5. Celebrate!
3. Configure Your PPA Locally
3.1. Remove Some Extraneous Files
3.2. The changelog File
3.3. The control File
3.4. The install File
3.5. Upload to PPA
3.6. Configuring for Multiple Distros
4. Adding Your PPA to your Machine
5. Updating Your Code
6. PPA Utilities
A. Installing the eBower PPA

1. What is a PPA? (and why do I want one?)

A PPA is a Personal Package Archive. Essentially when you do apt-get install cool-stuff you're pulling information from a public repository of code and compiled binaries. If you've written your own code you may want to share it with the world and a PPA is a great way to do this, using the familiar apt-get mechanisms Debian-based users have come to know and love.

A PPA is a great way to share files with people, but only certain types of files. It's designed to distribute code and binaries to a broad audience, if you want to share a video of your kid's birthday party you'd still be better off with email or a file sharing service (or, even better, just run cp birthday /dev/null since most parents vastly overestimate how much other people like those videos...). On the other hand, if you've written a nifty script that transmorgifies your framus widgets automatically and you think other people may be interested a PPA is a good way to go.


1.1. How is a PPA different from a .DEB file?

Many of you have probably downloaded and installed .deb files. These files are nice in that they can install an application and take care of dependencies just like a PPA can, but there is a big difference between them and a PPA.

The biggest difference is that a PPA will not only install an application, but it will also keep that application up-to-date for you. When you own a PPA and push out a new release, anyone who subscribes to your PPA will be notified and offered the download. With a .deb it's a one-time operation. People who install your application will need to check your website for updates (or you can build that into the application itself).

PPAs are also a bit more secure. Anyone can make a .deb file and it can do anything - especially since typically you'll install it with sudo dpkg -i coolstuff.deb giving it superuser privileges. A PPA is signed and controlled, anything in my PPA has been uploaded by someone with access to my GPG key and the password I use to lock it. Anyone could create google-chrome.deb that downloads and installs Google Chrome but also installs malware to do whatever they want. Now, I can also do the same thing with my PPA but at least then the PPA is traceable to me and Launchpad can terminate my account and/or turn my IP information over to the authorities so they can investigate.

Finally, PPAs tend to be for open source stuff. My scripts are all based on the Apache license which I find to be a bit more free than GPL - this means that anyone can look at my scripts, modify them, and use them as they see fit. It also means that anyone who spots me doing anything bad can report it - whether "bad" is a mistake like running a command a root when I can get away with running it as another user or "bad" is malicious like sending all of your ~/Documents to my personal webserver in the background. There's nothing about a PPA that says I can't include pre-compiled binaries, but you can bet that popular PPAs that include them get a lot more scrutiny than the ones that are open source.


2. Configure Launchpad

The first thing you'll need to do is setup your Launchpad account. Some of you may already have one of these so some steps may be redundant. For example, when I decided to setup my PPA I already had an account, had signed the Code of Conduct, and had secured my OpenPGP key with one-way encryption by forgetting the passphrase.


2.1. Sign up for a Launchpad Account

First, get a Launchpad account. This is quick, easy to do, costs zero dollars and only requires an annual fee of nothing. I think they have financing available for those who qualify... Getting a Launchpad account should be pretty simple, there's a link in the upper right to sign-in or register and you should be able to figure out what to do from there.


2.2. Create and Publish GPG/PGP Keys

After you sign up, you'll need to create a GPG/PGP key. Launchpad has a nice tutorial that explains this pretty well. When you create it, I recommend you use a strong passphrase. I use KeePassX to generate the passphrase (sudo apt-get install keepassx), and they've got an Android version for when you're on-the-go (note that you'll need to move your database to your phone for this to work, I use scp and QuickSSHd to keep mine in sync). Anyone who gets a hold of your key and can unlock the passphrase can send authenticated mail as you - not a pleasant thought.

After you've followed the instructions in the Launchpad link above you should have a key working its way through the Ubuntu keyservers. In a few minutes (probably 5-10, maybe longer) you should be able to log into your Launchpad account and click the "Edit" icon next to your OpenPGP Keys entry. Here you'll want to paste your key Fingerprint and Launchpad will send you an email to the associated address.

On the down side, reading email with your new key may be a little less straightforward than creating it. If you use Thunderbird, you can look into Enigmail. If you use Evolution you can look into Thunderbird (or check out this link). But I use webmail exclusively, so what's a guy to do until Gmail supports native encryption? Well, you can download the message and decrypt it offline, but that's no fun when you can do it on your phone!

First download APG to your phone. Now you'll need to export your key to your phone. To do so, first run gpg --list-keys to list your keys. Your output will look like this:


$ gpg --list-keys
/home/username/.gnupg/pubring.gpg
--------------------------------
pub   2048R/A1D934AC 2011-01-13
uid                  Your Name <email@here.com>
sub   2048R/9CA7D53D 2011-01-13

You may have multiples, in which case check for the email address and the name you used to create the key. If you've already uploaded your key to Launchpad you can see the identifier on your Launchpad page. What we're interested in is the hex code after the 2048R, in this case A1D934AC. To export those keys run the following commands:


gpg --output your_name_email_here_com_pub.gpg --armor --export A1D934AC
gpg --output your_name_email_here_com_sec.gpg --armor --export-secret-key A1D934AC

Now get them to your phone's SD card somehow. Using scp is a good choice, as is plugging the phone in or removing the SD card and putting it in a reader. Once they're there, open APG on your phone and hit Menu --> Manage Secret Keys. Click Menu --> Import Keys and find the key on your SD card. Use the back button to get to the main APG screen and click Menu --> Add Gmail Account. If you're having trouble, see if the APG site can help.

These are once-and-done steps. You should now have your keys installed and your Gmail account setup. If you click on your Gmail account from APG you should see a lock symbol next to any encrypted emails, which you can now open once you type in your passphrase. If you're not frustrated at this step you either didn't listen to me and didn't use a strong passphrase or you listened to me fully and figured out that KeepassDroid can allow you to copy and paste the password. Either way, hopefully you've opened the email from Launchpad, decrypted it, and can follow the link to activate your new key. This is the hard part, I promise!


2.3. Sign the Code of Conduct

The next step should be a piece of cake. Assuming the cake isn't a lie, of course. Go back to your Launchpad profile and click the link by the Code of Conduct entry and follow the instructions. You'll need an OpenPGP key for this step, hence the hassle from the previous step.


2.4. Create Your PPA

Finally, we're off to create your PPA. Just click the Create a new PPA link and we'll get started. Your PPA's URL will be of the format ppa:launchpad-id/ppaname, so the PPA name field should be a short, one-word description related to the use. The Displayname field is a short description, but is plaintext. And the PPA contents description is just a long description field and can be ignored if you like.


2.5. Celebrate!

If you've managed to get this far you're pretty much done. You've got your first PPA, but no projects for it. Initially you shouldn't try to add the PPA since the appropriate files haven't been generated yet. It's possible that this is simply a timing issue, but I believe you actually need to have an actual package available before the system will build the list of packages.


3. Configure Your PPA Locally

First we'll need to get some of the scripts and utilities needed to post your work to a PPA by running sudo apt-get install dh_make devscripts dput gpg-agent. This should take care of all of the dependencies and let us get to work.

You'll want to give some thought into your directory structure before we get too far. I've created a ppasrc directory what holds all of my files that I want to publish via PPA. From there I have a directory for each project, for example I have a Universal Ping utility that I have in ppasrc/uping. From there I have a directory for each version of uping, giving a bunch of directories like ppasrc/uping/uping-0.2.5. The reason for this is that some of the scripts we'll be running will put files into the ppasrc/uping directory and I find this structure is fairly clean.

It's also a good time to think about versioning. It's traditional in a lot of Linux projects to start with version 0.x instead of 1.x. This both indicates that 1.x is a stable, feature-rich utility as well as satisfies the C programmer in you who loves to start counting from 0. I like to try to have version a.b.c refer to a change that actually affects functionality. However I've had to use a.b.c.d to refer to a change that is just a mistake in configuring the PPA (for example, a change in dependencies, a goofed installation file, etc.). It took me six tries to get my first PPA working, and I wish I had started with the a.b.c.d nomenclature so I'd be at 0.2.0.5 instead of going from 0.2.0 to 0.2.5 with no real code changes.

Once you've created a directory for your utility and figured our what version you want it to be, simply copy all of the necessary files to the directory in whatever format makes sense. I frequently only have scripts so I don't use any special directory structure internally. If you have a lot of files you may wish to separate your executables from your images or any other directory structure that makes sense to you. From this directory you can get started by running dh_make --single --native --copyright apache --email you@email.com. Note that it's important to use the same email you created your GPG key for in Section 2.2. This will create a debian directory for you with a few relevant files.


3.1. Remove Some Extraneous Files

First, let's remove the irrelevant files with rm debian/*.ex debian/*.EX.


3.2. The changelog File

Now we want to look at debian/changelog. We want to check the version number, change unstable to an Ubuntu release such as maverick and add notes about what's changed (typically I start with a simple "Initial Release" and build up the changelog as needed). Note that if you want to build for multiple releases you'll probably want to pick your favorite release and then read Section 3.6.

Example 1. An Example changelog File

sample-package (0.1.0.2) maverick; urgency=low

  * Any changes go here
  * Including notes on how you changed the dependencies, etc.

 -- Joe Schmoe <joe.schmoe@ebower.com>  Mon, 17 Jan 2011 19:48:52 -0500

3.3. The control File

Next is debian/control. You'll need to change the line defining the Section to something more meaningful, typically I put mine in utils. Then add some extra information like a URL where you've documented the package, a quick description, as well as a more detailed description.

The most important thing is to make sure you've set up your dependencies properly. There should be a line in the control file starting with Depends (note that this is distinct from the Build-Depends line which is about compiling and not installing). After the two pre-populated entries just put a comma-delimited list of the required packages and version number.

If you use a program and you're not sure where it came from, you can use dpkg -S /path/to/file to figure out what the dependency should be. This can be useful if you use something that is installed by default under Ubuntu but perhaps Debian or an older/newer version of Ubuntu needs it installed manually. I also run into this a lot when developing on my Ubuntu Desktop and then trying to get it to run on my Ubuntu Server.


$ dpkg -S /usr/bin/xml_pp
xml-twig-tools: /usr/bin/xml_pp

If you need to find the version you should support you can visit http://packages.ubuntu.com/distro/package/. For example, http://packages.ubuntu.com/hardy/xml-twig-tools will tell us that Hardy uses xml-twig-tools version 3.32.

Example 2. An Example control File

Source: sample-package
Section: utils
Priority: extra
Maintainer: Johnny Doh <jdoh@ebower.com>
Build-Depends: debhelper (>= 7.0.50~)
Standards-Version: 3.8.4
Homepage: http://www.ebower.com/docs/ubuntu-ppa/
#Vcs-Git: git://git.debian.org/collab-maint/dbcompile.git
#Vcs-Browser: http://git.debian.org/?p=collab-maint/dbcompile.git;a=summary

Package: sample-package
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, vim (>= 7.1), xml-twig-tools (>= 3.3), imagemagick (>= 6.3)
Description: A simple sample package
 It really doesn't need to do anything.

3.4. The install File

The debian/install file simply states where each file should go and is of the format filename /path/to/install/.

Example 3. An Example install File

sample.sh /usr/bin/
script.sh /usr/bin/

3.5. Upload to PPA

To get things going you'll need to install two packages, run sudo apt-get install devscripts debhelper to get these out of the way. You may have done this up above as well.

Next you'll need to build the package using debuild -S in the version directory (one step below the debian directory you were just editing, so something like ~/ppcsrc/projectname/projectname-0.2.4). This will prompt you for your GPG key passphrase twice assuming things work.

If you get a message about not being able to find a GPG key (an error like clearsign failed: secret key not available), try running gpg --list-secret-keys and make sure that the name and email that show up next to your key matches exactly with what you've specified in your debian/changelog.

Once you've finished that, you're ready to upload to your PPA using the command dput ppa:launchpad-id/ppaname ../package_version_source.changes. For example, to put uping version 0.2.4 up I'd run dput ppa:ubuntu-ebower/ebower ../uping_0.2.4_source.changes.


3.6. Configuring for Multiple Distros

I try to make sure that my scripts run on as many systems as possible, but I at least need the latest LTS Ubuntu (which I run on my servers) and the latest stable Ubuntu (which I run on my desktops). The easiest way to have the same script run on multiple distros as of now is to simply copy the files once they've been accepted in the PPA. I tend to develop on Maverick these days which means that I typically set my changelog to maverick as I'm pushing the update. From there I copy the files to lucid and (just because I'm feeling brave) natty. Since I mostly upload scripts with a no-op compiling command I copy them over without rebuilding.


4. Adding Your PPA to your Machine

Under most modern Ubuntu systems you can run the command sudo add-apt-repository ppa:launchpad-id/ppaname to add the PPA. This will also download the security keys for you and set things up properly. If you make a mistake or want to remove the repository, run sudo add-apt-repository --remove ppa:launchpad-id/ppaname.

If you're running a streamlined server, you may not want to bother installing the add-apt-repository scripts. In which case you can edit /etc/apt/sources.lst and add the following lines to the bottom of the file:


deb http://ppa.launchpad.net/launchpad-id/ppa/ppaname lucid main
deb-src http://ppa.launchpad.net/launchpad-id/ppa/ppaname lucid main

If you open up a web browser to https://launchpad.net/~launchpad-id/+archive/ppaname and then click on the link "Technical details about this PPA" you can find the exact lines for your specific PPA.

With this method you'll need to install the key manually. The key can be found under the Technical Details link mentioned above, it's the eight numbers and letters after the 1024R/ under "Signing Key." Once you've gotten this, run sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1234ABCD and it will download the keys for you.

Once the repository has been added, you'll need to update your local databases with sudo apt-get update and check for errors. From there it's just a sudo apt-get install packagename to install any package from the PPA and it will be kept up-to-date automatically.

Additional information may be found on the PPA Help Site.

I've included a section in Appendix A on how to install my PPA for a more concrete example.


5. Updating Your Code

Now that you've got your PPA up and running, you'll probably find that you need to update your code (or, in my case, scripts). Doing so isn't all that tough. Let's say you're working on a package called cool-stuff and you're going from version 0.2 to 0.3. First go into the cool-stuff directory you created and run cp -r cool-stuff-0.2 cool-stuff-0.3. I like using a dash between the package name and the version just to make tab completion a little easier than if I used an underscore.

Now make the changes you need or copy all of your new files into this directory, remembering to delete the old ones as needed.

Now you'll want to cd cool-stuff-0.3 and vi debian/changelog. Edit the version number, add your change list, edit the date and save the file. If you need to, change the other files like debian/control to update dependencies or debian/install if you've added new files or changed the installation.

Once you're done and you've tested things, follow the instructions in Section 3.5 to upload the code to your PPA and kick off the build process.


6. PPA Utilities

If you intend on using your PPA frequently you may wish to explore some utilities to help you manage it. If you speak Python, you can create your own using the Launchpad API. I've also written a wrapper for this called ppa-tools. However, for most simple things you may be interested in my multi-build project which will automatically submit your package, copy to all available series, and then download the .deb files and convert them to .rpm files for RedHat-based users.


A. Installing the eBower PPA

I've created a Personal Packages Archive (PPA) on Launchpad.net. You can add this using the command sudo add-apt-repository ppa:ubuntu-ebower/ebower and then sudo apt-get update to load the list of packages. Alternatively you can add the following lines to your /etc/apt/sources.lst (this is useful if you're running server and don't want to add the add-apt-repository command):


deb http://ppa.launchpad.net/ubuntu-ebower/ebower/ubuntu precise main 
deb-src http://ppa.launchpad.net/ubuntu-ebower/ebower/ubuntu precise main 

Make sure you replace precise above with your distro (lucid, oneiric, etc.). If your distro is not available please contact me with the version and package name and I'll try to update things posthaste. After this is done, run the command sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C27A63B3 to import the keys.

By installing my scripts from the PPA you'll be sure to have the most up-to-date versions in case I need to make changes. However, note that I'm not a developer and I only play one on the Internet. If you use my scripts as a baseline and make changes yourself please let me know how you're changing things and I'll try to accommodate your efforts to ensure that I don't stomp on your customizations.