mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
nix-state now works, state is recursively commited (when necessary)
This commit is contained in:
parent
c0dcfed3c3
commit
3d22bd50b3
17 changed files with 457 additions and 277 deletions
|
|
@ -22,12 +22,15 @@ nonversionedpaths=( $4 )
|
|||
checkouts=( $5 )
|
||||
deletesvn=$6 #this flag can be set to 1 to DELETE all .svn folders and NOT commit
|
||||
|
||||
echo svnbin: $svnbin
|
||||
echo subversionedpaths: ${subversionedpaths[@]}
|
||||
echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]}
|
||||
echo nonversionedpaths: ${nonversionedpaths[@]}
|
||||
echo checkouts: ${checkouts[@]}
|
||||
echo deletesvn: $deletesvn
|
||||
|
||||
if [ "$debug" != "" ] ; then
|
||||
echo svnbin: $svnbin
|
||||
echo subversionedpaths: ${subversionedpaths[@]}
|
||||
echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]}
|
||||
echo nonversionedpaths: ${nonversionedpaths[@]}
|
||||
echo checkouts: ${checkouts[@]}
|
||||
echo deletesvn: $deletesvn
|
||||
fi
|
||||
|
||||
#
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1629,6 +1629,7 @@ void DerivationGoal::computeClosure()
|
|||
if(!drv.stateOutputs.find("state")->second.getCreateDirsBeforeInstall())
|
||||
createStateDirs(drv.stateOutputDirs, drv.stateOutputs, drv.env);
|
||||
|
||||
|
||||
/* Check whether the output paths were created, and grep each
|
||||
output path to determine what other paths it references. Also make all
|
||||
output paths read-only. */
|
||||
|
|
@ -1737,6 +1738,8 @@ void DerivationGoal::computeClosure()
|
|||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
{
|
||||
//printMsg(lvlError, format("SetValidPath: %1%") % i->second.path);
|
||||
|
||||
registerValidPath(txn, i->second.path,
|
||||
"", //dummy statePath
|
||||
contentHashes[i->second.path],
|
||||
|
|
@ -1749,14 +1752,17 @@ void DerivationGoal::computeClosure()
|
|||
* We first register alls paths as valid, and only scan for component references.
|
||||
* Now that those paths are registered as valid, we're able to call queryDeriversStatePath
|
||||
*
|
||||
* We already scanned for Component references in Component paths
|
||||
* Now we scan in Component paths for state references
|
||||
* We already scanned for [Component references in Component paths] //1
|
||||
* Now we scan in [Component paths for state references] //2
|
||||
*
|
||||
* If state is enabled for the path we:
|
||||
* scan for and state references and component references in the state path
|
||||
* [scan for and state references and component references in the state path] //3,4
|
||||
*/
|
||||
|
||||
//TODO we scan for each output, be then we do multiple scans inside for the state path .....
|
||||
|
||||
//TODO !!!!!!!!! we don not ONLY need to scan all outputs, but also (recursively) the component references in the state folders
|
||||
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i)
|
||||
{
|
||||
Path path = i->second.path;
|
||||
|
|
@ -1770,7 +1776,7 @@ void DerivationGoal::computeClosure()
|
|||
Path componentPath = *i;
|
||||
|
||||
if(isStateComponentTxn(txn, componentPath)){
|
||||
//printMsg(lvlError, format("Scanning for state path: %1%") % (*i));
|
||||
//printMsg(lvlError, format("Scanning for state path: %1%") % componentPath);
|
||||
PathSet stateRefs = queryDeriversStatePath(txn, componentPath ,"*",getCallingUserName());
|
||||
allStatePaths = mergePathSets(stateRefs, allStatePaths);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -507,16 +507,24 @@ void LocalStore::queryStateReferrers(const Path & storePath, PathSet & stateRefe
|
|||
|
||||
void setDeriver(const Transaction & txn, const Path & storePath, const Path & deriver)
|
||||
{
|
||||
printMsg(lvlError, format("xxxxxxxxxxxxxxxxxxxxxxx"));
|
||||
|
||||
assertStorePath(storePath);
|
||||
printMsg(lvlError, format("Ttttttttttttttttttttttttt"));
|
||||
if (deriver == "") return;
|
||||
printMsg(lvlError, format("uuuuuuuuuuuuuuuuuuuuuuuuuuuuu"));
|
||||
assertStorePath(deriver);
|
||||
printMsg(lvlError, format("yyyyyyyyyyyyyyyyyyyyyyyyy"));
|
||||
|
||||
if (!isRealisablePath(txn, storePath))
|
||||
throw Error(format("path `%1%' is not valid") % storePath);
|
||||
|
||||
if (isStateDrvPathTxn(txn, deriver)){ //Redirect if its a state component
|
||||
printMsg(lvlError, format("bbbbbbbbbbbbbbb"));
|
||||
addStateDeriver(txn, storePath, deriver);
|
||||
}
|
||||
else{
|
||||
printMsg(lvlError, format("ccccccccccccccccccc"));
|
||||
nixDB.setString(txn, dbDerivers, storePath, deriver);
|
||||
}
|
||||
}
|
||||
|
|
@ -530,13 +538,19 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path
|
|||
if (!isRealisablePath(txn, storePath))
|
||||
throw Error(format("path `%1%' is not valid") % storePath);
|
||||
|
||||
printMsg(lvlError, format("dddddddddddddd"));
|
||||
|
||||
Derivation drv = derivationFromPath(deriver);
|
||||
string identifier = drv.stateOutputs.find("state")->second.stateIdentifier;
|
||||
string user = drv.stateOutputs.find("state")->second.username;
|
||||
|
||||
printMsg(lvlError, format("eeeeeeeeeeeeeeeeee"));
|
||||
|
||||
PathSet currentDerivers = queryDerivers(txn, storePath, identifier, user);
|
||||
PathSet updatedDerivers = mergeNewDerivationIntoList(storePath, deriver, currentDerivers, true);
|
||||
|
||||
printMsg(lvlError, format("ffffffffffffffffffff"));
|
||||
|
||||
Strings data;
|
||||
for (PathSet::iterator i = updatedDerivers.begin(); i != updatedDerivers.end(); ++i) //Convert Paths to Strings
|
||||
data.push_back(*i);
|
||||
|
|
@ -597,7 +611,7 @@ Path queryDeriver(const Transaction & txn, const Path & storePath)
|
|||
bool b = nixDB.queryString(txn, dbDerivers, storePath, deriver);
|
||||
|
||||
Derivation drv = derivationFromPath(deriver);
|
||||
if (drv.outputs.size() != 0)
|
||||
if (isStateDrvTxn(txn, drv))
|
||||
throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver);
|
||||
|
||||
if (b)
|
||||
|
|
@ -769,18 +783,14 @@ void clearSubstitutes()
|
|||
|
||||
static void setHash(const Transaction & txn, const Path & storePath, const Hash & hash, bool stateHash = false)
|
||||
{
|
||||
if(stateHash){
|
||||
nixDB.setString(txn, dbValidStatePaths, storePath, "");
|
||||
}
|
||||
else{
|
||||
nixDB.setString(txn, dbValidPaths, storePath, "sha256:" + printHash(hash));
|
||||
assert(hash.type == htSHA256);
|
||||
}
|
||||
nixDB.setString(txn, dbValidPaths, storePath, "sha256:" + printHash(hash));
|
||||
assert(hash.type == htSHA256);
|
||||
}
|
||||
|
||||
static void setStateHash(const Transaction & txn, const Path & storePath, const Hash & hash)
|
||||
static void setStateValid(const Transaction & txn, const Path & statePath, const Path & drvPath)
|
||||
{
|
||||
setHash(txn, storePath, hash, true);
|
||||
printMsg(lvlError, format("setStateValid: '%1%' '%2%'") % statePath % drvPath);
|
||||
nixDB.setString(txn, dbValidStatePaths, statePath, drvPath);
|
||||
}
|
||||
|
||||
static Hash queryHash(const Transaction & txn, const Path & storePath)
|
||||
|
|
@ -806,6 +816,20 @@ Hash LocalStore::queryPathHash(const Path & path)
|
|||
return queryHash(noTxn, path);
|
||||
}
|
||||
|
||||
static Path queryStatePathDrv(const Transaction & txn, const Path & statePath)
|
||||
{
|
||||
string s;
|
||||
nixDB.queryString(txn, dbValidStatePaths, statePath, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Path LocalStore::queryStatePathDrv(const Path & statePath)
|
||||
{
|
||||
if (!isValidStatePath(statePath))
|
||||
throw Error(format("statepath `%1%' is not valid") % statePath);
|
||||
return nix::queryStatePathDrv(noTxn, statePath);
|
||||
}
|
||||
|
||||
|
||||
void registerValidPath(const Transaction & txn,
|
||||
const Path & path, const Path & statePath, const Hash & hash,
|
||||
|
|
@ -839,19 +863,18 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos)
|
|||
setHash(txn, i->path, i->hash);
|
||||
|
||||
if (i->statePath != "")
|
||||
setStateHash(txn, i->statePath, Hash()); //the hash value in the db now becomes empty, but if the key exists, we know that the state path is valid
|
||||
setStateValid(txn, i->statePath, i->deriver); //if the key exists, we know that the state path is valid, we set the value to the drvPath
|
||||
|
||||
setReferences(txn, i->path, i->references, i->stateReferences);
|
||||
|
||||
/* Check that all referenced paths are also valid (or about to) become valid). */
|
||||
//TODO Maybe also check this for stateReferences????
|
||||
for (PathSet::iterator j = i->references.begin();
|
||||
j != i->references.end(); ++j)
|
||||
if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end())
|
||||
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
|
||||
% i->path % *j);
|
||||
|
||||
//TODO Also do this for stateReferences????
|
||||
|
||||
setDeriver(txn, i->path, i->deriver);
|
||||
}
|
||||
}
|
||||
|
|
@ -1489,11 +1512,79 @@ void storePathRequisites(const Path & storePath, const bool includeOutputs, Path
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as storePathRequisites with withState=true, but now only returns the state paths
|
||||
*/
|
||||
void storePathStateRequisitesOnlyTxn(const Transaction & txn, const Path & storePath, const bool includeOutputs, PathSet & statePaths)
|
||||
{
|
||||
PathSet paths;
|
||||
storePathRequisites(storePath, includeOutputs, paths, true);
|
||||
|
||||
//filter out all non-state paths
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i){
|
||||
if (isValidStatePathTxn(txn, *i))
|
||||
statePaths.insert(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalStore::storePathStateRequisitesOnly(const Path & storePath, const bool includeOutputs, PathSet & statePaths)
|
||||
{
|
||||
nix::storePathStateRequisitesOnlyTxn(noTxn, storePath, includeOutputs, statePaths);
|
||||
}
|
||||
void LocalStore::storePathRequisites(const Path & storePath, const bool includeOutputs, PathSet & paths, const bool & withState)
|
||||
{
|
||||
return nix::storePathRequisites(storePath, includeOutputs, paths, withState);
|
||||
}
|
||||
|
||||
void convertStatePathsToDerivations(const Transaction & txn, const Path & storePath)
|
||||
{
|
||||
//TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
}
|
||||
|
||||
void getDependenciesAtBuildTime(const Transaction & txn, const Path & drvPath)
|
||||
{
|
||||
Derivation drv = derivationFromPath(drvPath);
|
||||
PathSet allPaths;
|
||||
PathSet inputPaths;
|
||||
|
||||
//TODO THIS IS A DIRECT COPY FROM BUILD.CC WE SHOULD MERGE !!!!!!!!!!!!1!!!!!!!!!!!!!
|
||||
|
||||
/* The outputs are referenceable paths. */
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||
i != drv.outputs.end(); ++i)
|
||||
{
|
||||
debug(format("building path `%1%'") % i->second.path);
|
||||
allPaths.insert(i->second.path);
|
||||
}
|
||||
|
||||
/* First, the input derivations. */
|
||||
for (DerivationInputs::iterator i = drv.inputDrvs.begin();
|
||||
i != drv.inputDrvs.end(); ++i)
|
||||
{
|
||||
/* Add the relevant output closures of the input derivation
|
||||
`*i' as input paths. Only add the closures of output paths
|
||||
that are specified as inputs. */
|
||||
assert(store->isValidPath(i->first));
|
||||
Derivation inDrv = derivationFromPath(i->first);
|
||||
for (StringSet::iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||
if (inDrv.outputs.find(*j) != inDrv.outputs.end())
|
||||
computeFSClosure(inDrv.outputs[*j].path, inputPaths, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE
|
||||
else
|
||||
throw Error(format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") % drvPath % *j % i->first);
|
||||
}
|
||||
|
||||
/* Second, the input sources. */
|
||||
for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i)
|
||||
computeFSClosure(*i, inputPaths, false); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO COPY STATE
|
||||
|
||||
//debug(format("added input paths %1%") % showPaths(inputPaths)); //TODO
|
||||
allPaths.insert(inputPaths.begin(), inputPaths.end());
|
||||
|
||||
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i)
|
||||
printMsg(lvlError, format("ALLPATHS2: %1%") % *i);
|
||||
}
|
||||
|
||||
/* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */
|
||||
static void upgradeStore07()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
Hash queryPathHash(const Path & path);
|
||||
|
||||
Path queryStatePathDrv(const Path & statePath);
|
||||
|
||||
void queryReferences(const Path & path, PathSet & references);
|
||||
|
||||
void queryStateReferences(const Path & storePath, PathSet & stateReferences);
|
||||
|
|
@ -96,6 +98,8 @@ public:
|
|||
|
||||
void storePathRequisites(const Path & storePath, const bool includeOutputs, PathSet & paths, const bool & withState);
|
||||
|
||||
void storePathStateRequisitesOnly(const Path & storePath, const bool includeOutputs, PathSet & statePaths);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -206,6 +210,8 @@ bool isStateDrvPathTxn(const Transaction & txn, const Path & drvPath);
|
|||
|
||||
bool isStateDrvTxn(const Transaction & txn, const Derivation & drv);
|
||||
|
||||
void convertStatePathsToDerivations(const Transaction & txn, const Path & storePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,28 +17,32 @@ Derivation derivationFromPath(const Path & drvPath)
|
|||
return parseDerivation(t);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void computeFSClosure(const Path & storePath,
|
||||
PathSet & paths, bool flipDirection)
|
||||
{
|
||||
if (paths.find(storePath) != paths.end()) return;
|
||||
paths.insert(storePath);
|
||||
|
||||
PathSet references;
|
||||
if (flipDirection)
|
||||
store->queryReferrers(storePath, references);
|
||||
else
|
||||
store->queryReferences(storePath, references);
|
||||
|
||||
for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
|
||||
computeFSClosure(*i, paths, flipDirection);
|
||||
}
|
||||
*/
|
||||
|
||||
void computeFSClosure(const Path & path, PathSet & paths, const bool & withState, bool flipDirection)
|
||||
{
|
||||
if (paths.find(path) != paths.end()) return;
|
||||
PathSet allPaths;
|
||||
computeFSClosureRec(path, allPaths, flipDirection);
|
||||
|
||||
//if withState is false, we filter out all state paths
|
||||
if(withState == false){
|
||||
for (PathSet::iterator i = allPaths.begin(); i != allPaths.end(); ++i){
|
||||
if ( ! store->isValidStatePath(*i) ){
|
||||
paths.insert(*i);
|
||||
|
||||
//TODO (OBSOLETE) CHECK TO SEE IF THERE WERE NO /NIX/STATE PATHS THAT ARENT VALID AT THIS POINT, REMOVE THIS IN THE FUTURE
|
||||
string test = "/nix/state";
|
||||
if((*i).substr(0, test.size()) == test)
|
||||
throw Error(format("THIS CANNOT HAPPEN ! computeFSClosure is called before the state path was valid...."));
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
paths = allPaths;
|
||||
}
|
||||
}
|
||||
|
||||
void computeFSClosureRec(const Path & path, PathSet & paths, const bool & flipDirection)
|
||||
{
|
||||
if (paths.find(path) != paths.end()) return; //takes care of double entries
|
||||
|
||||
paths.insert(path);
|
||||
|
||||
|
|
@ -47,23 +51,18 @@ void computeFSClosure(const Path & path, PathSet & paths, const bool & withState
|
|||
|
||||
if (flipDirection){
|
||||
store->queryReferrers(path, references);
|
||||
if(withState)
|
||||
store->queryStateReferrers(path, stateReferences);
|
||||
store->queryStateReferrers(path, stateReferences);
|
||||
}
|
||||
else{
|
||||
store->queryReferences(path, references);
|
||||
if(withState)
|
||||
store->queryStateReferences(path, stateReferences);
|
||||
store->queryStateReferences(path, stateReferences);
|
||||
}
|
||||
|
||||
PathSet allReferences;
|
||||
if(withState)
|
||||
allReferences = mergePathSets(references, stateReferences);
|
||||
else
|
||||
allReferences = references;
|
||||
allReferences = mergePathSets(references, stateReferences);
|
||||
|
||||
for (PathSet::iterator i = allReferences.begin(); i != allReferences.end(); ++i)
|
||||
computeFSClosure(*i, paths, withState, flipDirection);
|
||||
computeFSClosureRec(*i, paths, flipDirection);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ Derivation derivationFromPath(const Path & drvPath);
|
|||
`storePath' is returned; that is, the closures under the
|
||||
`referrers' relation instead of the `references' relation is
|
||||
returned. */
|
||||
void computeFSClosure(const Path & storePath,
|
||||
PathSet & paths, const bool & withState, bool flipDirection = false);
|
||||
void computeFSClosure(const Path & storePath, PathSet & paths, const bool & withState, bool flipDirection = false);
|
||||
|
||||
void computeFSClosureRec(const Path & path, PathSet & paths, const bool & flipDirection); //private
|
||||
|
||||
/* Return the path corresponding to the output identifier `id' in the
|
||||
given derivation. */
|
||||
|
|
|
|||
|
|
@ -206,6 +206,14 @@ Hash RemoteStore::queryPathHash(const Path & path)
|
|||
return parseHash(htSHA256, hash);
|
||||
}
|
||||
|
||||
Path RemoteStore::queryStatePathDrv(const Path & statePath)
|
||||
{
|
||||
writeInt(wopQueryStatePathDrv, to);
|
||||
writeString(statePath, to);
|
||||
processStderr();
|
||||
Path p = readString(from); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! check wheter from is the state path ????
|
||||
return p;
|
||||
}
|
||||
|
||||
void RemoteStore::queryReferences(const Path & path,
|
||||
PathSet & references)
|
||||
|
|
@ -449,4 +457,10 @@ void RemoteStore::storePathRequisites(const Path & storePath, const bool include
|
|||
|
||||
}
|
||||
|
||||
//TODO
|
||||
void RemoteStore::storePathStateRequisitesOnly(const Path & storePath, const bool includeOutputs, PathSet & statePaths)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public:
|
|||
|
||||
Hash queryPathHash(const Path & path);
|
||||
|
||||
Path queryStatePathDrv(const Path & statePath);
|
||||
|
||||
void queryReferences(const Path & path, PathSet & references);
|
||||
|
||||
void queryStateReferences(const Path & storePath, PathSet & stateReferences);
|
||||
|
|
@ -84,6 +86,7 @@ public:
|
|||
|
||||
void storePathRequisites(const Path & storePath, const bool includeOutputs, PathSet & paths, const bool & withState);
|
||||
|
||||
void storePathStateRequisitesOnly(const Path & storePath, const bool includeOutputs, PathSet & statePaths);
|
||||
|
||||
private:
|
||||
AutoCloseFD fdSocket;
|
||||
|
|
|
|||
|
|
@ -115,9 +115,7 @@ void checkStatePath(const Derivation & drv)
|
|||
Error(format("The statepath from the Derivation does not match the recalculated statepath, are u trying to spoof the statepath?"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Path makeStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier)
|
||||
void calculateStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier, Path & rootPath, Path & fullPath)
|
||||
{
|
||||
//This is a little trick: we could use the same hash as the statepath, but we change it so the repository also gets a unique scannable hash
|
||||
Hash hash = hashString(htSHA256, statePath);
|
||||
|
|
@ -127,7 +125,7 @@ Path makeStateReposPath(const string & type, const Path statePath, const string
|
|||
throw Error(format("Cannot create a repository for a subfolder without a name"));
|
||||
|
||||
string hash_subfolder = type + ":sha256:" + printHash(hash) + ":" + subfolder;
|
||||
string subfolder_ = printHash32(compressHash(hashString(htSHA256, hash_subfolder), 20)) + "-" + subfolder;
|
||||
string subfolder2 = printHash32(compressHash(hashString(htSHA256, hash_subfolder), 20)) + "-" + subfolder;
|
||||
|
||||
string suffix_stateIdentifier = stateIdentifier;
|
||||
if(suffix_stateIdentifier != "")
|
||||
|
|
@ -140,9 +138,27 @@ Path makeStateReposPath(const string & type, const Path statePath, const string
|
|||
checkStoreName(suffix);
|
||||
checkStoreName(stateIdentifier);
|
||||
|
||||
return nixStoreStateRepos + "/"
|
||||
rootPath = nixStoreStateRepos + "/"
|
||||
+ printHash32(compressHash(hashString(htSHA256, s), 20))
|
||||
+ "-" + suffix + suffix_stateIdentifier + "/" + subfolder_;
|
||||
+ "-" + suffix + suffix_stateIdentifier;
|
||||
|
||||
fullPath = rootPath + "/" + subfolder2;
|
||||
}
|
||||
|
||||
Path getStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier)
|
||||
{
|
||||
Path fullPath;
|
||||
Path rootPath;
|
||||
calculateStateReposPath(type, statePath, subfolder, suffix, stateIdentifier, rootPath, fullPath);
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
Path getStateReposRootPath(const string & type, const Path statePath, const string & suffix, const string & stateIdentifier)
|
||||
{
|
||||
Path fullPath;
|
||||
Path rootPath;
|
||||
calculateStateReposPath(type, statePath, "/", suffix, stateIdentifier, rootPath, fullPath);
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
Path makeFixedOutputPath(bool recursive,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ public:
|
|||
/* Queries the hash of a valid path. */
|
||||
virtual Hash queryPathHash(const Path & path) = 0;
|
||||
|
||||
/* Queries the derivation Path of a valid state path. */
|
||||
virtual Path queryStatePathDrv(const Path & statePath) = 0;
|
||||
|
||||
/* Queries the set of outgoing FS references for a store path.
|
||||
The result is not cleared. */
|
||||
virtual void queryReferences(const Path & path,
|
||||
|
|
@ -213,6 +216,7 @@ public:
|
|||
|
||||
virtual void storePathRequisites(const Path & storePath, const bool includeOutputs, PathSet & paths, const bool & withState) = 0;
|
||||
|
||||
virtual void storePathStateRequisitesOnly(const Path & storePath, const bool includeOutputs, PathSet & statePaths) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -245,9 +249,14 @@ Path makeStatePath(const string & componentHash, const string & suffix, const st
|
|||
/* TODO ... */
|
||||
void checkStatePath(const Derivation & drv);
|
||||
|
||||
/* Constructs a unique store state repos path name. */
|
||||
Path makeStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier);
|
||||
/* Calculates a unique store state repos path and also the root path */
|
||||
void calculateStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier, Path & rootPath, Path & fullPath);
|
||||
|
||||
/* Returns the full repository path */
|
||||
Path getStateReposPath(const string & type, const Path statePath, const string subfolder, const string & suffix, const string & stateIdentifier);
|
||||
|
||||
/* Returns the root path containing the repository's */
|
||||
Path getStateReposRootPath(const string & type, const Path statePath, const string & suffix, const string & stateIdentifier);
|
||||
|
||||
/* This is the preparatory part of addToStore() and addToStoreFixed();
|
||||
it computes the store path to which srcPath is to be copied.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
|
||||
PathSet intervalPaths;
|
||||
|
||||
//Make sure the 'root' path which holds the repositorys exists, so svn doenst complain.
|
||||
string repos_root_path = getStateReposRootPath("stateOutput:staterepospath", stateDir, drvName, stateIdentifier);
|
||||
executeAndPrintShellCommand("mkdir -p " + repos_root_path, "mkdir");
|
||||
|
||||
//TODO check if we can create state and staterepos dirs
|
||||
|
||||
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||
|
|
@ -56,13 +60,13 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
}
|
||||
|
||||
//Create a repository for this state location
|
||||
string repos = makeStateReposPath("stateOutput:staterepospath", stateDir, thisdir, drvName, stateIdentifier);
|
||||
executeAndPrintShellCommand("mkdir -p " + repos, "mkdir");
|
||||
string repos = getStateReposPath("stateOutput:staterepospath", stateDir, thisdir, drvName, stateIdentifier);
|
||||
|
||||
|
||||
if(IsDirectory(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 ??
|
||||
executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit then ??
|
||||
|
||||
if(d.type == "interval"){
|
||||
intervalPaths.insert(statePath);
|
||||
|
|
@ -70,12 +74,13 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
|
||||
printMsg(lvlTalkative, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos);
|
||||
|
||||
if(IsDirectory(fullstatedir + "/.svn/")){
|
||||
string fullstatedir_svn = fullstatedir + "/.svn/";
|
||||
if( ! IsDirectory(fullstatedir_svn) ){
|
||||
string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir;
|
||||
executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user
|
||||
}
|
||||
else
|
||||
printMsg(lvlTalkative, 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_svn);
|
||||
}
|
||||
|
||||
//Initialize the counters for the statePaths that have an interval to 0
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ typedef enum {
|
|||
wopQuerySubstitutes,
|
||||
wopHasSubstitutes,
|
||||
wopQueryPathHash,
|
||||
wopQueryStatePathDrv,
|
||||
wopQueryReferences,
|
||||
wopQueryStateReferences,
|
||||
wopQueryReferrers,
|
||||
|
|
|
|||
|
|
@ -1015,6 +1015,19 @@ string trim(const string & s) {
|
|||
|
||||
//TODO , check if we can replace!!! with runProgram like this: string a = runProgram("whoami", true, s);
|
||||
|
||||
/*
|
||||
|
||||
Strings args;
|
||||
args.push_back("rsautl");
|
||||
args.push_back("-sign");
|
||||
args.push_back("-inkey");
|
||||
args.push_back(secretKey);
|
||||
args.push_back("-in");
|
||||
args.push_back(hashFile);
|
||||
string signature = runProgram(OPENSSL_PATH, true, args);
|
||||
|
||||
*/
|
||||
|
||||
void executeAndPrintShellCommand(const string & command, const string & commandName)
|
||||
{
|
||||
string tempoutput = "/tmp/svnoutput.txt";
|
||||
|
|
@ -1073,20 +1086,18 @@ string time_t2string(const time_t & t)
|
|||
return s;
|
||||
}
|
||||
|
||||
//TODO Does this work on windows?
|
||||
bool FileExist(const string FileName)
|
||||
{
|
||||
const char* FileName_C = FileName.c_str();
|
||||
//strcpy(FileName_C, FileName.c_str());
|
||||
|
||||
struct stat my_stat;
|
||||
return (stat(FileName_C, &my_stat) == 0);
|
||||
}
|
||||
|
||||
//TODO Does this work on windows?
|
||||
bool IsDirectory(const string FileName)
|
||||
{
|
||||
const char* FileName_C = FileName.c_str();
|
||||
//strcpy(FileName_C, FileName.c_str());
|
||||
|
||||
struct stat my_stat;
|
||||
if (stat(FileName_C, &my_stat) != 0) return false;
|
||||
return ((my_stat.st_mode & S_IFDIR) != 0);
|
||||
|
|
@ -1095,7 +1106,7 @@ bool IsDirectory(const string FileName)
|
|||
|
||||
string getCallingUserName()
|
||||
{
|
||||
//TODO Make this work on WINDOWS
|
||||
//TODO Make this work on WINDOWS: Untested!
|
||||
/*
|
||||
#include <windows.h>
|
||||
char acUserName[100];
|
||||
|
|
@ -1109,12 +1120,11 @@ string getCallingUserName()
|
|||
//Linux
|
||||
Strings empty;
|
||||
string username = runProgram("whoami", true, empty); //the username of the user that is trying to build the component
|
||||
//TODO Can and Should NOT be faked, so this is clearly unsafe ... :(
|
||||
//TODO Can be faked, so this is clearly unsafe ... :(
|
||||
//Remove the \n
|
||||
int pos = username.find("\n",0);
|
||||
username.erase(pos,1);
|
||||
|
||||
//return "root6";
|
||||
return username;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ using std::cout;
|
|||
|
||||
typedef void (* Operation) (Strings opFlags, Strings opArgs);
|
||||
|
||||
//two global variables
|
||||
string stateIdentifier;
|
||||
string username;
|
||||
|
||||
|
||||
/************************* Build time Functions ******************************/
|
||||
|
||||
|
|
@ -36,12 +40,13 @@ void printHelp()
|
|||
|
||||
|
||||
//
|
||||
Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath, string & stateIdentifier, string & binary, string & derivationPath, bool isStatePath,
|
||||
bool getDerivers, PathSet & derivers, string & username) //optional
|
||||
Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath,
|
||||
string & binary, string & derivationPath, bool isStatePath, Strings & program_args,
|
||||
bool getDerivers, PathSet & derivers) //optional
|
||||
{
|
||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||
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]) )");
|
||||
if ( opArgs.size() != 1 && opArgs.size() != 2 )
|
||||
throw UsageError("only one or two arguments allowed component path and program arguments (counts as one) ");
|
||||
|
||||
//Parse the full path like /nix/store/...../bin/hello
|
||||
string fullPath = opArgs.front();
|
||||
|
|
@ -57,24 +62,32 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c
|
|||
//Check if path is statepath
|
||||
isStatePath = store->isStateComponent(componentPath);
|
||||
|
||||
//Extract the program arguments
|
||||
string allargs;
|
||||
if(opArgs.size() > 1){
|
||||
opArgs.pop_front();
|
||||
stateIdentifier = opArgs.front();
|
||||
allargs = opArgs.front();
|
||||
|
||||
Strings progam_args;
|
||||
//TODO !!!!!!!!!!!!!!!!!!!!!!
|
||||
}
|
||||
|
||||
if(username == "")
|
||||
username = getCallingUserName();
|
||||
printMsg(lvlError, format("'%1%' - '%2%' - '%3%' - '%4%' - '%5%'") % componentPath % stateIdentifier % binary % username % allargs);
|
||||
|
||||
//printMsg(lvlError, format("%1% - %2% - %3% - %4%") % componentPath % stateIdentifier % binary % username);
|
||||
|
||||
derivers = queryDerivers(noTxn, componentPath, stateIdentifier, username);
|
||||
if(isStatePath)
|
||||
derivers = queryDerivers(noTxn, componentPath, stateIdentifier, username);
|
||||
else
|
||||
derivers.insert(queryDeriver(noTxn, componentPath));
|
||||
|
||||
if(getDerivers == true)
|
||||
return Derivation();
|
||||
else if(derivers.size() == 0)
|
||||
throw UsageError(format("There are no derivers with this combination of identifier '%1%' and username '%2%'") % stateIdentifier % username);
|
||||
else if(derivers.size() != 1)
|
||||
throw UsageError(format("There is more than one deriver with identifier '%1%' and username '%2%'") % stateIdentifier % username);
|
||||
|
||||
if(isStatePath){
|
||||
if(derivers.size() == 0)
|
||||
throw UsageError(format("There are no derivers with this combination of identifier '%1%' and username '%2%'") % stateIdentifier % username);
|
||||
if(derivers.size() != 1)
|
||||
throw UsageError(format("There is more than one deriver with stateIdentifier '%1%' and username '%2%'") % stateIdentifier % username);
|
||||
}
|
||||
|
||||
Derivation drv;
|
||||
for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i){ //ugly workaround for drvs[0].
|
||||
|
|
@ -82,37 +95,33 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c
|
|||
drv = derivationFromPath(derivationPath);
|
||||
}
|
||||
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
statePath = stateOutputs.find("state")->second.statepath;
|
||||
if(isStatePath){
|
||||
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, bool & isStatePath)
|
||||
Derivation getDerivation_andCheckArgs(Strings opFlags, Strings opArgs, Path & componentPath, Path & statePath,
|
||||
string & binary, string & derivationPath, bool & isStatePath, Strings & program_args)
|
||||
{
|
||||
PathSet empty;
|
||||
string empty2;
|
||||
return getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, isStatePath, false, empty, empty2);
|
||||
return getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStatePath, program_args, false, empty);
|
||||
}
|
||||
|
||||
//
|
||||
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;
|
||||
bool isStatePath;
|
||||
Derivation drv = getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, true, isStatePath, derivers, username);
|
||||
Strings program_args;
|
||||
Derivation drv = getDerivation_andCheckArgs_(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStatePath, program_args, true, derivers);
|
||||
|
||||
if(!isStatePath)
|
||||
throw UsageError(format("This path '%1%' is not a state path") % componentPath);
|
||||
|
|
@ -127,11 +136,11 @@ static void opShowStatePath(Strings opFlags, Strings opArgs)
|
|||
{
|
||||
Path componentPath;
|
||||
Path statePath;
|
||||
string stateIdentifier;
|
||||
string binary;
|
||||
string derivationPath;
|
||||
bool isStatePath;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, isStatePath);
|
||||
Strings program_args;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStatePath, program_args);
|
||||
|
||||
if(!isStatePath)
|
||||
throw UsageError(format("This path '%1%' is not a state path") % componentPath);
|
||||
|
|
@ -144,191 +153,175 @@ static void opShowStateReposRootPath(Strings opFlags, Strings opArgs)
|
|||
{
|
||||
Path componentPath;
|
||||
Path statePath;
|
||||
string stateIdentifier;
|
||||
string binary;
|
||||
string derivationPath;
|
||||
bool isStatePath;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, isStatePath);
|
||||
Strings program_args;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStatePath, program_args);
|
||||
|
||||
if(!isStatePath)
|
||||
throw UsageError(format("This path '%1%' is not a state path") % componentPath);
|
||||
|
||||
//Get the a repository for this state location
|
||||
string drvName = drv.env.find("name")->second;
|
||||
string repos = makeStateReposPath("stateOutput:staterepospath", statePath, "/", drvName, stateIdentifier); //this is a copy from store-state.cc
|
||||
string repos = getStateReposPath("stateOutput:staterepospath", statePath, "/", drvName, stateIdentifier); //this is a copy from store-state.cc
|
||||
|
||||
printMsg(lvlError, format("%1%") % repos);
|
||||
}
|
||||
|
||||
|
||||
PathSet getReferencesClosureWithState(const Path & storepath)
|
||||
//Comment TODO
|
||||
PathSet getAllStateDerivationsRecursively(const Path & storePath)
|
||||
{
|
||||
PathSet paths;
|
||||
store->storePathRequisites(storepath, false, paths, true);
|
||||
//Get recursively all state paths
|
||||
PathSet statePaths;
|
||||
store->storePathStateRequisitesOnly(storePath, false, statePaths);
|
||||
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||
{
|
||||
printMsg(lvlError, format("REFCLOSURE %1%") % *i);
|
||||
}
|
||||
//Find the matching drv with the statePath
|
||||
PathSet derivations;
|
||||
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i)
|
||||
derivations.insert(store->queryStatePathDrv(*i));
|
||||
|
||||
//return drvs ! (combo of component + state | component path)
|
||||
//return single state paths
|
||||
return derivations;
|
||||
}
|
||||
|
||||
//TODO
|
||||
static void recheckrefsinstaterecursive()
|
||||
{
|
||||
|
||||
//PathSet state_references = scanForReferences(statePath, allPaths);
|
||||
//PathSet state_stateReferences = scanForStateReferences(statePath, allStatePaths);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void opRunComponent(Strings opFlags, Strings opArgs)
|
||||
{
|
||||
//get the derivation of the current component
|
||||
|
||||
//get the all the info of the component that is being called (we dont really use it yet)
|
||||
Path componentPath;
|
||||
Path statePath;
|
||||
string stateIdentifier;
|
||||
string binary;
|
||||
string derivationPath;
|
||||
bool isStatePath;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, stateIdentifier, binary, derivationPath, isStatePath);
|
||||
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
DerivationOutputs outputs = drv.outputs;
|
||||
string drvName = drv.env.find("name")->second;
|
||||
Strings program_args;
|
||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStatePath, program_args);
|
||||
|
||||
//Check if component is a state component !!!
|
||||
//Specifiy the SVN binarys
|
||||
string svnbin = nixSVNPath + "/svn";
|
||||
string svnadminbin = nixSVNPath + "/svnadmin";
|
||||
|
||||
//Check for locks ...
|
||||
|
||||
//Check for locks ... ?
|
||||
//add locks ... ?
|
||||
//svn lock ... ?
|
||||
|
||||
//******************* Run the component
|
||||
//TODO
|
||||
|
||||
|
||||
//******************* Afterwards, call the commit script (recursively)
|
||||
|
||||
//get dependecies (if neccecary | recusively) of all state components that need to be updated
|
||||
//
|
||||
//TODO nix-store -qR $(nix-store -qd /nix/store/6x6glnb9idn53yxfqrz6wq53459vv3qd-firefox-2.0.0.3/)
|
||||
|
||||
//TODO maybe also scan the parameters for state or component hashes?
|
||||
PathSet drvs = getAllStateDerivationsRecursively(componentPath);
|
||||
|
||||
//????
|
||||
//Transaction txn;
|
||||
//createStoreTransaction(txn);
|
||||
//txn.commit();
|
||||
|
||||
//or noTxn
|
||||
//******************* With everything in place, we call the commit script on all statePaths **********************
|
||||
|
||||
for (PathSet::iterator d = drvs.begin(); d != drvs.end(); ++d)
|
||||
{
|
||||
//Extract the neccecary info from each Drv
|
||||
Path drvPath = *d;
|
||||
Derivation drv = derivationFromPath(drvPath);
|
||||
DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
Path statePath = stateOutputs.find("state")->second.statepath;
|
||||
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
|
||||
string drvName = drv.env.find("name")->second;
|
||||
|
||||
//for(...){
|
||||
//
|
||||
//}
|
||||
//Print
|
||||
printMsg(lvlError, format("Committing statePath: %1%") % statePath);
|
||||
|
||||
string svnbin = nixSVNPath + "/svn";
|
||||
string svnadminbin = nixSVNPath + "/svnadmin";
|
||||
//Vector includeing all commit scripts:
|
||||
vector<string> subversionedpaths;
|
||||
vector<bool> subversionedpathsCommitBoolean;
|
||||
vector<string> nonversionedpaths; //of type none, no versioning needed
|
||||
vector<string> checkoutcommands;
|
||||
|
||||
//Vector includeing all commit scripts:
|
||||
vector<string> subversionedpaths;
|
||||
vector<bool> subversionedpathsCommitBoolean;
|
||||
vector<string> nonversionedpaths; //of type none, no versioning needed
|
||||
vector<string> checkoutcommands;
|
||||
//Get all the inverals from the database at once
|
||||
PathSet intervalPaths;
|
||||
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||
DerivationStateOutputDir d = i->second;
|
||||
|
||||
//Get all the inverals from the database at once
|
||||
PathSet intervalPaths;
|
||||
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||
DerivationStateOutputDir d = i->second;
|
||||
string thisdir = d.path;
|
||||
string fullstatedir = statePath + "/" + thisdir;
|
||||
|
||||
string thisdir = d.path;
|
||||
string fullstatedir = statePath + "/" + thisdir;
|
||||
|
||||
if(d.type == "interval"){
|
||||
intervalPaths.insert(fullstatedir);
|
||||
if(d.type == "interval"){
|
||||
intervalPaths.insert(fullstatedir);
|
||||
}
|
||||
}
|
||||
vector<int> intervals = store->getStatePathsInterval(intervalPaths);
|
||||
|
||||
int intervalAt=0;
|
||||
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||
DerivationStateOutputDir d = i->second;
|
||||
|
||||
string thisdir = d.path; //TODO CONVERT
|
||||
|
||||
string fullstatedir = statePath + "/" + thisdir;
|
||||
if(thisdir == "/") //exception for the root dir
|
||||
fullstatedir = statePath + "/";
|
||||
|
||||
if(d.type == "none"){
|
||||
nonversionedpaths.push_back(fullstatedir);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Get the a repository for this state location
|
||||
string repos = getStateReposPath("stateOutput:staterepospath", statePath, thisdir, drvName, stateIdentifier); //this is a copy from store-state.cc
|
||||
|
||||
//Add the checkout command in case its needed
|
||||
checkoutcommands.push_back(svnbin + " --ignore-externals checkout file://" + repos + " " + fullstatedir);
|
||||
subversionedpaths.push_back(fullstatedir);
|
||||
|
||||
if(d.type == "interval"){
|
||||
//Get the interval-counter from the database
|
||||
int interval_counter = intervals[intervalAt];
|
||||
int interval = d.getInterval();
|
||||
subversionedpathsCommitBoolean.push_back(interval_counter % interval == 0);
|
||||
|
||||
//update the interval
|
||||
intervals[intervalAt] = interval_counter + 1;
|
||||
intervalAt++;
|
||||
}
|
||||
else if(d.type == "full")
|
||||
subversionedpathsCommitBoolean.push_back(true);
|
||||
else if(d.type == "manual") //TODO !!!!!
|
||||
subversionedpathsCommitBoolean.push_back(false);
|
||||
else
|
||||
throw Error(format("interval '%1%' is not handled in nix-state") % d.type);
|
||||
}
|
||||
|
||||
//Update the intervals again
|
||||
//store->setStatePathsInterval(intervalPaths, intervals); //TODO UNCOMMENT
|
||||
|
||||
//Call the commit script with the appropiate paramenters
|
||||
string subversionedstatepathsarray;
|
||||
for (vector<string>::iterator i = subversionedpaths.begin(); i != subversionedpaths.end(); ++i)
|
||||
{
|
||||
subversionedstatepathsarray += *(i) + " ";
|
||||
}
|
||||
string subversionedpathsCommitBooleansarray;
|
||||
for (vector<bool>::iterator i = subversionedpathsCommitBoolean.begin(); i != subversionedpathsCommitBoolean.end(); ++i)
|
||||
{
|
||||
subversionedpathsCommitBooleansarray += bool2string(*i) + " ";
|
||||
}
|
||||
string nonversionedstatepathsarray;
|
||||
for (vector<string>::iterator i = nonversionedpaths.begin(); i != nonversionedpaths.end(); ++i)
|
||||
{
|
||||
nonversionedstatepathsarray += *(i) + " ";
|
||||
}
|
||||
string commandsarray;
|
||||
for (vector<string>::iterator i = checkoutcommands.begin(); i != checkoutcommands.end(); ++i)
|
||||
{
|
||||
//#HACK: I cant seem to find a way for bash to parse a 2 dimensional string array as argument, so we use a 1-d array with '|' as seperator
|
||||
commandsarray += "" + *(i) + " | ";
|
||||
}
|
||||
|
||||
//make the call
|
||||
executeAndPrintShellCommand(nixLibexecDir + "/nix/nix-statecommit.sh " + svnbin +
|
||||
" \"" + subversionedstatepathsarray + "\" " +
|
||||
" \"" + subversionedpathsCommitBooleansarray + "\" " +
|
||||
" \"" + nonversionedstatepathsarray + "\" " +
|
||||
" \"" + commandsarray + "\" ",
|
||||
"commit-script");
|
||||
}
|
||||
vector<int> intervals = store->getStatePathsInterval(intervalPaths);
|
||||
|
||||
int intervalAt=0;
|
||||
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||
DerivationStateOutputDir d = i->second;
|
||||
|
||||
string thisdir = d.path; //TODO CONVERT
|
||||
|
||||
string fullstatedir = statePath + "/" + thisdir;
|
||||
if(thisdir == "/") //exception for the root dir
|
||||
fullstatedir = statePath + "/";
|
||||
|
||||
|
||||
//Path fullStatePath = fullstatedir; //TODO call coerce function //TODO REMOVE?
|
||||
|
||||
if(d.type == "none"){
|
||||
nonversionedpaths.push_back(fullstatedir);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Get the a repository for this state location
|
||||
string repos = makeStateReposPath("stateOutput:staterepospath", statePath, thisdir, drvName, stateIdentifier); //this is a copy from store-state.cc
|
||||
|
||||
//
|
||||
checkoutcommands.push_back(svnbin + " --ignore-externals checkout file://" + repos + " " + fullstatedir);
|
||||
subversionedpaths.push_back(fullstatedir);
|
||||
|
||||
if(d.type == "interval"){
|
||||
//Get the interval-counter from the database
|
||||
int interval_counter = intervals[intervalAt];
|
||||
int interval = d.getInterval();
|
||||
subversionedpathsCommitBoolean.push_back(interval_counter % interval == 0);
|
||||
|
||||
//update the interval
|
||||
intervals[intervalAt] = interval_counter + 1;
|
||||
intervalAt++;
|
||||
}
|
||||
else if(d.type == "full")
|
||||
subversionedpathsCommitBoolean.push_back(true);
|
||||
else if(d.type == "manual") //TODO !!!!!
|
||||
subversionedpathsCommitBoolean.push_back(false);
|
||||
else
|
||||
throw Error(format("interval '%1%' is not handled in nix-state") % d.type);
|
||||
}
|
||||
|
||||
//Update the intervals again
|
||||
//store->setStatePathsInterval(intervalPaths, intervals);
|
||||
|
||||
//Call the commit script with the appropiate paramenters
|
||||
string subversionedstatepathsarray;
|
||||
for (vector<string>::iterator i = subversionedpaths.begin(); i != subversionedpaths.end(); ++i)
|
||||
{
|
||||
subversionedstatepathsarray += *(i) + " ";
|
||||
}
|
||||
string subversionedpathsCommitBooleansarray;
|
||||
for (vector<bool>::iterator i = subversionedpathsCommitBoolean.begin(); i != subversionedpathsCommitBoolean.end(); ++i)
|
||||
{
|
||||
subversionedpathsCommitBooleansarray += bool2string(*i) + " ";
|
||||
}
|
||||
string nonversionedstatepathsarray;
|
||||
for (vector<string>::iterator i = nonversionedpaths.begin(); i != nonversionedpaths.end(); ++i)
|
||||
{
|
||||
nonversionedstatepathsarray += *(i) + " ";
|
||||
}
|
||||
string commandsarray;
|
||||
for (vector<string>::iterator i = checkoutcommands.begin(); i != checkoutcommands.end(); ++i)
|
||||
{
|
||||
//#HACK: I cant seem to find a way for bash to parse a 2 dimensional string array as argument, so we use a 1-d array with '|' as seperator
|
||||
commandsarray += "" + *(i) + " | ";
|
||||
}
|
||||
|
||||
//make the call
|
||||
executeAndPrintShellCommand(nixLibexecDir + "/nix/nix-statecommit.sh " + svnbin +
|
||||
" \"" + subversionedstatepathsarray + "\" " +
|
||||
" \"" + subversionedpathsCommitBooleansarray + "\" " +
|
||||
" \"" + nonversionedstatepathsarray + "\" " +
|
||||
" \"" + commandsarray + "\" ",
|
||||
"commit-script");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -338,6 +331,7 @@ void run(Strings args)
|
|||
Strings opFlags, opArgs;
|
||||
Operation op = 0;
|
||||
|
||||
|
||||
/* test *
|
||||
store = openStore();
|
||||
Path p = "/nix/store/l569q3a2cfx834mcf3vhwczjgbaljnp7-hellohardcodedstateworld-1.0"; //
|
||||
|
|
@ -363,6 +357,14 @@ void run(Strings args)
|
|||
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->isStateDrvPath("/nix/store/2hpx60ibdfv2pslg4rjvp177frijamvi-hellostateworld-1.0.drv") ) );
|
||||
|
||||
store = openStore();
|
||||
convertStatePathsToDerivations(noTxn, "");
|
||||
return;
|
||||
|
||||
store = openStore();
|
||||
Path p = store->queryStatePathDrv("/nix/state/6g6kfgimz8szznlshf13s29fn01zp99d-hellohardcodedstateworld-1.0-test2");
|
||||
printMsg(lvlError, format("Result: %1%") % p);
|
||||
return;
|
||||
|
||||
*/
|
||||
|
|
@ -374,7 +376,7 @@ void run(Strings args)
|
|||
|
||||
Operation oldOp = op;
|
||||
|
||||
if (arg == "--run" || arg == "-r")
|
||||
if (arg == "--commit" || arg == "-c")
|
||||
op = opRunComponent;
|
||||
else if (arg == "--showstatepath")
|
||||
op = opShowStatePath;
|
||||
|
|
@ -400,15 +402,12 @@ void run(Strings args)
|
|||
|
||||
--delete state?
|
||||
|
||||
--user=...
|
||||
|
||||
--show-state-references- -rev = ...
|
||||
--show-state-references-current //in nix-store
|
||||
--show-state-referrers- -rev = ...
|
||||
--show-state-referrers-current //in nix-store
|
||||
|
||||
*/
|
||||
|
||||
else if (arg.substr(0,13) == "--identifier=")
|
||||
stateIdentifier = arg.substr(13,arg.length());
|
||||
else if (arg.substr(0,7) == "--user=")
|
||||
username = arg.substr(7,arg.length());
|
||||
else
|
||||
opArgs.push_back(arg);
|
||||
|
||||
|
|
@ -416,6 +415,10 @@ void run(Strings args)
|
|||
throw UsageError("only one operation may be specified");
|
||||
}
|
||||
|
||||
if(username == "")
|
||||
username = getCallingUserName();
|
||||
|
||||
printMsg(lvlError, format("%1% - %2%") % stateIdentifier % username);
|
||||
|
||||
if (!op) throw UsageError("no operation specified");
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ Operations:
|
|||
Query flags:
|
||||
|
||||
--outputs: query the output paths of a Nix derivation (default)
|
||||
--requisites / -R: print all paths necessary to realise a path
|
||||
--requisites-withstate: same as --requisites but now also including state paths
|
||||
--requisites / -R: print all component paths necessary to realise a path
|
||||
--requisites-state: same as --requisites but now only printing state paths
|
||||
--requisites-full: same as --requisites but now also including state paths
|
||||
--references: print all paths referenced by the given path
|
||||
--references-state: print all state paths referenced by the given path
|
||||
--referrers: print all paths directly refering to the given path
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static void printTree(const Path & path,
|
|||
/* Perform various sorts of queries. */
|
||||
static void opQuery(Strings opFlags, Strings opArgs)
|
||||
{
|
||||
enum { qOutputs, qRequisites, qRequisitesWithState, qReferences, qStateReferences, qReferrers, qStateReferrers
|
||||
enum { qOutputs, qRequisites, qRequisitesState, qRequisitesFull, qReferences, qStateReferences, qReferrers, qStateReferrers
|
||||
, qReferrersClosure, qReferrersClosureWithState, qDeriver, qBinding, qHash
|
||||
, qTree, qGraph, qResolve } query = qOutputs;
|
||||
bool useOutput = false;
|
||||
|
|
@ -234,7 +234,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
i != opFlags.end(); ++i)
|
||||
if (*i == "--outputs") query = qOutputs;
|
||||
else if (*i == "--requisites" || *i == "-R") query = qRequisites;
|
||||
else if (*i == "--requisites-withstate") query = qRequisitesWithState;
|
||||
else if (*i == "--requisites-state") query = qRequisitesState;
|
||||
else if (*i == "--requisites-full") query = qRequisitesFull;
|
||||
else if (*i == "--references") query = qReferences;
|
||||
else if (*i == "--references-state") query = qStateReferences;
|
||||
else if (*i == "--referrers" || *i == "--referers") query = qReferrers;
|
||||
|
|
@ -273,7 +274,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
}
|
||||
|
||||
case qRequisites:
|
||||
case qRequisitesWithState:
|
||||
case qRequisitesState:
|
||||
case qRequisitesFull:
|
||||
case qReferences:
|
||||
case qStateReferences:
|
||||
case qReferrers:
|
||||
|
|
@ -286,7 +288,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
{
|
||||
Path path = maybeUseOutput(fixPath(*i), useOutput, forceRealise);
|
||||
if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, false);
|
||||
else if (query == qRequisitesWithState) store->storePathRequisites(path, includeOutputs, paths, true);
|
||||
else if (query == qRequisitesState) store->storePathStateRequisitesOnly(path, includeOutputs, paths);
|
||||
else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true);
|
||||
else if (query == qReferences) store->queryReferences(path, paths);
|
||||
else if (query == qStateReferences) store->queryStateReferences(path, paths);
|
||||
else if (query == qReferrers) store->queryReferrers(path, paths);
|
||||
|
|
|
|||
|
|
@ -281,6 +281,15 @@ static void performOp(Source & from, Sink & to, unsigned int op)
|
|||
break;
|
||||
}
|
||||
|
||||
case wopQueryStatePathDrv: {
|
||||
Path path = readStorePath(from); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! needs to be the state path
|
||||
startWork();
|
||||
Path p = store->queryStatePathDrv(path);
|
||||
stopWork();
|
||||
writeString(p, to);
|
||||
break;
|
||||
}
|
||||
|
||||
case wopQueryReferences:
|
||||
case wopQueryReferrers: {
|
||||
Path path = readStorePath(from);
|
||||
|
|
@ -303,7 +312,7 @@ static void performOp(Source & from, Sink & to, unsigned int op)
|
|||
if (op == wopQueryStateReferences)
|
||||
store->queryStateReferences(path, paths);
|
||||
else
|
||||
store->queryStateReferrers(path, paths); //TODO Does this work???
|
||||
store->queryStateReferrers(path, paths); //TODO Does this work???, how about the state path?????????
|
||||
stopWork();
|
||||
writeStringSet(paths, to);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue