-
Notifications
You must be signed in to change notification settings - Fork 128
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=barecho hi > /tmp/filesomecmd 2> /dev/nullcmd1 | 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
deployCheckswas failing due toboot.initrd.extraFilesincluding 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.nixandunlock.shexample - Suggest a possible PR direction: skip or bypass parsing for
boot.initrd.extraFilesduring schema checks - Draft the issue template and Markdown body for submission
This saved time narrowing down and presenting the issue clearly.