diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-03-25T16·36+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-03-25T16·36+0000 |
commit | 0f40a560cab23f70881e5af405ea112a869dc39a (patch) | |
tree | 2bb622fd0230a5f53c330b946cbbe90714139ad5 | |
parent | 3f1a1457e9ad91f93151200fe43c7c33ea95417b (diff) |
* Added a script nix-activate which builds a list of "activated"
packages (i.e., the packages that should appear in the user's $PATH, and so on). Based on this list, the script nix-populate creates a hierarchy of symlinks to the relevant files in those packages (e.g., for pkg/bin and pkg/lib). A nice property of nix-populate is that on each run it creates a *new* tree, rather than updating the old one. It then atomically switches over to the new tree. This allows atomic upgrades or rollbacks on the set of activated packages.
-rwxr-xr-x | src/nix-activate | 22 | ||||
-rwxr-xr-x | src/nix-addroot | 18 | ||||
-rwxr-xr-x | src/nix-populate | 86 |
3 files changed, 108 insertions, 18 deletions
diff --git a/src/nix-activate b/src/nix-activate new file mode 100755 index 000000000000..9fe6466866df --- /dev/null +++ b/src/nix-activate @@ -0,0 +1,22 @@ +#! /usr/bin/perl -w + +use strict; + +my $pkglist = "/home/eelco/.nixactivations"; + +if (!-f $pkglist) { + system "touch $pkglist"; +} + +my $hash; +foreach $hash (@ARGV) { + system "grep -q $hash $pkglist"; + if ($?) { + print STDERR "activating $hash\n"; + system "nix getpkg $hash > /dev/null"; + if ($?) { die "`nix getpkg' failed"; } + system "echo $hash >> $pkglist"; + } +} + +system "nix-populate"; diff --git a/src/nix-addroot b/src/nix-addroot deleted file mode 100755 index 3ab9e8a252f8..000000000000 --- a/src/nix-addroot +++ /dev/null @@ -1,18 +0,0 @@ -#! /bin/sh - -ROOTLIST=~/.nixroots - -if ! test -f $ROOTLIST; then - touch $ROOTLIST -fi - -for i in $*; do - if nix ensure $i > /dev/null; then - if grep -q $i $ROOTLIST; then - echo $i already is a root - else - echo adding root $i - echo $i >> $ROOTLIST - fi - fi -done diff --git a/src/nix-populate b/src/nix-populate new file mode 100755 index 000000000000..294ded893ce0 --- /dev/null +++ b/src/nix-populate @@ -0,0 +1,86 @@ +#! /usr/bin/perl -w + +use strict; + +my $pkglist = $ENV{"NIX_ACTIVATIONS"}; +$pkglist or die "NIX_ACTIVATIONS not set"; +my $linkdir = $ENV{"NIX_LINKS"}; +$linkdir or die "NIX_LINKS not set"; +my @dirs = ("bin", "sbin", "lib"); + +# Figure out a generation number. +my $nr = 1; +while (-e "$linkdir/$nr") { $nr++; } +my $gendir = "$linkdir/$nr"; +print "populating $gendir\n"; + +# Create the subdirectories. +mkdir $gendir; +foreach my $dir (@dirs) { + mkdir "$gendir/$dir"; +} + +# For each activated package, create symlinks. + +sub createLinks { + my $srcdir = shift; + my $dstdir = shift; + + my @srcfiles = glob("$srcdir/*"); + + foreach my $srcfile (@srcfiles) { + my $basename = $srcfile; + $basename =~ s/^.*\///g; # strip directory + my $dstfile = "$dstdir/$basename"; + if (-d $srcfile) { + # !!! hack for resolving name clashes + if (!-e $dstfile) { + mkdir($dstfile) or + die "error creating directory $dstfile"; + } + -d $dstfile or die "$dstfile is not a directory"; + createLinks($srcfile, $dstfile); + } else { + print "linking $dstfile to $srcfile\n"; + symlink($srcfile, $dstfile) or + die "error creating link $dstfile"; + } + } +} + + +open PKGS, "< $pkglist"; + +while (<PKGS>) { + chomp; + my $hash = $_; + + my $pkgdir = `nix getpkg $hash`; + if ($?) { die "`nix getpkg' failed"; } + chomp $pkgdir; + + print "merging $pkgdir\n"; + + foreach my $dir (@dirs) { + createLinks("$pkgdir/$dir", "$gendir/$dir"); + } +} + +close PKGS; + +# Make $gendir the current generation by pointing $linkdir/current to +# it. The rename() system call is supposed to be essentially atomic +# on Unix. That is, if we have links `current -> X' and `new_current +# -> Y', and we rename new_current to current, a process accessing +# current will see X or Y, but never a file-not-found or other error +# condition. This is sufficient to atomically switch the current link +# tree. + +my $current = "$linkdir/current"; + +print "switching $current to $gendir\n"; + +my $tmplink = "$linkdir/new_current"; +symlink($gendir, $tmplink) or die "cannot create $tmplink"; +rename($tmplink, $current) or die "cannot rename $tmplink"; + |