From bcf9d3ab2f0961a61918d416f82df34d32fd2187 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Mon, 4 Jun 2007 16:51:15 +0000 Subject: [PATCH] --- src/libexpr/primops.cc | 52 ++++++++++++++++++---- src/libstore/build.cc | 5 ++- src/libstore/derivations.hh | 4 +- src/libstore/local-store.cc | 83 +++++++++++++++++++++++++++++++++++- src/libstore/local-store.hh | 5 +++ src/libstore/remote-store.cc | 13 ++++++ src/libstore/remote-store.hh | 4 ++ src/libstore/store-api.hh | 6 +++ src/libutil/util.cc | 7 +++ src/libutil/util.hh | 3 ++ src/nix-state/nix-state.cc | 32 +++++++++++--- 11 files changed, 194 insertions(+), 20 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 4d13bdcdd..d5518859e 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1,11 +1,13 @@ #include "misc.hh" #include "eval.hh" +#include "db.hh" #include "globals.hh" #include "store-api.hh" #include "util.hh" #include "archive.hh" #include "expr-to-xml.hh" #include "nixexpr-ast.hh" +#include "local-store.hh" #include #include @@ -313,24 +315,41 @@ static Expr prim_relativise(EvalState & state, const ATermVector & args) (basically) its outputHash. */ static Hash hashDerivationModulo(EvalState & state, Derivation drv) { + //printMsg(lvlError, format("DRV: %1% %2%") % drv.env.find("name")->second % (drv.outputs.size() == 1)); + /* Return a fixed hash for fixed-output derivations. */ if (drv.outputs.size() == 1) { DerivationOutputs::const_iterator i = drv.outputs.begin(); + if (i->first == "out" && i->second.hash != "") { + //printMsg(lvlError, format("%1% - %2% - %3%") % i->second.hashAlgo % i->second.hash % i->second.path); + return hashString(htSHA256, "fixed:out:" + i->second.hashAlgo + ":" + i->second.hash + ":" + i->second.path); } } + + /* If we have a state derivation, we clear these paramters because they dont affect to outPath */ + if(drv.stateOutputs.size() != 0){ + drv.env["statepath"] = ""; + drv.stateOutputs.clear(); + drv.stateOutputDirs.clear(); + + /* We do NOT clear the state identifier (what about the username ????) when there are NO + * runtime arguments, since this will affect the statePath and therefore the outPath + */ + //TODO + } + /* For other derivations, replace the inputs paths with recursive calls to this function.*/ DerivationInputs inputs2; - for (DerivationInputs::iterator i = drv.inputDrvs.begin(); - i != drv.inputDrvs.end(); ++i) + for (DerivationInputs::iterator i = drv.inputDrvs.begin(); i != drv.inputDrvs.end(); ++i) { Hash h = state.drvHashes[i->first]; if (h.type == htUnknown) { @@ -342,7 +361,9 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv) } drv.inputDrvs = inputs2; - return hashTerm(unparseDerivation(drv)); + //printMsg(lvlError, format("%1%") % unparseDerivation(drv)); + + return hashTerm(unparseDerivation(drv)); } /* Construct (as a unobservable side effect) a Nix derivation @@ -391,6 +412,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) string stateIdentifier = ""; bool createDirsBeforeInstall = false; string runtimeStateParamters = ""; + vector stateDirs; for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i) { string key = aterm2String(i->key); @@ -474,7 +496,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) } } - drv.stateOutputDirs[dir.path] = dir; + stateDirs.push_back(dir); } } @@ -572,21 +594,24 @@ 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); - + + //printMsg(lvlError, format("DerivationOutput %1% %2% %3%") % outPath % outputHashAlgo % outputHash); //only add state when we have to to keep compitibilty with the 'old' format. - //We add state when it's enbaled by the keywords, and NOT disabled by the user + //We add state when it's enbaled by the keywords, and not excplicitly disabled by the user if(enableState && !disableState){ /* 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 + string componentHash = outPath; //hash of the component path Hash statehash = hashString(htSHA256, callingUser + componentHash); //hash of the state path Path stateOutPath = makeStatePath("stateOutput:statepath", statehash, drvName, stateIdentifier); //State path - drv.env["statepath"] = stateOutPath; + string enableStateS = bool2string("true"); string createDirsBeforeInstallS = bool2string(createDirsBeforeInstall); - drv.stateOutputs["state"] = DerivationStateOutput(stateOutPath, outputHashAlgo, outputHash, stateIdentifier, enableStateS, shareState, syncState, createDirsBeforeInstallS, runtimeStateParamters); + + for(vector::iterator i = stateDirs.begin(); i != stateDirs.end(); ++i) + drv.stateOutputDirs[(*i).path] = *(i); } /* Write the resulting term into the Nix store directory. */ @@ -594,6 +619,15 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'") % drvName % drvPath); + /* TODO Write updated (no need to rebuild) state derivations to a special table, so they can be updated at build time */ + if(enableState && !disableState){ + Path deriver = queryDeriver(noTxn, outPath); //query deriver + if(deriver != drvPath){ + printMsg(lvlError, format("Adding to the db: update drv `%2%' with `%1%'") % drvPath % deriver); + store->setUpdatedStateDerivation(drvPath, deriver); + } + } + /* Optimisation, but required in read-only mode! because in that case we don't actually write store expressions, so we can't read them later. */ diff --git a/src/libstore/build.cc b/src/libstore/build.cc index d1c54d058..2d978915b 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -773,10 +773,11 @@ void DerivationGoal::haveDerivation() /* Check what outputs paths are not already valid. */ PathSet invalidOutputs = checkPathValidity(false); - - /* If they are all valid, then we're done. */ if (invalidOutputs.size() == 0) { + + printMsg(lvlError, format("Check State VALIDITY BEFORE: `%1%'") % drvPath); + amDone(ecSuccess); return; } diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 85083dc97..617e20e83 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -21,8 +21,8 @@ const string drvExtension = ".drv"; struct DerivationOutput { Path path; - string hashAlgo; /* hash used for expected hash computation */ - string hash; /* expected hash, may be null */ + string hashAlgo; /* hash used for expected hash computation */ + string hash; /* expected hash, may be null */ DerivationOutput() { } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 9ec8b9e20..c3ac233c9 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -11,7 +11,7 @@ #include "derivations.hh" #include "misc.hh" - + #include #include @@ -19,7 +19,7 @@ #include #include #include - +#include namespace nix { @@ -82,6 +82,11 @@ static TableId dbDerivers = 0; */ static TableId dbStateCounters = 0; +/* Path + + */ +static TableId dbUpdatedDerivations = 0; + bool Substitute::operator == (const Substitute & sub) const { @@ -147,6 +152,7 @@ LocalStore::LocalStore(bool reserveSpace) dbSubstitutes = nixDB.openTable("substitutes"); dbDerivers = nixDB.openTable("derivers"); dbStateCounters = nixDB.openTable("statecounters"); + dbUpdatedDerivations = nixDB.openTable("updatedDerivations"); int curSchema = 0; Path schemaFN = nixDBPath + "/schema"; @@ -1217,6 +1223,79 @@ PathSet LocalStore::getStateReferencesClosure(const Path & path) } +//TODO +void setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv) +{ + Transaction txn(nixDB); + + Strings data; + data.push_back(olddrv); + + time_t timestamp; + time (×tamp); + string timestamp_s = time_t2string(timestamp); + printMsg(lvlError, format("Adding new drv (%1%) to replace old drv (%2%) with timestamp: %3%") % newdrv % olddrv % timestamp_s); + data.push_back(timestamp_s); //create a timestamp to remember which one was last inserted + + nixDB.setStrings(txn, dbUpdatedDerivations, newdrv, data); + + //TODO check wheter were not duplicating an entry !! + + txn.commit(); +} + +//TODO +void LocalStore::setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv) +{ + nix::setUpdatedStateDerivation(newdrv, olddrv); +} + +//TODO +Path getUpdatedStateDerivation(const Path & olddrv) //TODO Path updateStateDerivationPath(const Path & storepath) +{ + Transaction txn(nixDB); //TODO should u do a transaction here? ... this might delay the process ... + + Path storepath = olddrv; //TODO FIX + Path drvPath = getStateDerivation(storepath); + Path newDerivation = drvPath; //the new drv path first equals the old one until a new one is found + + Strings keys; + + //Get the (multiple) derivations of references + nixDB.enumTable(txn, dbUpdatedDerivations, keys); + for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) + { + string key = *i; + printMsg(lvlError, format("getUpdatedStateDerivation KEY: `%1%'") % key); + + Strings data; + nixDB.queryStrings(txn, dbUpdatedDerivations, key, data); + for (Strings::iterator j = data.begin(); j != data.end(); ++j) + { + printMsg(lvlError, format("getUpdatedStateDerivation: `%1%'") % *j); + } + } + + + + //Set the current derivation of derivers + + + //if() + // throw Error(format("T derivation: `%1%'") % path); + + txn.commit(); + + return p; +} + +//TODO +Path LocalStore::getUpdatedStateDerivation(const Path & olddrv) +{ + return nix::getUpdatedStateDerivation(olddrv); +} + + /* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */ static void upgradeStore07() { diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 15466342f..05eb14bff 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -83,6 +83,11 @@ public: Derivation getStateDerivation(const Path & path); PathSet getStateReferencesClosure(const Path & path); + + void setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv); + + Path getUpdatedStateDerivation(const Path & olddrv); + }; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index ea4631b89..a57ae839d 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -402,5 +402,18 @@ PathSet RemoteStore::getStateReferencesClosure(const Path & path) return empty; } +//TODO +void RemoteStore::setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv) +{ + +} + +//TODO +Path RemoteStore::getUpdatedStateDerivation(const Path & olddrv) +{ + Path p; + return p; +} + } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 7d3007d76..c41c41a1a 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -72,6 +72,10 @@ public: PathSet getStateReferencesClosure(const Path & path); + void setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv); + + Path getUpdatedStateDerivation(const Path & olddrv); + private: AutoCloseFD fdSocket; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index a5475956f..12492d939 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -193,6 +193,12 @@ public: /* TODO */ virtual PathSet getStateReferencesClosure(const Path & path) = 0; + /* TODO */ + virtual void setUpdatedStateDerivation(const Path & newdrv, const Path & olddrv) = 0; + + /* TODO */ + virtual Path getUpdatedStateDerivation(const Path & olddrv) = 0; + }; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index cdd5f5c4d..a2e5810f7 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1064,5 +1064,12 @@ void executeAndPrintShellCommand(const string & command, const string & commandN remove(tempoutput.c_str()); //Remove the tempoutput file } + +string time_t2string(const time_t & t) +{ + int i = t; + string s = int2String(i); + return s; +} } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 75da18770..cbbf16ef5 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -293,6 +293,9 @@ string trim(const string & s); //excecute a shell command void executeAndPrintShellCommand(const string & command, const string & commandName); +//Convert time_t to a string +string time_t2string(const time_t & t); + } #endif /* !__UTIL_H */ diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 7d5a50660..f4565fb40 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -85,7 +85,7 @@ static void opShowStateReposRootPath(Strings opFlags, Strings opArgs) } -static void opCommitReferencesClosure(Strings opFlags, Strings opArgs) +static void opRunComponent(Strings opFlags, Strings opArgs) { //get the derivation of the current component @@ -100,9 +100,10 @@ static void opCommitReferencesClosure(Strings opFlags, Strings opArgs) DerivationOutputs outputs = drv.outputs; string drvName = drv.env.find("name")->second; - //Wait for locks? - + //Check if component is a state component !!! + //Wait for locks? + //******************* Run the component //TODO @@ -112,6 +113,17 @@ static void opCommitReferencesClosure(Strings opFlags, Strings opArgs) //get dependecies (if neccecary | recusively) of all state components that need to be updated PathSet paths = store->getStateReferencesClosure(componentPath); + + //TODO nix-store -q --tree $(nix-store -qd /nix/store/6x6glnb9idn53yxfqrz6wq53459vv3qd-firefox-2.0.0.3/) + + + //Transaction txn; + //createStoreTransaction(txn); + //txn.commit(); + + //or noTxn + + //for(...){ // //} @@ -217,18 +229,28 @@ void run(Strings args) Strings opFlags, opArgs; Operation op = 0; + store = openStore(); + Path p = "AADOLD"; + store->setUpdatedStateDerivation("NEW1", p); + store->setUpdatedStateDerivation("NEW2", p); + store->setUpdatedStateDerivation("NEW3", p); + store->getUpdatedStateDerivation(p); + + return; + for (Strings::iterator i = args.begin(); i != args.end(); ) { string arg = *i++; Operation oldOp = op; if (arg == "--run" || arg == "-r") - op = opCommitReferencesClosure; + op = opRunComponent; else if (arg == "--showstatepath") op = opShowStatePath; else if (arg == "--showstatereposrootpath") op = opShowStateReposRootPath; + /* --commit @@ -238,8 +260,8 @@ void run(Strings args) --exclude-commit-paths + TODO update getDerivation in nix-store to handle state indentifiers - */ else