forked from josch/mmdebstrap
fix mmdebstrap hanging if apt in download step failed (closes: #1017795)
This commit is contained in:
parent
df2226fb25
commit
226f86fea9
3 changed files with 60 additions and 34 deletions
|
@ -323,3 +323,5 @@ Modes: root unshare
|
|||
Needs-QEMU: true
|
||||
|
||||
Test: error-if-stdout-is-tty
|
||||
|
||||
Test: variant-custom-timeout
|
||||
|
|
81
mmdebstrap
81
mmdebstrap
|
@ -979,46 +979,59 @@ sub run_apt_download_progress {
|
|||
my $flags = fcntl($wfh, F_GETFD, 0) or error "fcntl F_GETFD: $!";
|
||||
fcntl($wfh, F_SETFD, $flags & ~FD_CLOEXEC) or error "fcntl F_SETFD: $!";
|
||||
my $fd = fileno $wfh;
|
||||
# 2022-05-02, #debian-apt on OFTC, times in UTC+2
|
||||
# 16:57 < josch> DonKult: how is -oDebug::pkgDpkgPm=1 -oDir::Log=/dev/null
|
||||
# a "fancy no-op"?
|
||||
# 11:52 < DonKult> josch: "fancy no-op" in sofar as it does nothing to the
|
||||
# system even through its not in a special mode ala
|
||||
# simulation or download-only. It does all the things it
|
||||
# normally does, except that it just prints the dpkg calls
|
||||
# instead of execv() them which in practice amounts means
|
||||
# it does nothing (the Dir::Log just prevents libapt from
|
||||
# creating the /var/log/apt directories. As the code
|
||||
# creates them even if no logs will be placed there…). As
|
||||
# said, midterm an apt --print-install-packages or
|
||||
# something would be nice to avoid running everything.
|
||||
run_apt_progress({
|
||||
ARGV => [
|
||||
'apt-get',
|
||||
'--yes',
|
||||
'-oDebug::pkgDpkgPm=1',
|
||||
'-oDir::Log=/dev/null',
|
||||
$options->{dryrun}
|
||||
? '-oAPT::Get::Simulate=true'
|
||||
: (
|
||||
"-oAPT::Keep-Fds::=$fd",
|
||||
"-oDPkg::Tools::options::'cat >&$fd'::InfoFD=$fd",
|
||||
"-oDpkg::Pre-Install-Pkgs::=cat >&$fd",
|
||||
# no need to lock the database if we are just downloading
|
||||
"-oDebug::NoLocking=1",
|
||||
# no need for pty magic if we write no log
|
||||
"-oDpkg::Use-Pty=0",
|
||||
),
|
||||
@{ $options->{APT_ARGV} },
|
||||
],
|
||||
});
|
||||
# run_apt_progress() can raise an exception which would leave this function
|
||||
# without cleaning up the other thread we started, making mmdebstrap hang
|
||||
# in case run_apt_progress() fails -- so wrap this in eval() instead
|
||||
eval {
|
||||
# 2022-05-02, #debian-apt on OFTC, times in UTC+2
|
||||
# 16:57 < josch> DonKult: how is -oDebug::pkgDpkgPm=1
|
||||
# -oDir::Log=/dev/null a "fancy no-op"?
|
||||
# 11:52 < DonKult> josch: "fancy no-op" in sofar as it does nothing to
|
||||
# the system even through its not in a special mode
|
||||
# ala simulation or download-only. It does all the
|
||||
# things it normally does, except that it just prints
|
||||
# the dpkg calls instead of execv() them which in
|
||||
# practice amounts means it does nothing (the Dir::Log
|
||||
# just prevents libapt from creating the /var/log/apt
|
||||
# directories. As the code creates them even if no
|
||||
# logs will be placed there…). As said, midterm an apt
|
||||
# --print-install-packages or something would be nice
|
||||
# to avoid running everything.
|
||||
run_apt_progress({
|
||||
ARGV => [
|
||||
'apt-get',
|
||||
'--yes',
|
||||
'-oDebug::pkgDpkgPm=1',
|
||||
'-oDir::Log=/dev/null',
|
||||
$options->{dryrun}
|
||||
? '-oAPT::Get::Simulate=true'
|
||||
: (
|
||||
"-oAPT::Keep-Fds::=$fd",
|
||||
"-oDPkg::Tools::options::'cat >&$fd'::InfoFD=$fd",
|
||||
"-oDpkg::Pre-Install-Pkgs::=cat >&$fd",
|
||||
# no need to lock the database if we are just downloading
|
||||
"-oDebug::NoLocking=1",
|
||||
# no need for pty magic if we write no log
|
||||
"-oDpkg::Use-Pty=0",
|
||||
),
|
||||
@{ $options->{APT_ARGV} },
|
||||
],
|
||||
});
|
||||
};
|
||||
my $err = '';
|
||||
if ($@) {
|
||||
$err = "apt download failed: $@";
|
||||
}
|
||||
# signal the child process that we are done
|
||||
close $wfh;
|
||||
# and then read from it what it got
|
||||
my @listofdebs = <$fh>;
|
||||
close $fh;
|
||||
if ($? != 0) {
|
||||
error "status child failed";
|
||||
$err = "status child failed";
|
||||
}
|
||||
if ($err) {
|
||||
error $err;
|
||||
}
|
||||
# remove trailing newlines
|
||||
chomp @listofdebs;
|
||||
|
|
11
tests/variant-custom-timeout
Normal file
11
tests/variant-custom-timeout
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
export LC_ALL=C.UTF-8
|
||||
|
||||
# mmdebstrap used to hang forever if apt in custom mode failed to resolve
|
||||
# dependencies because a process died without cleaning up its children.
|
||||
# https://bugs.debian.org/1017795
|
||||
ret=0
|
||||
{{ CMD }} --mode={{ MODE }} --variant=custom \
|
||||
--include=this-package-does-not-exist {{ DIST }} /dev/null {{ MIRROR }} || ret=1
|
||||
[ $ret -eq 1 ]
|
Loading…
Reference in a new issue