Skip to content

Host<->User Mutual Providers

Mutual Configs means that not only a User contributes configuration to a Host, but also that a Host contributes configurations to a User.

Den’s resolution pipeline starts with a host definition:

den.hosts.x86_64-linux.igloo.users.tux = {}

We need to build the nixos Nix module that will later be used by lib.nixosSystem. Policies drive entity topology — the built-in host-to-users policy fans out from each host to its users:

Tip: Zoom diagrams using your mouse wheel or drag to move.

sequenceDiagram
   participant Den
   participant host as host resolution
   participant user as user resolution
   participant igloo as den.aspects.igloo
   participant tux as den.aspects.tux

   Den  ->>  host  :  {host = igloo}

   host ->> igloo : request nixos class
   igloo -->> igloo : each .includes takes { host }
   igloo -->> host : { nixos = ... } owned and parametric results

   host ->> user : policy fans out for each user: { host, user }

   user ->> tux : request nixos class
   tux -->> tux : home classes forwarded as nixos class
   tux -->> tux : each .includes takes { host, user }
   tux -->> user : { nixos = ... } owned and parametric results

   user -->> host : { nixos = ... } all user contributions

   host -->> Den : complete nixos module for lib.nixosSystem

This is the normal host resolution pipeline. All OS contributions come from the host itself and from each of its users.

The den.provides.mutual-provider battery allows you to define mutual configurations by letting you define named aspects under .provides. to create explicit relationships between users and hosts.

# mutual-provider is activated at a {host,user} context
# either per-user or for all of them.
den.schema.user.includes = [ den._.mutual-provider ];
# user aspect provides to specific host or to all where it lives
den.aspects.tux = {
provides.igloo.nixos.programs.emacs.enable = true;
provides.to-hosts = { host, ... }: {
nixos.programs.nh.enable = host.name == "igloo";
};
};
# host aspect provides to specific user or to all its users
den.aspects.igloo = {
provides.alice.homeManager.programs.vim.enable = true;
provides.to-users = { user, ... }: {
homeManager.programs.helix.enable = user.name == "alice";
};
};

Tip: Zoom diagrams using your mouse wheel or drag to move.

sequenceDiagram
   participant Den
   participant host as host resolution
   participant user as user resolution
   participant igloo as den.aspects.igloo
   participant igloo-users as den.aspects.igloo.provides.to-users
   participant igloo-tux as den.aspects.igloo.provides.tux
   participant tux as den.aspects.tux
   participant tux-hosts as den.aspects.tux.provides.to-hosts
   participant tux-igloo as den.aspects.tux.provides.igloo

   Den  ->>  host  :  {host = igloo}

   host ->> igloo : request nixos class
   igloo -->> igloo : each .includes takes { host }
   igloo -->> host : { nixos = ... } owned and parametric results

   host ->> user : policy fans out for each user: { host, user }

   user ->> tux : request nixos class
   tux -->> tux : home classes forwarded as nixos class
   tux -->> tux : each .includes takes { host, user }
   tux -->> user : { nixos = ... } owned and parametric results

   user ->> igloo-users : host configs its users: { host, user }
   igloo-users -->> igloo-users : home classes forwarded as nixos class
   igloo-users -->> igloo-users : each .includes takes { host, user }
   igloo-users -->> user : { nixos = ... }

   user ->> igloo-tux : host configs tux: { host, user }
   igloo-tux -->> igloo-tux : home classes forwarded as nixos class
   igloo-tux -->> igloo-tux : each .includes takes { host, user }
   igloo-tux -->> user : { nixos = ... }

   user ->> tux-hosts : user configs its hosts: { host, user }
   tux-hosts -->> tux-hosts : home classes forwarded as nixos class
   tux-hosts -->> tux-hosts : each .includes takes { host, user }
   tux-hosts -->> user : { nixos = ... }

   user ->> tux-igloo : user configs igloo: { host, user }
   tux-igloo -->> tux-igloo : home classes forwarded as nixos class
   tux-igloo -->> tux-igloo : each .includes takes { host, user }
   tux-igloo -->> user : { nixos = ... }


   user -->> host : { nixos = ... } all user contributions

   host -->> Den : complete nixos module for lib.nixosSystem

A user alice can provide configurations for other users in the same system, either by name or for all of them (excluding alice itself).

den.schema.user.includes = [ den._.mutual-provider ];
den.aspects.alice = {
provides.bob = { homeManager.programs.vim.enable = true; };
provides.to-users = { user, ... }: {
homeManager.programs.tmux.enable = lib.elem user.userName [ "carl" "david" ];
};
};

Standalone HomeManager - Host Specific Configuration

Section titled “Standalone HomeManager - Host Specific Configuration”

If you have two standalone homes sharing same user aspect, you can provide host specific configuration even if the Host is not a NixOS system managed by you.

den.schema.home.includes = [ den._.mutual-provider ];
den.homes.x86_64-linux."tux@igloo" = {};
den.homes.x86_64-linux."tux@iceberg" = {};
den.aspects.tux = {
homeManager.programs.vim.enable = true; # tux on ALL homes and hosts.
provides.igloo = {
homeManager.programs.helix.enable = true; # ONLY at igloo
};
provides.iceberg = {
homeManager.programs.emacs.enable = true; # ONLY at iceberg
};
};
Contribute Community Sponsor