Select API
The select context is available in rule functions, class functions, and synth. It provides filtered views of the DOM relative to the current node.
Accessing select
Section titled “Accessing select”In a rule function:
{ is = nest.host; nixos = { select, host, ... }: let webs = select.siblings nest.web; in { services.haproxy.backends = map (w: w.addr) webs; };}In a class function:
nest.trait.host.class.nixos = select: cfg: nixpkgs.lib.nixosSystem { system = select.node.system; modules = [ cfg ]; };In a synth:
nest.trait.host.synth = select: { node.userCount = builtins.length (select.children nest.user);};select.node
Section titled “select.node”The current node attrset. Contains all inherited and own attributes, plus name, __path, __parentPath, and any synth-derived attrs:
select.node.name # "web-1"select.node.system # "x86_64-linux"select.node.env # "prod" (inherited from namespace)select.node.__path # "prod.web-1"select.node.__parentPath # null (or parent node's __path)select.parentNode
Section titled “select.parentNode”The direct parent DOM node, or null if this is a root node. (Namespace containers are not parent nodes — parentNode is the nearest ancestor with is.)
select.parentNode # the parent node attrset, or nullselect.parentNode.name # parent's nameselect.parentNode.system # parent's system attrselect (default functor)
Section titled “select (default functor)”Calling select sel filters all nodes in the DOM by selector sel. Returns a list of matching nodes:
select nest.web # all web-trait nodesselect nest.admin # all admin-trait nodes (including marker-only)select (nest.attrs { env = "prod"; }) # all prod nodesThis is the primary way to find nodes across the entire DOM from a rule.
select.siblings sel
Section titled “select.siblings sel”Filter the siblings of the current node — nodes that share the same __parentPath. Excludes the current node:
select.siblings nest.web # sibling web nodesselect.siblings nest.host # all sibling hostsSibling scoping is determined by __parentPath. Nodes under the same namespace (e.g., prod) share __parentPath = null and are siblings of each other across sub-namespaces.
select.children sel
Section titled “select.children sel”Filter the direct children of the current node — nodes whose __parentPath equals this node’s __path:
select.children nest.user # direct user childrenselect.children nest.host # direct host childrenIn rule functions, select.children uses contextCache (pre-rule-synth). In class functions (processNode), it uses finalAnnotated and includes rule-synth children.
select.parent sel
Section titled “select.parent sel”Filter the direct parent (0 or 1 results) by selector:
select.parent nest.host # [ parentHost ] or []select.parent "#cluster" # parent named cluster, or []select.parents sel
Section titled “select.parents sel”Filter all ancestors up to the root by selector:
select.parents nest.host # all ancestor host nodesselect.parents nest.cluster # all ancestor cluster nodesselect.within nd sel
Section titled “select.within nd sel”Filter all descendants of DOM node nd by selector:
select.within hostNode nest.user # all users under hostNodeselect.within clusterNode nest.web # all web nodes under clusterUnlike select.siblings (which is relative to the current node), select.within takes an explicit DOM node as its scope.
Select context fields (internal)
Section titled “Select context fields (internal)”Rule functions access select directly. If you need raw context data for advanced use:
{ is = nest.host; nixos = { select, ... }: let ctx = select; # select IS the context (has __functor) children = ctx.children; # list of direct child nodes (unfiltered) ancestors = ctx.ancestors; # list of ancestors (unfiltered) allNodes = ctx.allNodes; # all nodes in DOM in …;}select.children (without a selector arg) is the raw children list. select.children nest.user applies the filter.
Examples
Section titled “Examples”haproxy backends from sibling webs
Section titled “haproxy backends from sibling webs”{ is = nest.lb; nixos = { select, ... }: let webs = select.siblings nest.web; in { services.haproxy.backends = map (w: "${w.addr}:${toString w.httpPort}") webs; };}/etc/hosts from all peers
Section titled “/etc/hosts from all peers”{ is = nest.host; nixos = { select, ... }: let peers = select.siblings nest.host; in { networking.extraHosts = lib.concatMapStringsSep "\n" (p: "${p.addr} ${p.name}") peers; };}Access parent system from child
Section titled “Access parent system from child”{ is = nest.user; user = { select, user, ... }: let parentHost = builtins.head (select.parent nest.host); in { parentSystem = parentHost.system; };}Count users on a host
Section titled “Count users on a host”nest.trait.host.synth = select: { node.userCount = builtins.length (select.children nest.user);};