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

before making computeFSClosure recursively transactional ..... (adding Transaction txn)

This commit is contained in:
Wouter den Breejen 2007-07-12 14:46:15 +00:00
parent 7bfed0c104
commit f3dabd6206
11 changed files with 246 additions and 232 deletions

View file

@ -17,7 +17,7 @@ BUILT_SOURCES = derivations-ast.cc derivations-ast.hh
EXTRA_DIST = derivations-ast.def derivations-ast.cc EXTRA_DIST = derivations-ast.def derivations-ast.cc
AM_CXXFLAGS = -Wall \ AM_CXXFLAGS = -Wall \
-I$(srcdir)/.. ${bdb_include} ${aterm_include} -I$(srcdir)/../libutil -I$(srcdir)/.. ${bdb_include} ${aterm_include} -I$(srcdir)/../libutil -I$(srcdir)/../nix-state
derivations-ast.cc derivations-ast.hh: ../aterm-helper.pl derivations-ast.def derivations-ast.cc derivations-ast.hh: ../aterm-helper.pl derivations-ast.def
$(perl) $(srcdir)/../aterm-helper.pl derivations-ast.hh derivations-ast.cc < $(srcdir)/derivations-ast.def $(perl) $(srcdir)/../aterm-helper.pl derivations-ast.hh derivations-ast.cc < $(srcdir)/derivations-ast.def

View file

@ -7,7 +7,6 @@
#include "util.hh" #include "util.hh"
#include "store-state.hh" #include "store-state.hh"
#include <map> #include <map>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -1787,15 +1786,22 @@ void DerivationGoal::computeClosure()
//Register the state path valid //Register the state path valid
if(isStateDrvTxn(txn, drv)) if(isStateDrvTxn(txn, drv))
{ {
//TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!! //TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!! (why?)
Path statePath = drv.stateOutputs.find("state")->second.statepath; Path statePath = drv.stateOutputs.find("state")->second.statepath;
registerValidPath(txn, registerValidPath(txn,
statePath, statePath,
Hash(), //emtpy hash Hash(), //emtpy hash
state_references, state_references,
state_stateReferences, state_stateReferences,
drvPath, 0); drvPath, 0); //TODO !!!!!!!!!!!!
//Commit state
commitStatePathTxn(txn, statePath);
//Set first revision (if we committed something)
if(readRevisionNumber(statePath) == 1)
updateRevisionsRecursivelyTxn(txn, statePath);
} }
txn.commit(); txn.commit();
@ -2104,6 +2110,7 @@ void SubstitutionGoal::tryToRun()
logPipe.create(); logPipe.create();
/* Remove the (stale) output path if it exists. */ /* Remove the (stale) output path if it exists. */
/* TODO also remove state Path ? */
if (pathExists(storePath)) if (pathExists(storePath))
deletePathWrapped(storePath); deletePathWrapped(storePath);

View file

