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:
parent
7bfed0c104
commit
f3dabd6206
11 changed files with 246 additions and 232 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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-";
|
||||||
|
|
@ -606,8 +606,7 @@ void Database::setStateRevisions(const Transaction & txn, TableId table,
|
||||||
//Debugging
|
//Debugging
|
||||||
//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) {
|
||||||
|
|
@ -639,13 +638,17 @@ 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)
|
||||||
sortedStatePaths.push_back(*i);
|
sortedStatePaths.push_back(*i);
|
||||||
sort(sortedStatePaths.begin(), sortedStatePaths.end());
|
sort(sortedStatePaths.begin(), sortedStatePaths.end());
|
||||||
|
|
||||||
//Convert the Strings into int's and match them to the sorted statePaths
|
//Convert the Strings into int's and match them to the sorted statePaths
|
||||||
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i){
|
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i){
|
||||||
string getRevisionS = data.front();
|
string getRevisionS = data.front();
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ public:
|
||||||
bool queryStateRevisions(const Path & statePath, RevisionNumbersSet & revisions, const int revision);
|
bool queryStateRevisions(const Path & statePath, RevisionNumbersSet & revisions, const int revision);
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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 ****************************
|
||||||
|
|
||||||
executeShellCommand(root_componentPath + root_binary + " " + root_program_args); //more efficient way needed ???
|
if(!only_commit)
|
||||||
|
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,10 +439,11 @@ 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;
|
||||||
bool b = store->queryStateRevisions(root_statePath, getRivisions, -1);
|
bool b = store->queryStateRevisions(root_statePath, getRivisions, -1);
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue