From bdecf3bdbcb55c8d42961ab81c2056f2634e2d53 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Mon, 18 Jun 2007 19:54:31 +0000 Subject: [PATCH] In the middle of adding state references to derivations and the db... --- src/libexpr/primops.cc | 5 +- src/libstore/build.cc | 30 +++-- src/libstore/derivations.cc | 8 +- src/libstore/local-store.cc | 222 +++++++++++++---------------------- src/libstore/local-store.hh | 11 +- src/libstore/references.cc | 12 ++ src/libstore/references.hh | 4 + src/libstore/remote-store.cc | 13 +- src/libstore/remote-store.hh | 8 +- src/libstore/store-api.cc | 7 +- src/libstore/store-api.hh | 10 +- src/libstore/store-state.cc | 8 +- src/libutil/util.cc | 3 +- src/nix-env/nix-env.cc | 4 +- src/nix-state/nix-state.cc | 33 +++--- src/nix-worker/nix-worker.cc | 3 +- 16 files changed, 190 insertions(+), 191 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index bad3d36a6..f4b2dffd9 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -760,6 +760,7 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args) string contents = evalString(state, args[1], context); PathSet refs; + PathSet stateRefs; //TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! for (PathSet::iterator i = context.begin(); i != context.end(); ++i) { if (isDerivation(*i)) @@ -768,8 +769,8 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args) } Path storePath = readOnlyMode - ? computeStorePathForText(name, contents, refs) - : store->addTextToStore(name, contents, refs); + ? computeStorePathForText(name, contents, refs, stateRefs) + : store->addTextToStore(name, contents, refs, stateRefs); /* Note: we don't need to add `context' to the context of the result, since `storePath' itself has references to the paths diff --git a/src/libstore/build.cc b/src/libstore/build.cc index acecbae4e..bf32628ed 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1621,6 +1621,7 @@ PathSet parseReferenceSpecifiers(const Derivation & drv, string attr) void DerivationGoal::computeClosure() { map allReferences; + map allStateReferences; map contentHashes; //TODO MOVE THIS TO A PLACE THAT ALSO GETS CALLED WHEN WE DONT NEED TO BUILD ANYTHING @@ -1646,8 +1647,7 @@ void DerivationGoal::computeClosure() if (lstat(path.c_str(), &st) == -1) throw SysError(format("getting attributes of path `%1%'") % path); - startNest(nest, lvlTalkative, - format("scanning for references inside `%1%'") % path); + startNest(nest, lvlTalkative, format("scanning for component and state references inside `%1%'") % path); /* Check that fixed-output derivations produced the right outputs (i.e., the content hash should match the specified @@ -1689,10 +1689,20 @@ void DerivationGoal::computeClosure() /* For this output path, find the references to other paths contained in it. */ PathSet references = scanForReferences(path, allPaths); - /* For this state-output path, find the references to other paths contained in it. */ - Path statePath = drv.stateOutputs.find("state")->second.statepath; - PathSet state_references = scanForReferences(statePath, allPaths); - references = mergePathSets(references, state_references); + /* For this state-output path, find the references to other paths contained in it. + * Get the state paths (instead of out paths) from all components, and then call + * scanForStateReferences(). + */ + PathSet allStatePaths; + for (PathSet::const_iterator i = allPaths.begin(); i != allPaths.end(); i++){ + Path componentPath = *i; + if(store->isStateComponent(componentPath)){ + PathSet stateRefs = queryDerivers(noTxn, componentPath ,"*",getCallingUserName()); + stateRefs = mergePathSets(stateRefs, allStatePaths); + } + } + PathSet stateReferences = scanForStateReferences(path, allStatePaths); + /* For debugging, print out the referenced and unreferenced paths. */ @@ -1707,6 +1717,8 @@ void DerivationGoal::computeClosure() } allReferences[path] = references; + + allStateReferences[path] = stateReferences; /* If the derivation specifies an `allowedReferences' attribute (containing a list of paths that the output may @@ -1745,6 +1757,7 @@ void DerivationGoal::computeClosure() registerValidPath(txn, i->second.path, contentHashes[i->second.path], allReferences[i->second.path], + allStateReferences[i->second.path], drvPath); } txn.commit(); @@ -1873,6 +1886,9 @@ private: /* Outgoing references for this path. */ PathSet references; + + /* Outgoing state references for this path. */ //TODO CHECK THIS ENTIRE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + PathSet stateReferences; /* Pipe for the substitute's standard output/error. */ Pipe logPipe; @@ -2145,7 +2161,7 @@ void SubstitutionGoal::finished() Transaction txn; createStoreTransaction(txn); registerValidPath(txn, storePath, contentHash, - references, sub.deriver); + references, stateReferences, sub.deriver); txn.commit(); outputLock->setDeletion(true); diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 160756c78..c08c73216 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -27,11 +27,15 @@ Path writeDerivation(const Derivation & drv, const string & name) /* Note that the outputs of a derivation are *not* references (that can be missing (of course) and should not necessarily be held during a garbage collection). */ + + //TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + PathSet stateReferences; + string suffix = name + drvExtension; string contents = atPrint(unparseDerivation(drv)); return readOnlyMode - ? computeStorePathForText(suffix, contents, references) - : store->addTextToStore(suffix, contents, references); + ? computeStorePathForText(suffix, contents, references, stateReferences) + : store->addTextToStore(suffix, contents, references, stateReferences); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 36672b1aa..3077987b9 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -44,6 +44,15 @@ static TableId dbValidPaths = 0; paths. */ static TableId dbReferences = 0; +/* dbReferences :: Path -> [Path] + + This table lists the outgoing file system state references for each + output path that has been built by a Nix derivation. These are + found by scanning the path for the hash components of input + paths. */ +static TableId dbStateReferences = 0; + + /* dbReferrers :: Path -> Path This table is just the reverse mapping of dbReferences. This table @@ -83,6 +92,13 @@ static TableId dbDerivers = 0; static TableId dbStateCounters = 0; +/* dbStateCounters :: Path -> String + + This table lists the all the state managed components, TODO we could store the entire DRV in here in the future + +*/ +static TableId dbStateInfo = 0; + bool Substitute::operator == (const Substitute & sub) const { return program == sub.program @@ -143,10 +159,12 @@ LocalStore::LocalStore(bool reserveSpace) } dbValidPaths = nixDB.openTable("validpaths"); dbReferences = nixDB.openTable("references"); - dbReferrers = nixDB.openTable("referrers", true); /* must be sorted */ + dbReferrers = nixDB.openTable("referrers", true); /* must be sorted */ //TODO ADD STATE REFERERS? dbSubstitutes = nixDB.openTable("substitutes"); dbDerivers = nixDB.openTable("derivers"); + dbStateInfo = nixDB.openTable("stateinfo"); dbStateCounters = nixDB.openTable("statecounters"); + dbStateReferences = nixDB.openTable("references_state"); int curSchema = 0; Path schemaFN = nixDBPath + "/schema"; @@ -365,7 +383,7 @@ void queryReferences(const Transaction & txn, { Paths references2; - //WOUTER EDIT + //WOUTER EDIT TODO if (!isRealisablePath(txn, storePath)) throw Error(format("path `%1%' is not valid") % storePath); @@ -406,18 +424,18 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de if (!isRealisablePath(txn, storePath)) throw Error(format("path `%1%' is not valid") % storePath); - Derivation drv = derivationFromPath(deriver); //Redirect if its a state component - if (drv.outputs.size() != 0) - addStateDeriver(txn, storePath, deriver); - else + Derivation drv = derivationFromPath(deriver); + if (drv.outputs.size() != 0){ //Redirect if its a state component + addStateDeriver(txn, storePath, deriver); + } + else{ nixDB.setString(txn, dbDerivers, storePath, deriver); + } } void addStateDeriver(const Transaction & txn, const Path & storePath, const Path & deriver) { - printMsg(lvlError, format("Adding State Derivers into DB %1%") % deriver); - assertStorePath(storePath); if (deriver == "") return; assertStorePath(deriver); @@ -432,22 +450,44 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true); Strings data; - for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i){ - string deriver = *i; - - //TODO Remove obsolete check - assertStorePath(deriver); - Derivation drv = derivationFromPath(deriver); - if (drv.outputs.size() == 0) //Error if its not a state component - throw Error(format("path `%1%' is a NOT state Path at addStateDeriver") % storePath); - //TODO Remove obsolete check - - data.push_back(deriver); - } - - nixDB.setStrings(txn, dbDerivers, storePath, data); //update the db. + for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i) //Convert Paths to Strings + data.push_back(*i); + + nixDB.setStrings(txn, dbDerivers, storePath, data); //update the derivers db. + + nixDB.setString(txn, dbStateInfo, storePath, ""); //update the dbinfo db. (maybe TODO) + } +//TODO Add and .. +bool isStateComponent(const Path & storePath) +{ + store->isValidPath(storePath); + string deriver; + + string data; + return nixDB.queryString(noTxn, dbStateInfo, storePath, data); //update the dbinfo db. (maybe TODO) +} + +bool LocalStore::isStateComponent(const Path & storePath) +{ + return nix::isStateComponent(storePath); +} + +//TODO Add and .. +bool isStateDrv(const Path & drvPath) +{ + Derivation drv = derivationFromPath(drvPath); //maybe redirect the out path to isStateComponent? + if (drv.outputs.size() != 0) + return true; + else + return false; +} + +bool LocalStore::isStateDrv(const Path & isStateDrv) +{ + return nix::isStateDrv(isStateDrv); +} Path queryDeriver(const Transaction & txn, const Path & storePath) { @@ -455,10 +495,9 @@ Path queryDeriver(const Transaction & txn, const Path & storePath) throw Error(format("path `%1%' is not valid") % storePath); Path deriver; - bool b = nixDB.queryString(txn, dbDerivers, storePath, deriver); - Derivation drv = derivationFromPath(deriver); //Redirect if its a state component + Derivation drv = derivationFromPath(deriver); if (drv.outputs.size() != 0) throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver); @@ -491,12 +530,12 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str string getIdentifier = drv.stateOutputs.find("state")->second.stateIdentifier; string getUser = drv.stateOutputs.find("state")->second.username; - + + //printMsg(lvlError, format("queryDerivers '%1%' '%2%' '%3%' '%4%' '%5%'") % derivationpath % getIdentifier % identifier % getUser % user); if( (getIdentifier == identifier || identifier == "*") && (getUser == user || user == "*") ) filtereddata.insert(derivationpath); } - return filtereddata; } @@ -650,7 +689,8 @@ Hash LocalStore::queryPathHash(const Path & path) void registerValidPath(const Transaction & txn, - const Path & path, const Hash & hash, const PathSet & references, + const Path & path, const Hash & hash, + const PathSet & references, const PathSet & stateReferences, const Path & deriver) { ValidPathInfo info; @@ -748,7 +788,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, h, PathSet(), ""); + registerValidPath(txn, dstPath, h, PathSet(), PathSet(), ""); txn.commit(); } @@ -760,9 +800,9 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed, Path LocalStore::addTextToStore(const string & suffix, const string & s, - const PathSet & references) + const PathSet & references, const PathSet & stateReferences) { - Path dstPath = computeStorePathForText(suffix, s, references); + Path dstPath = computeStorePathForText(suffix, s, references, stateReferences); addTempRoot(dstPath); @@ -779,8 +819,7 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, - hashPath(htSHA256, dstPath), references, ""); + registerValidPath(txn, dstPath, hashPath(htSHA256, dstPath), references, stateReferences, ""); txn.commit(); } @@ -919,6 +958,9 @@ Path LocalStore::importPath(bool requireSignature, Source & source) Path dstPath = readStorePath(hashAndReadSource); PathSet references = readStorePaths(hashAndReadSource); + + //TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + PathSet stateReferences; Path deriver = readString(hashAndReadSource); if (deriver != "") assertStorePath(deriver); @@ -983,7 +1025,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) here. */ if (!isValidPath(deriver)) deriver = ""; registerValidPath(txn, dstPath, - hashPath(htSHA256, dstPath), references, deriver); + hashPath(htSHA256, dstPath), references, stateReferences, deriver); txn.commit(); } @@ -1315,125 +1357,21 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier; string getUser = getdrv.stateOutputs.find("state")->second.username; - if( !(identifier == getIdentifier && getUser == user) ) //only insert if it doenst already exist - newdrvs.insert(drv); - else{ + if(identifier == getIdentifier && getUser == user) //only insert if it doenst already exist + { if(deleteDrvs){ printMsg(lvlError, format("Deleting decrepated state derivation: %1% with identifier %2% and user %3%") % drv % identifier % user); deletePath(drv); //Deletes the DRV from DISK! } - } + } + else + newdrvs.insert(drv); } newdrvs.insert(newdrv); return newdrvs; } -//TODO INCLUDE USERNAME + IDENTIFIER, the can be multiple derivations for the same component -//TODO add mergeNewDerivationIntoList -void updateAllStateDerivations() -{ - - - //call AddStateDerivation !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - /* - Transaction txn(nixDB); - - // Filter out all decrepated derivations, e.g. with a decrepated timestamp / - Strings unique_paths; - Strings keys; - nixDB.enumTable(txn, dbUpdatedDerivations, keys); - for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) - { - string drv_key = *i; //the key is the derivation - Strings data; - - nixDB.queryStrings(txn, dbUpdatedDerivations, drv_key, data); - string path = data.front(); - bool exists = false; - for (Strings::iterator j = unique_paths.begin(); j != unique_paths.end(); ++j) - { - string unique_path = *j; - - if(path == unique_path) - exists = true; - } - - if(!exists) - unique_paths.push_back(path); - } - - - - // Now we merge the two sets of: storepath -> [derivations] together into the db / - for (Strings::iterator i = unique_paths.begin(); i != unique_paths.end(); ++i) - { - string storepath = *i; - printMsg(lvlError, format("Unique: %1%") % storepath); - - - Path drvPath = queryDeriver(txn, storepath); - Path originalDerivation = drvPath; - Path newDerivation = drvPath; //the new drv path first equals the old one until a new one is found - int timestamp = 0; - - //Get the (multiple) derivations of references - Strings keys; - nixDB.enumTable(txn, dbUpdatedDerivations, keys); - for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) - { - string drv_key = *i; //the key is the derivation - - Strings data; - nixDB.queryStrings(txn, dbUpdatedDerivations, drv_key, data); - string getstorepath = data.front(); - data.pop_front(); - string gettimestamp = data.front(); - - if(storepath == getstorepath){ - - int gettimestamp_i; - string2Int(gettimestamp, gettimestamp_i); - - if(gettimestamp_i == timestamp) - throw Error(format("Error! Multiple changes at store path %4% at the same time: derivations: `%1%' and `%2%' with timestamp `%3%'") % newDerivation % drv_key % timestamp % storepath); - - if(timestamp == 0 || gettimestamp_i > timestamp){ //we choose the new derivation as the latest submitted derivation - //printMsg(lvlError, format("Replacing at store path %4% the old drv (%1%) with new drv (%2%) with timestamp: %3%") % newDerivation % drv_key % gettimestamp_i % storepath); - newDerivation = drv_key; - timestamp = gettimestamp_i; - } - - //Always Remove the old updatelink in the dbUpdatedDerivations - nixDB.delPair(txn, dbUpdatedDerivations, drv_key); - } - } - - if(originalDerivation != newDerivation) //only update if neccecary - { - //Replace the old deriver link in the derivers database (TODO, maybe delete old deriver path????????) - setDeriver(txn, storepath, newDerivation); - - //Call the stateUpdate function for the new derivation? Yes since this function is called at build time - printMsg(lvlError, format("Calling new state drv %1% for storepath %2%") % newDerivation % storepath); - //TODO check wheter we update before or after ?? - //TODO - } - - - } - - - txn.commit(); - */ -} - -void LocalStore::updateAllStateDerivations() -{ - nix::updateAllStateDerivations(); -} - /* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */ diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 7f39ae551..f72da0b3b 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -54,7 +54,7 @@ public: PathFilter & filter = defaultPathFilter); Path addTextToStore(const string & suffix, const string & s, - const PathSet & references); + const PathSet & references, const PathSet & stateReferences); void exportPath(const Path & path, bool sign, Sink & sink); @@ -82,9 +82,9 @@ public: PathSet getStateReferencesClosure(const Path & path); - void addUpdatedStateDerivation(const Path & newdrv, const Path & storepath); - - void updateAllStateDerivations(); + bool isStateComponent(const Path & path); + + bool isStateDrv(const Path & drvpath); }; @@ -109,7 +109,8 @@ void clearSubstitutes(); of the file system contents of the path. The hash must be a SHA-256 hash. */ void registerValidPath(const Transaction & txn, - const Path & path, const Hash & hash, const PathSet & references, + const Path & path, const Hash & hash, + const PathSet & references, const PathSet & stateReferences, const Path & deriver); struct ValidPathInfo diff --git a/src/libstore/references.cc b/src/libstore/references.cc index 19cb288bd..9da545af1 100644 --- a/src/libstore/references.cc +++ b/src/libstore/references.cc @@ -152,5 +152,17 @@ PathSet scanForReferences(const string & path, const PathSet & paths) return found; } +/* A wrapper for now, but we may extend */ +PathSet scanForStateReferences(const string & path, const PathSet & statePaths) +{ + return scanForReferences(path, statePaths); +} + +PathSet scanForALLReferences(const string & path) +{ + PathSet p; + throw Error("TODO"); + return p; +} } diff --git a/src/libstore/references.hh b/src/libstore/references.hh index 76a7ee166..71db44688 100644 --- a/src/libstore/references.hh +++ b/src/libstore/references.hh @@ -6,6 +6,10 @@ namespace nix { PathSet scanForReferences(const Path & path, const PathSet & refs); + +PathSet scanForStateReferences(const string & path, const PathSet & statePaths); + +PathSet scanForALLReferences(const string & path); } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index ab04ac1e7..6bb2f0e88 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -230,12 +230,13 @@ Path RemoteStore::addToStore(const Path & _srcPath, bool fixed, Path RemoteStore::addTextToStore(const string & suffix, const string & s, - const PathSet & references) + const PathSet & references, const PathSet & stateReferences) { writeInt(wopAddTextToStore, to); writeString(suffix, to); writeString(s, to); writeStringSet(references, to); + writeStringSet(stateReferences, to); processStderr(); Path path = readStorePath(from); @@ -395,10 +396,14 @@ PathSet RemoteStore::getStateReferencesClosure(const Path & path) return empty; } -//TODO -void RemoteStore::updateAllStateDerivations() +bool RemoteStore::isStateComponent(const Path & path) { - + return false; +} + +bool RemoteStore::isStateDrv(const Path & drvpath) +{ + return false; } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index edcacda3c..9a1c54f31 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -42,7 +42,7 @@ public: PathFilter & filter = defaultPathFilter); Path addTextToStore(const string & suffix, const string & s, - const PathSet & references); + const PathSet & references, const PathSet & stateReferences); void exportPath(const Path & path, bool sign, Sink & sink); @@ -69,9 +69,11 @@ public: vector getStatePathsInterval(const PathSet & statePaths); PathSet getStateReferencesClosure(const Path & path); - - void updateAllStateDerivations(); + bool isStateComponent(const Path & path); + + bool isStateDrv(const Path & drvpath); + private: AutoCloseFD fdSocket; diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 14e8b5170..d6efcfd4a 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -179,7 +179,7 @@ std::pair computeStorePathForPath(const Path & srcPath, Path computeStorePathForText(const string & suffix, const string & s, - const PathSet & references) + const PathSet & references, const PathSet & stateReferences) { Hash hash = hashString(htSHA256, s); /* Stuff the references (if any) into the type. This is a bit @@ -190,6 +190,11 @@ Path computeStorePathForText(const string & suffix, const string & s, type += ":"; type += *i; } + for (PathSet::const_iterator i = stateReferences.begin(); i != stateReferences.end(); ++i) { + type += ":"; + type += *i; + } + return makeStorePath(type, hash, suffix); } diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 1056e3195..b36901e4a 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -92,7 +92,7 @@ public: /* Like addToStore, but the contents written to the output path is a regular file containing the given string. */ virtual Path addTextToStore(const string & suffix, const string & s, - const PathSet & references) = 0; + const PathSet & references, const PathSet & stateReferences) = 0; /* Export a store path, that is, create a NAR dump of the store path and append its references and its deriver. Optionally, a @@ -192,8 +192,12 @@ public: virtual PathSet getStateReferencesClosure(const Path & path) = 0; /* TODO */ - virtual void updateAllStateDerivations() = 0; + virtual bool isStateComponent(const Path & path) = 0; + /* TODO */ + virtual bool isStateDrv(const Path & drvpath) = 0; + + }; @@ -252,7 +256,7 @@ std::pair computeStorePathForPath(const Path & srcPath, affected), but it has some backwards compatibility issues (the hashing scheme changes), so I'm not doing that for now. */ Path computeStorePathForText(const string & suffix, const string & s, - const PathSet & references); + const PathSet & references, const PathSet & stateReferences); /* Remove the temporary roots file for this process. Any temporary diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 7d7d9c368..46f76c34d 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -21,7 +21,7 @@ void updatedStateDerivation(Path storePath) //We dont remove the old .svn folders //New repostorys are created by createStateDirs - printMsg(lvlError, format("Resetting state drv settings like repositorys")); + printMsg(lvlTalkative, format("Resetting state drv settings like repositorys")); //Create a repository for this state location @@ -60,7 +60,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De executeAndPrintShellCommand("mkdir -p " + repos, "mkdir"); if(IsDirectory(repos)) - printMsg(lvlError, format("Repos %1% already exists, so we use that repository") % repos); + printMsg(lvlTalkative, format("Repos %1% already exists, so we use that repository") % repos); else executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit than ?? @@ -68,14 +68,14 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De intervalPaths.insert(statePath); } - printMsg(lvlError, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos); + printMsg(lvlTalkative, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos); if(IsDirectory(fullstatedir + "/.svn/")){ string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir; executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user } else - printMsg(lvlError, format("Statedir %1% already exists, so dont check out its repository again") % fullstatedir); + printMsg(lvlTalkative, format("Statedir %1% already exists, so dont check out its repository again") % fullstatedir); } //Initialize the counters for the statePaths that have an interval to 0 diff --git a/src/libutil/util.cc b/src/libutil/util.cc index ce1feda84..b50f2e265 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1118,6 +1118,7 @@ string getCallingUserName() return username; } +//merges two PathSets into one, removing doubles PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2) { PathSet merged = paths2; @@ -1140,5 +1141,5 @@ PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2) return merged; } - + } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index d4c44fe95..a83090028 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -159,6 +159,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, /* Construct the whole top level derivation. */ PathSet references; + PathSet stateReferences; //TODO TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ATermList manifest = ATempty; ATermList inputs = ATempty; for (DrvInfos::const_iterator i = elems.begin(); @@ -203,8 +204,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems, /* 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); + Path manifestFile = store->addTextToStore("env-manifest", atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references, stateReferences); Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3( makeBind(toATerm("system"), diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index e545d2553..9fe9a3103 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -52,6 +52,8 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c //TODO REAL CHECK for validity of componentPath ... ? if(componentPath == "/nix/store") throw UsageError("You must specify the full! binary path"); + + //TODO CHECK IF PATH IS STATEPATH if(opArgs.size() > 1){ opArgs.pop_front(); @@ -61,7 +63,7 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c if(username == "") username = getCallingUserName(); - printMsg(lvlError, format("%1% - %2% - %3% - %4%") % componentPath % stateIdentifier % binary % username); + printMsg(lvlTalkative, format("%1% - %2% - %3% - %4%") % componentPath % stateIdentifier % binary % username); derivers = queryDerivers(noTxn, componentPath, stateIdentifier, username); @@ -108,7 +110,7 @@ static void opShowDerivations(Strings opFlags, Strings opArgs) Derivation drv = getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, true, derivers, username); for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i) - printMsg(lvlError, format("%1%") % (*i)); + printMsg(lvlTalkative, format("%1%") % (*i)); } @@ -121,7 +123,7 @@ static void opShowStatePath(Strings opFlags, Strings opArgs) string binary; string derivationPath; Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath); - printMsg(lvlError, format("%1%") % statePath); + printMsg(lvlTalkative, format("%1%") % statePath); } //Prints the root path that contains the repoisitorys of the state of a component - indetiefier combination @@ -141,7 +143,7 @@ static void opShowStateReposRootPath(Strings opFlags, Strings opArgs) //TODO Strip off //repos = repos.substr(0, repos.length() - .... ); - printMsg(lvlError, format("%1%") % repos); + printMsg(lvlTalkative, format("%1%") % repos); } @@ -299,7 +301,7 @@ PathSet getStateReferencesClosure_(const Path & drvpath, PathSet & drvPaths, con for (DerivationInputs::iterator i = drv.inputDrvs.begin(); i != drv.inputDrvs.end(); ++i){ Path checkDrvPath = i->first; - printMsg(lvlError, format("DRVPS: `%1%'") % checkDrvPath); + printMsg(lvlTalkative, format("DRVPS: `%1%'") % checkDrvPath); } @@ -316,7 +318,7 @@ PathSet getStateReferencesClosure(const Path & drvpath) for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i) { - printMsg(lvlError, format("Referen2ces: `%1%'") % *i); + printMsg(lvlTalkative, format("Referen2ces: `%1%'") % *i); } return drvRefs; @@ -340,19 +342,22 @@ void run(Strings args) return; string a = makeStatePathFromGolbalHash("8f3b56a9a985fce54fd88c3e95a81a4b6b11fb98da12b977aee7f278c73ad3d7-hellohardcodedstateworld-1.0-test2", "kaaz"); - printMsg(lvlError, format("%1%") % a); + printMsg(lvlTalkative, format("%1%") % a); return; - printMsg(lvlError, format("Result: \"%1%\"") % getCallingUserName()); + printMsg(lvlTalkative, format("Result: \"%1%\"") % getCallingUserName()); + return; + + store = openStore(); + store->addStateDeriver("/nix/store/0a151npn1aps8w75kpz2zm1yl3v11kbr-hellostateworld-1.0.drv", "/nix/store/k4v52ql98x2m09sb5pz7w1lrd4hamsm0-hellostateworld-1.0"); + store->addStateDeriver("/nix/store/2hpx60ibdfv2pslg4rjvp177frijamvi-hellostateworld-1.0.drv", "/nix/store/k4v52ql98x2m09sb5pz7w1lrd4hamsm0-hellostateworld-1.0"); return; */ + store = openStore(); - //store->addUpdatedStateDerivation("/nix/store/bk4p7378ndm1p5qdr6a99wgxbiklilxy-hellohardcodedstateworld-1.0.drv", "/nix/store/vjijdazrn2jyzyk9sqwrl8fjq0qsmi8y-hellohardcodedstateworld-1.0"); - //store->updateAllStateDerivations(); - //return; - - - PathSet paths = getStateReferencesClosure("/nix/store/928dd2wl5cgqg10hzc3aj4rqaips6bdk-hellohardcodedstateworld-dep1-1.0.drv"); + printMsg(lvlError, format("1: %1%") % bool2string( store->isStateComponent("/nix/store/7xkw5fkz5yw7dpx0pc6l12bh9a56135c-hellostateworld-1.0") ) ); + printMsg(lvlError, format("2: %1%") % bool2string( store->isStateComponent("/nix/store/05441jm8xmsidqm43ivk0micckf0mr2m-nvidiaDrivers") ) ); + printMsg(lvlError, format("3: %1%") % bool2string( store->isStateDrv("/nix/store/2hpx60ibdfv2pslg4rjvp177frijamvi-hellostateworld-1.0.drv") ) ); return; /* test */ diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index 078362e9c..bf1a8923b 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -301,8 +301,9 @@ static void performOp(Source & from, Sink & to, unsigned int op) string suffix = readString(from); string s = readString(from); PathSet refs = readStorePaths(from); + PathSet stateRefs; //TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! startWork(); - Path path = store->addTextToStore(suffix, s, refs); + Path path = store->addTextToStore(suffix, s, refs, stateRefs); stopWork(); writeString(path, to); break;