Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I apply another flake's overlays to pkgs? #106

Open
antifuchs opened this issue Jan 20, 2023 · 13 comments
Open

How do I apply another flake's overlays to pkgs? #106

antifuchs opened this issue Jan 20, 2023 · 13 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@antifuchs
Copy link

I'm trying out flake-parts for our company's devShell, and it does look a lot tidier than the previous flake-utils based mess we had! But there's one thing I'm not sure about: We're using fenix to provide a pinned cargo/rustc in our devShell, which strongly recommends using its overlay to install the fenix attribute on pkgs. So: Is there a way to apply other overlays to the "final" perSystem pkgs?

I found the so-called easyOverlay attributes, but it looks like that puts the packages only onto the default overlay exported from the flake, not on the internal pkgs available to the flake itself. Am I missing something? Is this something that could be supported in a convenient way by flake-parts?

@szlend
Copy link

szlend commented Jan 20, 2023

You can override pkgs like so:

{
  perSystem = { pkgs, system, ... }: {
    _module.args.pkgs = import nixpkgs { inherit system; overlays = [ myOverlay ]; };
  };
}

By default it's set to inputs'.nixpkgs.legacyPackages.

@dhess
Copy link

dhess commented Jan 21, 2023

You can override pkgs like so:

Thanks, that was very timely, as we're going through a similar process to @antifuchs.

FYI, we do this sort of thing in nearly all of our flakes, so it would be nice if it were more ergonomic.

@antifuchs
Copy link
Author

Thank you very much, @szlend, that is exactly what I was hoping for. Agreed that this would be an excellent thing to allow for a customization, but there are many nixpkgs options people might want to set - privileging overlays like that might make the other options annoying (I am thinking of #105 here, but other options exist too).

@roberth roberth added enhancement New feature or request question Further information is requested labels Feb 1, 2023
@ParetoOptimalDev
Copy link

So the best way to use something like emacs-overlay in a flake-parts flake would be this (working) flake?

{
  description = "Description for the project";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    emacs-overlay.url = "github:nix-community/emacs-overlay";
  };

  outputs = inputs@{ flake-parts, nixpkgs, emacs-overlay, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      systems = [ "x86_64-linux" "aarch64-darwin" ];
      perSystem = { config, self', inputs', pkgs, system, ... }: {
        _module.args.pkgs = import nixpkgs
          {
            inherit system;
            overlays = [ emacs-overlay.overlays.default ];
          };
        packages.default = pkgs.emacsGit;
      };
      flake = { };
    };
}

_module.args.pkgs = import nixpkgs seems hacky and _module seems like something that's internal. Is that untrue?

@szlend
Copy link

szlend commented Feb 10, 2023

