From f7e89a59da9f4531c21df0736b5fdfeba19d7c77 Mon Sep 17 00:00:00 2001 From: Anna Gillert Date: Thu, 7 Apr 2022 09:39:33 +0200 Subject: [PATCH] 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 ``` --- nixos/lib/test-driver/test_driver/machine.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nixos/lib/test-driver/test_driver/machine.py b/nixos/lib/test-driver/test_driver/machine.py index f3e615fe5bf..ed2aceb9658 100644 --- a/nixos/lib/test-driver/test_driver/machine.py +++ b/nixos/lib/test-driver/test_driver/machine.py @@ -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())