@ -449,9 +449,9 @@ void Database::enumTable(const Transaction & txn, TableId table,
Path Database::makeStatePathRevision(const Path & statePath, const int revision) Path Database::makeStatePathRevision(const Path & statePath, const int revision)
{ {
string prefix = "-REV-"; string prefix = "-REV-";
return statePath + prefix + int2String(revision); return statePath + prefix + int2String(revision);
} }
void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision) void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision)
{ {
string prefix = "-REV-"; string prefix = "-REV-";
@ -607,7 +607,6 @@ void Database::setStateRevisions(const Transaction & txn, TableId table,
//for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i) //for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i)
// printMsg(lvlError, format("Insert: %1% into %2%") % int2String(revisions.at(*i)) % *i); // printMsg(lvlError, format("Insert: %1% into %2%") % int2String(revisions.at(*i)) % *i);
//Convert the int's into Strings //Convert the int's into Strings
Strings data; Strings data;
for (RevisionNumbers::const_iterator i = sorted_revisions.begin(); i != sorted_revisions.end(); ++i) { for (RevisionNumbers::const_iterator i = sorted_revisions.begin(); i != sorted_revisions.end(); ++i) {
@ -640,6 +639,10 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table, const
Strings data; Strings data;
bool notempty = queryStrings(txn, table, key, data); //now that we have the key, we can query the revisions bool notempty = queryStrings(txn, table, key, data); //now that we have the key, we can query the revisions
//Check
if(statePath_deps.size() != data.size())
throw Error(format("The number of statepath references doenst equal the number of revisions for '%1%'") % statePath);
//sort all state references recursively //sort all state references recursively
vector<Path> sortedStatePaths; vector<Path> sortedStatePaths;
for (PathSet::iterator i = statePath_deps.begin(); i != statePath_deps.end(); ++i) for (PathSet::iterator i = statePath_deps.begin(); i != statePath_deps.end(); ++i)

View file

@ -13,6 +13,8 @@
#include "derivations.hh" #include "derivations.hh"
#include "misc.hh" #include "misc.hh"
#include "store-state.hh"
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
@ -668,8 +670,6 @@ void addStateDeriver(const Transaction & txn, const Path & storePath, const Path
} }
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! remove this entire function, replace by
/* /*
* Returns true or false wheter a store-component has a state component (e.g. has a state dir) or not. * Returns true or false wheter a store-component has a state component (e.g. has a state dir) or not.
* Do NOT confuse this function with isValidStatePath * Do NOT confuse this function with isValidStatePath
@ -1643,57 +1643,6 @@ void LocalStore::storePathRequisites(const Path & storeOrstatePath, const bool i
return nix::storePathRequisites(storeOrstatePath, includeOutputs, paths, withComponents, withState, revision); return nix::storePathRequisites(storeOrstatePath, includeOutputs, paths, withComponents, withState, revision);
} }
/*
* TODO
*
* Not used yet ......................... (should we use it .... ???)
*
*/
/*
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, true, 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, true, 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);
}
*/
void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, PathSet & allStatePaths) void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, PathSet & allStatePaths)
{ {
Paths allComponentPaths2; Paths allComponentPaths2;
@ -1725,6 +1674,8 @@ bool queryStateRevisionsTxn(const Transaction & txn, const Path & statePath, Rev
{ {
PathSet statePaths; PathSet statePaths;
storePathRequisites(statePath, false, statePaths, false, true, revision); //Get all current state dependencies storePathRequisites(statePath, false, statePaths, false, true, revision); //Get all current state dependencies
statePaths.insert(statePath); //also insert the root statePath
return nixDB.queryStateRevisions(txn, dbStateRevisions, statePaths, statePath, revisions, revision); return nixDB.queryStateRevisions(txn, dbStateRevisions, statePaths, statePath, revisions, revision);
} }
@ -1743,8 +1694,15 @@ bool LocalStore::queryAvailableStateRevisions(const Path & statePath, RevisionNu
return nix::queryAvailableStateRevisionsTxn(noTxn, statePath, revisions); return nix::queryAvailableStateRevisionsTxn(noTxn, statePath, revisions);
} }
void LocalStore::commitStatePath(const Path & statePath)
{
nix::commitStatePathTxn(noTxn, statePath);
}
void LocalStore::updateRevisionsRecursively(const Path & statePath)
{
nix::updateRevisionsRecursivelyTxn(noTxn, statePath);
}
/* 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). */
static void upgradeStore07() static void upgradeStore07()

View file

@ -106,6 +106,9 @@ public:
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions); bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
void commitStatePath(const Path & statePath);
void updateRevisionsRecursively(const Path & statePath);
}; };
@ -225,6 +228,8 @@ bool isValidStatePathTxn(const Transaction & txn, const Path & path);
void queryReferencesTxn(const Transaction & txn, const Path & path, PathSet & references, const int revision); void queryReferencesTxn(const Transaction & txn, const Path & path, PathSet & references, const int revision);
void queryStateReferencesTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferences, const int revision); void queryStateReferencesTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferences, const int revision);
Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath); Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath);
void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
void setStateRevisionsTxn(const Transaction & txn, const Path & statePath, const RevisionNumbersSet & revisions);
} }

View file

@ -486,5 +486,16 @@ bool RemoteStore::queryAvailableStateRevisions(const Path & statePath, RevisionN
return false; return false;
} }
//TODO
void RemoteStore::commitStatePath(const Path & statePath)
{
}
//TODO
void RemoteStore::updateRevisionsRecursively(const Path & statePath)
{
}
} }

View file

@ -94,6 +94,10 @@ public:
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions); bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
void commitStatePath(const Path & statePath);
void updateRevisionsRecursively(const Path & statePath);
private: private:
AutoCloseFD fdSocket; AutoCloseFD fdSocket;
FdSink to; FdSink to;

