Debian – Find source of all installed packages on Debian based systems

aptdebiandpkg

I am trying to find a good method to find the repository for each package that was stored on my system that can be easily parsed.

Backstory:

I have Debian wheezy systems and have setup the wheezy-backports repository, so I could get a newer version of a package. I made a mistake with my patterns in the pinning configuration, which I didn't notice. I pinned * for the backports repository. A few weeks later I issued a apt-get -y dist-upgrade and wasn't paying attention and upgraded far more packages to the wheezy-backports then I was interested in.

I had backups, so I could easily restore things easily, but this situation made me really want to find a way to find which repository each package came from.

About the closest method I have found so far is like this. apt-cache policy $(dpkg -l | awk '/ii/ {print $2}' ). Which is somewhat close, but ideally I would like to get a report like this for all the packages.

Package<tab>Version<tab>Origin<tab>Suite

Where Origin/Suite are the values from the repository Release files.

Best Answer

The following python script parse the output of apt-cache policy and generate the list of all installed packages with the output format

Package<tab>Version<tab>Origin<tab>Suite

apt-show-origins

#!/usr/bin/env python

# Should be written with python-apt
# but for now parse the output of apt-cache policy

import os
import re
command    = "apt-cache policy $(dpkg -l | awk '/ii/ {print $2}' )"
stream     = os.popen(command);
content    = stream.readlines()
getOrigin  = False
pkgList    = []

#Parse the output generated by apt-cache
for s in content:
  if(not s.startswith(' ')):
    pkg = type('', (), {})()   #Create an empty object 
    pkg.name = s[:-2]          #Remove trailing ':\n'
  elif(getOrigin):
    pkg.origin = re.split('\s+',s)[2]
    pkg.suite = re.split('\s+',s)[3]
    pkgList.append(pkg)
    getOrigin = False
  elif(s.startswith(' ***')):
    pkg.version = re.split('\s+',s)[2]
    getOrigin = True

#Display the list
for pkg in pkgList:
  print pkg.name    + '\t'\
      + pkg.version + '\t'\
      + pkg.origin  + '\t'\
      + pkg.suite

Notes:

  • Contrary as what is said in comments apt-show-versions is still maintained, check the official mailing list. But it can't help because it doesn't output the package's origin.
Related Question