diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 2bc21b286..cf79e3392 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -553,18 +553,21 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) /* Construct the final derivation store expression. */ drv.env["out"] = outPath; drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash); + + //only add state when we have to to keep compitibilty with the 'old' format. + if(enableState){ + /* Add the state path based on the outPath */ + string callingUser = "wouterdb"; //TODO: Change into variable + string componentHash = printHash(hashDerivationModulo(state, drv)); //hash of the component path + Hash statehash = hashString(htSHA256, stateIndentifier + callingUser + componentHash); //hash of the state path + Path stateOutPath = makeStatePath("stateOutput:statepath", statehash, drvName); // - /* Add the state path based on the outPath */ - string callingUser = "wouterdb"; //TODO: Change into variable - string componentHash = printHash(hashDerivationModulo(state, drv)); //hash of the component path - Hash statehash = hashString(htSHA256, stateIndentifier + callingUser + componentHash); //hash of the state path - Path stateOutPath = makeStatePath("stateOutput:statepath", statehash, drvName); // - - drv.env["statepath"] = stateOutPath; - string enableStateS = bool2string(enableState && disableState); - string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall); + drv.env["statepath"] = stateOutPath; + string enableStateS = bool2string(enableState && disableState); + string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall); - drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, outputHashAlgo, outputHash, enableStateS, shareState, syncState, createDirsBeforeInstallS); + drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, outputHashAlgo, outputHash, enableStateS, shareState, syncState, createDirsBeforeInstallS); + } /* Write the resulting term into the Nix store directory. */ Path drvPath = writeDerivation(drv, drvName); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 7cdb5c801..4dc10dd09 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1378,7 +1378,11 @@ void DerivationGoal::startBuilder() /* Create the state directory where the component can store it's state files place */ //TODO - stateDir = createStateDirs(drv.stateOutputDirs, drv.stateOutputs); + + //TODO include addDirsBefore ... + //if(enableState){ ... + //stateDir = createStateDirs(drv.stateOutputDirs, drv.stateOutputs); + //} //TODO create the startupscript diff --git a/src/libstore/derivations-ast.def b/src/libstore/derivations-ast.def index 0333d88ec..71217f537 100644 --- a/src/libstore/derivations-ast.def +++ b/src/libstore/derivations-ast.def @@ -3,12 +3,19 @@ init initDerivationsHelpers #wouter added 2 ATermList Derive | ATermList ATermList ATermList ATermList ATermList string string ATermList ATermList | ATerm | - | string string | ATerm | EnvBinding | | string ATermList | ATerm | DerivationInput | | string string string string | ATerm | DerivationOutput | | string string string string string string string string | ATerm | DerivationStateOutput | | string string string | ATerm | DerivationStateOutputDir | +#We use DeriveWithOutState to create derivations that dont use state, and thus dont have the stateDerivationStateOutput and DerivationStateOutputDir in their derivation +#Ive put this in because eelco requested it, and its easy to stay backwards compatible, but ultimately I thinks that it should be removed to prevent confusion & duplication + +DeriveWithOutState | ATermList ATermList ATermList string string ATermList ATermList | ATerm | +| string string | ATerm | EnvBindingWithOutState | +| string ATermList | ATerm | DerivationInputWithOutState | +| string string string string | ATerm | DerivationOutputWithOutState | + Closure | ATermList ATermList | ATerm | OldClosure | | string ATermList | ATerm | OldClosureElem | diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 308494f27..c4d5fe692 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -2,6 +2,7 @@ #include "store-api.hh" #include "aterm.hh" #include "globals.hh" +#include "util.hh" #include "derivations-ast.hh" #include "derivations-ast.cc" @@ -65,10 +66,15 @@ void throwBadDrv(ATerm t) Derivation parseDerivation(ATerm t) { Derivation drv; - ATermList outs, stateOuts, stateOutDirs, inDrvs, inSrcs, args, bnds; + ATermList outs, inDrvs, inSrcs, args, bnds; + ATermList stateOuts = ATempty, stateOutDirs = ATempty; + ATerm builder, platform; - if (!matchDerive(t, outs, stateOuts, stateOutDirs, inDrvs, inSrcs, platform, builder, args, bnds)) + bool withState; + if (matchDerive(t, outs, stateOuts, stateOutDirs, inDrvs, inSrcs, platform, builder, args, bnds) ) { withState = true; } + else if (matchDeriveWithOutState(t, outs, inDrvs, inSrcs, platform, builder, args, bnds) ) { withState = false; } + else throwBadDrv(t); for (ATermIterator i(outs); i; ++i) { @@ -83,35 +89,39 @@ Derivation parseDerivation(ATerm t) drv.outputs[aterm2String(id)] = out; } - //parse state part - for (ATermIterator i(stateOuts); i; ++i) { - ATerm id, statepath, hashAlgo, hash, enabled, shared, synchronization, createDirsBeforeInstall; - if (!matchDerivationStateOutput(*i, id, statepath, hashAlgo, hash, enabled, shared, synchronization, createDirsBeforeInstall)) - throwBadDrv(t); - DerivationStateOutput stateOut; - stateOut.statepath = aterm2String(statepath); - //checkPath(stateOut.path); //should we check the statpath .... ??? - stateOut.hashAlgo = aterm2String(hashAlgo); - stateOut.hash = aterm2String(hash); - stateOut.enabled = aterm2String(enabled); - stateOut.shared = aterm2String(shared); - stateOut.synchronization = aterm2String(synchronization); - stateOut.createDirsBeforeInstall = aterm2String(createDirsBeforeInstall); - drv.stateOutputs[aterm2String(id)] = stateOut; - } - - //parse state dirs part - for (ATermIterator i(stateOutDirs); i; ++i) { - ATerm id, path, type, interval; - if (!matchDerivationStateOutputDir(*i, id, /*path,*/ type, interval)) - throwBadDrv(t); - path = id; - DerivationStateOutputDir stateOutDirs; - stateOutDirs.path = aterm2String(path); - stateOutDirs.type = aterm2String(type); - stateOutDirs.interval = aterm2String(interval); - drv.stateOutputDirs[aterm2String(id)] = stateOutDirs; - } + if(withState){ + //parse state part + for (ATermIterator i(stateOuts); i; ++i) { + ATerm id, statepath, hashAlgo, hash, enabled, shared, synchronization, createDirsBeforeInstall; + if (!matchDerivationStateOutput(*i, id, statepath, hashAlgo, hash, enabled, shared, synchronization, createDirsBeforeInstall)) + throwBadDrv(t); + DerivationStateOutput stateOut; + stateOut.statepath = aterm2String(statepath); + //checkPath(stateOut.path); //should we check the statpath .... ??? + stateOut.hashAlgo = aterm2String(hashAlgo); + stateOut.hash = aterm2String(hash); + stateOut.enabled = aterm2String(enabled); + stateOut.shared = aterm2String(shared); + stateOut.synchronization = aterm2String(synchronization); + stateOut.createDirsBeforeInstall = aterm2String(createDirsBeforeInstall); + drv.stateOutputs[aterm2String(id)] = stateOut; + } + } + + if(withState){ + //parse state dirs part + for (ATermIterator i(stateOutDirs); i; ++i) { + ATerm id, path, type, interval; + if (!matchDerivationStateOutputDir(*i, id, type, interval)) + throwBadDrv(t); + path = id; //We prevent duplication since the key is also the path + DerivationStateOutputDir stateOutDirs; + stateOutDirs.path = aterm2String(path); + stateOutDirs.type = aterm2String(type); + stateOutDirs.interval = aterm2String(interval); + drv.stateOutputDirs[aterm2String(id)] = stateOutDirs; + } + } for (ATermIterator i(inDrvs); i; ++i) { ATerm drvPath; @@ -150,8 +160,7 @@ Derivation parseDerivation(ATerm t) ATerm unparseDerivation(const Derivation & drv) { ATermList outputs = ATempty; - for (DerivationOutputs::const_reverse_iterator i = drv.outputs.rbegin(); - i != drv.outputs.rend(); ++i) + for (DerivationOutputs::const_reverse_iterator i = drv.outputs.rbegin(); i != drv.outputs.rend(); ++i) outputs = ATinsert(outputs, makeDerivationOutput( toATerm(i->first), @@ -159,8 +168,14 @@ ATerm unparseDerivation(const Derivation & drv) toATerm(i->second.hashAlgo), toATerm(i->second.hash))); + //decide if we need to add state to the derivation + bool createState = false; + ATermList stateOutputs = ATempty; - for (DerivationStateOutputs::const_reverse_iterator i = drv.stateOutputs.rbegin(); i != drv.stateOutputs.rend(); ++i) + for (DerivationStateOutputs::const_reverse_iterator i = drv.stateOutputs.rbegin(); i != drv.stateOutputs.rend(); ++i){ + if(i->second.enabled == "true"){ + createState = true; + } stateOutputs = ATinsert(stateOutputs, makeDerivationStateOutput( toATerm(i->first), @@ -172,18 +187,17 @@ ATerm unparseDerivation(const Derivation & drv) toATerm(i->second.synchronization), toATerm(i->second.createDirsBeforeInstall) )); + } ATermList stateOutputDirs = ATempty; for (DerivationStateOutputDirs::const_reverse_iterator i = drv.stateOutputDirs.rbegin(); i != drv.stateOutputDirs.rend(); ++i) stateOutputDirs = ATinsert(stateOutputDirs, makeDerivationStateOutputDir( toATerm(i->first), - //toATerm(i->second.path), + //toATerm(i->second.path), //removed to prevent duplication since the key is also the path toATerm(i->second.type), toATerm(i->second.interval) )); - - //toATermList(i->second.dirs) ATermList inDrvs = ATempty; @@ -207,16 +221,28 @@ ATerm unparseDerivation(const Derivation & drv) toATerm(i->first), toATerm(i->second))); - return makeDerive( - outputs, - stateOutputs, - stateOutputDirs, - inDrvs, - toATermList(drv.inputSrcs), - toATerm(drv.platform), - toATerm(drv.builder), - args, - env); + if(createState){ + return makeDerive( + outputs, + stateOutputs, + stateOutputDirs, + inDrvs, + toATermList(drv.inputSrcs), + toATerm(drv.platform), + toATerm(drv.builder), + args, + env); + } + else{ + return makeDeriveWithOutState( + outputs, + inDrvs, + toATermList(drv.inputSrcs), + toATerm(drv.platform), + toATerm(drv.builder), + args, + env); + } }