mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
This commit is contained in:
parent
40161d0be1
commit
cc7d4c8bd7
8 changed files with 146 additions and 102 deletions
|
|
@ -4,7 +4,7 @@ bin_SCRIPTS = nix-collect-garbage \
|
|||
nix-pack-closure nix-unpack-closure \
|
||||
nix-copy-closure
|
||||
|
||||
noinst_SCRIPTS = nix-profile.sh generate-patches.pl find-runtime-roots.pl nix-statecommit.sh
|
||||
noinst_SCRIPTS = nix-profile.sh generate-patches.pl find-runtime-roots.pl nix-statecommit.sh nix-readrevisions.sh
|
||||
|
||||
nix-pull nix-push: readmanifest.pm readconfig.pm download-using-manifests.pl
|
||||
|
||||
|
|
@ -18,6 +18,7 @@ install-exec-local: readmanifest.pm download-using-manifests.pl find-runtime-roo
|
|||
$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix
|
||||
$(INSTALL_PROGRAM) generate-patches.pl $(DESTDIR)$(libexecdir)/nix
|
||||
$(INSTALL_PROGRAM) nix-statecommit.sh $(DESTDIR)$(libexecdir)/nix
|
||||
$(INSTALL_PROGRAM) nix-readrevisions.sh $(DESTDIR)$(libexecdir)/nix
|
||||
$(INSTALL) -d $(DESTDIR)$(sysconfdir)/nix
|
||||
|
||||
include ../substitute.mk
|
||||
|
|
@ -34,4 +35,6 @@ EXTRA_DIST = nix-collect-garbage.in \
|
|||
nix-pack-closure.in nix-unpack-closure.in \
|
||||
nix-copy-closure.in \
|
||||
find-runtime-roots.pl.in \
|
||||
nix-statecommit.sh.in
|
||||
nix-statecommit.sh.in \
|
||||
nix-readrevisions.sh
|
||||
|
||||
|
|
|
|||
|
|
@ -498,6 +498,8 @@ bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
|||
Strings keys;
|
||||
enumTable(txn, table, keys); //get all revisions
|
||||
|
||||
///////////////?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! create function
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TODO
|
||||
string key = ""; //final key that matches revision + statePath
|
||||
int highestRev = -1;
|
||||
|
||||
|
|
@ -520,6 +522,7 @@ bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
|||
}
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if(key == "" && highestRev == -1) //no records found (TODO throw error?)
|
||||
return false;
|
||||
|
|
@ -548,22 +551,94 @@ bool Database::queryStateReferrers(const Transaction & txn, TableId table,
|
|||
|
||||
|
||||
void Database::setStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, const int revision, const RevisionNumbers & revisions)
|
||||
const Path & statePath, const int revision, const RevisionNumbersClosure & revisions)
|
||||
{
|
||||
//TODO
|
||||
//Pack the data into Strings
|
||||
const string seperator = "|";
|
||||
Strings data;
|
||||
for (RevisionNumbersClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i) {
|
||||
RevisionNumbers revisionNumbers = *i;
|
||||
string packedNumbers = "";
|
||||
for (RevisionNumbers::iterator j = revisionNumbers.begin(); j != revisionNumbers.end(); ++j)
|
||||
packedNumbers += int2String(*j) + seperator;
|
||||
packedNumbers = packedNumbers.substr(0, packedNumbers.length()-1); //remove the last |
|
||||
data.push_back(packedNumbers);
|
||||
}
|
||||
|
||||
//Create the key
|
||||
string key = makeStatePathRevision(statePath, revision);
|
||||
|
||||
//Insert
|
||||
setStrings(txn, table, key, data);
|
||||
}
|
||||
|
||||
bool Database::queryStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbers & revisions, int revision)
|
||||
const Path & statePath, RevisionNumbersClosure & revisions, int revision)
|
||||
{
|
||||
//TODO
|
||||
const string seperator = "|";
|
||||
|
||||
Strings keys;
|
||||
enumTable(txn, table, keys); //get all revisions
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
string key = ""; //final key that matches revision + statePath
|
||||
int highestRev = -1;
|
||||
|
||||
//Lookup which key we need
|
||||
for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) {
|
||||
Path getStatePath_org = *i;
|
||||
Path getStatePath;
|
||||
int getRevision;
|
||||
splitStatePathRevision(*i, getStatePath, getRevision);
|
||||
|
||||
if(getStatePath == statePath){
|
||||
|
||||
if(revision == -1){ //the user wants the last revision
|
||||
if(getRevision > highestRev)
|
||||
highestRev = getRevision;
|
||||
}
|
||||
else if(revision == getRevision){
|
||||
key = getStatePath_org;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if(key == "" && highestRev == -1) //no records found (TODO throw error?)
|
||||
return false;
|
||||
|
||||
if(revision == -1)
|
||||
key = makeStatePathRevision(statePath, highestRev);
|
||||
|
||||
Strings data;
|
||||
bool succeed = queryStrings(txn, table, key, data); //now that we have the key, we can query the references
|
||||
|
||||
//Unpack Strings into RevisionNumbersClosure
|
||||
for (Strings::iterator i = data.begin(); i != data.end(); ++i){
|
||||
RevisionNumbers revisionsGroup;
|
||||
string packedNumbers = *i;
|
||||
Strings tokens = tokenizeString(packedNumbers, seperator);
|
||||
for (Strings::iterator j = tokens.begin(); j != tokens.end(); ++j){
|
||||
int getRevision;
|
||||
bool succeed = string2Int(*j, getRevision);
|
||||
if(!succeed)
|
||||
throw Error(format("Cannot read revision number from db of path '%1%'") % statePath);
|
||||
revisionsGroup.push_back(getRevision);
|
||||
}
|
||||
revisions.push_back(revisionsGroup);
|
||||
}
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
bool Database::queryAllStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbers & revisions)
|
||||
{
|
||||
//TODO
|
||||
|
||||
//LIST OF x ..... y which revisions are available for a rollback
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,11 +110,11 @@ public:
|
|||
|
||||
/* Set the revision number of the statePath and the revision numbers of all state paths in the references closure */
|
||||
void setStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, const int revision, const RevisionNumbers & revisions);
|
||||
const Path & statePath, const int revision, const RevisionNumbersClosure & revisions);
|
||||
|
||||
/* Returns all the revision numbers of the state references closure of the given state path */
|
||||
bool queryStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbers & revisions, int revision = -1);
|
||||
const Path & statePath, RevisionNumbersClosure & revisions, int revision = -1);
|
||||
|
||||
/* Returns all available revision numbers of the given state path */
|
||||
bool queryAllStateRevisions(const Transaction & txn, TableId table,
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
//Initialize the counters for the statePaths that have an interval to 0
|
||||
vector<int> empty;
|
||||
store->setStatePathsInterval(intervalPaths, empty, true);
|
||||
|
||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
|
||||
//Initialize the revisions recursively
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ typedef list<Path> Paths;
|
|||
typedef set<Path> PathSet;
|
||||
|
||||
//state types
|
||||
struct RevisionNumbersKey { Path statePath; int revision; } ;
|
||||
typedef list<int> RevisionNumbers; //the Strings (list) of StateReferences and this list are connected by position
|
||||
typedef list<RevisionNumbers> RevisionNumbersClosure;
|
||||
typedef map<int, Strings> StateReferences;
|
||||
|
||||
//typedef std::map<int, Strings> StateReferencesKey;
|
||||
|
|
|
|||
|
|
@ -769,12 +769,8 @@ void killUser(uid_t uid)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
string runProgram(Path program, bool searchPath, const Strings & args)
|
||||
{
|
||||
/* Split args based on | for pipe-ing */
|
||||
StringsList l;
|
||||
|
||||
/* Create a pipe. */
|
||||
Pipe pipe;
|
||||
pipe.create();
|
||||
|
|
@ -809,7 +805,6 @@ string runProgram(Path program, bool searchPath, const Strings & args)
|
|||
} catch (std::exception & e) {
|
||||
std::cerr << "error: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
quickExit(1);
|
||||
}
|
||||
|
||||
|
|
@ -817,70 +812,14 @@ string runProgram(Path program, bool searchPath, const Strings & args)
|
|||
|
||||
pipe.writeSide.close();
|
||||
|
||||
string result = drainFD(pipe.readSide);
|
||||
|
||||
/* Wait for the child to finish. */
|
||||
int status = pid.wait(true);
|
||||
if (!statusOk(status))
|
||||
throw Error(format("program `%1%' %2%")
|
||||
% program % statusToString(status));
|
||||
|
||||
|
||||
// Create a pipe.
|
||||
Pipe pipe2;
|
||||
pipe2.create();
|
||||
|
||||
// Fork.
|
||||
Pid pid2;
|
||||
pid2 = fork();
|
||||
switch (pid2) {
|
||||
|
||||
case -1:
|
||||
throw SysError("unable to fork");
|
||||
|
||||
case 0: // child
|
||||
try {
|
||||
|
||||
pipe2.readSide.close();
|
||||
|
||||
if (dup2(pipe2.writeSide, STDOUT_FILENO) == -1)
|
||||
throw SysError("dupping from-hook write side");
|
||||
|
||||
dup2(pipe.readSide, STDIN_FILENO);
|
||||
|
||||
Path s = "grep";
|
||||
Strings args2;
|
||||
args2.push_back("Revision");
|
||||
|
||||
std::vector<const char *> cargs; // careful with c_str()!
|
||||
cargs.push_back(s.c_str());
|
||||
for (Strings::const_iterator i = args2.begin(); i != args2.end(); ++i)
|
||||
cargs.push_back(i->c_str());
|
||||
cargs.push_back(0);
|
||||
|
||||
if (searchPath)
|
||||
execvp(s.c_str(), (char * *) &cargs[0]);
|
||||
else
|
||||
execv(s.c_str(), (char * *) &cargs[0]);
|
||||
throw SysError(format("executing `%1%'") % s);
|
||||
|
||||
} catch (std::exception & e) {
|
||||
std::cerr << "error: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
quickExit(1);
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
pipe2.writeSide.close();
|
||||
|
||||
/* wait for second ........... */
|
||||
int status2 = pid2.wait(true);
|
||||
if (!statusOk(status2))
|
||||
throw Error(format("program `%1%' %2%")
|
||||
% program % statusToString(status));
|
||||
|
||||
|
||||
string result = drainFD(pipe2.readSide);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1216,7 +1155,7 @@ PathSet pathSets_union(const PathSet & paths1, const PathSet & paths2)
|
|||
set_union(vector1.begin(), vector1.end(),vector2.begin(), vector2.end(), back_inserter(setResult)); //Also available: set_symmetric_difference and set_intersection
|
||||
|
||||
PathSet diff;
|
||||
for(int i=0; i<setResult.size(); i++)
|
||||
for(unsigned int i=0; i<setResult.size(); i++)
|
||||
diff.insert(setResult[i]);
|
||||
|
||||
return diff;
|
||||
|
|
|
|||
|
|
@ -263,7 +263,6 @@ MakeError(Interrupted, Error)
|
|||
string packStrings(const Strings & strings);
|
||||
Strings unpackStrings(const string & s);
|
||||
|
||||
|
||||
/* String tokenizer. */
|
||||
Strings tokenizeString(const string & s, const string & separators = " \t\n\r");
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ Derivation getDerivation_andCheckArgs_(Strings opFlags, Strings opArgs, Path & c
|
|||
}
|
||||
|
||||
Derivation drv;
|
||||
for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i){ //ugly workaround for drvs[0].
|
||||
for (PathSet::iterator i = derivers.begin(); i != derivers.end(); ++i){ //ugly workaround for drvs[0]. TODO !!!!!!!!!!!!!!!!!!!! change to *(derivers.begin())
|
||||
derivationPath = *i;
|
||||
drv = derivationFromPath(derivationPath);
|
||||
}
|
||||
|
|
@ -189,31 +189,41 @@ RevisionNumbers readRevisionNumbers(const Derivation & drv)
|
|||
string repos = getStateReposPath("stateOutput:staterepospath", statePath, thisdir, drvName, getStateIdentifier); //this is a copy from store-state.cc
|
||||
|
||||
if(IsDirectory(repos)){
|
||||
printMsg(lvlError, format("'%1%'") % repos);
|
||||
Strings p_args;
|
||||
p_args.push_back("info");
|
||||
p_args.push_back(svnbin);
|
||||
p_args.push_back("file://" + repos);
|
||||
|
||||
string output = runProgram(svnbin, true, p_args);
|
||||
|
||||
/*
|
||||
p_args.clear();
|
||||
p_args.push_back("-n");
|
||||
p_args.push_back("/^Revision: /p");
|
||||
p_args.push_back(output);
|
||||
output = runProgram("sed", true, p_args);
|
||||
*/
|
||||
|
||||
printMsg(lvlError, format("%2%") % repos % output);
|
||||
string output = runProgram(nixLibexecDir + "/nix/nix-readrevisions.sh", true, p_args);
|
||||
int pos = output.find("\n",0);
|
||||
output.erase(pos,1);
|
||||
int revision;
|
||||
bool succeed = string2Int(output, revision);
|
||||
if(!succeed)
|
||||
throw Error(format("Cannot read revision number of path '%1%'") % repos);
|
||||
revisions.push_back(revision);
|
||||
}
|
||||
|
||||
else
|
||||
revisions.push_back(-1);
|
||||
}
|
||||
|
||||
//svn info $repos | sed -n '/^Revision: /p' | sed 's/Revision: //' | tr -d "\12"
|
||||
|
||||
return revisions;
|
||||
}
|
||||
|
||||
void setAllRevisionNumbers(const PathSet & drvs)
|
||||
{
|
||||
//for.....
|
||||
|
||||
//DerivationStateOutputs stateOutputs = drv.stateOutputs;
|
||||
//Path statePath = stateOutputs.find("state")->second.statepath;
|
||||
//RevisionNumbers = readRevisionNumbers(drv);
|
||||
|
||||
|
||||
|
||||
//setStateRevisions(notxn, TableId table, const Path & statePath, const int revision, const RevisionNumbersClosure & revisions);
|
||||
/*
|
||||
bool queryStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbersClosure & revisions, int revision = -1);
|
||||
*/
|
||||
}
|
||||
|
||||
//Comment TODO
|
||||
PathSet getAllStateDerivationsRecursively(const Path & storePath)
|
||||
{
|
||||
|
|
@ -379,9 +389,11 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
|
|||
//Scan if needed
|
||||
//scanAndUpdateAllReferencesRecusively ...
|
||||
|
||||
//TODO
|
||||
//Update all revision numbers in the database
|
||||
}
|
||||
|
||||
//Update all revision numbers in the database
|
||||
setAllRevisionNumbers(drvs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -472,12 +484,25 @@ void run(Strings args)
|
|||
nixDB.splitStatePathRevision(gets, statePath2, revision2);
|
||||
printMsg(lvlError, format("'%1%' '%2%'") % statePath2 % int2String(revision2));
|
||||
|
||||
*/
|
||||
|
||||
store = openStore();
|
||||
Derivation drv = derivationFromPath("/nix/store/r2lvhrd8zhb877n07cqvcyp11j9ws5p0-hellohardcodedstateworld-dep1-1.0.drv");
|
||||
readRevisionNumbers(drv);
|
||||
return;
|
||||
|
||||
|
||||
Strings strings;
|
||||
strings.push_back("1");
|
||||
strings.push_back("3");
|
||||
strings.push_back("2");
|
||||
string packed = packStrings(strings);
|
||||
printMsg(lvlError, format("PA '%1%'") % packed);
|
||||
Strings strings2 = unpackStrings(packed);
|
||||
for (Strings::iterator i = strings2.begin(); i != strings2.end(); ++i)
|
||||
printMsg(lvlError, format("UN '%1%'") % *i);
|
||||
|
||||
*/
|
||||
|
||||
//updateRevisionNumbers("/nix/state/xf582zrz6xl677llr07rvskgsi3dli1d-hellohardcodedstateworld-dep1-1.0-test");
|
||||
//return;
|
||||
|
||||
/* test */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue