Package: python-central Version: 0.6.15 Severity: important Tags: patch User: vor...@debian.org Usertags: multiarch
Hi guys, python-central makes heavy reliance on the presence of /var/lib/dpkg/info/$pkg.list to determine the installation status of $pkg. In the multiarch world, this is no longer a valid assumption; status files are going to be under /var/lib/dpkg/info/$arch/ instead for each architecture. On a freshly-bootstrapped chroot using a multiarch-enabled dpkg, therefore, python-central consistently fails to find any packages, causing maintainer script failures. The attached patch accounts for this in the most naive way possible, by checking both /var/lib/dpkg/info and /var/lib/dpkg/info/$main_arch for the requested file. There are various ways that this may still be incorrect, but it's correct *enough* to make pycentral work again for native packages on a multiarched system, and we're a long, long away from having to worry about non-native python extension packages being installed (if, indeed, this is ever permitted). I've uploaded this change to Ubuntu with the following changelog: * Fix up for multiarch dpkg: /var/lib/dpkg/info/$pkg.list is now no longer guaranteed to exist, it may be /var/lib/dpkg/info/$arch/$pkg.list. Please apply this ASAP to the python-central package in Debian, or let me know if you think this needs to be fixed a different way. Thanks, -- Steve Langasek Give me a lever long enough and a Free OS Debian Developer to set it on, and I can move the world. Ubuntu Developer http://www.debian.org/ slanga...@ubuntu.com vor...@debian.org
=== modified file 'pycentral.py' --- pycentral.py 2010-09-10 08:56:59 +0000 +++ pycentral.py 2011-03-01 04:10:43 +0000 @@ -1377,6 +1377,18 @@ def run(self, global_opts): pass + def get_arch(self): + import subprocess + # a little convoluted, but we need to get the current architecture + # name + cmd = ['/usr/bin/dpkg', '--print-architecture'] + p = subprocess.Popen(cmd, bufsize=1, + shell=False, stdout=subprocess.PIPE) + fd = p.stdout + arch = fd.readline().strip().split() + fd.close() + return arch + class ActionByteCompile(Action): """byte compile the *.py files in <package> using the the @@ -1413,7 +1425,9 @@ if not self.runtime: self.error("unknown runtime version %s" % self.options.version) - if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname): + arch = self.get_arch() + if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, self.pkgname)): self.error("package %s is not installed" % self.pkgname) self.pkg = DebPackage('package', self.pkgname, oldstyle=False, default_runtime=self.runtime) @@ -1469,7 +1483,9 @@ self._option_parser.print_help() sys.exit(1) self.pkgname = self.args[0] - if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname): + arch = self.get_arch() + if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, self.pkgname)): self.error("package %s is not installed" % self.pkgname) return self.errors_occured @@ -1619,7 +1635,9 @@ self._option_parser.print_help() sys.exit(1) self.pkgname = self.args[0] - if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname): + arch = self.get_arch() + if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, self.pkgname)): self.error("package %s is not installed" % self.pkgname) return self.errors_occured @@ -1645,7 +1663,9 @@ self._option_parser.print_help() sys.exit(1) self.pkgname = self.args[0] - if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname): + arch = self.get_arch() + if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, self.pkgname)): self.error("package %s is not installed" % self.pkgname) return self.errors_occured @@ -1675,7 +1695,9 @@ self._option_parser.print_help() sys.exit(1) self.pkgname = self.args[0] - if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname): + arch = self.get_arch() + if not os.path.exists('/var/lib/dpkg/info/%s.list' % self.pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, self.pkgname)): self.error("package %s is not installed" % self.pkgname) return self.errors_occured @@ -1793,7 +1815,8 @@ needed_packages = [] import subprocess for pkgname, vstring in packages: - if not os.path.exists('/var/lib/dpkg/info/%s.list' % pkgname): + if not os.path.exists('/var/lib/dpkg/info/%s.list' % pkgname) \ + and not os.path.exists('/var/lib/dpkg/info/%s/%s.list' % (arch, pkgname)): # already removed, but /var/lib/dpkg/status not yet updated continue cmd = ['/usr/bin/dpkg-query', '-W', '-f', '${Status}\n', pkgname]