`PrivateTmp` option aftecs `ExecStartPre` execution

This is the scenario, I’m writing the openvpn service and I’ve set the option PrivateTmp=true however when I set this flag to true the code that I have in my ExecStartPre (which is just copy one file content to another) is not being executed.

If I remove the PrivateTmp option, i can see the file content being copied as declared in ExecStartPre however, the content is copied 4 times instead one.

ExecStartPre declaration:

ExecStartPre = ''${nixpkgs.bash}/bin/bash -c "${nixpkgs.coreutils}/bin/cat ${fileTemplate} >> ${ConfigFile}"'';

This fileTemplate is created based on a external .nix file

fileTemplate = nixpkgs.writeText "file-template.conf" (builtins.readFile (builtins.toPath (../templates/file-template.tpl)));

Any hints?

I would recommend to use the script nixos option instead of hacking a shell into ExecPreStart

I will recommend using resholve for a real script for ExecStartPre:

{
  ExecStartPre = lib.getExe (pkgs.resholve.writeScriptBin "my-script" 
  {
    interpreter = lib.getExe pkgs.bash;
    inputs = with pkgs; [ coreutils  ];
  }
  ''
    set -eEuo pipefail

    cat ${fileTemplate} >> ${ConfigFile}
  '');

As your script grows (they all start out as oneliners), resholve helps you make sure that you haven’t forgotten any dependencies.

Don’t use script in general - just get into the habit of using resholve for the ExecStart bit as well.

1 Like

Is the service restarting multiple times?

Yes but I think that’s overkill here.

Yes but I think that’s overkill here.

I use resholve even for one-liners, because they often don’t stay as one-liners.

With a snippet in emacs that inserts the few lines of boilerplate, there is very little extra work and you get the benefit of ensuring that your changes don’t break down the road.

resholve is really very much in the nix spirit - you ensure that you define all your dependencies. If we do this for all the regular software, why should we have a worse experience than we are used to for shell scripts?

I am without a doubt @abathur’s biggest fanboy (T-shirt not ordered yet).

1 Like

Personally that’s never an issue for me or at least barely. I more often need to deploy multiple times to fix things up because I actually made bad changes that the computer cannot know didn’t work or because the system I interact with is outside of nix and it cannot possible know if that works or not.
Also my scripts usually tend to stay short but I have many.

So far the extra complexity didn’t seem to be worth it to me and repeating already globally available packages feels more like code duplication.

What exactly is being duplicated?

I mean this part. coreutils is by default installed globally. Yes, it is technically more correct and so but IMO thats not worth the extra effort.

I mean this part. coreutils is by default installed globally. Yes, it is technically more correct and so but IMO thats not worth the extra effort.

Well, most scripts would need something in addition to coreutils, so that line is going to be there anyway.

Most machines would also end up having python, and yet we have no issues “wrapping” small python scripts.

We want to ensure that something runs now and will continue to run and the choice of language in which any program is implemented doesn’t matter and so shell scripts shouldn’t be any different from binaries written in $LANGUAGE.

We should absolutely recommend this approach (resholve is really just an implementation detail in this conversation - no disrespect intended) for anything that we do.

but they are and should be on purpose. First shell is not compiled and second it is simpler than any other interpreted language and does not require any other dependencies except things in PATH and a shell.

No, we absolutely shouldn’t recommend it everywhere. It is over complicated for most use cases and can often be replaced by exporting PATH in the first line with everything that is required. Recommending people the most complex and complicated but feature richest solution to easy problems makes it harder to debug things on their own.