nix-community / home-manager

Manage a user environment using Nix [maintainer=@rycee]
https://nix-community.github.io/home-manager/
MIT License
6.1k stars 1.65k forks source link

systemd service drop-ins #5401

Open devurandom opened 2 weeks ago

devurandom commented 2 weeks ago

Description

NixOS allows defining foo.service.d drop in files using systemd.user.services.<name>.overrideStrategy. How do I do the same with home-manager?

I tried various things, but do not get the result I would expect, a ~/.config/systemd/user/foo.service.d/override.conf file containing:

[Service]
EnvironmentFile=.../env

  systemd.user.services = {
    foo = {
      # https://nixos.org/manual/nixos/unstable/options#opt-systemd.user.services._name_.overrideStrategy
      overrideStrategy = "asDropin";
      # https://nixos.org/manual/nixos/unstable/options#opt-systemd.user.services._name_.serviceConfig
      serviceConfig = {
        EnvironmentFile = ".../env";
      };
    };
  };

causes:

error: A definition for option `home-manager.users.[REDACTED].systemd.user.services.foo.overrideStrategy' is not of type `attribute set of (boolean or signed integer or string or path or list of (boolean or signed integer or string or path))'.

  systemd.user.services = {
    foo = {
      # https://nixos.org/manual/nixos/unstable/options#opt-systemd.user.services._name_.serviceConfig
      serviceConfig = {
        EnvironmentFile = ".../env";
      };
    };
  };

creates ~/.config/systemd/user/foo.service:

[serviceConfig]
EnvironmentFile=.../env

which overrides the whole foo.service installed by NixOS.


  systemd.user.services = {
    foo = {
      Service = {
        EnvironmentFile = ".../env";
      };
    };
  };

creates ~/.config/systemd/user/foo.service:

[Service]
EnvironmentFile=.../env

which again overrides the whole foo.service installed by NixOS.


  systemd.user."services.d" = {
    foo = {
      Service = {
        EnvironmentFile = ".../env";
      };
    };
  };

causes:

error: The option `home-manager.users.[REDACTED].systemd.user."services.d"' does not exist.

I also skimmed through https://github.com/nix-community/home-manager/blob/44677a1c96810a8e8c4ffaeaad10c842402647c1/modules/systemd.nix but could not figure out how systemd service drop-ins are supposed to work.


My flake.nix:

{
  inputs = {
    nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
    home-manager = {
      url = flake:home-manager;
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, home-manager, ... }@inputs: {
      nixosConfigurations.system = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        specialArgs = inputs;
        modules = [
          ./hardware-configuration.nix
          ./configuration.nix
          home-manager.nixosModules.home-manager {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.[REDACTED] = import ./home/[REDACTED].nix;
          }
        ];
      };
    };
}
jackwilsdon commented 1 week ago

It seems like HM doesn't have built-in support for drop-in files, so I've been creating them like this:


xdg.configFile."systemd/user/my.service.d/overrides.conf".text = ''
  [Service]
  EnvironmentFile=.../env
'';
devurandom commented 1 week ago

Thanks! It worked:

  xdg.configFile."systemd/user/my.service.d/99-env.conf" = let
    envFile = pkgs.writeTextDir "override.env" ''
      VAR_A=1
      VAR_B=2
    '';
  in {
    text = ''
      [Service]
      EnvironmentFile=${envFile}/override.env
    '';
  };