1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 14:51:16 +02:00

Merge pull request #12166 from DeterminateSystems/upgrade-nix-error-msg

nix upgrade-nix: Give a better error message if the profile is using 'nix profile'
This commit is contained in:
mergify[bot] 2025-01-11 20:03:17 +00:00 committed by GitHub
commit d155e349fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -15,7 +15,7 @@ using namespace nix;
struct CmdUpgradeNix : MixDryRun, StoreCommand struct CmdUpgradeNix : MixDryRun, StoreCommand
{ {
Path profileDir; std::filesystem::path profileDir;
CmdUpgradeNix() CmdUpgradeNix()
{ {
@ -64,7 +64,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
if (profileDir == "") if (profileDir == "")
profileDir = getProfileDir(store); profileDir = getProfileDir(store);
printInfo("upgrading Nix in profile '%s'", profileDir); printInfo("upgrading Nix in profile %s", profileDir);
auto storePath = getLatestNix(store); auto storePath = getLatestNix(store);
@ -93,7 +93,9 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
{ {
Activity act(*logger, lvlInfo, actUnknown, Activity act(*logger, lvlInfo, actUnknown,
fmt("installing '%s' into profile '%s'...", store->printStorePath(storePath), profileDir)); fmt("installing '%s' into profile %s...", store->printStorePath(storePath), profileDir));
// FIXME: don't call an external process.
runProgram(getNixBin("nix-env").string(), false, runProgram(getNixBin("nix-env").string(), false,
{"--profile", profileDir, "-i", store->printStorePath(storePath), "--no-sandbox"}); {"--profile", profileDir, "-i", store->printStorePath(storePath), "--no-sandbox"});
} }
@ -102,31 +104,33 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
} }
/* Return the profile in which Nix is installed. */ /* Return the profile in which Nix is installed. */
Path getProfileDir(ref<Store> store) std::filesystem::path getProfileDir(ref<Store> store)
{ {
auto whereOpt = ExecutablePath::load().findName(OS_STR("nix-env")); auto whereOpt = ExecutablePath::load().findName(OS_STR("nix-env"));
if (!whereOpt) if (!whereOpt)
throw Error("couldn't figure out how Nix is installed, so I can't upgrade it"); throw Error("couldn't figure out how Nix is installed, so I can't upgrade it");
const auto & where = whereOpt->parent_path(); const auto & where = whereOpt->parent_path();
printInfo("found Nix in '%s'", where); printInfo("found Nix in %s", where);
if (hasPrefix(where.string(), "/run/current-system")) if (hasPrefix(where.string(), "/run/current-system"))
throw Error("Nix on NixOS must be upgraded via 'nixos-rebuild'"); throw Error("Nix on NixOS must be upgraded via 'nixos-rebuild'");
Path profileDir = where.parent_path().string(); auto profileDir = where.parent_path();
// Resolve profile to /nix/var/nix/profiles/<name> link. // Resolve profile to /nix/var/nix/profiles/<name> link.
while (canonPath(profileDir).find("/profiles/") == std::string::npos && std::filesystem::is_symlink(profileDir)) while (canonPath(profileDir.string()).find("/profiles/") == std::string::npos && std::filesystem::is_symlink(profileDir))
profileDir = readLink(profileDir); profileDir = readLink(profileDir);
printInfo("found profile '%s'", profileDir); printInfo("found profile %s", profileDir);
Path userEnv = canonPath(profileDir, true); Path userEnv = canonPath(profileDir.string(), true);
if (where.filename() != "bin" || if (std::filesystem::exists(profileDir / "manifest.json"))
!hasSuffix(userEnv, "user-environment")) throw Error("directory %s is managed by 'nix profile' and currently cannot be upgraded by 'nix upgrade-nix'", profileDir);
throw Error("directory %s does not appear to be part of a Nix profile", where);
if (!std::filesystem::exists(profileDir / "manifest.nix"))
throw Error("directory %s does not appear to be part of a Nix profile", profileDir);
if (!store->isValidPath(store->parseStorePath(userEnv))) if (!store->isValidPath(store->parseStorePath(userEnv)))
throw Error("directory '%s' is not in the Nix store", userEnv); throw Error("directory '%s' is not in the Nix store", userEnv);