Skip to content

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:

modules/sinks.nix
# 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) makes ports feed config: 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 of config with its own name. A sink cannot feed itself, so this forward goes strictly up: to the nearest config sink above the guest, the host’s.

Aspects give the elements:

modules/aspects.nix
{ 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:

result
{
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
ContributeCommunitySponsor