Nix: structuring Flakes with Blueprint

19 Likes

reminded me of GitHub - nix-community/haumea: Filesystem-based module system for Nix [maintainer=@figsoda] with the nix structure based on the filesystem (haumea is difficult to troubleshoot upon errors so I dont necessarily recommend it).
“Blueprint” is close to my own config so I could see myself using it.

A few remarks:

  • One thing I hesitate myself is for the packages/ structure is wether to follow the pkgs/by-name convention (that’s what I ended up doing)
  • there is no folder for overlays ?
  • I like to distinguish between “modules” that provides new mkOption from “profiles” which is a bunch of nix code shared between hosts. There doesn’t seem to be a nomenclature for this distinction which I think could be useful here and in the overall nix ecosystem.
  • I have a bunch of home-manager modules. Could be nice to have those supported out of the box in blueprint as well
8 Likes

I think home manager module support is on the horizon.

To answer your question about overlays in the flake output, that was a conscious choice. They aren’t supported, nor encouraged. @zimbatm can do a better job of explaining why.

1 Like

Don’t quote me on this: fixpoints are responsible for 90% of Nix’s “it’s hard to debug” reputation. I noticed that users tend to have an easier time with blueprint and it might be related to the project not using them.

Blueprint is trying to reach for the common case. The by-name/ with the letter prefixes is a bit overkill below 5-10k packages I would say.

It supports overlays in the config. Overlays are generally not needed (and another source of fixpoint issues) for leaf package changes as you can publish those as your flake’s packages. That’s also why we added the perSystem specialArgs, to make it easier to consume packages from flake inputs.

Sounds good, let’s discuss about this in an issue.

That’s supported, thanks to the recent work from @clo4. Take a look at blueprint/docs/folder-structure.md at 1330a08e62847fb7a4fd38fc021120921145503e · numtide/blueprint · GitHub

2 Likes

I disagree, they’re quite useful for cross-compilation, for example, which I wouldn’t call a particularly rare scenario.

EDIT: and also for exposing unfree packages. The alternative would be, of course, configuring a rogue nixpkgs instance, which would cause the sort of nixpkgs instance explosion you yourself warned against.

I’d even argue that overlays should be preferred whenever possible outside of nixpkgs, if only to prevent this sort of error.

I’ve used blueprint for a few projects before, and it’s pretty great. It gets rid of a lot of annoyances with flakes, but it also makes it incredibly easy to keep nix files organized from the start. Nice to see a blog post tutorial about it - it deserves to be better known!

4 Likes

The text you quote claims the are not needed, you claim that they are useful - both of those claims could be true at the same time.

Maybe you could provide an example of a cross-compilation setup which is either impossible or more complicated without them in a new blueprint issue so we can be sure we are talking about the same thing?

EDIT: and also for exposing unfree packages. The alternative would be, of course, configuring a rogue nixpkgs instance, which would cause the sort of nixpkgs instance explosion you yourself warned against.

You can configure the nixpkgs instance blueprint uses. So the following should work:

blueprint { inherit inputs; nixpkgs.config.allowUnfree = true; };

I’d even argue that overlays should be preferred whenever possible outside of nixpkgs, if only to prevent this sort of error.

What error? Even if one would agree to call an increase in nixpkgs instances from 1 to 2 per platform an “explosion”, how would that constitute an error - am I missing something here?

does blueprint support flake apps?

If you can make pkgsCross work without an overlay or creating a new nixpkgs instance, then I would stand corrected. As it stands, I believe an overlay is needed in such a scenario. (Generally I write my flakes to expose an overlay and package(s).)

The alternative is… creating yet another nixpkgs instance, which would also be way more unwieldy than an overlay if using a package that isn’t even part of the nixpkgs instance.

That’s exactly what was warned against :slight_smile:
That creates a new nixpkgs instance.
That’s acceptable if running a one-off program (nix run) since that becomes the only instance, but not when integrating it into a config.

Not a mere doubling - multiply by every flake input, who in turn may have their own transitive inputs doing the same thing…
But even a mere doubling may be noticeable given how massive nixpkgs has become.

Think more an error in judgment, not an error returned by nix.

Not yet. Is there a use-case that is not supported by packages?

It’s funny because when I wrote 1000 instances of nixpkgs, what I had in mind was that we would be composing packages more. Then part of the readers concluded we should use overlays for everything. This reminds me the composition vs inheritance debate we had in the OOP world a long time ago. Happy to debate this, but maybe in a different thread?

3 Likes

… i entirely forgot that nix run will run packages as well :laughing:

thanks!

2 Likes

I brought it up here to understand if the project was open to making overlays more friendly to expose and/or consume (which would dictate whether I’d use it), and I provided a rationale why that would be worthwhile. If the project’s goal is to essentially pass-through/ignore overlays, I will personally stick with my own glue code.

Sounds good. I can’t promise we’ll end up with overlays but I’ll definitely examine any use-cases or scenario you bring to the project seriously. The project’s shape isn’t locked in 100%.

I have some ideas on how to better handle input overrides and patch management that I haven’t realized yet.

1 Like

Does blueprint have the option of generating flake outputs for the users/hm configs (i.e. homeConfigurations) or are they exclusively defined within the nixos modules?

I may be the minority here, but I prefer to use home manager standalone with nixos. So I was just wondering if it enabled my use case.

I haven’t used it myself, but it looks like you can: blueprint/docs/folder-structure.md at 8853ea68f376237e9d9b896a8bb7e0c6ae980901 · numtide/blueprint · GitHub

1 Like

I was skimming that document and somehow missed it :sweat_smile:. Thanks!

1 Like

I like the look of blueprint, and would like to use it. But have a few questions.

Common config?

I am wondering though about how config common between hosts is recommended to be handled.

Should it just live in a root level folder not handled by blueprint, and then imported in each host config?

Nixpkgs patches

I don’t see any mention of how nixpkgs patches are to be applied?

Thanks!

That’s a great question. The doc currently only has reference material, but it should also cover topics like this.

Until then, take a look at my home configuration. For example I have this desktop module: modules/nixos/desktop.nix. Then in my machine config, I can load it like this:

{ flake, ... }:
{
  imports = [
    flake.nixosModules.desktop
  ];
}

All NixOS and nix-darwin evaluatoins provides a few more attributes than usual: flake gives you access to the current flake output. inputs to access all the inputs. And perSystem to access packages from the other inputs, filtered by the current system.

There are two ways:

  1. by pointing the nixpkgs input to your own fork that includes all the patches you want.
  2. by patching nixpkgs using the overlays systems.

I’m thinking of adding a third way with inputs/nixpkgs/*.patch to allow storing the patches locally with the flake. That would be more ergonomic in some scenarios.

Ah, thank you.

That does seem like a nice way to handle shared config, thank you for sharing. I hadn’t really considering using the nixos modules folder for anything but modules I plan on upstreaming to nixpkgs.

Regarding patching nixpkgs

  1. Maintain my own patched nixpkgs for seems annoying, especially if I end up using patches from a few PRS. More friction than I would like.
  2. I don’t think overlays allow for applying patches from PRS?
  3. This seems like the best option, although extra features to implement and maintain are far from ideal. For reference, I am trying to replicate the behaviour I have from my somewhat home grown glue helpers here.

Thanks again.

1 Like

Looks cool. I might be ahead of the curve with this question, but do you intend on upstreaming blueprint when it stabilizes?