Nixpkgs: Possible to exclude some package from environment.systemPackages?

Created on 7 Dec 2017  路  19Comments  路  Source: NixOS/nixpkgs

Issue description

How to exclude package from environment.systemPackages without patching nixpkgs source tree?
For example i want to remove cifs-utils from custom ISO, but i don't know how.

Most helpful comment

The thing with defaultPackages is that it again has the very same problem: You can't remove a single package from it without redefining the whole list. For your use case of having a minimal system it might work well, but for people who just want to remove a single package it doesn't. I think this might be a decent temporary partial solution though and I wouldn't be opposed to a PR.

Because this is a problem for all listOf options though, I'm intending to soon create an RFC to deprecate the listOf type completely, while introducing a lot of replacement types with better semantics. I think it might even be possible to even keep the existing environment.systemPackages in a fully backwards compatible way while still allowing overriding of anything.

All 19 comments

Am I missing something? cifs-utils shouldn't be present by default, can't you just not add it?

[root@nixos_iso:~]# ls -lha /nix/store/ | grep "cifs"
dr-xr-xr-x 1 root root     77 Jan  1  1970 dwf5l21li4cq9kr6sb2mp0wnbxwz08k5-cifs-utils-6.6

After build ISO with this nix config - https://gist.github.com/MrSorcus/bd445af65cb055fa7699ace40a541247

That doesn't necessarily mean it's installed: it may have been pulled in as a dependence of any other derivation that referenced it somehow.
You can do nix-store -q --referrers /nix/store/dwf5l21li4cq9kr6sb2mp0wnbxwz08k5-cifs-utils-6.6 to found out which one[s].

[root@nixos_iso:~]# nix-store -q --referrers /nix/store/dwf5l21li4cq9kr6sb2mp0wnbxwz08k5-cifs-utils-6.6
/nix/store/jrzvdn6jb478i5yg2r2lyvndlnaby8i6-system-path

[root@nixos_iso:~]# nix-store -q --referrers /nix/store/jrzvdn6jb478i5yg2r2lyvndlnaby8i6-system-path
/nix/store/0ajgk8fmnmcqn8bzyd2mpv5x9fx0rr9v-unit-systemd-fsck-.service
/nix/store/9yzhdd5zllcpz7fack8h4w8qwsz19q9c-unit-polkit.service
/nix/store/q9plx3bdvghxixy7vrjyhx2vbrw8493v-dbus-1
/nix/store/dszlldx4a82fv5d1p9amnnmkhi12d0c4-etc
/nix/store/jxg1cd1ywnccpl0r5nda2nirg3r3yxy1-nixos-system-nixos_iso-18.03.git.4c1cd74
[root@nixos_iso:~]# ls -lha /nix/store | grep "python"
dr-xr-xr-x 1 root root     96 Jan  1  1970 9n2npaz7xy8b4q0a8k28nr3sjzfy625i-python-2.7.14

[root@nixos_iso:~]# nix-store -q --referrers /nix/store/9n2npaz7xy8b4q0a8k28nr3sjzfy625i-python-2.7.14/
/nix/store/9n2npaz7xy8b4q0a8k28nr3sjzfy625i-python-2.7.14
/nix/store/vzhpw0jxm2ys8zg61bbi8d0qgfrrgr80-talloc-2.1.8

[root@nixos_iso:~]# nix-store -q --referrers /nix/store/vzhpw0jxm2ys8zg61bbi8d0qgfrrgr80-talloc-2.1.8
/nix/store/vzhpw0jxm2ys8zg61bbi8d0qgfrrgr80-talloc-2.1.8
/nix/store/dwf5l21li4cq9kr6sb2mp0wnbxwz08k5-cifs-utils-6.6

[root@nixos_iso:~]# nix-store -q --referrers /nix/store/dwf5l21li4cq9kr6sb2mp0wnbxwz08k5-cifs-utils-6.6
/nix/store/jrzvdn6jb478i5yg2r2lyvndlnaby8i6-system-path

I found that python 2.7.14 used only by talloc, that used by cifs-utils, but i can't found options for disabling them.

I built a vm with your config and I couldn't find cifs-utils in the nix store.
It probably means it's a dependency of something related to the live CD configuration.

I build ISO image only. Not VM.
Steps:

git clone https://github.com/NixOS/nixpkgs.git
cd nixpkgs/nixos
nix-build -A config.system.build.isoImage -I nixos-config=../../nixos_cd_iso.nix default.nix

I found some info about cifs here - https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/tasks/filesystems/cifs.nix
Maybe something calling all nix files from nixpkgs/nixos/modules/tasks/filesystems directory?

Yes, that's it. installation-cd-base.nix imports profiles/base.nix which defines

 boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" ];

filesystems/cifs.nix then adds cifs-utils to the system.fsPackages.

You could set

