You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The switch from writeShellScriptBin to writeShellApplication when enabling systemd.enableStrictShellChecks introduces one new shell flag: set -o nounset.
This effectively breaks the idiom test -n "$VARIABLE" for checking if an environment variable is set.
Unlike set -e which causes the pipeline to evaluate to a non-zero code (which inside an if causes the else to match), nounset causes a hard error apparently.
When using systemd-nspawns private networking this fails as follows:
/nix/store/vva5xl231m5bwfybi40k2vl6bgffp211-unit-script-container_mds-2-pre-start/bin/container_mds-2-pre-start: line 9: HOST_ADDRESS: unbound variable
#!/nix/store/p6k7xp1lsfmbdd731mlglrdj2d66mr82-bash-5.2p37/bin/bashset -o errexit
set -o nounset
set -o pipefail
# Clean up existing machined registration and interfaces.
machinectl terminate "$INSTANCE"2> /dev/null ||trueif [ -n"$HOST_ADDRESS" ] || [ -n"$LOCAL_ADDRESS" ] ||
[ -n"$HOST_ADDRESS6" ] || [ -n"$LOCAL_ADDRESS6" ];then
ip link del dev "ve-$INSTANCE"2> /dev/null ||true
ip link del dev "vb-$INSTANCE"2> /dev/null ||truefi
Steps To Reproduce
Steps to reproduce the behavior:
use containers option
provide container with the following options (but not the IPv4 equivalents)
hostAddress6 = "fc00::1"
localAddress6 = "2001:db8::1"
privateNetwork = true
try to start container
full reproducer
# flake.nix# run using# nix run --print-build-logs -v --show-trace .#nixosConfigurations.test.config.system.build.vm{inputs.nixpkgs.url="github:NixOS/nixpkgs/1807c2b91223227ad5599d7067a61665c52d1295";outputs={nixpkgs, ... }:
{nixosConfigurations.test=nixpkgs.lib.nixosSystem{system="x86_64-linux";modules=["${nixpkgs}/nixos/modules/virtualisation/build-vm.nix"({pkgs, ... }:
{services.getty.autologinUser="root";systemd.enableStrictShellChecks=true;containers.test-container={autoStart=true;ephemeral=true;hostAddress6="fc00::1";localAddress6="2001:db8::1";privateNetwork=true;config={};};})];};};}
You should be seeing this when running journalctl --no-pager -u [email protected] in the VM:
Dec 24 16:47:04 nixos systemd[1]: Starting Container 'test-container'...
Dec 24 16:47:04 nixos container test-container[785]: /nix/store/33kzxxdi2cz1g0cbik51nh7s176jsa3b-unit-script-container_test-container-pre-start/bin/container_test-container-pre-start: line 9: HOST_ADDRESS: unbound variable
Dec 24 16:47:04 nixos systemd[1]: [email protected]: Control process exited, code=exited, status=1/FAILURE
Dec 24 16:47:04 nixos systemd[1]: [email protected]: Failed with result 'exit-code'.
Dec 24 16:47:04 nixos systemd[1]: Failed to start Container 'test-container'.
Expected behavior
There should be no failure.
Screenshots
Additional context
I don't think that nounset has that much practical value in tandem with shellcheck since the latter should be able to catch typos IIRC (and would not complain about that piece of code to begin with, especially since it's an environment variable), and for code that wants this feature there exists ${SOME_VAR?} as a possibility (which also allows custom error messages) without breaking otherwise perfectly fine shell code (IMHO).
However as it is currently implemented (and while removal wouldn't be a breaking change) it would probably suffice to provide every single access to an environment variable in every single script with a default value of an empty string whenever they are used with test as in: test -n "${SOME_VAR-}"
Note that this requires the syntax with braces and therefore will require extensive escaping in most uses within Nix code.
Metadata
system: "x86_64-linux"
host os: Linux 6.6.67, NixOS, 24.11 (Vicuna), 24.11.20241222.1807c2b
multi-user?: no
sandbox: yes
version: nix-env (Nix) 2.24.10
nixpkgs: not found
Notify maintainers
Note for maintainers: Please tag this issue in your PR.
Describe the bug
The switch from
writeShellScriptBin
towriteShellApplication
when enablingsystemd.enableStrictShellChecks
introduces one new shell flag:set -o nounset
.This effectively breaks the idiom
test -n "$VARIABLE"
for checking if an environment variable is set.Unlike
set -e
which causes the pipeline to evaluate to a non-zero code (which inside an if causes the else to match),nounset
causes a hard error apparently.Output of failing code
When using systemd-nspawns private networking this fails as follows:
Steps To Reproduce
Steps to reproduce the behavior:
containers
optionhostAddress6 = "fc00::1"
localAddress6 = "2001:db8::1"
privateNetwork = true
full reproducer
You should be seeing this when running
journalctl --no-pager -u [email protected]
in the VM:Expected behavior
There should be no failure.
Screenshots
Additional context
I don't think that
nounset
has that much practical value in tandem with shellcheck since the latter should be able to catch typos IIRC (and would not complain about that piece of code to begin with, especially since it's an environment variable), and for code that wants this feature there exists${SOME_VAR?}
as a possibility (which also allows custom error messages) without breaking otherwise perfectly fine shell code (IMHO).However as it is currently implemented (and while removal wouldn't be a breaking change) it would probably suffice to provide every single access to an environment variable in every single script with a default value of an empty string whenever they are used with test as in:
test -n "${SOME_VAR-}"
Note that this requires the syntax with braces and therefore will require extensive escaping in most uses within Nix code.
Metadata
"x86_64-linux"
Linux 6.6.67, NixOS, 24.11 (Vicuna), 24.11.20241222.1807c2b
no
yes
nix-env (Nix) 2.24.10
not found
Notify maintainers
Note for maintainers: Please tag this issue in your PR.
Add a 👍 reaction to issues you find important.
The text was updated successfully, but these errors were encountered: