Host<->User Mutual Providers
What Mutual-Config Mean
Section titled “What Mutual-Config Mean”Mutual Configs means that not only a User contributes configuration to a Host, but also that a Host contributes configurations to a User.
Default, unidirectional OS configuration
Section titled “Default, unidirectional OS configuration”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.
Providing across entities
Section titled “Providing across entities”To define mutual configurations, declare named aspects under an aspect’s
provides namespace. Each provides.<target> key creates an explicit
relationship between a user and a host:
provides.<name>delivers to the host or user named<name>.provides.to-hostsdelivers to every host the user lives on.provides.to-usersdelivers to every user on the host.
# user aspect provides to a specific host or to all hosts where it livesden.aspects.tux = { provides.igloo.nixos.programs.emacs.enable = true; provides.to-hosts = { host, ... }: { nixos.programs.nh.enable = host.name == "igloo"; };};
# host aspect provides to a specific user or to all its usersden.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.to-users
participant igloo-tux as den.aspects.igloo.tux
participant tux as den.aspects.tux
participant tux-hosts as den.aspects.tux.to-hosts
participant tux-igloo as den.aspects.tux.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
Configuring peers from the host
Section titled “Configuring peers from the host”A provides key registered on a user aspect is subtree-scoped: it reaches that
user (and the hosts it lives on), but never sibling users on the same host.
To configure several users — or to select per-user — register the provides on
the host aspect, whose subtree spans every user on it:
den.aspects.igloo = { # all users except tux get vim provides.to-users = { user, ... }: { homeManager.programs.vim.enable = user.name != "tux"; }; # only alice gets tmux provides.alice.homeManager.programs.tmux.enable = true;};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.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 };};