nixos/test-driver: fix missing shellopts in execute

Without this fix, setting the shellopts in `machine.execute` is
inconsitent.  When no timeout is used, shellopts `set -euo pipefail` are
applied to the command as expected. When a timeout is specified, the
shellopts are not applied to the command itself (which is called inside
a `sh -c` that doesn't inherit the shellopts) but rather to the
`timeout` command, leading to the following full command:

```bash
(set -euo pipefail; timeout 900 sh -c 'cmd') | (base64 --wrap 0; echo)\n
```

With this fix, this is the command we get:

```bash
timeout 900 sh -c 'set -euo pipefail; false | true') | (base64 --wrap 0; echo)\n
```
This commit is contained in:
Anna Gillert 2022-04-07 09:39:33 +02:00
parent 7586158ac9
commit f7e89a59da

View file

@ -526,10 +526,14 @@ class Machine:
self.run_callbacks()
self.connect()
if timeout is not None:
command = "timeout {} sh -c {}".format(timeout, shlex.quote(command))
# Always run command with shell opts
command = f"set -euo pipefail; {command}"
if timeout is not None:
command = f"timeout {timeout} sh -c {shlex.quote(command)}"
out_command = f"({command}) | (base64 --wrap 0; echo)\n"
out_command = f"( set -euo pipefail; {command} ) | (base64 --wrap 0; echo)\n"
assert self.shell
self.shell.send(out_command.encode())