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

nix-shell dependencies can be garbage collected any time now / persistent nix-shell envs #2208

Closed
goodwillcoding opened this issue Jun 4, 2018 · 18 comments
Assignees
Labels
bug error-messages Confusing messages and better diagnostics UX The way in which users interact with Nix. Higher level than UI.

Comments

@goodwillcoding
Copy link

goodwillcoding commented Jun 4, 2018

There does not seem to be a way to prevent nix-shell dependencies from being garbage collected at any time. Related to this, for a while now there been possible to create persistent nix-shell environments that would be spared garbage collection. Neither of the two methods (see below) are now working.

shell.nix

with import <nixpkgs> {};
stdenv.mkDerivation {
    src = "./.";
    name = "test-0.1";
    buildInputs = [ hello ];
}

Previous Method 1 (https://nixos.org/nix-dev/2016-November/022173.html):

nix-instantiate shell.nix --show-trace  --indirect --add-root "$(pwd)/"shell.drv
nix-shell $(readlink $(pwd)/shell.drv)

While this does create a gcroot to the derivatation, it does not work (my guess cause it is not a gcroot to the build output)

$ tree /nix/var/nix/gcroots/auto/
/nix/var/nix/gcroots/auto/
└── rz3awpwi7lxpwfjmhqbab0rdfc3nj94m -> /home/user/tmp/persist-nix-shell/shell.drv

If nix-collect-gc is run while the shell is active it cleans up everything this derivation depends on

Previous Method 2:

mkdir gcroot
nix-shell shell.nix --indirect --add-root "gcroot/gc"

This used to create symlinks to dependencies, how ever since --indirect is now ignored as of 19477e8 this also no longer works as gcroot to the output is no longer created.

Please advise on this

@goodwillcoding
Copy link
Author

@edolstra any thoughts? suggestion on this ^

@srghma
Copy link

srghma commented Aug 11, 2018

Method 1 makes gcroot for shell derivation, this indeed doesnt prevent it dependencies to be garbage collected
Method 2 should makes gcroot for each dependency of shell derivation, but it's not working indeed

I have made script that makes same as method 2

#! /bin/sh -eu

# make gcroot for each dependency of shell and run nix-shell

mkdir -p .gcroots
nix-instantiate shell.nix --indirect --add-root $PWD/.gcroots/shell.drv
nix-store --indirect --add-root $PWD/.gcroots/shell.dep --realise $(nix-store --query --references $PWD/.gcroots/shell.drv)
exec nix-shell $(readlink $PWD/.gcroots/shell.drv)

tnx to http://nix-dev.science.uu.narkive.com/QjeSH005/truly-persistent-nix-shell

@lheckemann
Copy link
Member

lheckemann commented Aug 12, 2018

Do you have the keep-derivations and keep-outputs options set to true in your nix.conf? This is necessary for this to work iirc.

@srghma
Copy link

srghma commented Aug 13, 2018

@lheckemann no, I dont have this options

 ~  cat /etc/nix/nix.conf
# WARNING: this file is generated from the nix.* options in
# your NixOS configuration, typically
# /etc/nixos/configuration.nix.  Do not edit it!
build-users-group = nixbld
max-jobs = 40
cores = 0
sandbox = true
extra-sandbox-paths =
substituters = https://cache.nixos.org https://cachix.cachix.org https://srghma.cachix.org
trusted-substituters =
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM= srghma.cachix.org-1:EUHKjTh/WKs49hFtw6bwDE9oQLeX5afml0cAKc97MbI=
auto-optimise-store = false
require-sigs = true

trusted-users = root srghma
allowed-users = *
builders =

auto-optimise-store = true

@lheckemann
Copy link
Member

keep-derivations (sorry, got the name wrong in my previous comment) defaults to true, so that should be fine.
Try adding nix.extraOptions = "keep-outputs = true"; to your configuration.nix and rebuilding, then see if your shell dependencies still get gc'd when you use method 1.

keep-outputs
    If true, the garbage collector will keep the outputs of non-garbage derivations. If false (default), outputs
    will be deleted unless they are GC roots themselves (or reachable from other roots).
    In general, outputs must be registered as roots separately. However, even if the output of a derivation is
    registered as a root, the collector will still delete store paths that are used only at build time (e.g., the C
    compiler, or source tarballs downloaded from the network). To prevent it from doing so, set this option to true.

@srghma
Copy link

srghma commented Aug 13, 2018

@lheckemann with keep-outputs and using this script

#! /bin/sh -eu

mkdir -p .gcroots

# add shell as gc-root in /nix/var/nix/gcroots/auto
nix-instantiate shell.nix --indirect --add-root $PWD/.gcroots/shell.drv

exec nix-shell $(readlink $PWD/.gcroots/shell.drv) "$@"

garbage collector indeed keep dependencies of shell, neat trick, but I still use the previous version of the script since keep-outputs = true is not defaut

fiksn added a commit to fiksn/nix that referenced this issue Dec 3, 2019
matt-snider added a commit to matt-snider/nix-direnv that referenced this issue Mar 5, 2020
It appears that the derivations produced by nix-direnv are removed when running nix's garbage collection. Troubleshooting this issue led me to a git issue in the NixOS/nix repo [1]. Enabling both `keep-derivations` and `keep-outputs` worked for me as recommended, and now nix-direnv is working.

[1]: NixOS/nix#2208
@domenkozar domenkozar added bug error-messages Confusing messages and better diagnostics labels Dec 14, 2020
@Elvecent
Copy link

While the script above works, I'd really love to have a first-class feature like this. Protecting a shell's dependencies from garbage collection is something I'd expect to be immediately configurable, I mean, per shell.

Is it possible for nix-shell to check some "protected" setting in shell.nix and accordingly update relevant gc roots? Said roots should probably also be removed when the setting is switched off.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/pinned-nixpkgs-keeps-getting-garbage-collected/12912/5

@sleirsgoevy
Copy link

Found a solution:

nix-build -A inputDerivation -o gcroots

This will build a dummy derivation that has the shell's inputs as runtime dependencies, and place a GC root into gcroots.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/starting-nix-shell-without-rebuilding/16394/7

@con-f-use
Copy link

Isn't keep-outputs effectively equivalent to turning off garbage collection completely (except for build dependencies which still get collected)?

@kevincox
Copy link
Contributor

I was surprised that nix-shell --add-root result-shell runs successfully but doesn't actually add a root. I think if we could make that option work it would be a great first step. Then we can decide if it makes sense to do this by default.

@con-f-use
Copy link

con-f-use commented Jul 4, 2022

Gentle bumb @edolstra , since this seems like essential functionality. I suspect a lot of people would like to not download the entire internet every time an often used nix-shell gets garbage collected. Can we have an easy to use option to keep a nix-shell and its dependencies? See kevincox's post directly above.

@tengkuizdihar
Copy link

@sleirsgoevy will the old derivation be included in the GC when I change the shell.nix? I was hoping for that kind of behavior, where the only one that's GC'd is everything but the current one that's being used.

@fricklerhandwerk fricklerhandwerk added the UX The way in which users interact with Nix. Higher level than UI. label Dec 5, 2022
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2022-12-09-nix-team-meeting-minutes-15/23951/1

@fricklerhandwerk
Copy link
Contributor

Discussed in Nix team meeting on 2022-12-19.

Decision: closing as won't fix.
Reason: This is what nix develop will support, and fixing nix-shell is too complicated to be worth the effort. Previous attempts did not succeed. Nixpkgs implements this behavior using the Nix language, and probably so should nix develop – but that is a separate isuse.

Complete discussion

@fricklerhandwerk fricklerhandwerk closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2022
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2022-12-16-nix-team-meeting-minutes-17/24120/1

@tobiasBora
Copy link

What's the nix develop way to solve this? I tried to use nix develop --profile shell_profile_nix_develop but I can't find any link added in /nix/var/nix/gcroots, and I'm affraid to manually do something like nix develop --profile /nix/var/nix/gcroots/auto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug error-messages Confusing messages and better diagnostics UX The way in which users interact with Nix. Higher level than UI.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.