Bug#929860: apt-get hangs forever when invoked via timeout

2019-07-09 Thread Julian Andres Klode
On Sun, Jun 02, 2019 at 01:44:26AM +0200, Martin Olsson wrote:
> I login and create this script /root/foo.sh:   ('bc' can be replaced
> with any package)
> 
>   #!/bin/sh
>   timeout 1m apt-get -y -qq install bc
> 
> I run 'chmod 755 /root/foo.sh' and then execute it:
> # /root/foo.sh
> Selecting previously unselected package bc.
> (Reading database ... 18047 files and directories currently installed.)
> Preparing to unpack .../bc_1.06.95-9+b3_amd64.deb ...
> Unpacking bc (1.06.95-9+b3) ...
> Processing triggers for man-db (2.7.6.1-2) ...
> Setting up bc (1.06.95-9+b3) ...
> 
> Here it freezes!

Not sure what to do about that.

APT is calling tcsetattr() to TCSAFLUSH the terminal after finishing
all dpkg operations, and the kernel stops the program with SIGTTOU.

Setting up all that magic works, but when it comes to cleanup, the
kernel says no and stops it.

-- 
debian developer - deb.li/jak | jak-linux.org - free software dev
ubuntu core developer  i speak de, en



Bug#929860: apt-get hangs forever when invoked via timeout

2019-06-03 Thread Martin Olsson
Update:

5)
The problem only affects 'apt-get install', not 'apt-get update'.

6)
A workaround is to use --foreground
  timeout --foreground 1m apt-get -y install bc
This will finish successfully without any delay or strange exit-code.
However, this is a workaround. 'apt-get install' will launch child
processes and if they
should hang only the parent process will be killed.



Bug#929860: apt-get hangs forever when invoked via timeout

2019-06-01 Thread Martin Olsson
Package: apt
Version: 1.4.9

Hi!
I've found a reproduceable bug when using 'apt-get' together with
'timeout' within a shell.

How to reproduce:

I install a system using the debian-9.9.0-amd64-xfce-CD-1.iso.
I don't install anything at all except a ssh-server (not even any
sys-utils, just the base OS and sshd).
I login and create this script /root/foo.sh:   ('bc' can be replaced
with any package)

  #!/bin/sh
  timeout 1m apt-get -y -qq install bc

I run 'chmod 755 /root/foo.sh' and then execute it:
# /root/foo.sh
Selecting previously unselected package bc.
(Reading database ... 18047 files and directories currently installed.)
Preparing to unpack .../bc_1.06.95-9+b3_amd64.deb ...
Unpacking bc (1.06.95-9+b3) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up bc (1.06.95-9+b3) ...

Here it freezes!
Nothing more happens, and it would hang forever if not my timeout
expired after a minute, making foo.sh continue.
foo.sh has nothing more to do so it terminates and I get a new prompt.

But for some reason, the tty is no longer echoing my keystrokes!
I blindly run 'echo $?' and get the response "124".
This is the return code from 'timeout' after it killed the apt-get job.


1)
What is happening here? The package is successfully installed but
apt-get never terminates.

2)
Running 'timeout 1m apt-get -y -qq install bc' directly on the
commandline works fine.
Running 'apt-get -y -qq install bc' directly in the foo.sh shell,
without any timeout, works fine.
So why doesn't apt-get terminate when started via 'timeout', when run
inside a shell?

3)
Why is the tty no longer echoing my keystrokes?

4)
I'm pretty sure my install-script in Debian 9.6 worked just fine with
'apt-get' together with 'timeout' within a shell.
That is, 'apt-get' did its job and terminated immediately and sucessfully.
Now when I install a new machine using Debian 9.9 it didn't work as expected.
So I guess the problem was introduced somewhere between Debian 9.6 and 9.9.



Anyhow... I can now reproduce the bug over and over:
I run 'reset' to get a normal tty again, purge the installed 'bc' tool
and then install it again via foo.sh:

# reset
# apt-get -y purge bc
# /root/foo.sh

Again, apt-get hangs after installing 'bc'.



(
Why do I call this a bug and not just an annoyance?
Here's my use-case (that used to work fine):

I have a script that declare a function to add a new APT source,
update and then install a package using that source:

  install_foobar() {
cd /tmp
timeout 1m wget "https://apt.foobar.com/foobar.deb; || return $?
dpkg -i foobar.deb || return $?
timeout 1m apt-get update || return $?
timeout 4m apt-get -y install foobar-agent || return $?
return 0
  }

The function is called by the script, and depending on its exit status
it does things differently:

  install_foobar || touch /root/foobar_install_failed
  if [ ! -f /root/foobar_install_failed ]; then
...perform cleanup...
...disable unnecessary services...
...create a foobar user...
...set permissions...
  fi

Now when the apt-get command timeout instead of exiting normally, code
124 is returned.
This in turn creates the 'foobar_install_failed' file, and the user
and settings, etc are not processed even though the foobar-agent
package was successfully installed.
)