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

Nix now understands the difference between runtime-state-components and non-runtime-state-compontens. Components and Derivations are now properly (re)build/derived (or not) when necessary.

This commit is contained in:
Wouter den Breejen 2007-06-08 16:00:55 +00:00
parent fd2b8271e4
commit 267ccc589d
8 changed files with 135 additions and 66 deletions

View file

@ -5,7 +5,7 @@
debug=""; #set to "" for no debugging, set to "echo " to debug the commands debug=""; #set to "" for no debugging, set to "echo " to debug the commands
if [ "$#" != 5 ] || [ "$#" != 6 ] ; then if [ "$#" != 5 ] && [ "$#" != 6 ] ; then
echo "Incorrect number of arguments" echo "Incorrect number of arguments"
exit 1; exit 1;
fi fi
@ -22,11 +22,12 @@ nonversionedpaths=( $4 )
checkouts=( $5 ) checkouts=( $5 )
deletesvn=$6 #this flag can be set to 1 to DELETE all .svn folders and NOT commit deletesvn=$6 #this flag can be set to 1 to DELETE all .svn folders and NOT commit
#echo svnbin: $svnbin echo svnbin: $svnbin
#echo subversionedpaths: ${subversionedpaths[@]} echo subversionedpaths: ${subversionedpaths[@]}
#echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]} echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]}
#echo nonversionedpaths: ${nonversionedpaths[@]} echo nonversionedpaths: ${nonversionedpaths[@]}
#echo checkouts: ${checkouts[@]} echo checkouts: ${checkouts[@]}
echo deletesvn: $deletesvn
# #
# #
@ -125,23 +126,23 @@ function subversionSingleStateDir {
# #
i=0 i=0
i_checkout=0
for path in ${subversionedpaths[@]} for path in ${subversionedpaths[@]}
do do
if test -d $path; then #if the dir doesnt exist, than we dont hav to do anything if test -d $path; then #if the dir doesnt exist, than we dont hav to do anything
cd $path; cd $path;
#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 checkoutcommand=""; #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
if ! test -d $path/.svn/; then #if the dir exists but is not yet an svn dir: checkout repos, if it doenst exits (is removed or something) than we dont do anything while true; do
checkoutcommand=""; if [ "${checkouts[$i_checkout]}" = "|" ]; then
while true; do let "i_checkout+=1"
if [ "${checkouts[$i]}" = "|" ]; then break
break fi
let "i+=1" checkoutcommand="${checkoutcommand} ${checkouts[$i_checkout]}";
fi let "i_checkout+=1"
checkoutcommand="${checkoutcommand} ${checkouts[$i]}"; done
let "i+=1"
done if ! test -d "${path}.svn/"; then #if the dir exists but is not yet an svn dir: checkout repos, if it doenst exits (is removed or something) than we dont do anything
if [ "$deletesvn" != "1" ]; then if [ "$deletesvn" != "1" ]; then
$debug $checkoutcommand; $debug $checkoutcommand;
fi fi
@ -157,9 +158,10 @@ do
if [ "$deletesvn" != "1" ]; then if [ "$deletesvn" != "1" ]; then
$debug svn -m "" commit; $debug svn -m "" commit;
fi fi
fi fi
cd - &> /dev/null; cd - &> /dev/null;
let "i+=1"
fi fi
done done

View file

@ -317,14 +317,16 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
{ {
//printMsg(lvlError, format("DRV: %1% %2%") % drv.env.find("name")->second % (drv.outputs.size() == 1)); //printMsg(lvlError, format("DRV: %1% %2%") % drv.env.find("name")->second % (drv.outputs.size() == 1));
/* Return a fixed hash for fixed-output derivations. */ /* Return a fixed hash for fixed-output derivations.
* E.g. derivations that have a hash
*/
if (drv.outputs.size() == 1) { if (drv.outputs.size() == 1) {
DerivationOutputs::const_iterator i = drv.outputs.begin(); DerivationOutputs::const_iterator i = drv.outputs.begin();
if (i->first == "out" && if (i->first == "out" &&
i->second.hash != "") i->second.hash != "")
{ {
//printMsg(lvlError, format("%1% - %2% - %3%") % i->second.hashAlgo % i->second.hash % i->second.path); //printMsg(lvlError, format("FIXED OUTPUT: %1% - %2% - %3%") % i->second.hashAlgo % i->second.hash % i->second.path);
return hashString(htSHA256, "fixed:out:" return hashString(htSHA256, "fixed:out:"
+ i->second.hashAlgo + ":" + i->second.hashAlgo + ":"
@ -333,18 +335,30 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
} }
} }
/* If we have a state derivation, we clear these paramters because they dont affect to outPath */ /* If we have a state derivation, we clear state paramters because they (sometimes) dont affect to outPath:
* If this drv has runtime paramters: The state indentifier and thus statepath may change, but the componentPath (outPath) can stay the same
* If this drv doesnt have runtime paramters: The state indentifier and thus statepath may change, and thus the componentPath changes since it is build with another identifier
* In both cases: Other runtime state parameters like stateDirs, synchronisation and shareState never change the out or statepath so always need to be out of the hash
*/
if(drv.stateOutputs.size() != 0){ if(drv.stateOutputs.size() != 0){
drv.env["statepath"] = "";
drv.stateOutputs.clear(); if(drv.stateOutputs.size() != 1)
drv.stateOutputDirs.clear(); throw EvalError(format("There are more then one stateOutputs in the derviation....."));
/* We do NOT clear the state identifier (what about the username ????) when there are NO DerivationStateOutput drvso = drv.stateOutputs["state"];
* runtime arguments, since this will affect the statePath and therefore the outPath
*/ if(drvso.runtimeStateParamters != ""){ //Has runtime parameters --> Clear all state parameters
//TODO drv.stateOutputs.clear();
} drv.stateOutputDirs.clear();
drv.env["statepath"] = "";
printMsg(lvlError, format("YES RUNTIME"));
}
else{ //Has NO runtime parameters --> Clear state parameters selectively
drvso.clearAllRuntimeParamters();
drv.stateOutputDirs.clear();
printMsg(lvlError, format("NO RUNTIME"));
}
}
/* For other derivations, replace the inputs paths with recursive /* For other derivations, replace the inputs paths with recursive
calls to this function.*/ calls to this function.*/
@ -360,9 +374,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
inputs2[printHash(h)] = i->second; inputs2[printHash(h)] = i->second;
} }
drv.inputDrvs = inputs2; drv.inputDrvs = inputs2;
//printMsg(lvlError, format("%1% with %2% --> %3%") % drv.env.find("name")->second % printHash(hashTerm(unparseDerivation(drv))) % unparseDerivation(drv));
//printMsg(lvlError, format("%1%") % unparseDerivation(drv));
return hashTerm(unparseDerivation(drv)); return hashTerm(unparseDerivation(drv));
} }
@ -583,10 +595,25 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
output names do get reflected in the hash. */ output names do get reflected in the hash. */
drv.env["out"] = ""; drv.env["out"] = "";
drv.outputs["out"] = DerivationOutput("", outputHashAlgo, outputHash); drv.outputs["out"] = DerivationOutput("", outputHashAlgo, outputHash);
/* If there are no runtime paratermers, then we need to take the the stateIdentifier into account for the hash calcaulation below: hashDerivationModulo(...)
* We also add enableState to make it parse the drv to a state-drv
* We also add runtimeStateParamters for the hash calc in hashDerivationModulo(...) to check if its needs to take the stateIdentiefier into account in the hash
*/
if(enableState && !disableState){
if(runtimeStateParamters == ""){
string enableStateS = bool2string("true");
drv.stateOutputs["state"] = DerivationStateOutput("", "", "", stateIdentifier, enableStateS, "", "", "", runtimeStateParamters, false);
}
}
/* Use the masked derivation expression to compute the output /* Use the masked derivation expression to compute the output
path. */ path. */
Path outPath = makeStorePath("output:out", hashDerivationModulo(state, drv), drvName);
//TODO CLEANUP
Hash h = hashDerivationModulo(state, drv);
//printMsg(lvlError, format("USES: `%1%'") % printHash(h));
Path outPath = makeStorePath("output:out", h, drvName);
/* Construct the final derivation store expression. */ /* Construct the final derivation store expression. */
drv.env["out"] = outPath; drv.env["out"] = outPath;

View file

@ -49,15 +49,19 @@ struct DerivationStateOutput
string createDirsBeforeInstall; //if true: creates state dirs before installation string createDirsBeforeInstall; //if true: creates state dirs before installation
string runtimeStateParamters; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here) string runtimeStateParamters; //if not empty: these are the runtime parameters where state can be found (you can use $statepath here)
DerivationStateOutput() DerivationStateOutput()
{ {
} }
DerivationStateOutput(Path statepath, string hashAlgo, string hash, string stateIdentifier, string enabled, string shared, string synchronization, string createDirsBeforeInstall, string runtimeStateParamters)
DerivationStateOutput(Path statepath, string hashAlgo, string hash, string stateIdentifier, string enabled, string shared, string synchronization, string createDirsBeforeInstall, string runtimeStateParamters, bool check=true)
{ {
if(shared != "none" && shared != "full" && shared != "group") if(check){
throw Error(format("shared '%1%' is not a correct type") % shared); if(shared != "none" && shared != "full" && shared != "group")
if(synchronization != "none" && synchronization != "exclusive-lock" && synchronization != "recursive-exclusive-lock") throw Error(format("shared '%1%' is not a correct type") % shared);
throw Error(format("synchronization '%1%' is not a correct type") % synchronization); if(synchronization != "none" && synchronization != "exclusive-lock" && synchronization != "recursive-exclusive-lock")
throw Error(format("synchronization '%1%' is not a correct type") % synchronization);
}
//TODO //TODO
//commitReferences //commitReferences
@ -81,6 +85,21 @@ struct DerivationStateOutput
bool getCreateDirsBeforeInstall(){ bool getCreateDirsBeforeInstall(){
return string2bool(createDirsBeforeInstall); return string2bool(createDirsBeforeInstall);
} }
/*
* This sets all the paramters to "" to ensure they're not taken into account for the hash calculation in primops.cc
*/
void clearAllRuntimeParamters(){
this->statepath = "";
//this->hashAlgo; //Clear this one?
//this->hash; //Clear this one?
//this->stateIdentifier;
this->enabled = "";
this->shared = "";
this->synchronization = "";
this->createDirsBeforeInstall = "";
this->runtimeStateParamters = "";
}
}; };
struct DerivationStateOutputDir struct DerivationStateOutputDir