It feels a bit hacky yeah, but this is essentially how you define special args in the standard nixos module system. From what I gather, the long term plan is to remove nixpkgs entirely from the default flake-parts setup (#41) and replace it with an easily configurable nixpkgs module (#74) that you can import.

@ParetoOptimalDev
Copy link

@szlend Thank you so much for that context, that sounds like a good plan.

@antifuchs
Copy link
Author

antifuchs commented Mar 19, 2023

Just came up against another scenario where I don't quite get how to set the arguments on a flake part: I'm trying to define dockerContainers, and so (AIUI) I need to use withSystem, as they're not supported by perSystem.

My flake part defining these docker containers does the following:

{
  self,
  lib,
  pkgs',
  inputs,
  withSystem,
  ...
}: {
  flake.dockerContainers.boinkornet-monitor = withSystem "x86_64-linux" ({pkgs, ...}: pkgs.callPackage ./monitor {});
  flake.dockerContainers.boinkornet-media-forwarder = withSystem "x86_64-linux" ({pkgs, ...}: pkgs.callPackage ./media-forwarder {});
}

And the monitor/default.nix calls dockerTools.buildLayeredImage; I'd like the withSystem's pkgs argument to be augmented with overlays, but I don't quite see where to put the _module.args.pkgs in this scheme such that flake.parts can define the container with the right pkgs definition.

Update: The trick seems to be to use perSystem in my flake part and set a different argument (pkgs is already getting overridden with overlays in another part, and setting that leads to an infinite recursion). The following seems to work:

{
  self,
  lib,
  pkgs',
  inputs,
  withSystem,
  ...
}: {
  perSystem = {
    config,
    system,
    self',
    inputs',
    pkgs,
    ...
  }: {
    _module.args = {
      finalPkgs = import inputs.nixpkgs-linux {
        inherit system;
        overlays = [
          self.overlays.default # Pulls in the overlay defined by this flake
        ];
      };
    };
  };
  flake.dockerContainers.boinkornet-monitor = withSystem "x86_64-linux" ({finalPkgs, ...}: finalPkgs.callPackage ./monitor {}); # Uses the packages augmented with our flake's overlay
  flake.dockerContainers.boinkornet-media-forwarder = withSystem "x86_64-linux" ({pkgs, ...}: pkgs.callPackage ./media-forwarder {});
}

@sandangel
Copy link

Hi, could someone help me, how to use easyOverlay with _module.args.pkgs?

@sandangel
Copy link

sandangel commented Apr 1, 2023

      perSystem = { config, self', inputs', pkgs, system, lib, devenv, ... }: {
        _module.args = {
          pkgs = import nixpkgs {
            inherit system;
            # For ssm-session-manager-plugin
            config.allowUnfree = true;
            overlays = [
              (_: _: {
                inherit (config.packages) neovim-nightly vcluster kubeswitch yamlfmt comic-code flypie;
              })
            ];
          };
        };
        devenv.shells.default = {
          languages.nix.enable = true;
        };
        packages = with pkgs; {
          neovim-nightly = neovim.packages.${system}.neovim;
          vcluster = callPackage ./pkgs/vcluster { };
          kubeswitch = callPackage ./pkgs/kubeswitch { };
          yamlfmt = callPackage ./pkgs/yamlfmt { };
          comic-code = callPackage ./pkgs/comic-code { };
          flypie = callPackage ./pkgs/flypie { };
        };
        overlayAttrs = {
          inherit (config.packages) neovim-nightly vcluster kubeswitch yamlfmt comic-code flypie;
        };
      };

This is what I have so far. It's working but I like to do something like this:

        _module.args = {
          pkgs = import nixpkgs {
            inherit system;
            # For ssm-session-manager-plugin
            config.allowUnfree = true;
            overlays = [ config.flake.overlays.default ];
          };
        };
        overlayAttrs = {
          inherit (config.packages) neovim-nightly vcluster kubeswitch yamlfmt comic-code flypie;
        };

But it will generate error config.flake is not available.

@nazarewk
Copy link

nazarewk commented Nov 2, 2023

https://github.com/nazarewk-iac/nix-configs/blob/7267866a4ddc0800d157c6ac8ce6fe6e4fd14196/packages/flake.nix#L19-L29 works pretty well for me:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    poetry2nix.inputs.nixpkgs.follows = "nixpkgs";
    poetry2nix.url = "github:nix-community/poetry2nix";
    systems.url = "github:nix-systems/default";
  };

  outputs = inputs@{ flake-parts, self, ... }: flake-parts.lib.mkFlake { inherit inputs; } {
    systems = import inputs.systems;
    flake.overlays.default = (inputs.nixpkgs.lib.composeManyExtensions [
      inputs.poetry2nix.overlays.default
      (final: prev: { kdn = final.callPackages ./. { }; })
    ]);
    perSystem = { config, self', inputs', system, pkgs, ... }: {
      _module.args.pkgs = inputs'.nixpkgs.legacyPackages.extend self.overlays.default;
      packages = pkgs.kdn;
    };
  };
}

depending on your use case you can replicate inputs.nixpkgs.lib.composeManyExtensions pattern into _module.args.pkgs and move overlays between flake-level and args-level

@sandangel
Copy link

hi @nazarewk , thanks for your reply. I think I can not do the same because in the flake.overlays.default, i will need the value of system because I have neovim-nightly = neovim.packages.${system}.neovim;.

@nazarewk
Copy link

nazarewk commented Nov 8, 2023

hi @nazarewk , thanks for your reply. I think I can not do the same because in the flake.overlays.default, i will need the value of system because I have neovim-nightly = neovim.packages.${system}.neovim;.

You mean like this?

I'm pretty sure you can use ${pkgs.stdenv.system} whenever you need ${system} value, in case of overlays final.stdenv.system:

devenv = inputs.devenv.packages.${final.stdenv.system}.default;

@sandangel
Copy link

hmm, but then how can I set the allowUnfree for pkgs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

7 participants