From 66e94d3275e9a0a549c28b7d0ad5f3f897e2fbf0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 6 Feb 2004 10:30:20 +0000 Subject: [PATCH] * Improvements to profiles. Generations are now per-profile, e.g., default -> default-94-link default-82-link -> /nix/store/cc4480... default-83-link -> /nix/store/caeec8... ... default-94-link -> /nix/store/2896ca... experimental -> experimental-2-link experimental-1-link -> /nix/store/cc4480... experimental-2-link -> /nix/store/a3148f... * `--profile' / `-p' -> `--switch-profile' / `-S' * `--link' / `-l' -> `--profile' / `-p' * The default profile is stored in $prefix/var/nix/profiles. $prefix/var/nix/links is gone. Profiles can be stored anywhere. * The current profile is now referenced from ~/.nix-profile, not ~/.nix-userenv. * The roots to the garbage collector now have extension `.gcroot', not `.id'. --- doc/manual/installation.xml | 4 +- doc/manual/nix-env.xml | 10 ++-- doc/manual/overview.xml | 40 ++++++++-------- doc/manual/quick-start.xml | 2 +- scripts/nix-collect-garbage.in | 4 +- scripts/nix-profile.sh.in | 4 +- src/nix-env/Makefile.am | 3 ++ src/nix-env/help.txt | 4 +- src/nix-env/main.cc | 88 ++++++++++++++++++---------------- src/nix-store/Makefile.am | 3 -- 10 files changed, 84 insertions(+), 78 deletions(-) diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 1f45404e94..d35b3de5d6 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -192,9 +192,9 @@ rm -rf /nix/var To use Nix, some environment variables should be set. In particular, PATH should contain the directories prefix/bin and - ~/.nix-userenv/bin. The first directory + ~/.nix-profile/bin. The first directory contains the Nix tools themselves, while - ~/.nix-userenv is a symbolic link to the + ~/.nix-profile is a symbolic link to the current user environment (an automatically generated package consisting of symlinks to installed packages). The simplest way to set the required environment variables is to diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml index a943fd9760..bdf35bd32a 100644 --- a/doc/manual/nix-env.xml +++ b/doc/manual/nix-env.xml @@ -111,14 +111,14 @@ - ~/.nix-userenv + ~/.nix-profile - A symbolic link to the user's current user environment. - By default, it points to - prefix/var/nix/links/current. + A symbolic link to the user's current profile. The + default profile is + prefix/var/nix/profiles/default. The PATH environment variable should - include ~/.nix-userenv for the user + include ~/.nix-profile/bin for the user environment to be visible to the user. diff --git a/doc/manual/overview.xml b/doc/manual/overview.xml index a5bcccd343..e42c811c01 100644 --- a/doc/manual/overview.xml +++ b/doc/manual/overview.xml @@ -189,30 +189,32 @@ obtaining list of Nix archives at http://catamaran.labs.cs.uu.nl/dist/nix/nixpkg it can be used immediately, that is, it now appears in a directory in the PATH environment variable. Specifically, PATH includes the entry - prefix/var/nix/links/current/bin, + prefix/var/nix/profiles/default/bin, where - prefix/var/nix/links/current + prefix/var/nix/profiles/default is just a symlink to the current user environment: -$ ls -l /nix/var/nix/links/ +$ ls -l /nix/var/nix/profiles/ ... -lrwxrwxrwx 1 eelco ... 15 -> /nix/store/1871...12b0-user-environment -lrwxrwxrwx 1 eelco ... 16 -> /nix/store/59ba...df6b-user-environment -lrwxrwxrwx 1 eelco ... current -> /nix/var/nix/links/16 +lrwxrwxrwx 1 eelco ... default-15-link -> /nix/store/1871...12b0-user-environment +lrwxrwxrwx 1 eelco ... default-16-link -> /nix/store/59ba...df6b-user-environment +lrwxrwxrwx 1 eelco ... default -> default-16-link - That is, current in this example is a link to - 16, which is the current user environment. Before - the installation, it pointed to 15. Note that this - means that you can atomically roll-back to the previous user environment - by pointing the symlink current at - 15 again. This also shows that operations such as - installation are atomic in the Nix system: any arbitrarily complex - set of installation, uninstallation, or upgrade actions eventually boil - down to the single operation of pointing a symlink somewhere else (which - can be implemented atomically in Unix). + That is, default in this example is a link + to default-16-link, which is the current + user environment. Before the installation, it pointed to + default-15-link. Note that this means that + you can atomically roll-back to the previous user environment by + pointing the symlink default at + default-15-link again. This also shows + that operations such as installation are atomic in the Nix + system: any arbitrarily complex set of installation, + uninstallation, or upgrade actions eventually boil down to the + single operation of pointing a symlink somewhere else (which can + be implemented atomically in Unix). @@ -221,15 +223,15 @@ lrwxrwxrwx 1 eelco ... current -> /nix/var/nix/links/16 -$ ls -l /nix/var/nix/links/16/bin +$ ls -l /nix/var/nix/profiles/default-16-link/bin lrwxrwxrwx 1 eelco ... MozillaFirebird -> /nix/store/35f8...4ae6-MozillaFirebird-0.7/bin/MozillaFirebird lrwxrwxrwx 1 eelco ... svn -> /nix/store/3829...fb5d-subversion-0.32.1/bin/svn ... Note that, e.g., svn = - /nix/var/nix/links/current/bin/svn = - /nix/var/nix/links/16/bin/svn = + /nix/var/nix/profiles/default/bin/svn = + /nix/var/nix/profiles/default-16-link/bin/svn = /nix/store/59ba...df6b-user-environment/bin/svn = /nix/store/3829...fb5d-subversion-0.32.1/bin/svn. diff --git a/doc/manual/quick-start.xml b/doc/manual/quick-start.xml index ec49dfb279..b16fe7de8f 100644 --- a/doc/manual/quick-start.xml +++ b/doc/manual/quick-start.xml @@ -93,7 +93,7 @@ $ nix-env -iBf nixpkgs-version/ hello MozillaFirebird $ which hello -/home/eelco/.nix-userenv/bin/hello +/home/eelco/.nix-profile/bin/hello $ hello Hello, world! $ MozillaFirebird diff --git a/scripts/nix-collect-garbage.in b/scripts/nix-collect-garbage.in index d0552fd2f6..1effc14d67 100755 --- a/scripts/nix-collect-garbage.in +++ b/scripts/nix-collect-garbage.in @@ -3,7 +3,7 @@ use strict; use IPC::Open2; -my $linkdir = "@localstatedir@/nix/links"; +my $linkdir = "@localstatedir@/nix/profiles"; my $storedir = "@prefix@/store"; my %alive; @@ -24,7 +24,7 @@ closedir DIR; my @roots; foreach my $link (@links) { $link = $linkdir . "/" . $link; - next if (!($link =~ /.id$/)); + next if (!($link =~ /.gcroot$/)); open ROOT, "<$link" or die "cannot open $link: $!"; my $root = ; chomp $root; diff --git a/scripts/nix-profile.sh.in b/scripts/nix-profile.sh.in index 55cff3e62d..7f19f80148 100644 --- a/scripts/nix-profile.sh.in +++ b/scripts/nix-profile.sh.in @@ -1,9 +1,9 @@ if test -n "$HOME"; then - NIX_LINK="$HOME/.nix-userenv" + NIX_LINK="$HOME/.nix-profile" if ! test -L "$NIX_LINK"; then echo "creating $NIX_LINK" - _NIX_DEF_LINK=@localstatedir@/nix/links/current + _NIX_DEF_LINK=@localstatedir@/nix/profiles/default ln -s "$_NIX_DEF_LINK" "$NIX_LINK" fi diff --git a/src/nix-env/Makefile.am b/src/nix-env/Makefile.am index bfe7369c69..5353a7a6b8 100644 --- a/src/nix-env/Makefile.am +++ b/src/nix-env/Makefile.am @@ -14,3 +14,6 @@ main.o: help.txt.hh AM_CXXFLAGS = \ -I.. -I../../externals/inst/include -I../libutil -I../libstore \ -I../libexpr -I../libmain + +install-data-local: + $(INSTALL) -d $(DESTDIR)$(localstatedir)/nix/profiles diff --git a/src/nix-env/help.txt b/src/nix-env/help.txt index f1419cdf7a..3832f1655b 100644 --- a/src/nix-env/help.txt +++ b/src/nix-env/help.txt @@ -12,7 +12,7 @@ Operations: The previous operations take a list of derivation names. The special name `*' may be used to indicate all derivations. - --profile / -p [FILE]: switch to specified user environment + --switch-profile / -S [FILE]: switch to specified profile --import / -I FILE: set default Nix expression --version: output version information @@ -31,7 +31,7 @@ Query sources: Options: - --link / -l LINK: use symlink LINK instead of (...)/current + --profile / -p LINK: use specified profile instead of target of ~/.nix-profile --file / -f FILE: use Nix expression FILE for installation, etc. --verbose / -v: verbose operation (may be repeated) --keep-failed / -K: keep temporary directories of failed builds diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index 3810e91442..20b7da655d 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -10,7 +10,7 @@ struct Globals { - Path linkPath; + Path profile; Path nixExprPath; EvalState state; }; @@ -116,12 +116,6 @@ static Path getHomeDir() } -static Path getLinksDir() -{ - return canonPath(nixStateDir + "/links"); -} - - static Path getDefNixExprPath() { return getHomeDir() + "/.nix-defexpr"; @@ -143,23 +137,30 @@ void queryInstalled(EvalState & state, DrvInfos & drvs, } -Path createGeneration(Path outPath, Path drvPath) +Path createGeneration(Path profile, Path outPath, Path drvPath) { - Path linksDir = getLinksDir(); - + Path profileDir = dirOf(profile); + string profileName = baseNameOf(profile); + unsigned int num = 0; - Strings names = readDirectory(linksDir); + Strings names = readDirectory(profileDir); for (Strings::iterator i = names.begin(); i != names.end(); ++i) { - istringstream s(*i); - unsigned int n; - if (s >> n && s.eof() && n >= num) num = n + 1; + if (string(*i, 0, profileName.size() + 1) != profileName + "-") continue; + string s = string(*i, profileName.size() + 1); + int p = s.find("-link"); + if (p == string::npos) continue; + istringstream str(string(s, 0, p)); + unsigned int n; + if (str >> n && str.eof() && n >= num) num = n + 1; } - Path generation; + Path generation, gcrootSrc; while (1) { - generation = (format("%1%/%2%") % linksDir % num).str(); + Path prefix = (format("%1%-%2%") % profile % num).str(); + generation = prefix + "-link"; + gcrootSrc = prefix + "-src.gcroot"; if (symlink(outPath.c_str(), generation.c_str()) == 0) break; if (errno != EEXIST) throw SysError(format("creating symlink `%1%'") % generation); @@ -167,7 +168,7 @@ Path createGeneration(Path outPath, Path drvPath) num++; } - writeStringToFile(generation + "-src.id", drvPath); + writeStringToFile(gcrootSrc, drvPath); return generation; } @@ -175,6 +176,9 @@ Path createGeneration(Path outPath, Path drvPath) void switchLink(Path link, Path target) { + /* Hacky. */ + if (dirOf(target) == dirOf(link)) target = baseNameOf(target); + Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link)); if (symlink(target.c_str(), tmp.c_str()) != 0) throw SysError(format("creating symlink `%1%'") % tmp); @@ -190,7 +194,7 @@ void switchLink(Path link, Path target) void createUserEnv(EvalState & state, const DrvInfos & drvs, - const Path & linkPath) + const Path & profile) { /* Get the environment builder expression. */ Expr envBuilder = parseExprFromFile(state, @@ -243,9 +247,9 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, /* Switch the current user environment to the output path. */ debug(format("switching to new user environment")); - Path generation = createGeneration( + Path generation = createGeneration(profile, topLevelDrv.outPath, topLevelDrv.drvPath); - switchLink(linkPath, generation); + switchLink(profile, generation); } @@ -380,7 +384,7 @@ static DrvNames drvNamesFromArgs(const Strings & opArgs) static void installDerivations(EvalState & state, - Path nePath, DrvNames & selectors, const Path & linkPath) + Path nePath, DrvNames & selectors, const Path & profile) { debug(format("installing derivations from `%1%'") % nePath); @@ -415,10 +419,10 @@ static void installDerivations(EvalState & state, /* Add in the already installed derivations. */ DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, linkPath); + queryInstalled(state, installedDrvs, profile); selectedDrvs.insert(installedDrvs.begin(), installedDrvs.end()); - createUserEnv(state, selectedDrvs, linkPath); + createUserEnv(state, selectedDrvs, profile); } @@ -431,12 +435,12 @@ static void opInstall(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); installDerivations(globals.state, globals.nixExprPath, - drvNames, globals.linkPath); + drvNames, globals.profile); } static void upgradeDerivations(EvalState & state, - Path nePath, DrvNames & selectors, const Path & linkPath) + Path nePath, DrvNames & selectors, const Path & profile) { debug(format("upgrading derivations from `%1%'") % nePath); @@ -447,7 +451,7 @@ static void upgradeDerivations(EvalState & state, /* Load the currently installed derivations. */ DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, linkPath); + queryInstalled(state, installedDrvs, profile); /* Fetch all derivations from the input file. */ DrvInfos availDrvs; @@ -496,7 +500,7 @@ static void upgradeDerivations(EvalState & state, newDrvs.insert(*bestDrv); } - createUserEnv(state, newDrvs, linkPath); + createUserEnv(state, newDrvs, profile); } @@ -510,15 +514,15 @@ static void opUpgrade(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); upgradeDerivations(globals.state, globals.nixExprPath, - drvNames, globals.linkPath); + drvNames, globals.profile); } static void uninstallDerivations(EvalState & state, DrvNames & selectors, - Path & linkPath) + Path & profile) { DrvInfos installedDrvs; - queryInstalled(state, installedDrvs, linkPath); + queryInstalled(state, installedDrvs, profile); for (DrvInfos::iterator i = installedDrvs.begin(); i != installedDrvs.end(); ++i) @@ -533,7 +537,7 @@ static void uninstallDerivations(EvalState & state, DrvNames & selectors, } } - createUserEnv(state, installedDrvs, linkPath); + createUserEnv(state, installedDrvs, profile); } @@ -545,7 +549,7 @@ static void opUninstall(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); - uninstallDerivations(globals.state, drvNames, globals.linkPath); + uninstallDerivations(globals.state, drvNames, globals.profile); } @@ -576,7 +580,7 @@ static void opQuery(Globals & globals, switch (source) { case sInstalled: - queryInstalled(globals.state, drvs, globals.linkPath); + queryInstalled(globals.state, drvs, globals.profile); break; case sAvailable: { @@ -612,7 +616,7 @@ static void opQuery(Globals & globals, case qStatus: { DrvInfos installed; - queryInstalled(globals.state, installed, globals.linkPath); + queryInstalled(globals.state, installed, globals.profile); PathSet installedPaths; /* output paths of installed drvs */ for (DrvInfos::iterator i = installed.begin(); @@ -644,11 +648,11 @@ static void opSwitchProfile(Globals & globals, if (opArgs.size() > 1) throw UsageError(format("`--profile' takes at most one argument")); - Path linkPath = - absPath(opArgs.size() == 0 ? globals.linkPath : opArgs.front()); - Path linkPathFinal = getHomeDir() + "/.nix-userenv"; + Path profile = + absPath(opArgs.size() == 0 ? globals.profile : opArgs.front()); + Path profileLink = getHomeDir() + "/.nix-userenv"; - switchLink(linkPathFinal, linkPath); + switchLink(profileLink, profile); } @@ -676,7 +680,7 @@ void run(Strings args) Operation op = 0; Globals globals; - globals.linkPath = getLinksDir() + "/current"; + globals.profile = canonPath(nixStateDir + "/profiles/default"); globals.nixExprPath = getDefNixExprPath(); for (Strings::iterator i = args.begin(); i != args.end(); ++i) { @@ -694,11 +698,11 @@ void run(Strings args) op = opQuery; else if (arg == "--import" || arg == "-I") /* !!! bad name */ op = opDefaultExpr; - else if (arg == "--link" || arg == "-l") { + else if (arg == "--profile" || arg == "-p") { ++i; if (i == args.end()) throw UsageError( format("`%1%' requires an argument") % arg); - globals.linkPath = absPath(*i); + globals.profile = absPath(*i); } else if (arg == "--file" || arg == "-f") { ++i; @@ -706,7 +710,7 @@ void run(Strings args) format("`%1%' requires an argument") % arg); globals.nixExprPath = absPath(*i); } - else if (arg == "--profile" || arg == "-p") + else if (arg == "--switch-profile" || arg == "-S") op = opSwitchProfile; else if (arg[0] == '-') opFlags.push_back(arg); diff --git a/src/nix-store/Makefile.am b/src/nix-store/Makefile.am index 74cf814a7f..3a152e3e4b 100644 --- a/src/nix-store/Makefile.am +++ b/src/nix-store/Makefile.am @@ -15,9 +15,6 @@ AM_CXXFLAGS = \ install-data-local: $(INSTALL) -d $(DESTDIR)$(localstatedir)/nix $(INSTALL) -d $(DESTDIR)$(localstatedir)/nix/db - $(INSTALL) -d $(DESTDIR)$(localstatedir)/nix/links - rm -f $(DESTDIR)$(prefix)/current - ln -sf $(localstatedir)/nix/links/current $(DESTDIR)$(prefix)/current $(INSTALL) -d $(DESTDIR)$(localstatedir)/log/nix $(INSTALL) -d $(DESTDIR)$(prefix)/store # $(bindir)/nix-store --init