1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 04:00:59 +01:00

In the middle of adding state references to derivations and the db...

This commit is contained in:
Wouter den Breejen 2007-06-18 19:54:31 +00:00
parent 5e59387d40
commit bdecf3bdbc
16 changed files with 190 additions and 191 deletions

View file

@ -760,6 +760,7 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args)
string contents = evalString(state, args[1], context); string contents = evalString(state, args[1], context);
PathSet refs; PathSet refs;
PathSet stateRefs; //TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for (PathSet::iterator i = context.begin(); i != context.end(); ++i) { for (PathSet::iterator i = context.begin(); i != context.end(); ++i) {
if (isDerivation(*i)) if (isDerivation(*i))
@ -768,8 +769,8 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args)
} }
Path storePath = readOnlyMode Path storePath = readOnlyMode
? computeStorePathForText(name, contents, refs) ? computeStorePathForText(name, contents, refs, stateRefs)
: store->addTextToStore(name, contents, refs); : store->addTextToStore(name, contents, refs, stateRefs);
/* Note: we don't need to add `context' to the context of the /* Note: we don't need to add `context' to the context of the
result, since `storePath' itself has references to the paths result, since `storePath' itself has references to the paths

View file

@ -1621,6 +1621,7 @@ PathSet parseReferenceSpecifiers(const Derivation & drv, string attr)
void DerivationGoal::computeClosure() void DerivationGoal::computeClosure()
{ {
map<Path, PathSet> allReferences; map<Path, PathSet> allReferences;
map<Path, PathSet> allStateReferences;
map<Path, Hash> contentHashes; map<Path, Hash> contentHashes;
//TODO MOVE THIS TO A PLACE THAT ALSO GETS CALLED WHEN WE DONT NEED TO BUILD ANYTHING //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) if (lstat(path.c_str(), &st) == -1)
throw SysError(format("getting attributes of path `%1%'") % path); throw SysError(format("getting attributes of path `%1%'") % path);
startNest(nest, lvlTalkative, startNest(nest, lvlTalkative, format("scanning for component and state references inside `%1%'") % path);
format("scanning for references inside `%1%'") % path);
/* Check that fixed-output derivations produced the right /* Check that fixed-output derivations produced the right
outputs (i.e., the content hash should match the specified 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. */ /* For this output path, find the references to other paths contained in it. */
PathSet references = scanForReferences(path, allPaths); PathSet references = scanForReferences(path, allPaths);
/* For this state-output path, find the references to other paths contained in it. */ /* For this state-output path, find the references to other paths contained in it.
Path statePath = drv.stateOutputs.find("state")->second.statepath; * Get the state paths (instead of out paths) from all components, and then call
PathSet state_references = scanForReferences(statePath, allPaths); * scanForStateReferences().
references = mergePathSets(references, state_references); */
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 /* For debugging, print out the referenced and unreferenced
paths. */ paths. */
@ -1708,6 +1718,8 @@ void DerivationGoal::computeClosure()
allReferences[path] = references; allReferences[path] = references;
allStateReferences[path] = stateReferences;
/* If the derivation specifies an `allowedReferences' /* If the derivation specifies an `allowedReferences'
attribute (containing a list of paths that the output may attribute (containing a list of paths that the output may
refer to), check that all references are in that list. !!! refer to), check that all references are in that list. !!!
@ -1745,6 +1757,7 @@ void DerivationGoal::computeClosure()
registerValidPath(txn, i->second.path, registerValidPath(txn, i->second.path,
contentHashes[i->second.path], contentHashes[i->second.path],
allReferences[i->second.path], allReferences[i->second.path],
allStateReferences[i->second.path],
drvPath); drvPath);
} }
txn.commit(); txn.commit();
@ -1874,6 +1887,9 @@ private:
/* Outgoing references for this path. */ /* Outgoing references for this path. */
PathSet references; PathSet references;
/* Outgoing state references for this path. */ //TODO CHECK THIS ENTIRE FILE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PathSet stateReferences;
/* Pipe for the substitute's standard output/error. */ /* Pipe for the substitute's standard output/error. */
Pipe logPipe; Pipe logPipe;
@ -2145,7 +2161,7 @@ void SubstitutionGoal::finished()
Transaction txn; Transaction txn;
createStoreTransaction(txn); createStoreTransaction(txn);
registerValidPath(txn, storePath, contentHash, registerValidPath(txn, storePath, contentHash,
references, sub.deriver); references, stateReferences, sub.deriver);
txn.commit(); txn.commit();
outputLock->setDeletion(true); outputLock->setDeletion(true);

View file

