colmena icon indicating copy to clipboard operation
colmena copied to clipboard

Add a lib function to extract nixosConfigurations from raw flake

Open immae opened this issue 1 year ago • 10 comments

This PR adds a function to load colmena hive from the flake.

Use case: If I have a flake output like this:

  outputs = {}: {
    colmena = {
      systemA = {...};
      systemB = {...};
    };
  }

Currently I have no way to obtain the nixosConfiguration associated to systemA and systemB. With this new function, I can now do for instance

  inputs.colmena = "github:zhaofengli/colmena";
  outputs = { colmena }: {
    nixosConfiguration = (colmena.fromRawFlake self).nodes;
    colmena = {
      systemA = {...};
      systemB = {...};
    };
  }

And this nixosConfiguration will contain the same system as the one that would be built by colmena. This is incomplete (keys are not uploaded), but it is still useful in (at least) two situations:

  • If I want to test the configuration in a VM (or anywhere)
  • If I want to bootstrap the machine with for instance https://github.com/numtide/nixos-anywhere

This function roughly adds the same content as what "colmena repl" gives access to, but in a nix evaluation context.

immae avatar Jun 28 '23 12:06 immae

I use something similar but to convert from nixosConfigurations to colmena. Such as: https://github.com/otavio/nix-config/blob/acd39f39b97677e1bd7aadf542fc41c334b1890d/lib/default.nix#L4-L13 and used in https://github.com/otavio/nix-config/blob/acd39f39b97677e1bd7aadf542fc41c334b1890d/flake.nix#L78

otavio avatar Jun 28 '23 13:06 otavio

@otavio : we could indeed have two functions to do it both ways (colmena -> nixosConfiguration and nixosConfiguration -> colmena)

immae avatar Jun 28 '23 13:06 immae

Note however that in your case (nixosConfiguration -> colmena) you don’t get the exact same output between colmena build and nix build .#nixosConfigurations.hostName.config.system.build.toplevel, since colmena adds its own specific changes. The other way around ensures that colmena’s additions get included too

immae avatar Jun 28 '23 13:06 immae

I would also like this feature.

My use-case is that my colmena configuration contains the list of hosts, IP addresses, and DNS names. I have an app defined in my flake that takes this information and generates a Terraform config I can use to update Route 53 (i.e. I can run nix run .#route53-config to generate the config). Although all the information I need is in nodes, I don't think I can currently extract this for use in the flake.

I'm working around this by having an extra nix file that just duplicates the information and doesn't require any evaluation, but I'd love to get rid of it.

scvalex avatar Nov 01 '23 15:11 scvalex

I'm working around this by having an extra nix file that just duplicates the information and doesn't require any evaluation, but I'd love to get rid of it.

Why not use that extra file as single source of truth and import it onto the flake(s) instead?

bjornfor avatar Nov 01 '23 15:11 bjornfor

Why not use that extra file as single source of truth and import it onto the flake(s) instead?

It’s not sufficient if you have configuration that depends on other nodes (i.e. if you use the nodes parameters in some places). That’s why I introduced that change: it comes after the resolution

immae avatar Nov 01 '23 16:11 immae

I'm working around this by having an extra nix file that just duplicates the information and doesn't require any evaluation, but I'd love to get rid of it.

Why not use that extra file as single source of truth and import it onto the flake(s) instead?

That's basically what I'm doing, but I don't like it. As in, I'd much rather write config.some.option = "1.2.3.4" then config.some.option = (import ./machines.nix)."${hostname}".ipAddress.

The thing that makes me dislike the above is that the IP address string I have is the input of some potentially complicated expression. For example, my machines file specifies ipAddreess, lanIpAddress, and wgIpAddress for most hosts. Which of these is used in different configuration options depends on whether the machine is a VM in a cloud, a physical server in the cloud, or some machine in my home network. I've already written modules to figure out what to use and where, but if I want to write a script that uses this information, I have to duplicate the logic from my modules.

scvalex avatar Nov 01 '23 16:11 scvalex

I made a PR that documents how to install NixOS with Colmena, https://github.com/zhaofengli/colmena/pull/209

Hopefully this helps!

itslychee avatar May 14 '24 01:05 itslychee

@itslychee That's a nice tutorial, but I'm struggling to see how it relates to anything here.

This PR is about getting the generated nodes configuration out of colmena so that it can be used in other nix expressions. Your PR is about installing on a new machine.

scvalex avatar May 14 '24 10:05 scvalex

@itslychee That's a nice tutorial, but I'm struggling to see how it relates to anything here.

This PR is about getting the generated nodes configuration out of colmena so that it can be used in other nix expressions. Your PR is about installing on a new machine.

you're right, i should read more. Personally was having issues with this and was seeing if anyone else was confused so i could help out in any way!

itslychee avatar May 14 '24 11:05 itslychee