0

In my quest to get to know Nix and NixOS better, I'm going to try moving a small utility I have onto my NixOS server. There are two components to this utility:

  1. A Perl script, which requires both (a) the Perl module IPC::Run and (b) the command openssl to be present on the system when it runs.

  2. A shell script, which runs the aws CLI, but also runs the aforementioned Perl script (and thus also has its run-time dependencies.)

My mental model says "Oh but I just need Nix to set up a shell where all the above things are present and then run the shell script inside that. Easy!" but I have a feeling this is the wrong mental model for how to deploy software to NixOS. I should probably instead think in terms of a build step that sets up all the run-time dependencies and then chucks the scripts in the nix store, so that when they run they bring with them their dependencies.

But as for actually accomplishing this? I'm at a loss.

  • I have tried the helper utilities writePerlBin and feeding the output of that to writeShellApplication. When I invoked Perl from the shell script, it was not a perl with include IPC::Run.

  • I have tried manually creating a derivation containing both scripts with mkDerivation, but when I specify the dependencies as build inputs, naturally they aren't also considered run-time dependencies.

When I search the internet for this, I get suggestions to either (a) create a new script that wraps my existing script and modifies environment variables (PATH, PERL5LIB?) to refer to dependencies, or (b) perform a substituteInPlace on my script to change the string "perl" into ${perl.withPackages(p: [ p.IPCRun ])}. These solutions seem a little ... hacky! I'd like to confirm with someone knowledgeable that they are the right approach before going for it. Seems to me like their ought to be an easier way to declare which run-time dependencies a script has.

1 Answer 1

6

After reading my own question five times I managed to figure out what was wrong.

While I created mainPerlScript = writePerlBin ... correctly, the script that was created with writeShellApplication was still written to invoke Perl explicitly, as in perl ${mainPerlScript}. This ended up using the system Perl, which had none of the dependencies of the ${mainPerlScript} derivation.

The fix was to invoke ${mainPerlScript} directly in the shell script, without prefixing with perl.

Sign up to request clarification or add additional context in comments.

1 Comment

A slightly more backwards compatible approach is to handle this by setting the PATH: stackoverflow.com/a/68339169/1663462

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.