-
Notifications
You must be signed in to change notification settings - Fork 116
Description
🐛 Issue
deployChecks
fails on shell scripts in boot.initrd.extraFiles
with valid sh
syntax (=
, >
, 2>
, |
) or even echo
.
Overview
When using deploy-rs
v1.0 with nix
2.28.3, deployChecks
fails if a shell script in boot.initrd.extraFiles
includes common valid shell syntax like:
=
>
2>
|
echo
Even though nixos-rebuild
succeeds and the system works correctly at runtime.
Minimal Reproduction
Directory structure:
.
├── flake.nix
├── flake.lock
└── unlock.sh
flake.nix
:
{
description = "Deploy bug with shell script in extraFiles";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
deploy-rs.url = "github:serokell/deploy-rs";
};
outputs = { self, nixpkgs, deploy-rs, ... }:
let
system = "x86_64-linux";
in {
nixosConfigurations.test = nixpkgs.lib.nixosSystem {
inherit system;
modules = [{
system.stateVersion = "25.05";
boot.initrd.extraFiles."/unlock.sh" = ./unlock.sh;
# Required dummy options
fileSystems."/".device = "/dev/null";
# Disable bootloader entirely for evaluation
boot.loader.grub.enable = false;
boot.loader.systemd-boot.enable = false;
boot.loader.generic-extlinux-compatible.enable = false;
}];
};
checks = builtins.mapAttrs
(system: deployLib: deployLib.deployChecks self.deploy)
deploy-rs.lib;
deploy.test = {
hostname = "my-host";
sshUser = "root";
profiles.system.path = self.nixosConfigurations.test.config.system.build.toplevel;
};
};
}
unlock.sh:
#!/bin/sh
echo "Remote unlock initrd shell"
Each of these causes failure independently:
foo=bar
echo hi > /tmp/file
somecmd 2> /dev/null
cmd1 | cmd2
Steps to Reproduce
nix flake check
Fails with:
error: undefined variable 'echo'
at /nix/store/vi24zyx5bvl9baxac3x5z2b7273hxdqi-source/unlock.sh:2:1:
1| #!/bin/sh
2| echo "example script here"
| ^
3|
Environment
- deploy-rs: 1.0
- nix: 2.28.3
- nixos: 25.04 / 25.05
- system: x86_64-linux
Why This Matters
Shell scripts in boot.initrd.extraFiles are copied verbatim to the initrd and should never be parsed as Nix. This bug blocks valid remote-unlock workflows (e.g. over SSH).
✅ Suggested Fix
- Treat extraFiles contents as opaque
- Don’t evaluate or parse their syntax
- Optionally allow opt-out from parsing via __noDeployCheck = true or similar
🤖 ChatGPT assistance note
I worked with ChatGPT to debug this issue. It helped me:
- Identify that
deployChecks
was failing due toboot.initrd.extraFiles
including valid shell syntax like=
,>
,2>
, and|
- Confirm that the files were being misinterpreted by the Nix expression parser even though they were valid for the initrd
- Reproduce the issue using a minimal
flake.nix
andunlock.sh
example - Suggest a possible PR direction: skip or bypass parsing for
boot.initrd.extraFiles
during schema checks - Draft the issue template and Markdown body for submission
This saved time narrowing down and presenting the issue clearly.