View file

@ -1282,7 +1282,7 @@ void updateAllStateDerivations()
for (Strings::iterator i = unique_paths.begin(); i != unique_paths.end(); ++i) for (Strings::iterator i = unique_paths.begin(); i != unique_paths.end(); ++i)
{ {
string path = *i; string path = *i;
printMsg(lvlError, format("Unique: %1%") % path); //printMsg(lvlError, format("Unique: %1%") % path);
store->updateStateDerivation(txn, path); //TODO replace store-> store->updateStateDerivation(txn, path); //TODO replace store->
} }

View file

@ -18,21 +18,14 @@ namespace nix {
void updatedStateDerivation(Path storePath) void updatedStateDerivation(Path storePath)
{ {
//Remove the old .svn folders //We dont remove the old .svn folders
//New repostorys are created by createStateDirs
//Create new repositorys, or use existing...
//createStateDirs already does that ...
printMsg(lvlError, format("Resetting state drv settings like repositorys")); printMsg(lvlError, format("Resetting state drv settings like repositorys"));
//Create a repository for this state location //Create a repository for this state location
//string repos = makeStateReposPath("stateOutput:staterepospath", stateDir, thisdir, drvName, stateIdentifier); //
//executeAndPrintShellCommand("mkdir -p " + repos, "mkdir");
//executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit than ??
//createStateDirs
} }
void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs, const StringPairs & env) void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const DerivationStateOutputs & stateOutputs, const StringPairs & env)
@ -47,7 +40,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
PathSet intervalPaths; PathSet intervalPaths;
//TODO check if we can create stata and staterepos dirs //TODO check if we can create state and staterepos dirs
for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){ for (DerivationStateOutputDirs::const_reverse_iterator i = stateOutputDirs.rbegin(); i != stateOutputDirs.rend(); ++i){
DerivationStateOutputDir d = i->second; DerivationStateOutputDir d = i->second;
@ -56,31 +49,33 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
string fullstatedir = stateDir + "/" + thisdir; string fullstatedir = stateDir + "/" + thisdir;
Path statePath = fullstatedir; //TODO call coerce function Path statePath = fullstatedir; //TODO call coerce function
//TODO REPLACE TRUE INTO VAR OF CREATEING DIRS BEFORE OR AFTER INSTALL
//Check if and how this dir needs to be versioned //Check if and how this dir needs to be versioned
if(d.type == "none"){ if(d.type == "none"){
if(true){ executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir");
executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir");
}
continue; continue;
} }
//Create a repository for this state location //Create a repository for this state location
string repos = makeStateReposPath("stateOutput:staterepospath", stateDir, thisdir, drvName, stateIdentifier); string repos = makeStateReposPath("stateOutput:staterepospath", stateDir, thisdir, drvName, stateIdentifier);
executeAndPrintShellCommand("mkdir -p " + repos, "mkdir"); executeAndPrintShellCommand("mkdir -p " + repos, "mkdir");
executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit than ??
// //TODO Check if repos already exitst? if(IsDirectory(repos))
executeAndPrintShellCommand(svnadminbin + " create " + repos, "svnadmin"); //TODO create as nixbld.nixbld chmod 700... can you still commit than ??
else
printMsg(lvlError, format("Repos %1% already exists, so we use that repository") % repos);
if(d.type == "interval"){ if(d.type == "interval"){
intervalPaths.insert(statePath); intervalPaths.insert(statePath);
} }
//TODO REPLACE TRUE INTO VAR OF CREATEING DIRS BEFORE OR AFTER INSTALL printMsg(lvlError, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos);
if(true){
printMsg(lvlError, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos); if(IsDirectory(fullstatedir + "/.svn/")){
string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir; string checkoutcommand = svnbin + " checkout file://" + repos + " " + fullstatedir;
executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user executeAndPrintShellCommand(checkoutcommand, "svn"); //TODO checkout as user
} }
else
printMsg(lvlError, format("Statedir %1% already exists, so dont check out its repository again") % fullstatedir);
} }
//Initialize the counters for the statePaths that have an interval to 0 //Initialize the counters for the statePaths that have an interval to 0

