libcmd/profiles: keep derivations if keep-env-derivations = true
nix3 CLI never honored that setting. When we update a nix3 profile element with new built store paths for which we know the deriver (the derivation path which built it), we add the derivation paths to the profile element to prevent garbage collection the same way the nix2 CLI logic does. Fixes #1095. Change-Id: Icc236d174c5ce5ffe042d1c8e1968f6cb5b50359 Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
---
|
||||
synopsis: "keep-env-derivations is now supported for nix3 CLI (nix profile)"
|
||||
cls: [5332]
|
||||
issues: [fj#1095]
|
||||
category: "Features"
|
||||
credits: [raito]
|
||||
---
|
||||
|
||||
The `keep-env-derivations` feature is now available for `nix profile`. This allows users to prevent the garbage collection of derivations used to install a profile, even when `keep-derivations = false` (set to `true` by default).
|
||||
|
||||
Previously, `nix-env` supported this feature, but `nix profile` **never** did. This caused issues when garbage collection removed the associated `.drv` files, which are required, for example, by vulnerability management tools (e.g. [vulnix](https://github.com/nix-community/vulnix)) for proper operation.
|
||||
|
||||
This issue has now been resolved.
|
||||
@@ -98,6 +98,10 @@ void ProfileElement::updateStorePaths(
|
||||
for (auto & output : bfd.outputs) {
|
||||
storePaths.insert(output.second);
|
||||
}
|
||||
|
||||
if (settings.envKeepDerivations) {
|
||||
storePaths.insert(bfd.drvPath.path);
|
||||
}
|
||||
},
|
||||
},
|
||||
buildable.raw()
|
||||
|
||||
@@ -2,6 +2,7 @@ import re
|
||||
import json
|
||||
import pytest
|
||||
from textwrap import dedent
|
||||
from pathlib import Path
|
||||
|
||||
from testlib.fixtures.file_helper import File, with_files
|
||||
from testlib.fixtures.nix import Nix
|
||||
@@ -279,3 +280,39 @@ def test_conflict_resolution_cppnix_8284(nix: Nix):
|
||||
|
||||
expr = f'(builtins.getFlake "./flake2").packages.{system}.default'
|
||||
nix.nix(["profile", "install", "--impure", "--expr", expr]).run().expect(1)
|
||||
|
||||
|
||||
class TestKeepEnvDerivations:
|
||||
@with_files({"flake1": flake})
|
||||
def test_keep_derivations_enabled(self, nix: Nix, env: ManagedEnv):
|
||||
nix.settings["keep-env-derivations"] = "true"
|
||||
nix.settings["keep-derivations"] = "false" # NOTE: This defaults to `true`.
|
||||
|
||||
nix.nix(["profile", "install", "./flake1", "-L"]).run().ok()
|
||||
assert run_hello(env) == "Hello World\n"
|
||||
res = nix.nix(["eval", "--raw", "./flake1#default.drvPath"]).run().ok()
|
||||
drv_path = Path(res.stdout_s.strip())
|
||||
|
||||
assert drv_path.exists()
|
||||
|
||||
# The derivation should NOT be collected because `keep-env-derivations` is true
|
||||
nix.nix(["store", "gc"]).run().ok()
|
||||
|
||||
assert drv_path.exists()
|
||||
|
||||
@with_files({"flake1": flake})
|
||||
def test_keep_derivations_disabled(self, nix: Nix, env: ManagedEnv):
|
||||
nix.settings["keep-derivations"] = "false" # NOTE: This defaults to `true`
|
||||
|
||||
nix.nix(["profile", "install", "./flake1", "-L"]).run().ok()
|
||||
assert run_hello(env) == "Hello World\n"
|
||||
|
||||
res = nix.nix(["eval", "--raw", "./flake1#default.drvPath"]).run().ok()
|
||||
drv_path = Path(res.stdout_s.strip())
|
||||
|
||||
assert drv_path.exists()
|
||||
|
||||
# The derivation should be collected because `keep-env-derivations` is false AND `keep-derivations` is false.
|
||||
res = nix.nix(["store", "gc"]).run().ok()
|
||||
|
||||
assert not drv_path.exists()
|
||||
|
||||
Reference in New Issue
Block a user