How to prevent custom systemd service from restarting on nixos-rebuild switch?

Hi,

I’ve setup a oneshot systemd service in my configuration.nix.
I want it to run before the display-manager starts.
But unfortunately it also runs on every nixos-rebuild switch.
How to prevent that?

Here’s my service:

# Copy random wallpaper to /tmp/wp.gif
  systemd.services.wallpaper = {
    before = [ "display-manager.target" ];
    description = "Copy random wallpaper to /tmp/wp.gif";
    path = [ pkgs.bash pkgs.imagemagick ];
    serviceConfig = {
      ExecStart = "${pkgs.wallpapers}/wp.sh ${pkgs.wallpapers}/wp";
      Type = "oneshot";
    };

    wantedBy = [ "multi-user.target" ];
  };

According to the docs, by default a service should only restart if the unit changed. So either one of its dependencies is changing (e.g., pkgs.wallpapers? Perhaps looking at the nix store hashes may reveal something), or somewhere it’s manually being told to restart.

Only other thing that I can think of is maybe changing wantedBy to wantedBy = [ "display-manager.target" ];?

There’s an option specifically for this: systemd.services.<name>.restartIfChanged which can be set to false if you want to prevent it being automatically restarted.

EDIT: Oh, but for oneshot services, this won’t help. It won’t need to be restarted because it’s not even running. So nixos will just start it. You can avoid this by also setting serviceConfig.RemainAfterExit = true;

1 Like

I’ve set restartIfChanged = false; and also serviceConfig.RemainAfterExit = true;.
This did the trick! Thank you very much!

And FWIW, I’m just guessing about the purpose of this service based on what you’ve posted here, but you probably actually don’t need restartIfChanged, because it probably didn’t actually need to be restarted in the first place. It was probably only being started again because it was inactive because it was a oneshot without RemainAfterExit. If you omit restartIfChanged = false;, then it will be properly restarted if a real change actually is made to it, like changing the pkgs.wallpapers derivation.

I already guessed so, but I actually don’t want the service to be started while I’m logged in (even if something inside the service has changed).
My KDE Plasma wallpaper plugin really doesn’t like it when the wallpaper file is replaced while running :wink: