control: tag -1 +patch Hello Holger, Andreas,
New patch attached. I'm not totally sure about the version number comparison code, because LooseVersion doesn't understand things like "~beta2". However, it gives the right answer for the versions of apt in all current Debian suites. -- Sean Whitton
From 2e4bf077af395829898a34bde9aa4eb967d6cc28 Mon Sep 17 00:00:00 2001 From: Sean Whitton <[email protected]> Date: Sat, 24 Dec 2016 21:51:56 +0000 Subject: [PATCH] use apt-get install /tmp/foo.deb --- debian/changelog | 8 ++++++++ piuparts.py | 55 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9cb1565..6534322 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +piuparts (0.74) UNRELEASED; urgency=medium + + * piuparts.py: use `apt-get install ./foo.deb` instead of `dpkg -i + ./foo.deb && apt-get install -yf` for more reliable dependency + resolution (Closes: #825487). + + -- Sean Whitton <[email protected]> Sat, 24 Dec 2016 21:50:21 +0000 + piuparts (0.73) unstable; urgency=medium * Add new option, --hard-link, and do *not* use it by default. diff --git a/piuparts.py b/piuparts.py index dbf2b18..06d7901 100644 --- a/piuparts.py +++ b/piuparts.py @@ -52,6 +52,7 @@ import subprocess import urllib import uuid from collections import namedtuple +from distutils.version import LooseVersion from signal import alarm, signal, SIGALRM, SIGTERM, SIGKILL try: @@ -1162,14 +1163,39 @@ class Chroot: self.install_packages_by_name(packages, with_scripts=with_scripts) return if package_files: + # We need an absolute path here so that apt-get can + # distinguish our deb from a request to install a package + # from a suite called 'tmp' self.copy_files(package_files, "tmp") tmp_files = [os.path.basename(a) for a in package_files] - tmp_files = [os.path.join("tmp", name) for name in tmp_files] + tmp_files = [os.path.join("/tmp", name) for name in tmp_files] + + # Check whether apt can install debs + # + # If it can, this is preferable to the traditional `dpkg + # -i foo.deb && apt-get install -yf` approach: + # + # - the traditional approach can 'resolve' the dependency + # by removing the package we are trying to install + # + # - the new approach successfully handles simultaneously + # installing a new binary package and its transitional + # dummy package + (status, output) = run(["dpkg-query", "-f", "${Version}\n", "-W", "apt"], ignore_errors=True) + apt_can_install_debs = LooseVersion(output.strip()) >= LooseVersion("1.1") if with_scripts: self.run_scripts("pre_install") - apt_get_install = ["apt-get", "-yf"] + if apt_can_install_debs: + # --allow-downgrades is required in order to permit + # installing a deb with the same version as that + # already installed, which we need to do at various + # points in piuparts testing + apt_get_install = ["apt-get", "-y", "--allow-downgrades"] + else: + apt_get_install = ["apt-get", "-yf"] + apt_get_install.extend(settings.distro_config.get_target_flags( os.environ["PIUPARTS_DISTRIBUTION"])) apt_get_install.append("install") @@ -1177,18 +1203,23 @@ class Chroot: if settings.list_installed_files: pre_info = self.save_meta_data() - (ret, out) = self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True) - if ret != 0: - if "dependency problems - leaving unconfigured" in out: - pass - else: - logging.error("Installation failed") - panic() + if apt_can_install_debs: + self.run(apt_get_install + tmp_files) + else: + logging.info("apt too old; falling back to dpkg -i && apt-get install -yf") - if settings.list_installed_files: - self.list_installed_files(pre_info, self.save_meta_data()) + (ret, out) = self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True) + if ret != 0: + if "dependency problems - leaving unconfigured" in out: + pass + else: + logging.error("Installation failed") + panic() + + if settings.list_installed_files: + self.list_installed_files(pre_info, self.save_meta_data()) - self.run(apt_get_install) + self.run(apt_get_install) if settings.list_installed_files: self.list_installed_files(pre_info, self.save_meta_data()) -- 2.10.2
signature.asc
Description: PGP signature

