From 184443d18d11a358b5260f06f8060939ee96c407 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Wed, 13 Jun 2007 15:18:57 +0000 Subject: [PATCH] Before adjusting getStateReferencesClosure_ --- src/libexpr/primops.cc | 2 + src/libstore/build.cc | 25 ++++++----- src/libstore/local-store.cc | 47 ++++++++++++++++----- src/libstore/local-store.hh | 3 ++ src/libutil/util.cc | 23 ++++++++++ src/libutil/util.hh | 3 ++ src/nix-state/nix-state.cc | 84 +++++++++++++++++++++++++++---------- 7 files changed, 144 insertions(+), 43 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index a49cf0975..bad3d36a6 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -639,6 +639,8 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'") % drvName % drvPath); + + //printMsg(lvlError, format("PRIMOPS %1%") % drvPath); /* Write updated (no need to rebuild) state derivations to the database, so they can be updated at build time if(enableState && !disableState){ if(store->isValidPath(outPath)){ //Only add when the path is already valid diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 3870c9ef6..acecbae4e 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -773,6 +773,11 @@ void DerivationGoal::haveDerivation() /* Check what outputs paths are not already valid. */ PathSet invalidOutputs = checkPathValidity(false); + //Just before we build, we resolve the multiple derivations linked to one store path issue, by choosing the latest derivation + printMsg(lvlError, format("updateAllStateDerivations %1%") % drvPath); + //addStateDeriver(....); //only on succesfull! build + + /* If they are all valid, then we're done. */ if (invalidOutputs.size() == 0) { amDone(ecSuccess); @@ -1678,13 +1683,17 @@ void DerivationGoal::computeClosure() % path % algo % printHash(h) % printHash(h2)); } - /* Get rid of all weird permissions. */ - canonicalisePathMetaData(path); + /* Get rid of all weird permissions. */ + canonicalisePathMetaData(path); - /* For this output path, find the references to other paths contained - in it. */ + /* 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 debugging, print out the referenced and unreferenced paths. */ for (PathSet::iterator i = inputPaths.begin(); @@ -2479,13 +2488,7 @@ void LocalStore::buildDerivations(const PathSet & drvPaths) startNest(nest, lvlDebug, format("building %1%") % showPaths(drvPaths)); - //Just before we build, we resolve the multiple derivations linked to one store path issue, by choosing the latest derivation - - printMsg(lvlError, format("updateAllStateDerivations %1%") % showPaths(drvPaths)); - store->updateAllStateDerivations(); - Worker worker; - Goals goals; for (PathSet::const_iterator i = drvPaths.begin(); i != drvPaths.end(); ++i){ goals.insert(worker.makeDerivationGoal(*i)); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index d06a38e35..790e6a848 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -408,7 +408,7 @@ void setDeriver(const Transaction & txn, const Path & storePath, const Path & de Derivation drv = derivationFromPath(deriver); //Redirect if its a state component if (drv.outputs.size() != 0) - addStateDeriver(txn, storePath, deriver); //TODO remove store-> + addStateDeriver(txn, storePath, deriver); else nixDB.setString(txn, dbDerivers, storePath, deriver); } @@ -474,14 +474,14 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str if (!isRealisablePath(txn, storePath)) throw Error(format("path `%1%' is not valid") % storePath); - if(identifier == "" || user == "") - throw Error(format("The identifer or user argument is empty, use queryDeriver(...) for non-state components")); + if(user == "") + throw Error(format("The user argument is empty, use queryDeriver(...) for non-state components")); Strings alldata; nixDB.queryStrings(txn, dbDerivers, storePath, alldata); //get all current derivers PathSet filtereddata; - for (Strings::iterator i = alldata.begin(); i != alldata.end(); ++i) { + for (Strings::iterator i = alldata.begin(); i != alldata.end(); ++i) { //filter on username and identifier string derivationpath = (*i); Derivation drv = derivationFromPath(derivationpath); @@ -496,6 +496,7 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str filtereddata.insert(derivationpath); } + return filtereddata; } @@ -1244,25 +1245,48 @@ vector LocalStore::getStatePathsInterval(const PathSet & statePaths) //TODO direct or all recursive parameter //TODO check if these are state components -PathSet getStateReferencesClosure(const Path & path) +//TODO CHECK FOR DERIVATION INSTEAD OF +PathSet getStateReferencesClosure(const Path & drvpath) +{ + PathSet empty; + return getStateReferencesClosure_(drvpath, empty); +} + +PathSet getStateReferencesClosure_(const Path & drvpath, PathSet & paths) { Transaction txn(nixDB); //TODO should u do a transaction here? ... this might delay the process ... Strings data; - PathSet paths; + + TODODODODOD.......... + Paths referencesKeys; nixDB.queryStrings(txn, dbReferences, path, data); for (Strings::iterator i = data.begin(); i != data.end(); ++i) { - //printMsg(lvlError, format("References: `%1%'") % *i); - paths.insert(*i); + string storePath = *i; + + bool alreadyExists = false; + for (PathSet::iterator j = paths.begin(); j != paths.end(); ++j) //Get also the references of this dep. + { + string checkPath = *j; + if(storePath == checkPath){ + alreadyExists = true; + break; + } + } + + if( !alreadyExists ){ + printMsg(lvlError, format("References: `%1%'") % storePath); + paths.insert(storePath); + PathSet rec = getStateReferencesClosure_(storePath, paths); //go recursive + //paths = mergePathSets(paths, rec); //merge + } } txn.commit(); - return paths; - } PathSet LocalStore::getStateReferencesClosure(const Path & path) @@ -1293,7 +1317,7 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, newdrvs.insert(drv); else{ if(deleteDrvs){ - printMsg(lvlError, format("Deleting decrepated state derivation: %1%") % drv); + printMsg(lvlError, format("Deleting decrepated state derivation: %1% with identifier %2% and user %3%") % drv % identifier % user); deletePath(drv); //Deletes the DRV from DISK! } } @@ -1308,6 +1332,7 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, void updateAllStateDerivations() { + //call AddStateDerivation !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /* diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index ac50e24f6..46b627ec6 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -183,6 +183,9 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path /* TODO */ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, const PathSet drvs, bool deleteDrvs = false); + +/* TODO */ +PathSet getStateReferencesClosure_(const Path & drvpath, PathSet & paths); } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index f6bb21acc..ce1feda84 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1117,5 +1117,28 @@ string getCallingUserName() //return "root6"; return username; } + +PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2) +{ + PathSet merged = paths2; + + for (PathSet::iterator i = paths1.begin(); i != paths1.end(); ++i) //were inserting all paths from pathset1 into pathset2 + { + bool alreadyExists = false; + for (PathSet::iterator j = paths2.begin(); j != paths2.end(); ++j) //search in p2 for duplicates + { + if(*i == *j){ + alreadyExists = true; + break; + } + } + + if( !alreadyExists ){ //insert into p2 if not duplicate + merged.insert(*i); + } + } + + return merged; +} } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index db5922706..da9e82dea 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -302,6 +302,9 @@ bool IsDirectory(const string FileName); string getCallingUserName(); +/* TODO */ +PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2); + } #endif /* !__UTIL_H */ diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 66b37575c..75e4b1ab2 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -33,13 +33,14 @@ void printHelp() cout << string((char *) helpText, sizeof helpText); } -// // -Derivation getDerivation_andCheckArgs(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath, string & stateIdentifier, string & binary) +Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath, string & stateIdentifier, string & binary, string & derivationPath, + bool getDerivers, PathSet & derivers, string & username) //optional { if (!opFlags.empty()) throw UsageError("unknown flag"); - if (opArgs.size() != 1 && opArgs.size() != 2) throw UsageError("only one or two arguments allowed (the component path & the identiefier which can be empty)"); + if ( (opArgs.size() != 1 && opArgs.size() != 2) && (getDerivers && opArgs.size() != 3) ) + throw UsageError("only one or two arguments allowed component path / identiefier (or a third when you need to see the derivations: [username]) )"); //Parse the full path like /nix/store/...../bin/hello string fullPath = opArgs.front(); @@ -52,29 +53,65 @@ Derivation getDerivation_andCheckArgs(Strings opFlags, Strings opArgs, Path & co if(componentPath == "/nix/store") throw UsageError("You must specify the full! binary path"); - stateIdentifier = ""; - if(opArgs.size() == 2){ + if(opArgs.size() > 1){ opArgs.pop_front(); stateIdentifier = opArgs.front(); } - string username = getCallingUserName(); + + if(username == "") + username = getCallingUserName(); - //printMsg(lvlError, format("%1% - %2% - %3% - %4% - %5%") % componentPath % statePath % stateIdentifier % binary % username); + printMsg(lvlError, format("%1% - %2% - %3% - %4%") % componentPath % stateIdentifier % binary % username); - PathSet drvs = queryDerivers(noTxn, componentPath, stateIdentifier, username); - if(drvs.size() != 1) - throw UsageError("You must specify the full! binary path"); + derivers = queryDerivers(noTxn, componentPath, stateIdentifier, username); + + if(getDerivers == true) + return Derivation(); + else if(derivers.size() != 1) + throw UsageError("There is more than one deriver...."); + Derivation drv; - for (PathSet::iterator i = drvs.begin(); i != drvs.end(); ++i) //ugly workaround for drvs[0]. - drv = derivationFromPath(*i); + for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i){ //ugly workaround for drvs[0]. + derivationPath = *i; + drv = derivationFromPath(derivationPath); + } - queryDeriver(noTxn, ""); - DerivationStateOutputs stateOutputs = drv.stateOutputs; statePath = stateOutputs.find("state")->second.statepath; return drv; } +//Wrapper +Derivation getDerivation_andCheckArgs(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath, string & stateIdentifier, string & binary, string & derivationPath) +{ + PathSet empty; + string empty2; + return getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, false, empty, empty2); +} + +// +static void opShowDerivations(Strings opFlags, Strings opArgs) +{ + string username; + + if(opArgs.size() == 3) + username = opArgs.back(); + else if(opArgs.size() == 2) + username = getCallingUserName(); + + string stateIdentifier; + Path componentPath; + Path statePath; + string binary; + PathSet derivers; + string derivationPath; + 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)); +} + + //Prints the statepath of a component - indetiefier combination static void opShowStatePath(Strings opFlags, Strings opArgs) { @@ -82,7 +119,8 @@ static void opShowStatePath(Strings opFlags, Strings opArgs) Path statePath; string stateIdentifier; string binary; - Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary); + string derivationPath + Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath); printMsg(lvlError, format("%1%") % statePath); } @@ -93,7 +131,8 @@ static void opShowStateReposRootPath(Strings opFlags, Strings opArgs) Path statePath; string stateIdentifier; string binary; - Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary); + string derivationPath; + Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath); string drvName = drv.env.find("name")->second; //Get the a repository for this state location @@ -114,8 +153,8 @@ static void opRunComponent(Strings opFlags, Strings opArgs) Path statePath; string stateIdentifier; string binary; - - Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary); + string derivationPath + Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath); DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs; DerivationStateOutputs stateOutputs = drv.stateOutputs; DerivationOutputs outputs = drv.outputs; @@ -134,7 +173,7 @@ static void opRunComponent(Strings opFlags, Strings opArgs) //******************* Afterwards, call the commit script (recursively) //get dependecies (if neccecary | recusively) of all state components that need to be updated - PathSet paths = store->getStateReferencesClosure(componentPath); + PathSet paths = store->getStateReferencesClosure(derivationPath); //TODO nix-store -q --tree $(nix-store -qd /nix/store/6x6glnb9idn53yxfqrz6wq53459vv3qd-firefox-2.0.0.3/) @@ -276,8 +315,10 @@ void run(Strings args) */ store = openStore(); //store->addUpdatedStateDerivation("/nix/store/bk4p7378ndm1p5qdr6a99wgxbiklilxy-hellohardcodedstateworld-1.0.drv", "/nix/store/vjijdazrn2jyzyk9sqwrl8fjq0qsmi8y-hellohardcodedstateworld-1.0"); + //store->updateAllStateDerivations(); + //return; - store->updateAllStateDerivations(); + PathSet paths = store->getStateReferencesClosure("/nix/store/928dd2wl5cgqg10hzc3aj4rqaips6bdk-hellohardcodedstateworld-dep1-1.0.drv"); return; /* test */ @@ -293,7 +334,8 @@ void run(Strings args) op = opShowStatePath; else if (arg == "--showstatereposrootpath") op = opShowStateReposRootPath; - + else if (arg == "--showderivations") + op = opShowDerivations; /* --commit