@ -27,11 +27,15 @@ Path writeDerivation(const Derivation & drv, const string & name)
/* Note that the outputs of a derivation are *not* references /* Note that the outputs of a derivation are *not* references
(that can be missing (of course) and should not necessarily be (that can be missing (of course) and should not necessarily be
held during a garbage collection). */ held during a garbage collection). */
//TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PathSet stateReferences;
string suffix = name + drvExtension; string suffix = name + drvExtension;
string contents = atPrint(unparseDerivation(drv)); string contents = atPrint(unparseDerivation(drv));
return readOnlyMode return readOnlyMode
? computeStorePathForText(suffix, contents, references) ? computeStorePathForText(suffix, contents, references, stateReferences)
: store->addTextToStore(suffix, contents, references); : store->addTextToStore(suffix, contents, references, stateReferences);
} }

View file

@ -44,6 +44,15 @@ static TableId dbValidPaths = 0;
paths. */ paths. */
static TableId dbReferences = 0; 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 /* dbReferrers :: Path -> Path
This table is just the reverse mapping of dbReferences. This table This table is just the reverse mapping of dbReferences. This table
@ -83,6 +92,13 @@ static TableId dbDerivers = 0;
static TableId dbStateCounters = 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 bool Substitute::operator == (const Substitute & sub) const
{ {
return program == sub.program return program == sub.program
@ -143,10 +159,12 @@ LocalStore::LocalStore(bool reserveSpace)
} }
dbValidPaths = nixDB.openTable("validpaths"); dbValidPaths = nixDB.openTable("validpaths");
dbReferences = nixDB.openTable("references"); 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"); dbSubstitutes = nixDB.openTable("substitutes");
dbDerivers = nixDB.openTable("derivers"); dbDerivers = nixDB.openTable("derivers");
dbStateInfo = nixDB.openTable("stateinfo");
dbStateCounters = nixDB.openTable("statecounters"); dbStateCounters = nixDB.openTable("statecounters");
dbStateReferences = nixDB.openTable("references_state");
int curSchema = 0; int curSchema = 0;
Path schemaFN = nixDBPath + "/schema"; Path schemaFN = nixDBPath + "/schema";
@ -365,7 +383,7 @@ void queryReferences(const Transaction & txn,
{ {
Paths references2; Paths references2;
//WOUTER EDIT //WOUTER EDIT TODO
if (!isRealisablePath(txn, storePath)) if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % 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)) if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath); throw Error(format("path `%1%' is not valid") % storePath);
Derivation drv = derivationFromPath(deriver); //Redirect if its a state component Derivation drv = derivationFromPath(deriver);
if (drv.outputs.size() != 0) if (drv.outputs.size() != 0){ //Redirect if its a state component
addStateDeriver(txn, storePath, deriver); addStateDeriver(txn, storePath, deriver);
else }
else{
nixDB.setString(txn, dbDerivers, storePath, deriver); nixDB.setString(txn, dbDerivers, storePath, deriver);
}
} }
void addStateDeriver(const Transaction & txn, const Path & storePath, const Path & deriver) void addStateDeriver(const Transaction & txn, const Path & storePath, const Path & deriver)
{ {
printMsg(lvlError, format("Adding State Derivers into DB %1%") % deriver);
assertStorePath(storePath); assertStorePath(storePath);
if (deriver == "") return; if (deriver == "") return;
assertStorePath(deriver); assertStorePath(deriver);
@ -432,22 +450,44 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path
PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true); PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true);
Strings data; Strings data;
for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i){ for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i) //Convert Paths to Strings
string deriver = *i; data.push_back(*i);
//TODO Remove obsolete check nixDB.setStrings(txn, dbDerivers, storePath, data); //update the derivers db.
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.setString(txn, dbStateInfo, storePath, ""); //update the dbinfo db. (maybe TODO)
}
nixDB.setStrings(txn, dbDerivers, storePath, data); //update the db.
} }
//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) 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); throw Error(format("path `%1%' is not valid") % storePath);
Path deriver; Path deriver;
bool b = nixDB.queryString(txn, dbDerivers, storePath, 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) if (drv.outputs.size() != 0)
throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver); throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver);
@ -492,11 +531,11 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str
string getIdentifier = drv.stateOutputs.find("state")->second.stateIdentifier; string getIdentifier = drv.stateOutputs.find("state")->second.stateIdentifier;
string getUser = drv.stateOutputs.find("state")->second.username; 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 == "*") ) if( (getIdentifier == identifier || identifier == "*") && (getUser == user || user == "*") )
filtereddata.insert(derivationpath); filtereddata.insert(derivationpath);
} }
return filtereddata; return filtereddata;
} }
@ -650,7 +689,8 @@ Hash LocalStore::queryPathHash(const Path & path)
void registerValidPath(const Transaction & txn, 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) const Path & deriver)
{ {
ValidPathInfo info; ValidPathInfo info;
@ -748,7 +788,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed,
canonicalisePathMetaData(dstPath); canonicalisePathMetaData(dstPath);
Transaction txn(nixDB); Transaction txn(nixDB);
registerValidPath(txn, dstPath, h, PathSet(), ""); registerValidPath(txn, dstPath, h, PathSet(), PathSet(), "");
txn.commit(); txn.commit();
} }
@ -760,9 +800,9 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed,
Path LocalStore::addTextToStore(const string & suffix, const string & s, 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); addTempRoot(dstPath);
@ -779,8 +819,7 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s,
canonicalisePathMetaData(dstPath); canonicalisePathMetaData(dstPath);
Transaction txn(nixDB); Transaction txn(nixDB);
registerValidPath(txn, dstPath, registerValidPath(txn, dstPath, hashPath(htSHA256, dstPath), references, stateReferences, "");
hashPath(htSHA256, dstPath), references, "");
txn.commit(); txn.commit();
} }
@ -920,6 +959,9 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
PathSet references = readStorePaths(hashAndReadSource); PathSet references = readStorePaths(hashAndReadSource);
//TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PathSet stateReferences;
Path deriver = readString(hashAndReadSource); Path deriver = readString(hashAndReadSource);
if (deriver != "") assertStorePath(deriver); if (deriver != "") assertStorePath(deriver);
@ -983,7 +1025,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
here. */ here. */
if (!isValidPath(deriver)) deriver = ""; if (!isValidPath(deriver)) deriver = "";
registerValidPath(txn, dstPath, registerValidPath(txn, dstPath,
hashPath(htSHA256, dstPath), references, deriver); hashPath(htSHA256, dstPath), references, stateReferences, deriver);
txn.commit(); txn.commit();
} }
@ -1315,125 +1357,21 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv,
string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier; string getIdentifier = getdrv.stateOutputs.find("state")->second.stateIdentifier;
string getUser = getdrv.stateOutputs.find("state")->second.username; string getUser = getdrv.stateOutputs.find("state")->second.username;
if( !(identifier == getIdentifier && getUser == user) ) //only insert if it doenst already exist if(identifier == getIdentifier && getUser == user) //only insert if it doenst already exist
newdrvs.insert(drv); {
else{
if(deleteDrvs){ if(deleteDrvs){
printMsg(lvlError, format("Deleting decrepated state derivation: %1% with identifier %2% and user %3%") % drv % identifier % user); printMsg(lvlError, format("Deleting decrepated state derivation: %1% with identifier %2% and user %3%") % drv % identifier % user);
deletePath(drv); //Deletes the DRV from DISK! deletePath(drv); //Deletes the DRV from DISK!
} }
} }
else
newdrvs.insert(drv);
} }
newdrvs.insert(newdrv); newdrvs.insert(newdrv);
return newdrvs; 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). */ /* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */

View file

@ -54,7 +54,7 @@ public:
PathFilter & filter = defaultPathFilter); PathFilter & filter = defaultPathFilter);
Path addTextToStore(const string & suffix, const string & s, Path addTextToStore(const string & suffix, const string & s,
const PathSet & references); const PathSet & references, const PathSet & stateReferences);
void exportPath(const Path & path, bool sign, void exportPath(const Path & path, bool sign,
Sink & sink); Sink & sink);
@ -82,9 +82,9 @@ public:
PathSet getStateReferencesClosure(const Path & path); PathSet getStateReferencesClosure(const Path & path);
void addUpdatedStateDerivation(const Path & newdrv, const Path & storepath); bool isStateComponent(const Path & path);
void updateAllStateDerivations(); bool isStateDrv(const Path & drvpath);
}; };
@ -109,7 +109,8 @@ void clearSubstitutes();
of the file system contents of the path. The hash must be a of the file system contents of the path. The hash must be a
SHA-256 hash. */ SHA-256 hash. */
void registerValidPath(const Transaction & txn, 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); const Path & deriver);
struct ValidPathInfo struct ValidPathInfo

View file

@ -152,5 +152,17 @@ PathSet scanForReferences(const string & path, const PathSet & paths)
return found; 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;
}
} }

View file

@ -7,6 +7,10 @@ namespace nix {
PathSet scanForReferences(const Path & path, const PathSet & refs); PathSet scanForReferences(const Path & path, const PathSet & refs);
PathSet scanForStateReferences(const string & path, const PathSet & statePaths);
PathSet scanForALLReferences(const string & path);
} }
#endif /* !__REFERENCES_H */ #endif /* !__REFERENCES_H */