boot.supportedFilesystems = lib.mkForce [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" ];

Or don't use installation-cd-base.nix at all and define your base configuration.

You right, it's working.
But still no answer about excluding packages from predefined systemPackages.
cifs-utils was just an example. But this not the only one package, that i want to remove/replace in ISO.

I don't think there is a way besides using lib.mkForce [...].
Why do you care so much? Are you trying to make a stripped down image?

Just interesting. Interesting in features provided by NixOS
NixOS is a wonderful project, but it is very unfinished.
Too many places where instead of simplification you get complications.
NixOS looks simple only at the beginning of the path.
And the nix syntax only complicates everything.
I have a lot of free time and I could contribute in nixpkgs,
but nix does not dispose of this.
NixOS obviously needs serious refactoring.

@rnhmjoj It'd be great to be able to do that, actually. The defining feature of NixOS is exactly that: not every artifact in Nix store is pulled into system environment.

In other words, NixOS has a concept of end user dependencies, while most other distros don't.

Another use case: services.xserver.desktopManager.xfce is rather bloated, and there is no excludePackages option that is sometimes present in such case (I should really get to that). It would be neat to be able to exclude some package that is pulled into system environment, say, mousepad:

{ config, lib, pkgs, ... }:

{
  environment.systemPackages =
    lib.mkForce (lib.subtractLists [ pkgs.xfce.mousepad ] config.environment.systemPackages);
}

The problem is here is that there is no way that I know of to self-reference a module option without triggering infinite recursion. If you know, do tell me!

I think it should not be semantically ambiguous to at least be able to reference an option value with lower priority, but that would probably require a change in the way overrides are stored (and called).

The problem is here is that there is no way that I know of to self-reference a module option without triggering infinite recursion. If you know, do tell me!

It doesn't seem possible without changing either they way Nix works or the sources in nixpkgs.
@Infinisil noted that the apply argument of mkOption can be used to implement this filter but still one need to change the expression in nixpkgs.

Another use case: services.xserver.desktopManager.xfce is rather bloated

In this case one or more options could be implemented to control the set of packages.
Actually there are a few already.

I'm afraid there is no other way to go beside tracking where the package came from and disabling it if possible.

Thank you for your contributions.

This has been automatically marked as stale because it has had no activity for 180 days.

If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.

Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.

This is still relevant. I think I have a good idea for how to solve it: Instead of environment.systemPackages being a list, we make it an attribute set, let's call it environment.systemPackageAttrs to not be confusing. This would be defined like

{
  options.environment.systemPackageAttrs = mkOption {
    type = attrsOf (nullOr package);
    default = {};
  };

  config.environment.systemPackages =
    attrValues (filterAttrs (n: v: v != null)
    config.environment.systemPackageAttrs);
}

With this you can add packages with

{
  environment.systemPackageAttrs = {
    inherit (pkgs)
      foo
      bar
      baz;
  };
}

You can also remove packages with

{
  environment.systemPackageAttrs.foo = mkForce null;
}

My goal was to create a minimal NixOS image, since a LXC image with nginx was about 600 MB!

I asked where the default packages are defined: https://discourse.nixos.org/t/where-are-default-programs-defined/7757/4

Answer: https://github.com/NixOS/nixpkgs/blob/e0ece5aebe886d11c9e14f054e0af3cec3a60636/nixos/modules/config/system-path.nix#L10-L45

And how to overwrite that with an empty list. There seem to be no solution right now, but this issue seem related.

My idea is to add a new option environment.defaultPackages with packages a user would expect from a minimal linux. But they can just overwrite it environment.defaultPackages = [];. But that needs to be tested and should not break the system!

I guess in best case requiredPackages would not exist, since it defines dependencies implicitly. At least it should not contain packages that are actually not required. So defaultPackages is needed. environment.systemPackages can just be empty then.

I removed 3 items from requiredPackages and it turned out that some packages had implicit dependencies on them. https://github.com/NixOS/nixpkgs/pull/91213

@Infinisil your proposed overwriting mechanic seems very complicated and not userfriendly. Something named systemPackageAttrs is not self explaining to new NixOS users. I would prefer that we have a list like defaultPackages and remove items from the list. That should be intuitive to anyone.

I would add such changes for 21.03, so we have enough time to test it.

What to you think?

The thing with defaultPackages is that it again has the very same problem: You can't remove a single package from it without redefining the whole list. For your use case of having a minimal system it might work well, but for people who just want to remove a single package it doesn't. I think this might be a decent temporary partial solution though and I wouldn't be opposed to a PR.

Because this is a problem for all listOf options though, I'm intending to soon create an RFC to deprecate the listOf type completely, while introducing a lot of replacement types with better semantics. I think it might even be possible to even keep the existing environment.systemPackages in a fully backwards compatible way while still allowing overriding of anything.

+1 on the defaultPackages idea. We really need to decouple

what we test to yield a working system

from

what people might want in a standard installation

Could also be done without an additional option of course, but I think its nice to have a place where this distinction is reified in the source.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

grahamc picture grahamc  路  3Comments

matthiasbeyer picture matthiasbeyer  路  3Comments

langston-barrett picture langston-barrett  路  3Comments

copumpkin picture copumpkin  路  3Comments

copumpkin picture copumpkin  路  3Comments