View file

@ -227,6 +227,10 @@ public:
/* TODO */ /* TODO */
virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0; virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0;
virtual void commitStatePath(const Path & statePath) = 0;
virtual void updateRevisionsRecursively(const Path & statePath) = 0;
}; };

View file

@ -12,6 +12,8 @@
#include "derivations.hh" #include "derivations.hh"
#include "store-api.hh" #include "store-api.hh"
#include "local-store.hh" #include "local-store.hh"
#include "misc.hh"
#include "archive.hh"
namespace nix { namespace nix {
@ -89,5 +91,160 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
store->setStatePathsInterval(intervalPaths, empty, true); store->setStatePathsInterval(intervalPaths, empty, true);
} }
void commitStatePathTxn(const Transaction & txn, const Path & statePath)
{
if(!isValidStatePathTxn(txn, statePath))
throw Error(format("path `%1%' is not a valid state path") % statePath);
//queryDeriversStatePath??
Derivation drv = derivationFromPath(queryStatePathDrvTxn(txn, statePath));
//Extract the neccecary info from each Drv
DerivationStateOutputs stateOutputs = drv.stateOutputs;
//Path statePath = stateOutputs.find("state")->second.statepath;
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
//Specifiy the SVN binarys
string svnbin = nixSVNPath + "/svn";
string svnadminbin = nixSVNPath + "/svnadmin";
//Print
printMsg(lvlError, format("Committing statePath: %1%") % statePath);
//Vector includeing all commit scripts:
vector<string> subversionedpaths;
vector<bool> subversionedpathsCommitBoolean;
vector<string> nonversionedpaths; //of type none, no versioning needed
//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;
if(d.type == "interval"){
intervalPaths.insert(fullstatedir);
}
}
vector<int> intervals = store->getStatePathsInterval(intervalPaths); //TODO !!!!!!!!!!!!! txn ??
int intervalAt=0;
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
DerivationStateOutputDir d = i->second;
string thisdir = d.path;
string fullstatedir = statePath + "/" + thisdir;
if(thisdir == "/") //exception for the root dir
fullstatedir = statePath + "/";
if(d.type == "none"){
nonversionedpaths.push_back(fullstatedir);
continue;
}
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);
}
//Get the a repository for this state location
string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc
string checkoutcommand = svnbin + " --ignore-externals checkout file://" + repos + " " + statePath;
//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) + " ";
//make the call to the commit script
Strings p_args;
p_args.push_back(svnbin);
p_args.push_back(subversionedstatepathsarray);
p_args.push_back(subversionedpathsCommitBooleansarray);
p_args.push_back(nonversionedstatepathsarray);
p_args.push_back(checkoutcommand);
p_args.push_back(statePath);
runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-statecommit.sh", true, p_args, "svn");
//Update the intervals again
//setStatePathsIntervalTxn(txn, intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! uncomment and txn ??
}
void updateRevisionsRecursivelyTxn(const Transaction & txn, const Path & statePath)
{
//Save all revisions for the call to
RevisionNumbersSet rivisionMapping;
PathSet statePaths;
storePathRequisites(statePath, false, statePaths, false, true, -1); //Get all current state dependencies
//Add own statePath (may already be in there, but its a set, so no doubles)
statePaths.insert(statePath);
//Sort
vector<Path> sortedStatePaths;
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i)
sortedStatePaths.push_back(*i);
sort(sortedStatePaths.begin(), sortedStatePaths.end());
//call scanForAllReferences again on all newly found statePaths
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i)
rivisionMapping[*i] = readRevisionNumber(*i);
//Store the revision numbers in the database for this statePath with revision number
setStateRevisionsTxn(txn, statePath, rivisionMapping);
}
int readRevisionNumber(Path statePath)
{
string svnbin = nixSVNPath + "/svn";
RevisionNumbers revisions;
string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc
//TODO Check if the .svn exists, it might be deleted, then we dont have to remember the state revision (set -1)
Strings p_args;
p_args.push_back(svnbin);
p_args.push_back("file://" + repos);
string output = runProgram(nixLibexecDir + "/nix/nix-readrevisions.sh", true, p_args); //run
int pos = output.find("\n",0); //remove trailing \n
output.erase(pos,1);
int revision;
bool succeed = string2Int(output, revision);
if(!succeed)
throw Error(format("Cannot read revision number of path '%1%'") % repos);
return revision;
}
} }

