Forwards
The keys of a sink, other than reduce, of, at and out, give elements to other sinks.
They run at the receiver, with the receiver’s args. You already know one: out gives to the flake
(see Flake outputs).
In this example a host has a guest. The kinds are in the example code. These are the sinks:
# A sink's other keys give elements to other sinks. They run at the receiver, with its args.{ yen, ... }:let inherit (yen.lib.reduce) merge;in{ yen.kinds.host.sinks = { ports.config = { ports, ... }: { firewall.allowedTCPPorts = ports; }; # (1) ports feed config config = { reduce = merge; out = { host, config, ... }: { config.${host.name} = config; }; }; }; yen.kinds.guest.sinks = { ports.config = { ports, ... }: { firewall.allowedTCPPorts = ports; }; # (2) config = { reduce = merge; config = { guest, config, ... }: { vms.${guest.name} = config; }; # (3) its own name: a forward up, to the host }; };}- At a host,
(1)makesportsfeedconfig: aspects give port numbers, and the host turns them into firewall config. - At a guest,
(2)does the same. - At a guest,
(3)is a key ofconfigwith its own name. A sink cannot feed itself, so this forward goes strictly up: to the nearestconfigsink above the guest, the host’s.
Aspects give the elements:
{ yen, ... }:{ yen.aspects.ssh = { at = yen.kinds.host; ports = 22; # (1) }; yen.aspects.runner = { at = yen.guest.ci; ports = 8080; config.runner.enable = true; # (2) };}(1) gives a port at every host. (2) is a config element at the guest ci.
The guest’s config arrives inside the host’s config, under vms.ci:
{ server = { firewall = { allowedTCPPorts = [ 22 ]; }; vms = { ci = { firewall = { allowedTCPPorts = [ 8080 ]; }; runner = { enable = true; }; }; }; };}flowchart BT n6c4c773b6d["fleet main"] n04467a35ae["host server"] n99b25160dc["guest ci"] n99b25160dc -->|"config"| n04467a35ae n04467a35ae -->|"out"| n6c4c773b6d