Home-manager is a false enlightenment

I agree with you, but I think I’d draw a different conclusion. File systems are great for human consumption because we have tools like ls, cd, tree, vim/emacs/nano, vscode/jetbrains/atom, and dolphin and Nautilus. If we had to browse our filesystems in a Haskell repl it would be a pretty terrible experience for humans. So I would conclude that this isn’t a problem inherent to wrapping vs blessed filenames, but a tooling issue.

2 Likes

I’ve been working on a few projects to address the downsides of wrappers. The one that’s farthest along is home-wrapper-manager. The idea is to take advantage of all the great home-manager modules with as little maintenance/implementation burden as possible. The current (very WIP) code for a home-wrapper-manager module looks like this:

{ wrapper-lib }:
{
  pkgs,
  ...
}:
(wrapper-lib.mkWrapperModule "fcitx5" "i18n/input-method/fcitx5.nix" (
  module: moduleEval: {
    packagePathStr = "config.i18n.inputMethod.fcitx5.fcitx5-with-addons";
    wrapperArgs = {
      wrapArgs = [
        "--set FCITX_CONFIG_HOME ${moduleEval.config.xdg.configFile.fcitx5.source or wrapper-lib.emptyDir}"
        "--set FCITX_DATA_HOME ${pkgs.linkFarm "fcitx-config-data" (wrapper-lib.homeFileToLinkFarmFormat moduleEval.config.xdg.dataFile)}"
      ];
    };
  }
))

This generates a module that when enabled, replaces the original home-manager module with one that only uses wrappers. wrapper-manager style options aren’t in yet, but there’s already some advantages to the wrapper implementation. .override gets passed to the original package and when wrapping a wrapper, the new .overrideWrapper will be used to combine them.

All this to say, for most software you don’t have to give up home-manager to get the advantages of wrappers.

I agree with @ttamttam1 that there’s a lot of room for good wrapper tooling. It just needs a little love.

3 Likes

I had a think more about it, and I think I know why there hasn’t been much demand for rationalising dependence on /etc for things like SSH/PAM.

I predict our community’s longest lasting contribution [to distributed yak-shaving :)] will be nixpkgs’s pkgs subdir, by which I mean a large suite of programs, able to be portably executed, without concern for LD_LIBRARY_PATH or FHS, both of which we inherited, but overly constrain where programs can run.

That said, a bunch of /etc are cross-cutting concerns (remote admin via SSH; naming via NSS; auth via PAM) that other execution environments have their own way of doing cross cutting concerns.

For example, things in containers probably do auth via SSO, and wouldn’t jump at the chance to try to wedge in a PAM shim.

Perhaps there’s other benefits for NixOS, like knowing which programs have access to escalate via polkit. Suddenly we have something SELinux shaped, and their “if SELinux is blocking you it’s because you’re doing unusual things” starts to sound like our “if you’re relying on FHS then you’ve got implicit dependencies”. They were right all along! Our systems are just a mess of oversharing!

The other big implicit dependency is the kernel (each syscall, and each Kconfig). There are projects working on figuring out controlling that:

  • Seccomp filters defined in unit files or OCI seccomp profiles
  • gVisor is a kernel compatibility layer, a Go program acting as the kernel in a KVM guest

Why bother tracking such kernel dependence? To control and reduce it, thereby enabling next-gen runtimes (WASI, or virtio unikernels) to benefit from nixpkgs.

1 Like

I’m also getting reminded of pledge() and unveil() of OpenBSD.

1 Like

the core thing this discussion seems to be about is the fundamental difference between automation for human consumption (configuration of productivity tools a.k.a. “home”, mostly) and automation for machine consumption (services, containers, deployment, what have you)

2 Likes

Yes, and beneath that lurks a UX design issue. My years-old suspicion is that one of the central value propositions of NixOS and Home Manager is that they offer a uniform interface over a heterogeneous software ecosystem. So while many properties of what comes out of that are suboptimal, “our kind” tends to accept that as a trade-off against having to deal with incomplete, confusing documentation and all sorts of arcane configuration languages for dozens of tools. foo.enable = true; is very much a game changer – it requires some Linux hacking experience (command line, plain text editing, version control) but allows one to skip most of the application-specifics.

4 Likes

Very interesting! I went the other way instead - I have a compatibility layer which allows me to bring in home-manager modules, and use them to create wrappers instead, which I can then add to home.packages or just use nix shell on any computer. I use it most extensively for being able to use my helix configuration trivially on any machine.

3 Likes

False enlightenment or not, home-manager allows me to reproduce my non-trivial Emacs environment across air gaps; an incredible amount of hours have been saved thanks to all involved contributors.

My work flow is just git and Org-mode, anyway; very seldom do I have to poke at configuration files. HM unit errors do occur, but the alternative costs are magnitudes higher.