Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/containers: not functional with enableStrictShellChecks (but building fine) #367966

Open
benaryorg opened this issue Dec 24, 2024 · 0 comments
Labels
0.kind: bug Something is broken

Comments

@benaryorg
Copy link
Contributor

benaryorg commented Dec 24, 2024

Describe the bug

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.

Output of failing code

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/bash
set -o errexit
set -o nounset
set -o pipefail

# Clean up existing machined registration and interfaces.
machinectl terminate "$INSTANCE" 2> /dev/null || true

if [ -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 || true
fi

Steps To Reproduce

Steps to reproduce the behavior:

  1. use containers option
  2. provide container with the following options (but not the IPv4 equivalents)
    • hostAddress6 = "fc00::1"
    • localAddress6 = "2001:db8::1"
    • privateNetwork = true
  3. 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.


Add a 👍 reaction to issues you find important.

@benaryorg benaryorg added the 0.kind: bug Something is broken label Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug Something is broken
Projects
None yet
Development

No branches or pull requests

1 participant