View file

@ -230,12 +230,13 @@ Path RemoteStore::addToStore(const Path & _srcPath, bool fixed,
Path RemoteStore::addTextToStore(const string & suffix, const string & s, Path RemoteStore::addTextToStore(const string & suffix, const string & s,
const PathSet & references) const PathSet & references, const PathSet & stateReferences)
{ {
writeInt(wopAddTextToStore, to); writeInt(wopAddTextToStore, to);
writeString(suffix, to); writeString(suffix, to);
writeString(s, to); writeString(s, to);
writeStringSet(references, to); writeStringSet(references, to);
writeStringSet(stateReferences, to);
processStderr(); processStderr();
Path path = readStorePath(from); Path path = readStorePath(from);
@ -395,10 +396,14 @@ PathSet RemoteStore::getStateReferencesClosure(const Path & path)
return empty; return empty;
} }
//TODO bool RemoteStore::isStateComponent(const Path & path)
void RemoteStore::updateAllStateDerivations()
{ {
return false;
}
bool RemoteStore::isStateDrv(const Path & drvpath)
{
return false;
} }

View file

@ -42,7 +42,7 @@ public:
PathFilter & filter = defaultPathFilter); PathFilter & filter = defaultPathFilter);
Path addTextToStore(const string & suffix, const string & s, Path addTextToStore(const string & suffix, const string & s,
const PathSet & references); const PathSet & references, const PathSet & stateReferences);
void exportPath(const Path & path, bool sign, void exportPath(const Path & path, bool sign,
Sink & sink); Sink & sink);
@ -70,7 +70,9 @@ public:
PathSet getStateReferencesClosure(const Path & path); PathSet getStateReferencesClosure(const Path & path);
void updateAllStateDerivations(); bool isStateComponent(const Path & path);
bool isStateDrv(const Path & drvpath);
private: private:

View file

