mirror of
https://github.com/NixOS/nix.git
synced 2025-11-25 19:51:00 +01:00
* Fixed very old transactional bug that caused a freeze sometimes
* State components that get their state at runtime can now be (un)installed with nix-env
This commit is contained in:
parent
05297240ea
commit
53a6b9aaa5
20 changed files with 186 additions and 87 deletions
|
|
@ -10,9 +10,12 @@ STDOUT->autoflush(1);
|
|||
my $out = $ENV{"out"};
|
||||
mkdir "$out", 0755 || die "error creating $out";
|
||||
|
||||
sub readlink_or_StateWrapper;
|
||||
|
||||
my $symlinks = 0;
|
||||
my %path_identifier;
|
||||
my %path_state_identifier;
|
||||
my %path_runtimeArgs;
|
||||
|
||||
|
||||
my $nixBinDir = $ENV{"nixBinDir"};
|
||||
my $nixStore = $ENV{"nixStore"};
|
||||
|
|
@ -22,12 +25,13 @@ my $nixStore = $ENV{"nixStore"};
|
|||
sub createLinks {
|
||||
my $srcDir = shift;
|
||||
|
||||
#Lookup each $stateIdentifiers in $path_identifier
|
||||
#Lookup each $stateIdentifiers in $path_state_identifier
|
||||
#we strip $srcDir to its rootdir e.g. /nix/store/......./
|
||||
my @srcDirParts = split /\// , substr($srcDir, length ($nixStore), length ($srcDir));
|
||||
my $srcDirRoot = $nixStore . "/" . $srcDirParts[1];
|
||||
# print "srcDirRoot $srcDirRoot \n";
|
||||
my $pkgStateIdentifier = $path_identifier{$srcDirRoot};
|
||||
my $pkgStateIdentifier = $path_state_identifier{$srcDirRoot};
|
||||
my $pkgRuntimeStateArgs = $path_runtimeArgs{$srcDirRoot};
|
||||
|
||||
my $dstDir = shift;
|
||||
my $ignoreCollisions = shift;
|
||||
|
|
@ -93,7 +97,7 @@ sub createLinks {
|
|||
|
||||
if( $parentDir eq "bin" || $parentDir eq "sbin"){ #hacky....
|
||||
|
||||
print "STATELINK $srcFile to $dstFile \n";
|
||||
print "STATELINK $srcFile to $dstFile - $pkgStateIdentifier \n";
|
||||
|
||||
my $new_dstFile;
|
||||
my $new_stateIdentifier;
|
||||
|
|
@ -106,23 +110,29 @@ sub createLinks {
|
|||
$new_stateIdentifier = $pkgStateIdentifier;
|
||||
}
|
||||
|
||||
if (-l $new_dstFile) {
|
||||
# We also check with -e if the wrapperscript-file exists, and if is it a symlink (with -l)
|
||||
if (-l $new_dstFile || -e $new_dstFile) {
|
||||
if (!$ignoreCollisions) {
|
||||
my $target = readlink $new_dstFile;
|
||||
die "(state) collission between `$srcFile' and `$target'";
|
||||
my $target = readlink_or_StateWrapper $new_dstFile;
|
||||
die "(state) collission between `$srcFile' and `$target' (over $new_dstFile)";
|
||||
}
|
||||
}
|
||||
|
||||
sysopen (DSTFILEHANDLE, $new_dstFile, O_RDWR|O_EXCL|O_CREAT, 0755);
|
||||
printf DSTFILEHANDLE "#! @shell@ \n";
|
||||
printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n";
|
||||
|
||||
if($pkgRuntimeStateArgs eq "__NOARGS__")
|
||||
{ printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" \n"; }
|
||||
else
|
||||
{ printf DSTFILEHANDLE "$nixBinDir/nix-state --run --identifier=$new_stateIdentifier $srcFile \"\$@\" $pkgRuntimeStateArgs \n"; } # TODO, maybe first R.T.A. then other args ?
|
||||
|
||||
close (DSTFILEHANDLE);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (-l $dstFile) {
|
||||
if (-l $dstFile || -e $dstFile) {
|
||||
if (!$ignoreCollisions) {
|
||||
my $target = readlink $dstFile;
|
||||
my $target = readlink_or_StateWrapper $dstFile;
|
||||
die "collission between `$srcFile' and `$target'";
|
||||
}
|
||||
}
|
||||
|
|
@ -162,18 +172,37 @@ sub addPkg {
|
|||
}
|
||||
}
|
||||
|
||||
sub readlink_or_StateWrapper {
|
||||
|
||||
my $src = shift;
|
||||
my $target;
|
||||
|
||||
if (-l $src)
|
||||
{ $target = readlink $src; }
|
||||
else{
|
||||
open(DAT, $src) || die("Could not open file!");
|
||||
my @raw_data=<DAT>;
|
||||
close(DAT);
|
||||
$target = $raw_data[1];
|
||||
}
|
||||
return $target
|
||||
}
|
||||
|
||||
# Symlink to the packages that have been installed explicitly by the user.
|
||||
my @storePaths = split ' ', $ENV{"derivations"};
|
||||
my @stateIdentifiers = split ' ', $ENV{"stateIdentifiers"};
|
||||
my @runtimeStateArgs = split ' ', $ENV{"runtimeStateArgs_arg"};
|
||||
my $si_counter = 0;
|
||||
|
||||
foreach my $pkgDir (@storePaths) { #Commented the sort out
|
||||
|
||||
#Link each $pkgDir to a $stateIdentifiers in $path_identifier
|
||||
#print "SP: $pkgDir \n";
|
||||
$path_identifier{$pkgDir} = $stateIdentifiers[$si_counter];
|
||||
#print "SI: $path_identifier{$pkgDir} \n";
|
||||
#Link each $pkgDir to a $stateIdentifiers in $path_state_identifier
|
||||
$path_state_identifier{$pkgDir} = $stateIdentifiers[$si_counter];
|
||||
$path_runtimeArgs{$pkgDir} = $runtimeStateArgs[$si_counter];
|
||||
|
||||
# print "SP: $pkgDir \n";
|
||||
# print "SI: $path_state_identifier{$pkgDir} \n";
|
||||
# print "RT: $path_runtimeArgs{$pkgDir} \n";
|
||||
|
||||
addPkg($pkgDir, 0);
|
||||
$si_counter++;
|
||||
|
|
@ -193,8 +222,6 @@ while (scalar(keys %postponed) > 0) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
print STDERR "created $symlinks symlinks in user environment\n";
|
||||
|
||||
|
||||
symlink($ENV{"manifest"}, "$out/manifest") or die "cannot create manifest";
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
{system, derivations, stateIdentifiers, manifest, nixBinDir, nixStore}:
|
||||
{system, derivations, stateIdentifiers, runtimeStateArgs, manifest, nixBinDir, nixStore}:
|
||||
|
||||
derivation {
|
||||
name = "user-environment";
|
||||
system = system;
|
||||
builder = ./builder.pl;
|
||||
derivations = derivations;
|
||||
runtimeStateArgs_arg = runtimeStateArgs;
|
||||
stateIdentifiers = stateIdentifiers;
|
||||
manifest = manifest;
|
||||
inherit nixBinDir nixStore;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,29 @@ string DrvInfo::queryStateIdentifier(EvalState & state) const
|
|||
return stateIdentifier;
|
||||
}
|
||||
|
||||
string DrvInfo::queryRuntimeStateArgs(EvalState & state) const
|
||||
{
|
||||
if (runtimeStateArgs == "") {
|
||||
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*
|
||||
if(key == "runtimeStateArgs"){
|
||||
PathSet context;
|
||||
string value = coerceToString(state, i->value, context);
|
||||
(string &) runtimeStateArgs = value;
|
||||
}
|
||||
}
|
||||
|
||||
//If still empty
|
||||
if (trim(runtimeStateArgs) == "")
|
||||
(string &) runtimeStateArgs = "__NOARGS__";
|
||||
}
|
||||
|
||||
return runtimeStateArgs;
|
||||
}
|
||||
|
||||
|
||||
MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ private:
|
|||
string drvPath;
|
||||
string outPath;
|
||||
string stateIdentifier;
|
||||
string runtimeStateArgs;
|
||||
|
||||
public:
|
||||
string name;
|
||||
|
|
@ -35,6 +36,7 @@ public:
|
|||
string queryDrvPath(EvalState & state) const;
|
||||
string queryOutPath(EvalState & state) const;
|
||||
string queryStateIdentifier(EvalState & state) const;
|
||||
string queryRuntimeStateArgs(EvalState & state) const;
|
||||
MetaInfo queryMetaInfo(EvalState & state) const;
|
||||
|
||||
void setDrvPath(const string & s)
|
||||
|
|
@ -52,6 +54,11 @@ public:
|
|||
stateIdentifier = s;
|
||||
}
|
||||
|
||||
void setRuntimeStateArgs(const string & s)
|
||||
{
|
||||
runtimeStateArgs = s;
|
||||
}
|
||||
|
||||
void setMetaInfo(const MetaInfo & meta);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
|
|||
|
||||
DerivationStateOutput drvso = drv.stateOutputs["state"];
|
||||
|
||||
if(drvso.runtimeStateParamters != ""){ //Has runtime parameters --> Clear all state parameters
|
||||
if(drvso.runtimeStateArgs != ""){ //Has runtime parameters --> Clear all state parameters
|
||||
drv.stateOutputs.clear();
|
||||
drv.stateOutputDirs.clear();
|
||||
drv.env["statePath"] = "";
|
||||
|
|
@ -365,7 +365,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
|
|||
{
|
||||
Hash h = state.drvHashes[i->first];
|
||||
if (h.type == htUnknown) {
|
||||
Derivation drv2 = derivationFromPath(i->first);
|
||||
Derivation drv2 = derivationFromPathTxn(noTxn, i->first);
|
||||
h = hashDerivationModulo(state, drv2);
|
||||
state.drvHashes[i->first] = h;
|
||||
}
|
||||
|
|
@ -421,7 +421,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
|||
string syncState = "none";
|
||||
string stateIdentifier = "";
|
||||
bool createDirsBeforeInstall = false;
|
||||
string runtimeStateParamters = "";
|
||||
string runtimeStateArgs = "";
|
||||
string sharedState = "";
|
||||
vector<DerivationStateOutputDir> stateDirs;
|
||||
|
||||
|
|
@ -526,7 +526,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
|||
else if(key == "disableState") { disableState = evalBool(state, value); }
|
||||
else if(key == "identifier"){ stateIdentifier = coerceToString(state, value, context, true); }
|
||||
else if(key == "createDirsBeforeInstall"){ createDirsBeforeInstall = evalBool(state, value); }
|
||||
else if(key == "runtimeStateParamters"){ runtimeStateParamters = coerceToString(state, value, context, true); }
|
||||
else if(key == "runtimeStateArgs"){ runtimeStateArgs = coerceToString(state, value, context, true); }
|
||||
else if(key == "shareStateFrom"){ sharedState = coerceToString(state, value, context, true); }
|
||||
|
||||
/* All other attributes are passed to the builder through
|
||||
|
|
@ -611,12 +611,12 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
|||
|
||||
/* If there are no runtime paratermers, then we need to take the the stateIdentifier into account for the hash calcaulation below: hashDerivationModulo(...)
|
||||
* We also add enableState to make it parse the drv to a state-drv
|
||||
* We also add runtimeStateParamters for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash
|
||||
* We also add runtimeStateArgs for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash
|
||||
*/
|
||||
if(enableState && !disableState){
|
||||
if(runtimeStateParamters == ""){
|
||||
if(runtimeStateArgs == ""){
|
||||
string enableStateS = bool2string("true");
|
||||
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateParamters, getCallingUserName(), "", false);
|
||||
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateArgs, getCallingUserName(), "", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +652,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
|||
string enableStateS = bool2string("true");
|
||||
string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall);
|
||||
drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, printHash(componentHash), outputHashAlgo, outputHash, stateIdentifier, enableStateS,
|
||||
shareType, syncState, createDirsBeforeInstallS, runtimeStateParamters, getCallingUserName(), sharedState);
|
||||
shareType, syncState, createDirsBeforeInstallS, runtimeStateArgs, getCallingUserName(), sharedState);
|
||||
|
||||
for(vector<DerivationStateOutputDir>::iterator i = stateDirs.begin(); i != stateDirs.end(); ++i)
|
||||
drv.stateOutputDirs[(*i).path] = *(i);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ libstore_la_SOURCES = \
|
|||
pkginclude_HEADERS = \
|
||||
store-api.hh local-store.hh remote-store.hh derivations.hh misc.hh \
|
||||
globals.hh db.hh references.hh pathlocks.hh \
|
||||
worker-protocol.hh store-state.hh
|
||||
worker-protocol.hh store-state.hh build.hh
|
||||
|
||||
libstore_la_LIBADD = ../libutil/libutil.la \
|
||||
../libext3cow/libext3cow.la \
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "db.hh"
|
||||
#include "util.hh"
|
||||
#include "store-state.hh"
|
||||
#include "build.hh"
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
|
@ -770,7 +771,7 @@ void DerivationGoal::haveDerivation()
|
|||
assert(store->isValidPath(drvPath));
|
||||
|
||||
/* Get the derivation. */
|
||||
drv = derivationFromPath(drvPath);
|
||||
drv = derivationFromPathTxn(noTxn, drvPath);
|
||||
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
|
|
@ -1319,7 +1320,7 @@ bool DerivationGoal::prepareBuild()
|
|||
`*i' as input paths. Only add the closures of output paths
|
||||
that are specified as inputs. */
|
||||
assert(store->isValidPath(i->first));
|
||||
Derivation inDrv = derivationFromPath(i->first);
|
||||
Derivation inDrv = derivationFromPathTxn(noTxn, i->first);
|
||||
for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||
if (inDrv.outputs.find(*j) != inDrv.outputs.end()){
|
||||
computeFSClosure(inDrv.outputs[*j].path, inputPaths, true, false, -1); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE (done?)
|
||||
|
|
@ -2600,10 +2601,12 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
|
|||
}
|
||||
|
||||
|
||||
void LocalStore::ensurePath(const Path & path)
|
||||
void ensurePathTxn(const Transaction & txn, const Path & path)
|
||||
{
|
||||
/* If the path is already valid, we're done. */
|
||||
if (store->isValidPath(path)) return;
|
||||
|
||||
if (isValidPathTxn(txn, path))
|
||||
return;
|
||||
|
||||
Worker worker;
|
||||
GoalPtr goal = worker.makeSubstitutionGoal(path);
|
||||
|
|
@ -2615,5 +2618,10 @@ void LocalStore::ensurePath(const Path & path)
|
|||
throw Error(format("path `%1%' does not exist and cannot be created") % path);
|
||||
}
|
||||
|
||||
void LocalStore::ensurePath(const Path & path)
|
||||
{
|
||||
ensurePathTxn(noTxn, path);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
12
src/libstore/build.hh
Normal file
12
src/libstore/build.hh
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef BUILD_HH_
|
||||
#define BUILD_HH_
|
||||
|
||||
#include "db.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void ensurePathTxn(const Transaction & txn, const Path & path);
|
||||
|
||||
}
|
||||
|
||||
#endif /*BUILD_HH_*/
|
||||
|
|
@ -701,7 +701,7 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_ta
|
|||
|
||||
//query state versioined directorys/files
|
||||
vector<Path> sortedPaths;
|
||||
Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, getStatePath));
|
||||
Derivation drv = derivationFromPathTxn(txn, queryStatePathDrvTxn(txn, getStatePath));
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
|
||||
for (DerivationStateOutputDirs::const_iterator j = stateOutputDirs.begin(); j != stateOutputDirs.end(); ++j){
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ void throwBadDrv(ATerm t)
|
|||
Derivation parseDerivation(ATerm t)
|
||||
{
|
||||
Derivation drv;
|
||||
ATermList outs, solidStateDeps, inDrvs, inSrcs, args, bnds;
|
||||
ATermList stateOuts = ATempty, stateOutDirs = ATempty;
|
||||
ATermList outs, inDrvs, inSrcs, args, bnds;
|
||||
ATermList stateOuts = ATempty, stateOutDirs = ATempty, solidStateDeps = ATempty;
|
||||
|
||||
ATerm builder, platform;
|
||||
|
||||
|
|
@ -93,8 +93,8 @@ Derivation parseDerivation(ATerm t)
|
|||
{
|
||||
//parse state part
|
||||
for (ATermIterator i(stateOuts); i; ++i) {
|
||||
ATerm id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateParamters, username, sharedState;
|
||||
if (!matchDerivationStateOutput(*i, id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateParamters, username, sharedState))
|
||||
ATerm id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateArgs, username, sharedState;
|
||||
if (!matchDerivationStateOutput(*i, id, statepath, componentHash, hashAlgo, hash, stateIdentifier, enabled, shareType, synchronization, createDirsBeforeInstall, runtimeStateArgs, username, sharedState))
|
||||
throwBadDrv(t);
|
||||
DerivationStateOutput stateOut;
|
||||
stateOut.statepath = aterm2String(statepath);
|
||||
|
|
@ -107,7 +107,7 @@ Derivation parseDerivation(ATerm t)
|
|||
stateOut.shareType = aterm2String(shareType);
|
||||
stateOut.synchronization = aterm2String(synchronization);
|
||||
stateOut.createDirsBeforeInstall = aterm2String(createDirsBeforeInstall);
|
||||
stateOut.runtimeStateParamters = aterm2String(runtimeStateParamters);
|
||||
stateOut.runtimeStateArgs = aterm2String(runtimeStateArgs);
|
||||
stateOut.username = aterm2String(username);
|
||||
stateOut.sharedState = aterm2String(sharedState);
|
||||
drv.stateOutputs[aterm2String(id)] = stateOut;
|
||||
|
|
@ -199,7 +199,7 @@ ATerm unparseDerivation(const Derivation & drv)
|
|||
toATerm(i->second.shareType),
|
||||
toATerm(i->second.synchronization),
|
||||
toATerm(i->second.createDirsBeforeInstall),
|
||||
toATerm(i->second.runtimeStateParamters),
|
||||
toATerm(i->second.runtimeStateArgs),
|
||||
toATerm(i->second.username),
|
||||
toATerm(i->second.sharedState)
|
||||
));
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct DerivationStateOutput
|
|||
string commitBinaries; //TODO list of binaries that need (or not) to be committed when these binaries are called
|
||||
|
||||
string createDirsBeforeInstall; //if true: creates state dirs before installation
|
||||
string runtimeStateParamters; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here)
|
||||
string runtimeStateArgs; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here)
|
||||
|
||||
string username;
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ struct DerivationStateOutput
|
|||
}
|
||||
|
||||
//TODO add const ??
|
||||
DerivationStateOutput(Path statepath, string componentHash, string hashAlgo, string hash, string stateIdentifier, string enabled, string shareType, string synchronization, string createDirsBeforeInstall, string runtimeStateParamters, string username, string sharedState, bool check=true)
|
||||
DerivationStateOutput(Path statepath, string componentHash, string hashAlgo, string hash, string stateIdentifier, string enabled, string shareType, string synchronization, string createDirsBeforeInstall, string runtimeStateArgs, string username, string sharedState, bool check=true)
|
||||
{
|
||||
if(check){
|
||||
if(shareType != "none" && shareType != "full" && shareType != "group")
|
||||
|
|
@ -71,6 +71,10 @@ struct DerivationStateOutput
|
|||
throw Error(format("Username cannot be empty"));
|
||||
if(stateIdentifier == "__EMTPY__" || stateIdentifier == "__NOSTATE__")
|
||||
throw Error(format("the stateIdenfier cannot be this value '%1%'") % stateIdentifier);
|
||||
if(runtimeStateArgs == "__NOARGS__")
|
||||
throw Error(format("the runtimeStateArgs cannot be this value '%1%'") % runtimeStateArgs);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
|
@ -86,7 +90,7 @@ struct DerivationStateOutput
|
|||
this->shareType = shareType;
|
||||
this->synchronization = synchronization;
|
||||
this->createDirsBeforeInstall = createDirsBeforeInstall;
|
||||
this->runtimeStateParamters = runtimeStateParamters;
|
||||
this->runtimeStateArgs = runtimeStateArgs;
|
||||
this->username = username;
|
||||
this->sharedState = sharedState;
|
||||
}
|
||||
|
|
@ -112,7 +116,7 @@ struct DerivationStateOutput
|
|||
this->shareType = "";
|
||||
this->synchronization = "";
|
||||
this->createDirsBeforeInstall = "";
|
||||
this->runtimeStateParamters = "";
|
||||
this->runtimeStateArgs = "";
|
||||
//this->username; //Changes the statepath directly
|
||||
this->sharedState = "";
|
||||
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
|
|||
for (PathSet::iterator i = livePaths.begin();
|
||||
i != livePaths.end(); ++i)
|
||||
if (isDerivation(*i)) {
|
||||
Derivation drv = derivationFromPath(*i);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, *i);
|
||||
for (DerivationOutputs::iterator j = drv.outputs.begin();
|
||||
j != drv.outputs.end(); ++j)
|
||||
if (store->isValidPath(j->second.path))
|
||||
|
|
|
|||
|
|
@ -453,7 +453,6 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
|||
throw Error(format("cannot set references for path `%1%' which is invalid and has no substitutes") % store_or_statePath);
|
||||
|
||||
|
||||
printMsg(lvlError, format("Setting references for %1% (revision:%2%)") % store_or_statePath % int2String(revision));
|
||||
/*
|
||||
for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
|
||||
printMsg(lvlError, format("'%2%' has references: %1%") % *i % store_or_statePath);
|
||||
|
|
@ -463,6 +462,8 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
|||
|
||||
if(isRealisablePath(txn, store_or_statePath))
|
||||
{
|
||||
printMsg(lvlError, format("Setting references for storepath '%1%'") % store_or_statePath);
|
||||
|
||||
//Just overwrite the old references, since there is oly 1 revision of a storePath
|
||||
|
||||
Paths oldReferences_c_c;
|
||||
|
|
@ -481,6 +482,8 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
|||
else if(isRealisableStatePath(txn, store_or_statePath))
|
||||
{
|
||||
|
||||
printMsg(lvlError, format("Setting references for statepath '%1%' (revision:%2%)") % store_or_statePath % int2String(revision));
|
||||
|
||||
//Write references to a special revision (since there are multiple revisions of a statePath)
|
||||
|
||||
//query the references of revision (-1 is query the latest references)
|
||||
|
|
@ -498,7 +501,7 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
|||
}
|
||||
else
|
||||
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void queryXReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & references, const bool component_or_state, const int revision, int timestamp)
|
||||
|
|
@ -693,9 +696,7 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de
|
|||
if (!isRealisablePath(txn, storePath))
|
||||
throw Error(format("path `%1%' is not valid") % storePath);
|
||||
|
||||
//printMsg(lvlError, format("Ttttttttttttttttttttttttt %1%") % deriver);
|
||||
|
||||
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component //hanges somtimes !!!!!!!!!!!!!!!!!!!
|
||||
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component
|
||||
addStateDeriver(txn, storePath, deriver);
|
||||
}
|
||||
else{
|
||||
|
|
@ -712,14 +713,14 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv,
|
|||
{
|
||||
PathSet newdrvs;
|
||||
|
||||
Derivation drv = derivationFromPath(newdrv);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, newdrv);
|
||||
string identifier = drv.stateOutputs.find("state")->second.stateIdentifier;
|
||||
string user = drv.stateOutputs.find("state")->second.username;
|
||||
|
||||
for (PathSet::iterator i = drvs.begin(); i != drvs.end(); ++i) //Check if we need to remove old drvs
|
||||
{
|
||||
Path drv = *i;
|
||||
Derivation getdrv = derivationFromPath(drv);
|
||||
Derivation getdrv = derivationFromPathTxn(noTxn, drv);
|
||||
string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier;
|
||||
string getUser = getdrv.stateOutputs.find("state")->second.username;
|
||||
|
||||
|
|
@ -747,7 +748,7 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path
|
|||
if (!isRealisablePath(txn, storePath))
|
||||
throw Error(format("path `%1%' is not valid") % storePath);
|
||||
|
||||
Derivation drv = derivationFromPath(deriver);
|
||||
Derivation drv = derivationFromPathTxn(txn, deriver);
|
||||
string identifier = drv.stateOutputs.find("state")->second.stateIdentifier;
|
||||
string user = drv.stateOutputs.find("state")->second.username;
|
||||
|
||||
|
|
@ -786,8 +787,7 @@ bool LocalStore::isStateComponent(const Path & storePath)
|
|||
|
||||
bool isStateDrvPathTxn(const Transaction & txn, const Path & drvPath)
|
||||
{
|
||||
//printMsg(lvlError, format("Sssssssssssssssssss %1%") % drvPath);
|
||||
Derivation drv = derivationFromPath(drvPath);
|
||||
Derivation drv = derivationFromPathTxn(txn, drvPath);
|
||||
return isStateDrvTxn(txn, drv);
|
||||
}
|
||||
|
||||
|
|
@ -817,7 +817,7 @@ Path queryDeriver(const Transaction & txn, const Path & storePath)
|
|||
|
||||
bool b = nixDB.queryString(txn, dbDerivers, storePath, deriver);
|
||||
|
||||
Derivation drv = derivationFromPath(deriver);
|
||||
Derivation drv = derivationFromPathTxn(txn, deriver);
|
||||
if (isStateDrvTxn(txn, drv))
|
||||
throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver);
|
||||
|
||||
|
|
@ -843,7 +843,7 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str
|
|||
for (Strings::iterator i = alldata.begin(); i != alldata.end(); ++i) { //filter on username and identifier
|
||||
|
||||
string derivationpath = (*i);
|
||||
Derivation drv = derivationFromPath(derivationpath);
|
||||
Derivation drv = derivationFromPathTxn(txn, derivationpath);
|
||||
|
||||
if (drv.outputs.size() != 1)
|
||||
throw Error(format("The call queryDerivers with storepath %1% is not a statePath") % storePath);
|
||||
|
|
@ -1093,8 +1093,9 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos)
|
|||
|
||||
//We cannot check the statePath since registerValidPath is called twice, first for the component path, and then for the state path....
|
||||
|
||||
if(isStorePath_b)
|
||||
if(isStorePath_b){
|
||||
setDeriver(txn, i->path, i->deriver);
|
||||
}
|
||||
|
||||
//TODO maybe also set a state deriver into dbStateDerivers .... well state is already linked to a drvpath in dbValidStatePaths ....
|
||||
}
|
||||
|
|
@ -1649,7 +1650,7 @@ void storePathRequisitesTxn(const Transaction & txn, const Path & storeOrstatePa
|
|||
for (PathSet::iterator i = paths.begin();
|
||||
i != paths.end(); ++i)
|
||||
if (isDerivation(*i)) {
|
||||
Derivation drv = derivationFromPath(*i);
|
||||
Derivation drv = derivationFromPathTxn(txn, *i);
|
||||
for (DerivationOutputs::iterator j = drv.outputs.begin();
|
||||
j != drv.outputs.end(); ++j)
|
||||
if (isValidPathTxn(txn, j->second.path))
|
||||
|
|
@ -1816,9 +1817,8 @@ PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePa
|
|||
Path statePath_ns = toNonSharedPathTxn(txn, statePath);
|
||||
PathSet empty;
|
||||
return getSharedWithPathSetRecTxn_private(txn, statePath_ns, empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */
|
||||
static void upgradeStore07()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -244,6 +244,8 @@ PathSet toNonSharedPathSetTxn(const Transaction & txn, const PathSet & statePath
|
|||
Path toNonSharedPathTxn(const Transaction & txn, const Path & statePath);
|
||||
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath);
|
||||
|
||||
void ensurePathTxn(const Transaction & txn, const Path & path);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@
|
|||
namespace nix {
|
||||
|
||||
|
||||
Derivation derivationFromPath(const Path & drvPath)
|
||||
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath)
|
||||
{
|
||||
assertStorePath(drvPath);
|
||||
store->ensurePath(drvPath);
|
||||
//printMsg(lvlError, format("uuuuuuuuuuuuuuuuuu"));
|
||||
ensurePathTxn(txn, drvPath);
|
||||
ATerm t = ATreadFromNamedFile(drvPath.c_str());
|
||||
if (!t) throw Error(format("cannot read aterm from `%1%'") % drvPath);
|
||||
if (!t)
|
||||
throw Error(format("cannot read aterm from `%1%'") % drvPath);
|
||||
return parseDerivation(t);
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ void queryMissing(const PathSet & targets,
|
|||
|
||||
if (isDerivation(p)) {
|
||||
if (!store->isValidPath(p)) continue;
|
||||
Derivation drv = derivationFromPath(p);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, p);
|
||||
|
||||
bool mustBuild = false;
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace nix {
|
|||
|
||||
/* Read a derivation, after ensuring its existence through
|
||||
ensurePath(). */
|
||||
Derivation derivationFromPath(const Path & drvPath);
|
||||
Derivation derivationFromPathTxn(const Transaction & txn, const Path & drvPath);
|
||||
|
||||
/* Place in `paths' the set of all store paths in the file system
|
||||
closure of `storePath'; that is, all paths than can be directly or
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ Snapshots commitStatePathTxn(const Transaction & txn, const Path & statePath)
|
|||
throw Error(format("path `%1%' is not a valid state path") % statePath);
|
||||
|
||||
//queryDeriversStatePath??
|
||||
Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, statePath));
|
||||
Derivation drv = derivationFromPathTxn(txn, queryStatePathDrvTxn(txn, statePath));
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
|
|||
ATermList manifest = ATempty;
|
||||
ATermList inputs = ATempty;
|
||||
ATermList stateIdentifiers = ATempty;
|
||||
ATermList runtimeStateArgs = ATempty;
|
||||
for (DrvInfos::const_iterator i = elems.begin();
|
||||
i != elems.end(); ++i)
|
||||
{
|
||||
|
|
@ -193,6 +194,8 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
|
|||
|
||||
//Insert the new stateIdentifier into the stateIdentifiers Atermlist
|
||||
stateIdentifiers = ATinsert(stateIdentifiers, makeStr(i->queryStateIdentifier(state)));
|
||||
//Insert the new runtime state args into the runtimeStateArgs Atermlist
|
||||
runtimeStateArgs = ATinsert(runtimeStateArgs, makeStr(i->queryRuntimeStateArgs(state)));
|
||||
|
||||
inputs = ATinsert(inputs, makeStr(i->queryOutPath(state)));
|
||||
|
||||
|
|
@ -207,25 +210,34 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
|
|||
}
|
||||
|
||||
//printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(stateIdentifiers)))) );
|
||||
//printMsg(lvlError, format("TEST '%1%'") % atPrint(canonicaliseExpr(makeList(ATreverse(runtimeStateArgs)))) );
|
||||
|
||||
/* 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(ATmakeList6(
|
||||
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<PathSet>(manifestFile)), makeNoPos()),
|
||||
makeBind(toATerm("nixBinDir"),
|
||||
makeStr(nixBinDir), makeNoPos()),
|
||||
Expr topLevel = makeCall(envBuilder, makeAttrs(
|
||||
|
||||
ATinsert(
|
||||
ATmakeList6(
|
||||
makeBind(toATerm("system"),
|
||||
makeStr(thisSystem), makeNoPos()),
|
||||
makeBind(toATerm("derivations"),
|
||||
makeList(ATreverse(manifest)), makeNoPos()),
|
||||
makeBind(toATerm("stateIdentifiers"),
|
||||
makeList(ATreverse(stateIdentifiers)), makeNoPos()),
|
||||
makeBind(toATerm("runtimeStateArgs"),
|
||||
makeList(ATreverse(runtimeStateArgs)), makeNoPos()),
|
||||
makeBind(toATerm("manifest"),
|
||||
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos()),
|
||||
makeBind(toATerm("nixBinDir"),
|
||||
makeStr(nixBinDir), makeNoPos()) )
|
||||
,
|
||||
makeBind(toATerm("nixStore"),
|
||||
makeStr(nixStore), makeNoPos())
|
||||
)));
|
||||
)
|
||||
|
||||
));
|
||||
|
||||
/* Instantiate it. */
|
||||
debug(format("evaluating builder expression `%1%'") % topLevel);
|
||||
|
|
@ -391,7 +403,7 @@ static void queryInstSources(EvalState & state,
|
|||
|
||||
if (isDerivation(*i)) {
|
||||
elem.setDrvPath(*i);
|
||||
elem.setOutPath(findOutput(derivationFromPath(*i), "out"));
|
||||
elem.setOutPath(findOutput(derivationFromPathTxn(noTxn, *i), "out"));
|
||||
|
||||
if (name.size() >= drvExtension.size() &&
|
||||
string(name, name.size() - drvExtension.size()) == drvExtension)
|
||||
|
|
@ -484,7 +496,7 @@ static void installDerivations(Globals & globals,
|
|||
|
||||
//Set the state indentifier if it is a state-component
|
||||
printMsg(lvlError, format("New component to install DRV: '%1%'") % i->queryDrvPath(globals.state));
|
||||
Derivation drv = derivationFromPath(i->queryDrvPath(globals.state));
|
||||
Derivation drv = derivationFromPathTxn(noTxn, i->queryDrvPath(globals.state));
|
||||
if(store->isStateDrv(drv))
|
||||
{
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
|
|
@ -515,6 +527,7 @@ static void installDerivations(Globals & globals,
|
|||
{
|
||||
DrvName drvName(i->name);
|
||||
|
||||
//We may need to share state
|
||||
if (!globals.preserveInstalled && newNames.find(drvName.name) != newNames.end()){
|
||||
|
||||
//******** We're gonna check if the component and state indentifiers are the same,
|
||||
|
|
@ -530,7 +543,7 @@ static void installDerivations(Globals & globals,
|
|||
for (DrvInfos::iterator j = newElems.begin(); j != newElems.end(); ++j) {
|
||||
DrvName newDrvName(j->name);
|
||||
if(newDrvName.name == drvName.name){
|
||||
Derivation newDrv = derivationFromPath(j->queryDrvPath(globals.state));
|
||||
Derivation newDrv = derivationFromPathTxn(noTxn, j->queryDrvPath(globals.state));
|
||||
DerivationStateOutputs newStateOutputs = newDrv.stateOutputs;
|
||||
newStateIdentifier = newStateOutputs.find("state")->second.stateIdentifier;
|
||||
newStatePath = newDrv.stateOutputs.find("state")->second.statepath;
|
||||
|
|
@ -540,6 +553,8 @@ static void installDerivations(Globals & globals,
|
|||
}
|
||||
//printMsg(lvlError, format("old '%1%' new '%2%'") % oldStateIdentifier % newStateIdentifier);
|
||||
|
||||
//if it doesnt need to share state with some other component
|
||||
//&& the identifiers are equal
|
||||
if( newSharedState == ""
|
||||
&&
|
||||
(oldStateIdentifier == newStateIdentifier
|
||||
|
|
@ -553,7 +568,7 @@ static void installDerivations(Globals & globals,
|
|||
throw Error(format("Internal Error: There is not exactly one deriver with state_identifier '%1%' for path '%2%'")
|
||||
% newStateIdentifier % i->queryOutPath(globals.state));
|
||||
Path oldDrvPath = *(derivers.begin());
|
||||
Derivation oldDrv = derivationFromPath(oldDrvPath);
|
||||
Derivation oldDrv = derivationFromPathTxn(noTxn, oldDrvPath);
|
||||
oldStatePath = oldDrv.stateOutputs.find("state")->second.statepath;
|
||||
|
||||
//SharePaths
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ Derivation getDerivation(const string & fullPath, const Strings & program_args,
|
|||
|
||||
//Retrieve the derivation, there is only 1 drvPath in derivers
|
||||
derivationPath = *(derivers.begin());
|
||||
Derivation drv = derivationFromPath(derivationPath);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, derivationPath);
|
||||
|
||||
if(isStateComponent){
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
|
|
@ -275,7 +275,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
|||
int timestamp = getTimestamps[statePath];
|
||||
|
||||
//get its derivation-state-items
|
||||
Derivation statePath_drv = derivationFromPath(queryStatePathDrvTxn(noTxn, statePath));
|
||||
Derivation statePath_drv = derivationFromPathTxn(noTxn, queryStatePathDrvTxn(noTxn, statePath));
|
||||
DerivationStateOutputDirs stateOutputDirs = statePath_drv.stateOutputDirs;
|
||||
|
||||
//TODO Sort snapshots??? eg first restore root, then the subdirs??
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ static Path realisePath(const Path & path)
|
|||
PathSet paths;
|
||||
paths.insert(path);
|
||||
store->buildDerivations(paths);
|
||||
Path outPath = findOutput(derivationFromPath(path), "out");
|
||||
Path outPath = findOutput(derivationFromPathTxn(noTxn, path), "out");
|
||||
|
||||
if (gcRoot == "")
|
||||
printGCWarning();
|
||||
|
|
@ -184,7 +184,7 @@ static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRea
|
|||
if (forceRealise)
|
||||
realisePath(storePath);
|
||||
if (useOutput && isDerivation(storePath)) {
|
||||
Derivation drv = derivationFromPath(storePath);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, storePath);
|
||||
return findOutput(drv, "out");
|
||||
}
|
||||
else return storePath;
|
||||
|
|
@ -290,7 +290,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
{
|
||||
*i = fixPath(*i);
|
||||
if (forceRealise) realisePath(*i);
|
||||
Derivation drv = derivationFromPath(*i);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, *i);
|
||||
cout << format("%1%\n") % findOutput(drv, "out");
|
||||
}
|
||||
break;
|
||||
|
|
@ -342,7 +342,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
i != opArgs.end(); ++i)
|
||||
{
|
||||
Path path = useDeriver(fixPath(*i));
|
||||
Derivation drv = derivationFromPath(path);
|
||||
Derivation drv = derivationFromPathTxn(noTxn, path);
|
||||
StringPairs::iterator j = drv.env.find(bindingName);
|
||||
if (j == drv.env.end())
|
||||
throw Error(format("derivation `%1%' has no environment binding named `%2%'")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue