mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
Created commit shell script; next adding nix-state
This commit is contained in:
parent
97eb8c32a0
commit
c9e78a973a
5 changed files with 195 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
|
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
|
||||||
libexpr nix-instantiate nix-env nix-worker nix-setuid-helper \
|
libexpr nix-instantiate nix-env nix-worker nix-setuid-helper \
|
||||||
nix-log2xml bsdiff-4.3
|
nix-log2xml bsdiff-4.3 nix-state
|
||||||
|
|
||||||
EXTRA_DIST = aterm-helper.pl
|
EXTRA_DIST = aterm-helper.pl
|
||||||
|
|
|
||||||
|
|
@ -439,12 +439,17 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
||||||
if (!matchAttrRHS(staterhs, statevalue, statepos)) abort();
|
if (!matchAttrRHS(staterhs, statevalue, statepos)) abort();
|
||||||
startNest(nest, lvlVomit, format("processing statedir attribute `%1%'") % statekey);
|
startNest(nest, lvlVomit, format("processing statedir attribute `%1%'") % statekey);
|
||||||
try {
|
try {
|
||||||
string s = coerceToString(state, statevalue, context, true);
|
string s = trim(coerceToString(state, statevalue, context, true));
|
||||||
if (statekey == "dir") {
|
if (statekey == "dir") {
|
||||||
|
|
||||||
//Add a / to the end if it's not there
|
//Add a / to the end if it's not there
|
||||||
if(s[s.length() - 1] != '/')
|
if(s[s.length() - 1] != '/')
|
||||||
dir.path = s + "/";
|
s = s + "/";
|
||||||
else
|
|
||||||
|
//Remove the / at the beginning if it's there
|
||||||
|
if(s[0] == '/')
|
||||||
|
s = s.substr(1, s.length());
|
||||||
|
|
||||||
dir.path = s;
|
dir.path = s;
|
||||||
}
|
}
|
||||||
else if (statekey == "type") { dir.type = s; }
|
else if (statekey == "type") { dir.type = s; }
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,10 @@ struct DerivationStateOutputDir
|
||||||
this->interval = interval;
|
this->interval = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getInterval(){
|
||||||
|
return 0; //TODO
|
||||||
|
}
|
||||||
|
|
||||||
//sort function
|
//sort function
|
||||||
bool operator<(const DerivationStateOutputDir& a) const { return path < a.path; }
|
bool operator<(const DerivationStateOutputDir& a) const { return path < a.path; }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
165
src/libstore/store-state.cc
Normal file
165
src/libstore/store-state.cc
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "store-state.hh"
|
||||||
|
#include "globals.hh"
|
||||||
|
#include "util.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
#include "store-api.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs, const StringPairs & env)
|
||||||
|
{
|
||||||
|
string stateDir = stateOutputs.find("state")->second.statepath;
|
||||||
|
string drvName = env.find("name")->second;
|
||||||
|
|
||||||
|
//Convert the map into a sortable vector
|
||||||
|
vector<DerivationStateOutputDir> stateDirsVector;
|
||||||
|
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
|
||||||
|
stateDirsVector.push_back(i->second);
|
||||||
|
}
|
||||||
|
sort(stateDirsVector.begin(), stateDirsVector.end());
|
||||||
|
|
||||||
|
printMsg(lvlError, format("stateDir `%1%'") % stateDir);
|
||||||
|
|
||||||
|
string svnbin = nixSVNPath + "/svn";
|
||||||
|
string svnadminbin = nixSVNPath + "/svnadmin";
|
||||||
|
|
||||||
|
//Vector includeing all commit scripts:
|
||||||
|
vector<string> commitscript;
|
||||||
|
vector<string> subversionedpaths;
|
||||||
|
vector<int> subversionedpathsInterval;
|
||||||
|
vector<string> nonversionedpaths; //of type none, no versioning needed
|
||||||
|
vector<string> checkoutcommands;
|
||||||
|
|
||||||
|
for (vector<DerivationStateOutputDir>::iterator i = stateDirsVector.begin(); i != stateDirsVector.end(); ++i)
|
||||||
|
{
|
||||||
|
DerivationStateOutputDir d = *(i);
|
||||||
|
|
||||||
|
string thisdir = d.path;
|
||||||
|
string fullstatedir = stateDir + "/" + thisdir;
|
||||||
|
|
||||||
|
//calc create repos for this state location
|
||||||
|
Hash hash = hashString(htSHA256, stateDir + thisdir);
|
||||||
|
string repos = makeStateReposPath("stateOutput:staterepospath", hash, drvName);
|
||||||
|
|
||||||
|
//Were going to execute svn shell commands
|
||||||
|
executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700
|
||||||
|
|
||||||
|
//TODO REPLACE TRUE INTO VAR
|
||||||
|
|
||||||
|
//Check if and how this dir needs to be versioned
|
||||||
|
if(d.type == "none"){
|
||||||
|
if(true){
|
||||||
|
executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir");
|
||||||
|
}
|
||||||
|
nonversionedpaths.push_back(fullstatedir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir;
|
||||||
|
checkoutcommands.push_back(checkoutcommand);
|
||||||
|
subversionedpaths.push_back(fullstatedir);
|
||||||
|
|
||||||
|
if(d.type == "interval")
|
||||||
|
subversionedpathsInterval.push_back(d.getInterval());
|
||||||
|
else
|
||||||
|
subversionedpathsInterval.push_back(0);
|
||||||
|
|
||||||
|
if(true){
|
||||||
|
printMsg(lvlError, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos);
|
||||||
|
executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create super commit script
|
||||||
|
printMsg(lvlError, format("svnbin=%1%") % svnbin);
|
||||||
|
string subversionedstatepathsarray = "subversionedpaths=( ";
|
||||||
|
for (vector<string>::iterator i = subversionedpaths.begin(); i != subversionedpaths.end(); ++i)
|
||||||
|
{
|
||||||
|
subversionedstatepathsarray += *(i) + " ";
|
||||||
|
}
|
||||||
|
printMsg(lvlError, format("%1%)") % subversionedstatepathsarray);
|
||||||
|
string subversionedpathsIntervalsarray = "subversionedpathsInterval=( ";
|
||||||
|
for (vector<int>::iterator i = subversionedpathsInterval.begin(); i != subversionedpathsInterval.end(); ++i)
|
||||||
|
{
|
||||||
|
subversionedpathsIntervalsarray += int2String(*i) + " ";
|
||||||
|
}
|
||||||
|
printMsg(lvlError, format("%1%)") % subversionedpathsIntervalsarray);
|
||||||
|
string nonversionedstatepathsarray = "nonversionedpaths=( ";
|
||||||
|
for (vector<string>::iterator i = nonversionedpaths.begin(); i != nonversionedpaths.end(); ++i)
|
||||||
|
{
|
||||||
|
nonversionedstatepathsarray += *(i) + " ";
|
||||||
|
}
|
||||||
|
printMsg(lvlError, format("%1%)") % nonversionedstatepathsarray);
|
||||||
|
string commandsarray = "checkouts=( ";
|
||||||
|
for (vector<string>::iterator i = checkoutcommands.begin(); i != checkoutcommands.end(); ++i)
|
||||||
|
{
|
||||||
|
commandsarray += "\"" + *(i) + "\" ";
|
||||||
|
}
|
||||||
|
printMsg(lvlError, format("%1%)") % commandsarray);
|
||||||
|
for (vector<string>::iterator i = commitscript.begin(); i != commitscript.end(); ++i)
|
||||||
|
{
|
||||||
|
string s = *(i);
|
||||||
|
printMsg(lvlError, format("%1%") % s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void executeAndPrintShellCommand(const string & command, const string & commandName)
|
||||||
|
{
|
||||||
|
string tempoutput = "svnoutput.txt";
|
||||||
|
string newcommand = command + " > " + tempoutput;
|
||||||
|
|
||||||
|
int kidstatus, deadpid;
|
||||||
|
pid_t kidpid = fork();
|
||||||
|
switch (kidpid) {
|
||||||
|
case -1:
|
||||||
|
throw SysError("unable to fork");
|
||||||
|
case 0:
|
||||||
|
try { // child
|
||||||
|
int rv = system(newcommand.c_str());
|
||||||
|
//int rv = execlp(svnbin.c_str(), svnbin.c_str(), ">", tempoutput.c_str(), NULL); //TODO make this work ... ?
|
||||||
|
|
||||||
|
string line;
|
||||||
|
std::ifstream myfile (tempoutput.c_str());
|
||||||
|
if (myfile.is_open()){
|
||||||
|
while (! myfile.eof() )
|
||||||
|
{
|
||||||
|
getline (myfile,line);
|
||||||
|
if(trim(line) != "")
|
||||||
|
printMsg(lvlError, format("[%2%]: %1%") % line % commandName);
|
||||||
|
}
|
||||||
|
myfile.close();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw SysError("svn state error");
|
||||||
|
quickExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv == -1) {
|
||||||
|
throw SysError("svn state error");
|
||||||
|
quickExit(99);
|
||||||
|
}
|
||||||
|
quickExit(0);
|
||||||
|
|
||||||
|
} catch (std::exception & e) {
|
||||||
|
std::cerr << format("state child error: %1%\n") % e.what();
|
||||||
|
quickExit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deadpid = waitpid(kidpid, &kidstatus, 0);
|
||||||
|
if (deadpid == -1) {
|
||||||
|
std::cerr << format("state child waitpid error\n");
|
||||||
|
quickExit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(tempoutput.c_str()); //Remove the tempoutput file
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
src/libstore/store-state.hh
Normal file
16
src/libstore/store-state.hh
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __STORESTATE_H
|
||||||
|
#define __STORESTATE_H
|
||||||
|
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/* Create a state directory. */
|
||||||
|
void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs, const StringPairs & env);
|
||||||
|
|
||||||
|
/* Create and prints the output prefixed with '[commandName]:' via print(lvlError,... of a shell command. */
|
||||||
|
void executeAndPrintShellCommand(const string & command, const string & commandName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !__STORESTATE_H */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue