Do not unconditionally read standard input

mmdebstrap used to attempt reading stdin if it was not a tty. This leads
to unexpected behaviour when mmdebstrap is used through ssh without a
pseudo-terminal allocated like so:

    $ ssh remote mmdebstrap unstable /output/dir http://mirror

This will stall forever, waiting for data on standard input. Or
consider:

    $ ssh remote << END
    > somecommand
    > mmdebstrap unstable /output/dir http://mirror
    > othercommand
    END

This will make mmdebstrap read "othercommand" and everything that
follows as a sources.list entry. To prevent this unexpected behaviour,
the following ways to use mmdebstrap will not be supported anymore:

    $ mmdebstrap unstable /output/dir < sources.list
    $ mmdebstrap unstable /output/dir http://mirror < sources.list

Instead, one must now explicitly pass "-" if one wants mmdebstrap to
read from stdin:

    $ mmdebstrap unstable /output/dir - < sources.list
    $ mmdebstrap unstable /output/dir http://mirror - < sources.list
This commit is contained in:
Johannes 'josch' Schauer 2019-08-28 00:53:04 +02:00
parent 1219a65723
commit a921e32e6c
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1
2 changed files with 24 additions and 42 deletions

View file

@ -550,12 +550,13 @@ else
./run_null.sh ./run_null.sh
fi fi
print_header "mode=$defaultmode,variant=apt: no mirror but data on stdin" print_header "mode=$defaultmode,variant=apt: automatic mirror from suite"
cat << END > shared/test.sh cat << END > shared/test.sh
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
echo "deb $mirror $DEFAULT_DIST main" | $CMD --mode=$defaultmode --variant=apt $DEFAULT_DIST /tmp/debian-chroot.tar echo "127.0.0.1 deb.debian.org" >> /etc/hosts
$CMD --mode=$defaultmode --variant=apt $DEFAULT_DIST /tmp/debian-chroot.tar
tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
rm /tmp/debian-chroot.tar rm /tmp/debian-chroot.tar
END END

View file

@ -1998,23 +1998,17 @@ sub main() {
} }
my $sourceslist = ''; my $sourceslist = '';
my $stdindata = '';
# make sure that we only attempt to read from STDIN if it's *not*
# connected to the terminal (because we don't expect the user to type
# the sources.list file
if (! -t STDIN) {
info "Reading sources.list from standard input...";
$stdindata = do { local $/; <STDIN> };
}
if (! defined $suite) { if (! defined $suite) {
# If no suite was specified, then the whole sources.list has to # If no suite was specified, then the whole sources.list has to
# come from standard input # come from standard input
$sourceslist .= $stdindata; info "Reading sources.list from standard input...";
$sourceslist = do { local $/; <STDIN> };
} else { } else {
if (scalar @ARGV > 0) { if (scalar @ARGV > 0) {
for my $arg (@ARGV) { for my $arg (@ARGV) {
if ($arg eq '-') { if ($arg eq '-') {
$sourceslist .= $stdindata; info "Reading sources.list from standard input...";
$sourceslist .= do { local $/; <STDIN> };
} elsif ($arg =~ /^deb(-src)? /) { } elsif ($arg =~ /^deb(-src)? /) {
$sourceslist .= "$arg\n"; $sourceslist .= "$arg\n";
} elsif ($arg =~ /:\/\//) { } elsif ($arg =~ /:\/\//) {
@ -2029,15 +2023,6 @@ sub main() {
error "invalid mirror: $arg"; error "invalid mirror: $arg";
} }
} }
# if there was no explicit '-' mirror listed and something was
# read on standard input, then just append it to the end
if (none { $_ eq '-' } @ARGV) {
# if nothing was read on standard input then nothing will
# be appended
$sourceslist .= $stdindata;
}
} elsif ($stdindata ne '') {
$sourceslist .= $stdindata;
} else { } else {
# FIXME: change default mirror depending on $suite # FIXME: change default mirror depending on $suite
# (for derivatives) # (for derivatives)
@ -2465,27 +2450,23 @@ section B<DEBOOTSTRAP>). In contrast to debootstrap it uses apt to resolve
dependencies and is thus able to use more than one mirror and resolve more dependencies and is thus able to use more than one mirror and resolve more
complex dependencies. complex dependencies.
If no I<MIRROR> option is provided, L<http://deb.debian.org/debian> is used, If no I<MIRROR> option is provided, L<http://deb.debian.org/debian> is used.
except if data was given on standard input in which case the lines read from If I<SUITE> is a stable release name and no I<MIRROR> is specified, then
there are used as the content of the chroot's sources.list file. If I<SUITE> mirrors for updates and security are automatically added. If a I<MIRROR>
is a stable release name and no I<MIRROR> is specified, then mirrors for option starts with "deb " or "deb-src " then it is used as a one-line-style
updates and security are automatically added. If a I<MIRROR> option starts format entry for apt's sources.list inside the chroot. If a I<MIRROR> option
with "deb " or "deb-src " then it is used as a one-line-style format entry for contains a "://" then it is interpreted as a mirror URI and the apt line
apt's sources.list inside the chroot. If a I<MIRROR> option contains a "://" inside the chroot is assembled as "deb [arch=A] B C D" where A is the host's
then it is interpreted as a mirror URI and the apt line inside the chroot is native architecture, B is the I<MIRROR>, C is the given I<SUITE> and D is the
assembled as "deb [arch=A] B C D" where A is the host's native architecture, B components given via B<--components> (defaults to "main"). If a I<MIRROR>
is the I<MIRROR>, C is the given I<SUITE> and D is the components given via option happens to be an existing file, then its contents are pasted into the
B<--components> (defaults to "main"). If a I<MIRROR> option happens to be an chroot's sources.list. This can be used to supply a deb822 style
existing file, then its contents are pasted into the chroot's sources.list. sources.list. If I<MIRROR> is C<-> then standard input is pasted into the
This can be used to supply a deb822 style sources.list. If I<MIRROR> is C<-> chroot's sources.list. More than one mirror can be specified and are appended
then standard input is pasted into the chroot's sources.list. If there was to the chroot's sources.list in the given order. If any mirror contains a
data on standard input but no C<-> mirror was listed, the lines read from https URI, then the packages apt-transport-https and ca-certificates will be
standard input will be appended to the end of the chroot's sources.list. More installed inside the chroot. If any mirror contains a tor+xxx URI, then the
than one mirror can be specified and are appended to the chroot's sources.list apt-transport-tor package will be installed inside the chroot.
in the given order. If any mirror contains a https URI, then the packages
apt-transport-https and ca-certificates will be installed inside the chroot.
If any mirror contains a tor+xxx URI, then the apt-transport-tor package will
be installed inside the chroot.
The optional I<TARGET> argument can either be the path to a directory, the The optional I<TARGET> argument can either be the path to a directory, the
path to a tarball filename or C<->. If I<TARGET> ends with C<.tar>, or with path to a tarball filename or C<->. If I<TARGET> ends with C<.tar>, or with