From 7424d72098d597a3742546879b5152fbc831a307 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Fri, 10 Aug 2007 15:39:02 +0000 Subject: [PATCH] Partially integrated state components (startscripts) into nix-env --- corepkgs/buildenv/builder.pl.in | 104 +++++++++++++++++++++------ corepkgs/buildenv/default.nix | 3 +- scripts/Makefile.am | 8 +-- scripts/nix-readrevisions.sh | 13 ---- scripts/nix-readrevisions.sh.in | 13 ---- scripts/nix-restorerevision.sh | 13 ---- scripts/nix-restorerevision.sh.in | 13 ---- src/libexpr/get-drvs.cc | 38 ++++++++-- src/libexpr/get-drvs.hh | 7 ++ src/libstore/build.cc | 3 + src/libstore/derivations.hh | 2 + src/libstore/local-store.cc | 10 +-- src/libstore/local-store.hh | 2 +- src/libutil/util.cc | 1 + src/nix-env/nix-env.cc | 112 +++++++++++++++++++++++------- src/nix-env/profiles.cc | 5 +- src/nix-state/nix-state.cc | 16 +++-- 17 files changed, 241 insertions(+), 122 deletions(-) delete mode 100755 scripts/nix-readrevisions.sh delete mode 100755 scripts/nix-readrevisions.sh.in delete mode 100755 scripts/nix-restorerevision.sh delete mode 100755 scripts/nix-restorerevision.sh.in diff --git a/corepkgs/buildenv/builder.pl.in b/corepkgs/buildenv/builder.pl.in index 57fa56903..22ac48f50 100755 --- a/corepkgs/buildenv/builder.pl.in +++ b/corepkgs/buildenv/builder.pl.in @@ -3,6 +3,7 @@ use strict; use Cwd; use IO::Handle; +use Fcntl; STDOUT->autoflush(1); @@ -11,15 +12,29 @@ mkdir "$out", 0755 || die "error creating $out"; my $symlinks = 0; - +my %path_identifier; +my $srcDirSlashes = 3; # For each activated package, create symlinks. sub createLinks { my $srcDir = shift; + + my @srcDirParts = split /\// , $srcDir; + my $srcDirRoot = ""; + my $srcDirCounter=1; + while ($srcDirCounter <= $srcDirSlashes) { + $srcDirRoot = $srcDirRoot . "/" . $srcDirParts[$srcDirCounter]; + $srcDirCounter++; + } + #print "srcDirRoot $srcDirRoot \n"; + + my $pkgStateIdentifier = $path_identifier{$srcDirRoot}; my $dstDir = shift; my $ignoreCollisions = shift; + # print "createLinks $srcDir to $dstDir with iden $pkgStateIdentifier \n"; + my @srcFiles = glob("$srcDir/*"); foreach my $srcFile (@srcFiles) { @@ -27,20 +42,21 @@ sub createLinks { $baseName =~ s/^.*\///g; # strip directory my $dstFile = "$dstDir/$baseName"; - # Urgh, hacky... - if ($srcFile =~ /\/propagated-build-inputs$/ || + # Urgh, hacky... + if ($srcFile =~ /\/propagated-build-inputs$/ || $srcFile =~ /\/nix-support$/ || $srcFile =~ /\/perllocal.pod$/ || $srcFile =~ /\/info\/dir$/ || $srcFile =~ /\/log$/) { # Do nothing. - } + } elsif (-d $srcFile) { lstat $dstFile; + #go recursive on directorys if (-d _) { createLinks($srcFile, $dstFile, $ignoreCollisions); } @@ -51,30 +67,66 @@ sub createLinks { die "collission between directory `$srcFile' and non-directory `$target'"; } unlink $dstFile or die "error unlinking `$dstFile': $!"; - mkdir $dstFile, 0755 || - die "error creating directory `$dstFile': $!"; + mkdir $dstFile, 0755 || die "error creating directory `$dstFile': $!"; createLinks($target, $dstFile, $ignoreCollisions); createLinks($srcFile, $dstFile, $ignoreCollisions); } else { + + # print "1STLINK $srcFile to $dstFile with iden $pkgStateIdentifier \n"; + symlink($srcFile, $dstFile) || die "error creating link `$dstFile': $!"; $symlinks++; } } - elsif (-l $dstFile) { - if (!$ignoreCollisions) { - my $target = readlink $dstFile; - die "collission between `$srcFile' and `$target'"; - } - } - else { - symlink($srcFile, $dstFile) || - die "error creating link `$dstFile': $!"; - $symlinks++; + + # print "ELSE LINK $srcFile to $dstFile with iden $pkgStateIdentifier \n"; + + # if we have ..... + if($pkgStateIdentifier ne "__NOSTATE__" && $pkgStateIdentifier ne ""){ + + my @pathparts = split /\// , $srcFile; + my $parentDir = $pathparts[scalar(@pathparts) - 2]; + + if( $parentDir eq "bin" || $parentDir eq "sbin"){ #hacky.... + + print "STATELINK $srcFile to $dstFile \n"; + + my $new_dstFile; + if($pkgStateIdentifier eq "__EMTPY__") + { $new_dstFile = $dstFile; } + else + { $new_dstFile = "$dstFile-$pkgStateIdentifier"; } + + if (-l $new_dstFile) { + if (!$ignoreCollisions) { + my $target = readlink $new_dstFile; + die "(state) collission between `$srcFile' and `$target'"; + } + } + + sysopen (DSTFILEHANDLE, $new_dstFile, O_RDWR|O_EXCL|O_CREAT, 0755); + printf DSTFILEHANDLE "#! @shell@ \n"; + printf DSTFILEHANDLE "/nixstate/nix/bin/nix-state --run --identifier=$pkgStateIdentifier \$* $srcFile \n"; + close (DSTFILEHANDLE); + } + } + else{ + if (-l $dstFile) { + if (!$ignoreCollisions) { + my $target = readlink $dstFile; + die "collission between `$srcFile' and `$target'"; + } + } + + symlink($srcFile, $dstFile) || + die "error creating link `$dstFile': $!"; + $symlinks++; + } } } } @@ -86,6 +138,7 @@ my %postponed; sub addPkg; sub addPkg { my $pkgDir = shift; + my $pkgStateIdentifier = shift; my $ignoreCollisions = shift; return if (defined $done{$pkgDir}); @@ -108,10 +161,18 @@ sub addPkg { # Symlink to the packages that have been installed explicitly by the user. -my @args = split ' ', $ENV{"derivations"}; +my @storePaths = split ' ', $ENV{"derivations"}; +my @stateIdentifiers = split ' ', $ENV{"stateIdentifiers"}; +my $si_counter = 0; -foreach my $pkgDir (sort @args) { - addPkg($pkgDir, 0); +foreach my $pkgDir (@storePaths) { #Commented the sort out + + print "SP: $pkgDir \n"; + $path_identifier{$pkgDir} = $stateIdentifiers[$si_counter]; + print "SI: $path_identifier{$pkgDir} \n"; + + addPkg($pkgDir, $stateIdentifiers[$si_counter], 0); + $si_counter++; } @@ -120,9 +181,10 @@ foreach my $pkgDir (sort @args) { # installed as well). We do these later because they have a lower # priority in case of collisions. while (scalar(keys %postponed) > 0) { - my @pkgDirs = keys %postponed; + + my @pkgDirs = keys %postponed; # TODODODODODOD !!!!!!!!!!!!!!!!!!!!! %postponed = (); - foreach my $pkgDir (sort @pkgDirs) { + foreach my $pkgDir (sort @pkgDirs) { addPkg($pkgDir, 1); } } diff --git a/corepkgs/buildenv/default.nix b/corepkgs/buildenv/default.nix index 9bc704d8d..9f5a12f8b 100644 --- a/corepkgs/buildenv/default.nix +++ b/corepkgs/buildenv/default.nix @@ -1,9 +1,10 @@ -{system, derivations, manifest}: +{system, derivations, stateIdentifiers, manifest}: derivation { name = "user-environment"; system = system; builder = ./builder.pl; derivations = derivations; + stateIdentifiers = stateIdentifiers; manifest = manifest; } diff --git a/scripts/Makefile.am b/scripts/Makefile.am index b3afe45fd..e16b36d61 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,7 +4,7 @@ bin_SCRIPTS = nix-collect-garbage \ nix-pack-closure nix-unpack-closure \ nix-copy-closure -noinst_SCRIPTS = nix-profile.sh generate-patches.pl find-runtime-roots.pl nix-readrevisions.sh nix-restorerevision.sh +noinst_SCRIPTS = nix-profile.sh generate-patches.pl find-runtime-roots.pl nix-pull nix-push: readmanifest.pm readconfig.pm download-using-manifests.pl @@ -17,8 +17,6 @@ install-exec-local: readmanifest.pm download-using-manifests.pl find-runtime-roo $(INSTALL_PROGRAM) download-using-manifests.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) generate-patches.pl $(DESTDIR)$(libexecdir)/nix - $(INSTALL_PROGRAM) nix-readrevisions.sh $(DESTDIR)$(libexecdir)/nix - $(INSTALL_PROGRAM) nix-restorerevision.sh $(DESTDIR)$(libexecdir)/nix $(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix include ../substitute.mk @@ -34,6 +32,4 @@ EXTRA_DIST = nix-collect-garbage.in \ generate-patches.pl.in \ nix-pack-closure.in nix-unpack-closure.in \ nix-copy-closure.in \ - find-runtime-roots.pl.in \ - nix-readrevisions.sh.in \ - nix-restorerevision.sh.in + find-runtime-roots.pl.in diff --git a/scripts/nix-readrevisions.sh b/scripts/nix-readrevisions.sh deleted file mode 100755 index bdbb449dc..000000000 --- a/scripts/nix-readrevisions.sh +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh -e - -svnbin=$1 -repos=$2 - -if [ "$#" != 2 ] ; then - echo "Incorrect number of arguments" - exit 1; -fi - -$svnbin info $repos | sed -n '/^Revision: /p' | sed 's/Revision: //' - -# | tr -d "\12" diff --git a/scripts/nix-readrevisions.sh.in b/scripts/nix-readrevisions.sh.in deleted file mode 100755 index bdbb449dc..000000000 --- a/scripts/nix-readrevisions.sh.in +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh -e - -svnbin=$1 -repos=$2 - -if [ "$#" != 2 ] ; then - echo "Incorrect number of arguments" - exit 1; -fi - -$svnbin info $repos | sed -n '/^Revision: /p' | sed 's/Revision: //' - -# | tr -d "\12" diff --git a/scripts/nix-restorerevision.sh b/scripts/nix-restorerevision.sh deleted file mode 100755 index d12b3355b..000000000 --- a/scripts/nix-restorerevision.sh +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh -e - -svnbin=$1 -torevision=$2 -repos=$3 -statepath=$4 - -if [ "$#" != 4 ] ; then - echo "Incorrect number of arguments" - exit 1; -fi - -$svnbin merge -r HEAD:$torevision $repos $statepath diff --git a/scripts/nix-restorerevision.sh.in b/scripts/nix-restorerevision.sh.in deleted file mode 100755 index d12b3355b..000000000 --- a/scripts/nix-restorerevision.sh.in +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh -e - -svnbin=$1 -torevision=$2 -repos=$3 -statepath=$4 - -if [ "$#" != 4 ] ; then - echo "Incorrect number of arguments" - exit 1; -fi - -$svnbin merge -r HEAD:$torevision $repos $statepath diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index bd0ec4781..f4f4e8813 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -35,6 +35,30 @@ string DrvInfo::queryOutPath(EvalState & state) const return outPath; } +string DrvInfo::queryStateIdentifier(EvalState & state) const +{ + if (stateIdentifier == "") { + ATermMap attrs2 = *attrs; + + for (ATermMap::const_iterator i = attrs2.begin(); i != attrs2.end(); ++i) { + + string key = (string)aterm2String(i->key); //cast because aterm2String returns a char* + //printMsg(lvlError, format("ATTR2: '%1%'") % key); + if(key == "stateIdentifier"){ + PathSet context; + string value = coerceToString(state, i->value, context); + (string &) stateIdentifier = value; + } + } + + //If still empty + if (trim(stateIdentifier) == "") + (string &) stateIdentifier = "__NOSTATE__"; + } + + return stateIdentifier; +} + MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const { @@ -93,20 +117,23 @@ static bool getDerivation(EvalState & state, Expr e, boost::shared_ptr attrs(new ATermMap()); queryAllAttrs(e, *attrs, false); - + Expr a = attrs->get(toATerm("type")); - if (!a || evalStringNoCtx(state, a) != "derivation") return true; + if (!a || evalStringNoCtx(state, a) != "derivation") + return true; /* Remove spurious duplicates (e.g., an attribute set like `rec { x = derivation {...}; y = x;}'. */ - if (doneExprs.find(e) != doneExprs.end()) return false; + if (doneExprs.find(e) != doneExprs.end()) + return false; doneExprs.insert(e); DrvInfo drv; a = attrs->get(toATerm("name")); /* !!! We really would like to have a decent back trace here. */ - if (!a) throw TypeError("derivation name missing"); + if (!a) + throw TypeError("derivation name missing"); drv.name = evalStringNoCtx(state, a); a = attrs->get(toATerm("system")); @@ -133,7 +160,8 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv) Exprs doneExprs; DrvInfos drvs; getDerivation(state, e, "", drvs, doneExprs); - if (drvs.size() != 1) return false; + if (drvs.size() != 1) + return false; drv = drvs.front(); return true; } diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index 24894efdc..f0ca9205b 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -20,6 +20,7 @@ struct DrvInfo private: string drvPath; string outPath; + string stateIdentifier; public: string name; @@ -33,6 +34,7 @@ public: string queryDrvPath(EvalState & state) const; string queryOutPath(EvalState & state) const; + string queryStateIdentifier(EvalState & state) const; MetaInfo queryMetaInfo(EvalState & state) const; void setDrvPath(const string & s) @@ -45,6 +47,11 @@ public: outPath = s; } + void setStateIdentifier(const string & s) + { + stateIdentifier = s; + } + void setMetaInfo(const MetaInfo & meta); }; diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 9a6d72c32..a9dbac70a 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2587,6 +2587,9 @@ void LocalStore::buildDerivations(const PathSet & drvPaths) Worker worker; Goals goals; for (PathSet::const_iterator i = drvPaths.begin(); i != drvPaths.end(); ++i){ + + printMsg(lvlError, format("BUILD: '%1%'") % *i); + goals.insert(worker.makeDerivationGoal(*i)); } diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 5e0e1b39c..40a736197 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -69,6 +69,8 @@ struct DerivationStateOutput throw Error(format("synchronization '%1%' is not a correct type") % synchronization); if(username == "") throw Error(format("Username cannot be empty")); + if(stateIdentifier == "__EMTPY__" || stateIdentifier == "__NOSTATE__") + throw Error(format("the stateIdenfier cannot be this value '%1%'") % stateIdentifier); } //TODO diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 8b6bf62cc..e777d1b3b 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -768,19 +768,19 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path * Returns true or false wheter a store-component has a state component (e.g. has a state dir) or not. * Do NOT confuse this function with isValidStatePath */ -bool isStateComponentTxn(const Transaction & txn, const Path & statePath) +bool isStateComponentTxn(const Transaction & txn, const Path & storePath) { - isValidPathTxn(txn, statePath); + isValidPathTxn(txn, storePath); string data; - bool nonempty = nixDB.queryString(txn, dbStateInfo, statePath, data); + bool nonempty = nixDB.queryString(txn, dbStateInfo, storePath, data); return nonempty; } -bool LocalStore::isStateComponent(const Path & statePath) +bool LocalStore::isStateComponent(const Path & storePath) { - return nix::isStateComponentTxn(noTxn, statePath); + return nix::isStateComponentTxn(noTxn, storePath); } diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 73290c0b4..e8a3766d3 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -92,7 +92,7 @@ public: vector getStatePathsInterval(const PathSet & statePaths); - bool isStateComponent(const Path & path); + bool isStateComponent(const Path & storePath); bool isStateDrvPath(const Path & drvpath); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 1f995241f..e9223bae0 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -371,6 +371,7 @@ void writeStringToFile(const Path & path, const string & s) LogType logType = ltPretty; Verbosity verbosity = lvlInfo; +//Verbosity verbosity = lvlDebug; static int nestingLevel = 0; diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index da69b4580..bb5c59ce0 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -146,8 +146,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, i != elems.end(); ++i) /* Call to `isDerivation' is for compatibility with Nix <= 0.7 user environments. */ - if (i->queryDrvPath(state) != "" && - isDerivation(i->queryDrvPath(state))) + if (i->queryDrvPath(state) != "" && isDerivation(i->queryDrvPath(state))) drvsToBuild.insert(i->queryDrvPath(state)); debug(format("building user environment dependencies")); @@ -161,6 +160,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, PathSet references; ATermList manifest = ATempty; ATermList inputs = ATempty; + ATermList stateIdentifiers = ATempty; for (DrvInfos::const_iterator i = elems.begin(); i != elems.end(); ++i) { @@ -169,7 +169,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, the meta attributes. */ Path drvPath = keepDerivations ? i->queryDrvPath(state) : ""; - ATermList as = ATmakeList4( + ATermList as = ATmakeList5( makeBind(toATerm("type"), makeStr("derivation"), makeNoPos()), makeBind(toATerm("name"), @@ -177,18 +177,26 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, makeBind(toATerm("system"), makeStr(i->system), makeNoPos()), makeBind(toATerm("outPath"), - makeStr(i->queryOutPath(state)), makeNoPos())); + makeStr(i->queryOutPath(state)), makeNoPos()), + makeBind(toATerm("stateIdentifier"), + makeStr(i->queryStateIdentifier(state)), makeNoPos()) ); - if (drvPath != "") as = ATinsert(as, - makeBind(toATerm("drvPath"), - makeStr(drvPath), makeNoPos())); + if (drvPath != "") + as = ATinsert(as, makeBind(toATerm("drvPath"), makeStr(drvPath), makeNoPos())); - if (i->attrs->get(toATerm("meta"))) as = ATinsert(as, - makeBind(toATerm("meta"), - strictEvalExpr(state, i->attrs->get(toATerm("meta"))), - makeNoPos())); + if (i->attrs->get(toATerm("meta"))) + as = ATinsert(as, makeBind(toATerm("meta"), + strictEvalExpr(state, i->attrs->get(toATerm("meta"))), makeNoPos())); - manifest = ATinsert(manifest, makeAttrs(as)); + manifest = ATinsert(manifest, makeAttrs(as)); //All DrvInfo's are inserted here + + /*ATermList ass = ATmakeList1( + makeBind(toATerm("stateIdentifier"), makeStr(i->queryStateIdentifier(state)), makeNoPos()) + );*/ + + stateIdentifiers = ATinsert(stateIdentifiers, makeStr(i->queryStateIdentifier(state))); + + //printMsg(lvlError, format("TEST2 '%1%'") % makeAttrs(as)); inputs = ATinsert(inputs, makeStr(i->queryOutPath(state))); @@ -197,31 +205,52 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, store->addTempRoot(i->queryOutPath(state)); store->ensurePath(i->queryOutPath(state)); references.insert(i->queryOutPath(state)); - if (drvPath != "") references.insert(drvPath); + + if (drvPath != "") + references.insert(drvPath); } + + //printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))) ); + //printMsg(lvlError, format("TEST2 '%1%'") % makeList(ATreverse(manifest)) ); + //printMsg(lvlError, format("TEST2 '%1%'") % makeBind(toATerm("stateIdentifiers"), makeList(ATreverse(manifest)), makeNoPos()) ); + printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(stateIdentifiers)))) ); + + /* Extract ... */ + /* Also write a copy of the list of inputs to the store; we need it for future modifications of the environment. */ Path manifestFile = store->addTextToStore("env-manifest", atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references); - Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3( + Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList4( makeBind(toATerm("system"), makeStr(thisSystem), makeNoPos()), makeBind(toATerm("derivations"), makeList(ATreverse(manifest)), makeNoPos()), + makeBind(toATerm("stateIdentifiers"), + makeList(ATreverse(stateIdentifiers)), makeNoPos()), makeBind(toATerm("manifest"), makeStr(manifestFile, singleton(manifestFile)), makeNoPos()) ))); + //printMsg(lvlError, format("Write manifest '%1%'") % topLevel); + /* Instantiate it. */ debug(format("evaluating builder expression `%1%'") % topLevel); DrvInfo topLevelDrv; if (!getDerivation(state, topLevel, topLevelDrv)) abort(); - + + printMsg(lvlError, format("TEST5 '%1%'") % topLevelDrv.queryStateIdentifier(state)); + printMsg(lvlError, format("BUILD ENV DRV: '%1%'") % topLevelDrv.queryDrvPath(state) ); + /* Realise the resulting store expression. */ debug(format("building user environment")); - store->buildDerivations(singleton(topLevelDrv.queryDrvPath(state))); + store->buildDerivations(singleton(topLevelDrv.queryDrvPath(state))); //HERE IS THE DRV !!!!!!!!!!! + + //switch ..... + + printMsg(lvlError, format("TEST6")); /* Switch the current user environment to the output path. */ debug(format("switching to new user environment")); @@ -312,6 +341,11 @@ static void queryInstSources(EvalState & state, DrvInfos & elems, bool newestOnly) { InstallSourceType type = instSource.type; + + for (Strings::const_iterator i = args.begin(); i != args.end(); ++i) + printMsg(lvlError, format("queryInstSources arg '%1%'") % *i); + printMsg(lvlError, format("queryInstSources TYPE '%1%'") % (type == srcUnknown)); + if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/') type = srcStorePaths; @@ -365,10 +399,14 @@ static void queryInstSources(EvalState & state, for (Strings::const_iterator i = args.begin(); i != args.end(); ++i) { + printMsg(lvlError, format("AAAAA333 %1%'") % *i); + assertStorePath(*i); + printMsg(lvlError, format("AAAAA444 %1%'") % *i); + DrvInfo elem; - elem.attrs = boost::shared_ptr(new ATermMap(0)); /* ugh... */ + elem.attrs = boost::shared_ptr(new ATermMap(0)); /* ugh... */ string name = baseNameOf(*i); string::size_type dash = name.find('-'); if (dash != string::npos) @@ -377,13 +415,18 @@ static void queryInstSources(EvalState & state, if (isDerivation(*i)) { elem.setDrvPath(*i); elem.setOutPath(findOutput(derivationFromPath(*i), "out")); - //TODO !!!!!!!!!!!!!!!!!!!! setStatePath?? if (name.size() >= drvExtension.size() && string(name, name.size() - drvExtension.size()) == drvExtension) name = string(name, 0, name.size() - drvExtension.size()); } - else elem.setOutPath(*i); + else + { + elem.setOutPath(*i); + + //if(drv.stateOutputs.size() != 0) + // elem.setStateIdentifier(drv.stateOutputs.find("state")->second.stateIdentifier); + } elem.name = name; @@ -466,6 +509,21 @@ static void installDerivations(Globals & globals, one-click installs, namely those where the name used in the path is not the one we want (e.g., `java-front' versus `java-front-0.9pre15899'). */ + + //printMsg(lvlError, format("New component to install DRV: '%1%'") % i->queryDrvPath(globals.state)); + + //Set the state indentifier + if( store->isStateComponent(i->queryOutPath(globals.state)) ) + { + Derivation drv = derivationFromPath(i->queryDrvPath(globals.state)); + DerivationStateOutputs stateOutputs = drv.stateOutputs; + string stateIdentifier = stateOutputs.find("state")->second.stateIdentifier; + if(stateIdentifier == "") + i->setStateIdentifier("__EMTPY__"); + else + i->setStateIdentifier(stateIdentifier); + } + if (globals.forceName != "") i->name = globals.forceName; newNames.insert(DrvName(i->name).name); @@ -478,14 +536,18 @@ static void installDerivations(Globals & globals, DrvInfos installedElems = queryInstalled(globals.state, profile); DrvInfos allElems(newElems); - for (DrvInfos::iterator i = installedElems.begin(); - i != installedElems.end(); ++i) + for (DrvInfos::iterator i = installedElems.begin(); i != installedElems.end(); ++i) { DrvName drvName(i->name); - if (!globals.preserveInstalled && - newNames.find(drvName.name) != newNames.end()) - printMsg(lvlInfo, - format("replacing old `%1%'") % i->name); + + //TODO !!!!!!!!!!!!!!!!!!!!!!!! SHARE (OR COPY) STATE HERE IF NEEDED + //if( newNames.find(drvName.name) != newNames.end() && identifier == identifier ) + //{ + + //} + + if (!globals.preserveInstalled && newNames.find(drvName.name) != newNames.end()) + printMsg(lvlInfo, format("replacing old `%1%'") % i->name); else allElems.push_back(*i); } diff --git a/src/nix-env/profiles.cc b/src/nix-env/profiles.cc index 75585b1b2..df5ef4419 100644 --- a/src/nix-env/profiles.cc +++ b/src/nix-env/profiles.cc @@ -93,6 +93,8 @@ Path createGeneration(Path profile, Path outPath) makeName(profile, num + 1, generation); addPermRoot(outPath, generation, false, true); + printMsg(lvlError, format("TEST3 '%1%' '%2%' --> '%3%'") % profile % outPath % generation); + return generation; } @@ -115,7 +117,8 @@ void deleteGeneration(const Path & profile, unsigned int gen) void switchLink(Path link, Path target) { /* Hacky. */ - if (dirOf(target) == dirOf(link)) target = baseNameOf(target); + 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) diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 888801533..23f8deaaf 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -28,6 +28,7 @@ string comment; int revision_arg; bool scanforReferences = false; bool only_commit = false; +bool revert_recursively = false; /************************* Build time Functions ******************************/ @@ -59,7 +60,7 @@ Derivation getDerivation(const string & fullPath, const string & program_args, s if( !(store->isValidPath(componentPath) || store->isValidStatePath(componentPath)) ) throw UsageError(format("Path '%1%' is not a valid state or store path") % componentPath); - //Check if path is statepath + //Check if path is store-statepath isStateComponent = store->isStateComponent(componentPath); //printMsg(lvlError, format("'%1%' - '%2%' - '%3%' - '%4%' - '%5%'") % componentPath % state_identifier % binary % username % program_args); @@ -80,7 +81,8 @@ Derivation getDerivation(const string & fullPath, const string & program_args, s } //Retrieve the derivation, there is only 1 drvPath in derivers - Derivation drv = derivationFromPath(*(derivers.begin())); + derivationPath = *(derivers.begin()); + Derivation drv = derivationFromPath(derivationPath); if(isStateComponent){ DerivationStateOutputs stateOutputs = drv.stateOutputs; @@ -239,7 +241,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs) string program_args; Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStateComponent, program_args); - bool recursive = true; //TODO !!!!!!!!!!!!!!!!! + bool recursive = revert_recursively; //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! add TXN here ??????????? @@ -368,7 +370,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa PathSet allComponentPaths2; //without derivations for (PathSet::iterator i = allComponentPaths.begin(); i != allComponentPaths.end(); ++i){ string path = *i; - if(path.substr(path.length() - 4,path.length()) != ".drv") //TODO HACK: we should have a typed table or a seperate table .... + if(path.substr(path.length() - 4,path.length()) != drvExtension) //TODO HACK: we should have a typed table or a seperate table .... drvExtension == ".drv" allComponentPaths2.insert(path); } @@ -462,7 +464,9 @@ static void opRunComponent(Strings opFlags, Strings opArgs) bool root_isStateComponent; string root_program_args; Derivation root_drv = getDerivation_andCheckArgs(opFlags, opArgs, root_componentPath, root_statePath, root_binary, root_derivationPath, root_isStateComponent, root_program_args); - + + printMsg(lvlError, format("compp: '%1%'\nstatep: '%2%'\nbinary: '%3%'\ndrv:'%4%'") % root_componentPath % root_statePath % root_binary % root_derivationPath); + //TODO //Check for locks ... ? or put locks on the neseccary state components //WARNING: we need to watch out for deadlocks! @@ -724,6 +728,8 @@ void run(Strings args) username = arg.substr(7,arg.length()); else if (arg.substr(0,10) == "--comment=") comment = arg.substr(10,arg.length()); + else if (arg.substr(0,10) == "--revert-to-revision-recursively") + revert_recursively = true; else opArgs.push_back(arg);