View file

@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
extern char * * environ; extern char * * environ;
@ -1071,5 +1072,25 @@ string time_t2string(const time_t & t)
string s = int2String(i); string s = int2String(i);
return s; return s;
} }
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);
}
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);
}
} }

View file

@ -296,6 +296,11 @@ void executeAndPrintShellCommand(const string & command, const string & commandN
//Convert time_t to a string //Convert time_t to a string
string time_t2string(const time_t & t); string time_t2string(const time_t & t);
bool FileExist(const string FileName);
bool IsDirectory(const string FileName);
} }
#endif /* !__UTIL_H */ #endif /* !__UTIL_H */

View file

@ -189,7 +189,7 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
string repos = makeStateReposPath("stateOutput:staterepospath", statePath, thisdir, drvName, stateIdentifier); //this is a copy from store-state.cc string repos = makeStateReposPath("stateOutput:staterepospath", statePath, thisdir, drvName, stateIdentifier); //this is a copy from store-state.cc
// //
checkoutcommands.push_back(svnbin + " checkout file://" + repos + " " + fullstatedir); checkoutcommands.push_back(svnbin + " --ignore-externals checkout file://" + repos + " " + fullstatedir);
subversionedpaths.push_back(fullstatedir); subversionedpaths.push_back(fullstatedir);
if(d.type == "interval"){ if(d.type == "interval"){
@ -260,7 +260,7 @@ void run(Strings args)
store->updateAllStateDerivations(); store->updateAllStateDerivations();
return; return;
/* test */ /* test */
for (Strings::iterator i = args.begin(); i != args.end(); ) { for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++; string arg = *i++;