Scopes and spawns
A scope is one instance at one place in the tree. The root kind is the kind that no kind spawns.
spawns.<kind> is a function of the parent scope. It gives the instances that live under it.
# `spawns.<kind>` gives the children of a scope: a function of the parent scope.{ yen, lib, ... }:let inherit (yen.lib) same is;in{ yen.kinds.fleet.spawns.environment = _: yen.environment; yen.kinds.environment.spawns.host = s: lib.filterAttrs (_: h: same h.environment s) yen.host; yen.kinds.host = { fields.environment = yen.kinds.environment; spawns.user = s: lib.filterAttrs (_: u: lib.any (same s) u.hosts) yen.user; }; yen.kinds.user.fields.hosts = is lib.isList; # refs to the hosts the user logs in to
yen.fleet.main = { };}{ yen, ... }:{ yen.environment.prod = { }; yen.environment.lab = { }; yen.host.web.environment = yen.environment.prod; yen.host.db.environment = yen.environment.prod; yen.host.box.environment = yen.environment.lab; yen.user.alice.hosts = [ yen.host.web yen.host.box ]; # one user, two scopes yen.user.bob.hosts = [ yen.host.db ];}The tree comes from the data. Nothing lists the children by hand:
flowchart TD n6c4c773b6d["fleet main"] nf631382c77["environment lab"] nc33ee814ad["host box"] n86d1c002a8["user alice"] n4a308930d1["environment prod"] n4019172c9d["host web"] n8bd47cb553["user alice"] nc60807bd8b["host db"] n614abf7a41["user bob"] n6c4c773b6d --> nf631382c77 nf631382c77 --> nc33ee814ad nc33ee814ad --> n86d1c002a8 n6c4c773b6d --> n4a308930d1 n4a308930d1 --> n4019172c9d n4019172c9d --> n8bd47cb553 n4a308930d1 --> nc60807bd8b nc60807bd8b --> n614abf7a41
Identity is a path
Section titled “Identity is a path”The id of a scope is its path: fleet:main/environment:prod/host:web/user:alice.
One instance can live in several places. alice has two scopes, one under each of her hosts.
Names need not be unique.
r.scopes gives the scopes in order:
[ "fleet:main" "fleet:main/environment:lab" "fleet:main/environment:lab/host:box" "fleet:main/environment:lab/host:box/user:alice" "fleet:main/environment:prod" "fleet:main/environment:prod/host:web" "fleet:main/environment:prod/host:web/user:alice" "fleet:main/environment:prod/host:db" "fleet:main/environment:prod/host:db/user:bob"]A parent comes before its children. Siblings sort by the order sink (default 0), then by name.
web comes before db because of this aspect:
# Siblings sort by the `order` sink (default 0), then by name. A parent comes before its children.{ yen, ... }:{ yen.aspects.web-first = { at = yen.host.web; order = -1; };}Read the tree inside the fleet
Section titled “Read the tree inside the fleet”yen.lib.graph is readable by any module. This example gives its scope ids as a flake output:
# The flake gives the scope ids: `yen.lib.graph` is readable inside the fleet.{ yen, ... }:{ yen.kinds.fleet.sinks.out.reduce = yen.lib.reduce.merge; yen.flake = { out, ... }: out; yen.aspects.tree = { at = yen.kinds.fleet; out.scopes = map (s: s.id) yen.lib.graph.scopes; };}