Commit 941f76ed authored by Simon McVittie's avatar Simon McVittie

debi: Consider installing foreign 'Multi-Arch: same' packages

Multi-Arch: same packages need to be installed in lockstep.

For example, if you have a merged .changes file for dbus on amd64,
i386 and s390x, and you use

    debi --upgrade dbus_x.y-z_source+amd64+i386+s390x+all.changes

with i386 enabled as a foreign architecture and libdbus-1-3:amd64 and
libdbus-1-3:i386 both installed, it seems better to install both than
to fail to configure some packages.  However, installing dbus:i386 is
undesirable, assuming dbus:amd64 is the one currently installed.

The logic used when dpkg -Oi decides whether a package is already
installed appears to be: if it is Multi-Arch: same, see whether this
(package, architecture) pair is already installed; if not, see whether
this package is already installed for any architecture.

However, we don't want to try to install packages for unconfigured
foreign architectures (s390x in the example above).
Signed-off-by: Simon McVittie's avatarSimon McVittie <>
Closes: #915668
parent fd318bac
......@@ -32,6 +32,8 @@ use filetest 'access';
use Cwd;
use Dpkg::Control;
use Dpkg::Changelog::Parse qw(changelog_parse);
use IPC::Run qw(run);
use IO::Handle;
my $progname = basename($0, '.pl'); # the '.pl' is for when we're debugging
my $modified_conf_msg;
......@@ -242,6 +244,12 @@ if ($? != 0 or !$arch) {
chomp $arch;
my @foreign_architectures;
unless ($opt_a || $opt_t || $progname eq 'debc') {
= map { chomp; $_ } `dpkg --print-foreign-architectures`;
my $chdir = 0;
if (!defined $changes) {
......@@ -363,12 +371,23 @@ for (split(/\n/, $ctrl->{Files})) {
# udebs are only supported for debc
if ( (($progname eq 'debi') && (/ (\S*\.deb)$/))
|| (($progname eq 'debc') && (/ (\S*\.u?deb)$/))) {
my $deb = $1;
$deb =~ /^([a-z0-9+\.-]+)_/ or warn "unrecognised .deb name: $deb\n";
# don't want other archs' .debs:
next unless $deb =~ /[_+]($arch|all)[\.+]/ || $progname eq 'debc';
my $pkg = $deb;
$pkg =~ s/_.*$//;
my $deb = $1;
my $stdout = IO::Handle->new();
run(['dpkg-deb', '-f', $deb], '>pipe', \*$stdout);
my $fields = Dpkg::Control->new(name => $deb, type => CTRL_PKG_DEB);
$fields->parse($stdout, $deb);
my $pkg = $fields->{Package};
# don't want to install other archs' .debs, unless they are
# Multi-Arch: same:
unless (
$progname eq 'debc'
|| $fields->{Architecture} eq 'all'
|| $fields->{Architecture} eq $arch
|| (($fields->{'Multi-Arch'} || 'no') eq 'same'
&& grep { $_ eq $fields->{Architecture} }
if (@ARGV) {
if (exists $pkgs{$pkg}) {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment