Open wmertens opened 7 years ago
I know next to nothing about macOS so unfortunately I cannot be of very much assistance here. I believe @league uses (or has used) Home Manager under macOS so perhaps he has some ideas?
Does launchd offer per-user services. If so then I suppose it is a decent target for Home Manager. How similar are they? Would it be possible to generate a launchd service from a systemd description? Otherwise I suppose one would need to add launchd descriptions to those services where it makes sense and somehow generate the manual page so that only services supported by your platform show up.
Oh and of course, I don't know how Home Manager and @LnL7's nix-darwin relates. It seems to me they would overlap quite a bit if we add launchd support and such…
Yes, I don't know the code but I'd love to make this work, so maybe a general overview of how home-manager integrates with the OS would be good. Then we can make issues for each and work towards them.
Launchd has per-user files yes, they're quite simple, and you just run commands to activate/disactivate them. They will probably map quite well from systemd, but of course any string-form configuration (extraConfig
) will be hard.
Another nice thing is that you can set the environment variables of everything that is launched, so that way the nix settings can be easily injected into the desktop.
So, as I understand it, home-manager normally uses systemd, and writes $HOME files upon activation? Anything else?
Yeah, that is pretty much it. It mostly installs packages, creates systemd user services, and links files into $HOME
. But like NixOS, the activation is done using a free-form script that can be added to by any module. For example, the gnome-terminal module uses the dconf
tool to insert its configuration into the dconf database.
About the service activation, Home Manager currently uses its own systemd module which is a direct translation of the systemd INI format. I.e., there is no abstractions like in the NixOS systemd module. The hope is that when the NixUP work starts again the systemd module in NixOS will be made more accessible for use in Home Manager…
I'm not very familiar with home-manager, but I think nix-darwin is more similar to the nixos modules then home-manager. The projects have some overlap but my main focus was bringing declarative system configuration to OSX.
Just anecdotally, when I run home-manager build
on the Mac at work it completely freezes...
@dermetfan I use home-manager on a mac at work (Sierra), are you running High Sierra by any chance?
If you are, you may be running into this: https://github.com/NixOS/nix/issues/1583
@eqyiel Thanks, good catch! It's not home manager itself then. Since that issue is closed I'll try again next time I get a chance.
I made a small step towards a more pleasant Darwin experience in #501. It adds support for conditional module loading, in particular it will only load Linux specific modules on Linux. I haven't tested it very thoroughly on Darwin, though since I have no direct access to such a system. If anybody here that uses Home Manager on macOS could try that branch out it would be much appreciated.
@rycee I can try to give it a spin tomorrow, but I use the Mac very sparingly, and these days my nix configuration on the Mac is even more minimal. I was more ambitious in the past, but now I basically have unison file synchronizer installed and my bash & zsh configuration, and that's about it.
@league Thanks! I think that is fine. I'm happy to merge if it evaluates OK (which the Travis CI tests indicate) and the generated man page seems good (includes the portable modules but excludes, e.g., the service modules).
This seems like a good resource: https://www.launchd.info/
I would LOVE support for launchd
. It does allow for per-user services with User Agents, and having to write your own .plist files is always a pain.
I am not using nix-darwin right now as it's too obtrusive for my taste (it creates system users, runs the nix-daemon etc.) and I am a strong believer in doing as much as possible in userland on a dev machine (lean machine, fat user) so home-manager is my tool.
User agents support would immediately give it the power to run services like PostgreSQL, Redis etc. straight out of the box, that I have now manually set up (undeclaratively) to write in ~/var/postgres and ~/var/redis.
I'm very new to nix and I'm not exactly launchd expert either, but if I find some time, I'll see if I can toss something together.
Something else I'd love, would be a declarative way to get applications installed. I can see how much work it would be to piggy-back on Homebrew's Cask project (that tries to allow you to install, uninstall and even update any macos application from the terminal).
Something else I'd love, would be a declarative way to get applications installed.
The tricky part here, is handling all of the files that Mac apps add outside of the .app directory.
I have got something locally that can support launchd
services. It does not unload/load/reload them on changes, though I do intend to write an activation script similar to the one for systemd
that suggests the commands that should be run to update the state. I think we could do it automatically, but I'm not 100% confident to do it by default and I don't think there is any analogue to sd-switch
I've currently got this to support gpg-agent
and dirmngr
which I have patched to support launchd
socket activation - I also intend to see if that is a patch we could take in nixpkgs
This is for dirmngr
for example:
{
launchd.user.agents.dirmngr = {
serviceConfig = {
Umask = "0600";
Program = "${pkgs.gnupg}/bin/dirmngr";
ProgramArguments = [
"${pkgs.gnupg}/bin/dirmngr"
"--supervised"
(mkIf cfg.verbose "--verbose")
];
Sockets = {
std = {
SockPathName = "${config.home.homeDirectory}/.gnupg/S.dirmngr";
SockPathMode = "0600";
};
};
};
};
}
It would be nice to have an abstraction around some things, like both systemd
and launchd
can support timers in some fasion, but I think even being able to add support to the service modules would be good.
To add to this - I currently have this as part of my own flake - but I would be happy to try and get this into home-manager if others would be interested: https://github.com/benpye/nix-config/tree/main/modules/launchd
It does currently depend on an additional package that isn't in nixpkgs. This is to avoid needing to patch gnupg and dirmngr, instead it is a small wrapper that will get the launchd sockets and populate the systemd environment variables.
Couldn't we copy out the launchd support from nix-darwin? https://github.com/LnL7/nix-darwin/blob/master/modules/launchd/default.nix
Is there a solution / workaround for using launchd
inside home-manager
config?
@jwiegley does it mean that copying https://github.com/LnL7/nix-darwin/blob/master/modules/launchd into my home-manager modules and using it should work?
Or I can somehow access nix-darwin
's one from home-manager
since I use both?
@jwiegley I did base my changes (updated at: https://github.com/benpye/nix-config/tree/main/hm/launchd ) on the launchd
support in nix-darwin
however nix-darwin
doesn't have the changes for socket activation, or detecting the agents to enable - I added a script to determine the agents that the user should load/unload https://github.com/benpye/nix-config/blob/main/hm/launchd/launchd-activate.sh , similarly to the print we give for systemd
user sessions today.
Currently my module expects launchd.user.agents
for user services, which is obviously different to systemd
. I think this makes sense and then in the future for simple services we could have some abstraction to create the appropriate systemd
or launchd
entry.
Home Manager gained support for launchd services recently.
I dream of a future where you can set up services (as a module writer) for both platforms in an easy way. Are there any services enabled on both systems at this moment to serve as a baseline?
maybe @montchr can help. his darwin config is pretty advanced
Yeah, I've got a couple modules adapted from nix-darwin for use within home-manager's scope. I've been using them in my fork and in my config repo. Both have some lurking issues, but I don't think there's too much left to fix up.
services.skhd
seems to be running in a different shell environment than my login shell – a couple of my scripts that used to work with the nix-darwin module complain about missing functions and environment variables. That's probably more an issue with my personal configs rather than the module itself though.
There's also https://github.com/nix-community/home-manager/pull/2964 – this adds a launchd
service configuration to the existing services.gpg-agent
module. I've been using it locally for months now, but it needs some adjustment before I'd consider it ready to go i.e. not a draft. For more info, I would refer to that PR.
Though I will add here that I struggled to configure a launchd
service to match the features of the existing systemd
service, which gives me some concern about the ongoing maintainability of cross-platform (or, perhaps more accurately, cross-service-manager) modules once we start to add more of those. But I'm sure that continued practice writing such translations and testing through trial-and-error will help too 😅
I'm really curious about whether others think it would be worth looking into using https://github.com/svanderburg/nix-processmgmt as an abstraction for service configuration in home-manager? From the README:
This repository contains a very experimental prototype implementation of an operating system and process manager agnostic Nix-based process managed framework that can be used to run multiple instances of services on a single machine, using Nix to deliver and isolate all required package dependencies and configuration files.
It seems to me like that library could help reduce the amount of configuration needed in maintaining such services
modules. But, the project's emphasis on "very experimental prototype" is of course offputting, I wonder if using it to reduce maintainence overhead in home-manager might be a fitting "real-world" application of that library.
Also, I took an initial pass at a services.yabai
module based on the one from nix-darwin, but gave up since I don't have any experience with similar window managers on Linux (though I intend to change that soon).
It seemed wrong to treat yabai
as different by not fitting it into the same general structure as the other window manager modules since I get the sense the configuration syntax and concepts are somewhat similar. I was thinking that giving them a similar structure could actually be really awesome for users that want their WM experience on Linux and macOS to be as close as possible:
i3
/sway
/bspwm
users who are more familiar with Linux but need to use macOS for work, so end up using yabai
/skhd
yabai
/skhd
users who come from a macOS background but struggle to migrate their configs over to sway
etc. on NixOS.Full disclosure: I fall into the latter group, which makes me think simultaneously that making a services.yabai
module following in the footsteps of the other TWM modules would be a great learning opportunity, but also a big challenge bound to result in rendering something unusable temporarily 😆
I've been happily using HM (including launchd agents) since I started using Nix a year or two ago, it seems to work well.
@wmertens can this issue be closed?
What needs to be done for Darwin support? I imagine launchd support, environment variable injection, others?
Right now the basic package installation works, I didn't try anything else.