State of the Hackage

This summer (2010), I’ve tasked myself with porting the current Hackage codebase, which is served at to web browsers and cabal-install processes alike, to a newer one which is still in development but nonetheless pretty polished. The older one is known as hackage-scripts, and you can find it here:

$ darcs get

Its primary goal is to serve both cabal files (package metadata) for the cabal-install tool to parse and package tarballs for it to compile, and the server uses a glorified directory tree to accomplish this. It also has a minimalistic web interface for finding packages, viewing their metadata, and perusing Haddock-generated documentation. hacakge-scripts uses a combination of static files and Network.CGI executables, which are invoked by the web server, read information about the request using the CGI specification, and then print the HTML response to standard output. Not the least of these scripts is the one that uploads new packages, using either cabal upload or the web interface.

hackage-scripts is portable in that it should run on any standard Apache installation. Unfortunately, it usually doesn’t run out of the box. The directory tree and static files have to be set up manually, and the Makefile and source code need to be hardcoded with pathnames indicating where the set up is. Even if you can’t get it running on your own, it is happily chugging away on, which your cabal configs (~/.cabal/config) undoubtedly point to.

The candidate replacement is known simply as hackage-server, and you can get it here in its pre-summer-of-code state:

$ darcs get

It uses the Happstack web framework to deconstruct URIs by their path hierarchy, rather than letting Apache root through a large directory tree of mostly static files. It also uses the happstack-state package, at present keeping approximately 186 MiB of package data for 8376 package versions in memory to serve requests, falling back to the disk for larger files such as the package tarballs.

This summer’s project is particular in that it involves work on a code base which most Haskellers won’t install themselves, but provides a service most of us will end up dealing with frequently. This makes it important to get right from an architecture standpoint. Nonetheless, I hope to make it painless to set up a secondary Hackage repository as a drop-in replacement for the main one, potentially allowing you to pull from a variety of sources of varying stabilities. Setting up a server on http://localhost:8080/ over an empty repository is as easy as changing to the repository’s top-level Darcs directory for the repository and running

$ cabal install
$ hackage-server --initialise

(albeit not as easy if the dependencies end up failing: I had to change the Happstack dependency brackets in hackage-server.cabal from ==0.4.* to ==0.5.* because I use an older base) Setting up a clone with the current tarballs is a bit more complex, but within the realm of science to solve!

$ cabal install
$ wget -P /tmp
$ wget -P /tmp
$ wget -P /tmp
$ echo 'admin:wywGGkc7Qc/6I' > /tmp/htpasswd
$ echo 'admin' > /tmp/adminlist
$ hackage-server --import-index=/tmp/00-index.tar.gz \
    --import-log=/tmp/log --import-accounts=/tmp/htpasswd \
    --import-archive=/tmp/archive.tar \

Be warned: archive.tar is 128MB at the moment! As for wywGGkc7Qc/6I, it is one of 4096 crypt-salted hashings of the password admin. On Wednesday I implemented digest authentication, which would instead hash admin:hackage:admin in MD5 and use a nonce challenge/response for reasonably secure authentication (the current scheme sends your password in near-plaintext with every request). I found a minor Chromium bug in the process, too!

Tersely put, the design goals are for hackage-server to become a more consistent, extensible, modular and (most importantly) runnable Hackage server. This means duplicating the existing functionality, a task mostly done by Antoine Latter and Duncan Coutts in the span of the last two years, and organizing the modules into a URI hierarchy that obeys REST and ROA principles. I’ve outlined all of the resources Hackage currently provides (partially listed on the trac wiki), and I’m working on a mapping to a new and improved set of URIs.

For the more commonly accessed Hackage URIs (those that have been linked from other websites or hardcoded in cabal), backwards-compatibility is a priority, and mostly already implemented as a series of 301 redirects. Such a legacy redirect system might be considered a “feature”, a plug-in functionality which can be enabled and disabled. Part of making the new Hackage modular and hackable is defining a consistent interface for features. Much like lambdabot‘s Module typeclass, each feature can be defined discretely, and the behavior of the web server becomes the msum of each feature’s ServerPart Response.

The above is the state of affairs on Day 1 (well, Day 4, but I’m still getting started with these new-fangled blags!). The title of my proposal is “Infrastructure for a more social Hacakge 2.0“, not “A more social Hackage 2.0”. I expect that the exact array of social services that Hackage will provide will need a hefty bout of fine-tuning and analysis (see also some insightful thoughts on this), so my job is to provide the technical base to make the shiny new features easy to plug in and modify, as well as implementing as many as possible in a mad rush of coding late July and early August.

If you have any kind of wish list for Hackage features, it is imperative that you let me know—eventually. Duncan and others have encouraged me to concentrate on setting up the infrastructure before building features, so at some point I’ll try to facilitate a community discussion about what you all want to see in our favorite package repository. If you need me, you can find me as Gracenotes on the #haskell and #hackage channels on And best of luck to my fellow gsoc-ers, whose blogs I’ve linked in the sidebar.


May 27, 2010. Uncategorized. 4 comments.