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.

  • 1
    Would the apt-show-versions package be helpful? – Faheem Mitha Jan 5 '15 at 22:45
  • @FaheemMitha theoretically, that command might be useful, but it seems to be unmaintained. It doesn't appear to support gzip Package files. bugs.debian.org/cgi-bin/bugreport.cgi?bug=617856 – Zoredache Jan 6 '15 at 18:25
  • That';s too bad. I've used it without problems quite recently, specifically without running into this bug. Perhaps submit a patch? – Faheem Mitha Jan 6 '15 at 18:28
up vote 4 down vote accepted

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.
  • Personally, if I was writing a Python script from scratch to do this, I'd use the APT Python API, per python-apt. – Faheem Mitha Feb 21 '15 at 1:22
  • Your are right, I said it in the comments of the script but for now it takes less effort and time to do it like this. – Ortomala Lokni Feb 21 '15 at 1:24

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.