@ -179,7 +179,7 @@ std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
Path computeStorePathForText(const string & suffix, const string & s, Path computeStorePathForText(const string & suffix, const string & s,
const PathSet & references) const PathSet & references, const PathSet & stateReferences)
{ {
Hash hash = hashString(htSHA256, s); Hash hash = hashString(htSHA256, s);
/* Stuff the references (if any) into the type. This is a bit /* 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 += ":";
type += *i; type += *i;
} }
for (PathSet::const_iterator i = stateReferences.begin(); i != stateReferences.end(); ++i) {
type += ":";
type += *i;
}
return makeStorePath(type, hash, suffix); return makeStorePath(type, hash, suffix);
} }

View file

@ -92,7 +92,7 @@ public:
/* Like addToStore, but the contents written to the output path is /* Like addToStore, but the contents written to the output path is
a regular file containing the given string. */ a regular file containing the given string. */
virtual Path addTextToStore(const string & suffix, const string & s, 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 /* Export a store path, that is, create a NAR dump of the store
path and append its references and its deriver. Optionally, a path and append its references and its deriver. Optionally, a
@ -192,7 +192,11 @@ public:
virtual PathSet getStateReferencesClosure(const Path & path) = 0; virtual PathSet getStateReferencesClosure(const Path & path) = 0;
/* TODO */ /* 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<Path, Hash> computeStorePathForPath(const Path & srcPath,
affected), but it has some backwards compatibility issues (the affected), but it has some backwards compatibility issues (the
hashing scheme changes), so I'm not doing that for now. */ hashing scheme changes), so I'm not doing that for now. */
Path computeStorePathForText(const string & suffix, const string & s, 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 /* Remove the temporary roots file for this process. Any temporary

View file

@ -21,7 +21,7 @@ void updatedStateDerivation(Path storePath)
//We dont remove the old .svn folders //We dont remove the old .svn folders
//New repostorys are created by createStateDirs //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 //Create a repository for this state location
@ -60,7 +60,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
executeAndPrintShellCommand("mkdir -p " + repos, "mkdir"); executeAndPrintShellCommand("mkdir -p " + repos, "mkdir");
if(IsDirectory(repos)) 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 else
executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit than ?? 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); 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/")){ if(IsDirectory(fullstatedir + "/.svn/")){
string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir; string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir;
executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user
} }
else 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 //Initialize the counters for the statePaths that have an interval to 0

View file

@ -1118,6 +1118,7 @@ string getCallingUserName()
return username; return username;
} }
//merges two PathSets into one, removing doubles
PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2) PathSet mergePathSets(const PathSet & paths1, const PathSet & paths2)
{ {
PathSet merged = paths2; PathSet merged = paths2;

View file

@ -159,6 +159,7 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
/* Construct the whole top level derivation. */ /* Construct the whole top level derivation. */
PathSet references; PathSet references;
PathSet stateReferences; //TODO TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ATermList manifest = ATempty; ATermList manifest = ATempty;
ATermList inputs = ATempty; ATermList inputs = ATempty;
for (DrvInfos::const_iterator i = elems.begin(); 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 /* Also write a copy of the list of inputs to the store; we need
it for future modifications of the environment. */ it for future modifications of the environment. */
Path manifestFile = store->addTextToStore("env-manifest", Path manifestFile = store->addTextToStore("env-manifest", atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references, stateReferences);
atPrint(canonicaliseExpr(makeList(ATreverse(manifest)))), references);
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3( Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
makeBind(toATerm("system"), makeBind(toATerm("system"),

View file

@ -53,6 +53,8 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c
if(componentPath == "/nix/store") if(componentPath == "/nix/store")
throw UsageError("You must specify the full! binary path"); throw UsageError("You must specify the full! binary path");
//TODO CHECK IF PATH IS STATEPATH
if(opArgs.size() > 1){ if(opArgs.size() > 1){
opArgs.pop_front(); opArgs.pop_front();
stateIdentifier = opArgs.front(); stateIdentifier = opArgs.front();
@ -61,7 +63,7 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c
if(username == "") if(username == "")
username = getCallingUserName(); 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); 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); Derivation drv = getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, true, derivers, username);
for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i) 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 binary;
string derivationPath; string derivationPath;
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, 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 //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 //TODO Strip off
//repos = repos.substr(0, repos.length() - .... ); //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){ for (DerivationInputs::iterator i = drv.inputDrvs.begin(); i != drv.inputDrvs.end(); ++i){
Path checkDrvPath = i->first; 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) for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
{ {
printMsg(lvlError, format("Referen2ces: `%1%'") % *i); printMsg(lvlTalkative, format("Referen2ces: `%1%'") % *i);
} }
return drvRefs; return drvRefs;
@ -340,19 +342,22 @@ void run(Strings args)
return; return;
string a = makeStatePathFromGolbalHash("8f3b56a9a985fce54fd88c3e95a81a4b6b11fb98da12b977aee7f278c73ad3d7-hellohardcodedstateworld-1.0-test2", "kaaz"); string a = makeStatePathFromGolbalHash("8f3b56a9a985fce54fd88c3e95a81a4b6b11fb98da12b977aee7f278c73ad3d7-hellohardcodedstateworld-1.0-test2", "kaaz");
printMsg(lvlError, format("%1%") % a); printMsg(lvlTalkative, format("%1%") % a);
return; 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; return;
*/ */
store = openStore(); store = openStore();
//store->addUpdatedStateDerivation("/nix/store/bk4p7378ndm1p5qdr6a99wgxbiklilxy-hellohardcodedstateworld-1.0.drv", "/nix/store/vjijdazrn2jyzyk9sqwrl8fjq0qsmi8y-hellohardcodedstateworld-1.0"); printMsg(lvlError, format("1: %1%") % bool2string( store->isStateComponent("/nix/store/7xkw5fkz5yw7dpx0pc6l12bh9a56135c-hellostateworld-1.0") ) );
//store->updateAllStateDerivations(); printMsg(lvlError, format("2: %1%") % bool2string( store->isStateComponent("/nix/store/05441jm8xmsidqm43ivk0micckf0mr2m-nvidiaDrivers") ) );
//return; printMsg(lvlError, format("3: %1%") % bool2string( store->isStateDrv("/nix/store/2hpx60ibdfv2pslg4rjvp177frijamvi-hellostateworld-1.0.drv") ) );
PathSet paths = getStateReferencesClosure("/nix/store/928dd2wl5cgqg10hzc3aj4rqaips6bdk-hellohardcodedstateworld-dep1-1.0.drv");
return; return;
/* test */ /* test */

View file

@ -301,8 +301,9 @@ static void performOp(Source & from, Sink & to, unsigned int op)
string suffix = readString(from); string suffix = readString(from);
string s = readString(from); string s = readString(from);
PathSet refs = readStorePaths(from); PathSet refs = readStorePaths(from);
PathSet stateRefs; //TODO TODO TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
startWork(); startWork();
Path path = store->addTextToStore(suffix, s, refs); Path path = store->addTextToStore(suffix, s, refs, stateRefs);
stopWork(); stopWork();
writeString(path, to); writeString(path, to);
break; break;