Custom Ubuntu repository containing recursive dependencies of a *.deb package

I have a custom Debian/Ubuntu package (let’s call it gnu) that I want to distribute to a number of users. gnu's dependencies include quite a few libraries available in Ubuntu’s main repos, as well as a couple extra packages that I’ve had to roll myself. At the time of distribution, I can’t guarantee the users’ access to the internet, or the state of installed dependencies on the users’ machines.

My current (perhaps crude) solution is to create an offline/local repository for gnu and its full dependency tree. The main idea is to use apt-rdepends [1] to obtain a listing of the desired package’s recursive dependencies, download all of them, and then setup a repository either on a CD/DVD, USB flash drive, or local storage. Then, no matter what subset of dependencies (and the dependencies’ dependencies, and so on…) are currently installed on a user’s machine, the local repository should be able to handle the rest and then install gnu program successfully.

  • List the recursive dependencies for package gnu using apt-rdepends. Note apt-rdepends bug [2]; use man AptPkg to get the following mapping for the --follow option:
    Depends = 1, Predepends = 2, Suggests = 3, Recommends = 4, Conflicts = 5, Replaces = 6, Obsoletes = 7.
  • foo$ apt-rdepends --follow=1 --show=Depends gnu | cat > dependencies_long.txt

  • Massage the output to produce a list of packages to download into your local repository. In this case, I’m grabbing all dependencies listed, cutting out extraneous (for my purposes) information, sorting, and removing duplicate listings.
  • foo$ cat dependencies_long.txt | grep ':' | cut -d' ' -f4 | sort -u | cat > dependencies_short.txt

  • Now download the dependencies into the current directory foo. Note, these will be binary packages for your local machine’s architecture, grabbing i386 packages on an amd64 machine is something I haven’t investigated. Also, there may be warnings if virtual packages are included in the list of dependencies… however, this wasn’t a stopping block in my particular case.
  • foo$ cat dependencies_short.txt | xargs -I {} apt-get download {}

  • Don’t forget to add gnu (it’s not in the dependencies list).
  • foo$ apt-get download gnu

  • Scan foo for all packages and make the Packages.gz index file for your repo.
  • foo$ dpkg-scanpackages . | gzip -9c > Packages.gz

  • Some cleanup.
  • foo$ rm dependencies_long.txt dependencies_short.txt

  • Finally, burn the contents of foo to a CD/DVD (Note: pick a label/name for the CD/DVD without spaces – I had problems later on with the command sudo apt-cdrom add) or you can add the current folder as a local repo directly [3].

My next steps are to look for (arguably) cleaner solutions, including creating a self-installer script to place on the CD, or making a custom LiveCD with the package and dependencies pre-installed [4]. Also, worth a mention that I came across apt-cache depends [5] after apt-rdepends, but in my cursory usage found that it didn’t offer the same granularity of options as apt-rdepends.

[1] http://manpages.ubuntu.com/manpages/natty/man8/apt-rdepends.8.html
[2] https://bugs.launchpad.net/ubuntu/+source/apt-rdepends/+bug/315567
[3] https://help.ubuntu.com/community/Repositories/Personal
[4] https://help.ubuntu.com/community/LiveCDCustomization
[5] http://manpages.ubuntu.com/manpages/natty/man8/apt-cache.8.html

This entry was posted in Linux. Bookmark the permalink.

Leave a comment