View file

@ -2,12 +2,23 @@
#define __STORESTATE_H #define __STORESTATE_H
#include "derivations.hh" #include "derivations.hh"
#include "types.hh"
#include "db.hh"
namespace nix { namespace nix {
/* Create a state directory. */ /* Create a state directory. */
void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs); void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs);
/* TODO */
void commitStatePathTxn(const Transaction & txn, const Path & statePath);
/* TODO */
void updateRevisionsRecursivelyTxn(const Transaction & txn, const Path & statePath);
/* TODO */
int readRevisionNumber(Path statePath);
} }
#endif /* !__STORESTATE_H */ #endif /* !__STORESTATE_H */

View file

@ -11,6 +11,7 @@
#include "local-store.hh" #include "local-store.hh"
#include "derivations.hh" #include "derivations.hh"
#include "references.hh" #include "references.hh"
#include "store-state.hh"
using namespace nix; using namespace nix;
using std::cin; using std::cin;
@ -24,6 +25,7 @@ string stateIdentifier;
string username; string username;
int revision_arg; int revision_arg;
bool scanforReferences = false; bool scanforReferences = false;
bool only_commit = false;
/************************* Build time Functions ******************************/ /************************* Build time Functions ******************************/
@ -225,33 +227,6 @@ static void queryAvailableStateRevisions(Strings opFlags, Strings opArgs)
printMsg(lvlError, format("Available Revisions: %1%") % revisions_txt); printMsg(lvlError, format("Available Revisions: %1%") % revisions_txt);
} }
int readRevisionNumber(Path statePath)
{
string svnbin = nixSVNPath + "/svn";
RevisionNumbers revisions;
string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc
//TODO Check if the .svn exists, it might be deleted, then we dont have to remember the state revision (set -1)
Strings p_args;
p_args.push_back(svnbin);
p_args.push_back("file://" + repos);
string output = runProgram(nixLibexecDir + "/nix/nix-readrevisions.sh", true, p_args); //run
int pos = output.find("\n",0); //remove trailing \n
output.erase(pos,1);
int revision;
bool succeed = string2Int(output, revision);
if(!succeed)
throw Error(format("Cannot read revision number of path '%1%'") % repos);
return revision;
}
static void revertToRevision(Strings opFlags, Strings opArgs) static void revertToRevision(Strings opFlags, Strings opArgs)
{ {
Path componentPath; Path componentPath;
@ -415,30 +390,6 @@ void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path
} }
} }
void updateRevisionsRecursively(Path statePath)
{
//Save all revisions for the call to
RevisionNumbersSet rivisionMapping;
PathSet statePaths;
store->storePathRequisites(statePath, false, statePaths, false, true, -1); //Get all current state dependencies
//Add own statePath (may already be in there, but its a set, so no doubles)
statePaths.insert(statePath);
//Sort
vector<Path> sortedStatePaths;
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i)
sortedStatePaths.push_back(*i);
sort(sortedStatePaths.begin(), sortedStatePaths.end());
//call scanForAllReferences again on all newly found statePaths
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i)
rivisionMapping[*i] = readRevisionNumber(*i);
//Store the revision numbers in the database for this statePath with revision number
store->setStateRevisions(statePath, rivisionMapping);
}
static void opRunComponent(Strings opFlags, Strings opArgs) static void opRunComponent(Strings opFlags, Strings opArgs)
@ -452,136 +403,34 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
string root_program_args; string root_program_args;
Derivation root_drv = getDerivation_andCheckArgs(opFlags, opArgs, root_componentPath, root_statePath, root_binary, root_derivationPath, root_isStateComponent, root_program_args); Derivation root_drv = getDerivation_andCheckArgs(opFlags, opArgs, root_componentPath, root_statePath, root_binary, root_derivationPath, root_isStateComponent, root_program_args);
//Specifiy the SVN binarys
string svnbin = nixSVNPath + "/svn";
string svnadminbin = nixSVNPath + "/svnadmin";
//Check for locks ... ? or put locks on the neseccary state components //Check for locks ... ? or put locks on the neseccary state components
//WARNING: we need to watch out for deadlocks! //WARNING: we need to watch out for deadlocks!
//add locks ... ? //add locks ... ?
//svn lock ... ? //svn lock ... ?
//get all current dependecies (if neccecary | recusively) of all state components that need to be updated //get all current dependecies (if neccecary | recusively) of all state components that need to be updated
PathSet root_drvs = getAllStateDerivationsRecursively(root_componentPath, -1); PathSet statePaths;
//TODO WHAT ABOUT YOURSELF?????????? store->storePathRequisites(root_componentPath, false, statePaths, false, true, -1);
statePaths.insert(root_statePath);
//TODO maybe also scan the parameters for state or component hashes? //TODO maybe also scan the parameters for state or component hashes?
//program_args //program_args
//???? //TODO
Transaction txn; Transaction txn;
//createStoreTransaction(txn); //createStoreTransaction(txn);
//txn.commit();
//******************* Run **************************** //******************* Run ****************************
if(!only_commit)
executeShellCommand(root_componentPath + root_binary + " " + root_program_args); //more efficient way needed ??? executeShellCommand(root_componentPath + root_binary + " " + root_program_args); //more efficient way needed ???
//******************* With everything in place, we call the commit script on all statePaths (in)directly referenced ********************** //******************* With everything in place, we call the commit script on all statePaths (in)directly referenced **********************
PathSet statePaths; //Commit all statePaths
RevisionNumbersSet rivisionMapping; for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i) //TODO first commit own state path?
commitStatePathTxn(txn, *i);
for (PathSet::iterator d = root_drvs.begin(); d != root_drvs.end(); ++d) //TODO first commit own state path?
{
//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;
//Print
printMsg(lvlError, format("Committing statePath: %1%") % statePath);
//Vector includeing all commit scripts:
vector<string> subversionedpaths;
vector<bool> subversionedpathsCommitBoolean;
vector<string> nonversionedpaths; //of type none, no versioning needed
//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;
if(d.type == "interval"){
intervalPaths.insert(fullstatedir);
}
}
vector<int> intervals = store->getStatePathsInterval(intervalPaths); //TODO !!!!!!!!!!!!! txn ??
int intervalAt=0;
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
DerivationStateOutputDir d = i->second;
string thisdir = d.path;
string fullstatedir = statePath + "/" + thisdir;
if(thisdir == "/") //exception for the root dir
fullstatedir = statePath + "/";
if(d.type == "none"){
nonversionedpaths.push_back(fullstatedir);
continue;
}
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);
}
//Get the a repository for this state location
string repos = getStateReposPath("stateOutput:staterepospath", statePath); //this is a copy from store-state.cc
string checkoutcommand = svnbin + " --ignore-externals checkout file://" + repos + " " + statePath;
//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) + " ";
}
//make the call to the commit script
Strings p_args;
p_args.push_back(svnbin);
p_args.push_back(subversionedstatepathsarray);
p_args.push_back(subversionedpathsCommitBooleansarray);
p_args.push_back(nonversionedstatepathsarray);
p_args.push_back(checkoutcommand);
p_args.push_back(statePath);
runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-statecommit.sh", true, p_args, "svn");
//Update the intervals again
//store->setStatePathsInterval(intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! uncomment and txn ??
}
//Start transaction TODO //Start transaction TODO
@ -590,9 +439,10 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
scanAndUpdateAllReferencesRecusivelyTxn(txn, root_statePath); scanAndUpdateAllReferencesRecusivelyTxn(txn, root_statePath);
//Get new revision number //Get new revision number
updateRevisionsRecursively(root_statePath); updateRevisionsRecursivelyTxn(txn, root_statePath);
//Commit transaction TODO //Commit transaction
//txn.commit();
//Debugging //Debugging
RevisionNumbersSet getRivisions; RevisionNumbersSet getRivisions;
@ -720,6 +570,10 @@ void run(Strings args)
if (arg == "--run" || arg == "-r") if (arg == "--run" || arg == "-r")
op = opRunComponent; op = opRunComponent;
else if (arg == "--commit-only"){
op = opRunComponent;
only_commit = true;
}
else if (arg == "--showstatepath") else if (arg == "--showstatepath")
op = opShowStatePath; op = opShowStatePath;
else if (arg == "--showstatereposrootpath") else if (arg == "--showstatereposrootpath")