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:
parent
fd2b8271e4
commit
267ccc589d
8 changed files with 135 additions and 66 deletions
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
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"
|
||||
exit 1;
|
||||
fi
|
||||
|
|
@ -22,11 +22,12 @@ nonversionedpaths=( $4 )
|
|||
checkouts=( $5 )
|
||||
deletesvn=$6 #this flag can be set to 1 to DELETE all .svn folders and NOT commit
|
||||
|
||||
#echo svnbin: $svnbin
|
||||
#echo subversionedpaths: ${subversionedpaths[@]}
|
||||
#echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]}
|
||||
#echo nonversionedpaths: ${nonversionedpaths[@]}
|
||||
#echo checkouts: ${checkouts[@]}
|
||||
echo svnbin: $svnbin
|
||||
echo subversionedpaths: ${subversionedpaths[@]}
|
||||
echo subversionedpathsCommitBools: ${subversionedpathsCommitBools[@]}
|
||||
echo nonversionedpaths: ${nonversionedpaths[@]}
|
||||
echo checkouts: ${checkouts[@]}
|
||||
echo deletesvn: $deletesvn
|
||||
|
||||
#
|
||||
#
|
||||
|
|
@ -125,23 +126,23 @@ function subversionSingleStateDir {
|
|||
#
|
||||
|
||||
i=0
|
||||
i_checkout=0
|
||||
for path in ${subversionedpaths[@]}
|
||||
do
|
||||
if test -d $path; then #if the dir doesnt exist, than we dont hav to do anything
|
||||
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
|
||||
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
|
||||
checkoutcommand="";
|
||||
while true; do
|
||||
if [ "${checkouts[$i]}" = "|" ]; then
|
||||
break
|
||||
let "i+=1"
|
||||
fi
|
||||
checkoutcommand="${checkoutcommand} ${checkouts[$i]}";
|
||||
let "i+=1"
|
||||
done
|
||||
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
|
||||
while true; do
|
||||
if [ "${checkouts[$i_checkout]}" = "|" ]; then
|
||||
let "i_checkout+=1"
|
||||
break
|
||||
fi
|
||||
checkoutcommand="${checkoutcommand} ${checkouts[$i_checkout]}";
|
||||
let "i_checkout+=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
|
||||
$debug $checkoutcommand;
|
||||
fi
|
||||
|
|
@ -157,9 +158,10 @@ do
|
|||
if [ "$deletesvn" != "1" ]; then
|
||||
$debug svn -m "" commit;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
cd - &> /dev/null;
|
||||
let "i+=1"
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
/* 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) {
|
||||
DerivationOutputs::const_iterator i = drv.outputs.begin();
|
||||
|
||||
if (i->first == "out" &&
|
||||
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:"
|
||||
+ 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){
|
||||
drv.env["statepath"] = "";
|
||||
drv.stateOutputs.clear();
|
||||
drv.stateOutputDirs.clear();
|
||||
|
||||
/* We do NOT clear the state identifier (what about the username ????) when there are NO
|
||||
* runtime arguments, since this will affect the statePath and therefore the outPath
|
||||
*/
|
||||
//TODO
|
||||
}
|
||||
if(drv.stateOutputs.size() != 1)
|
||||
throw EvalError(format("There are more then one stateOutputs in the derviation....."));
|
||||
|
||||
DerivationStateOutput drvso = drv.stateOutputs["state"];
|
||||
|
||||
if(drvso.runtimeStateParamters != ""){ //Has runtime parameters --> Clear all state parameters
|
||||
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
|
||||
calls to this function.*/
|
||||
|
|
@ -360,9 +374,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
|
|||
inputs2[printHash(h)] = i->second;
|
||||
}
|
||||
drv.inputDrvs = inputs2;
|
||||
|
||||
//printMsg(lvlError, format("%1%") % unparseDerivation(drv));
|
||||
|
||||
//printMsg(lvlError, format("%1% with %2% --> %3%") % drv.env.find("name")->second % printHash(hashTerm(unparseDerivation(drv))) % unparseDerivation(drv));
|
||||
return hashTerm(unparseDerivation(drv));
|
||||
}
|
||||
|
||||
|
|
@ -584,9 +596,24 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
|||
drv.env["out"] = "";
|
||||
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
|
||||
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. */
|
||||
drv.env["out"] = outPath;
|
||||
|
|
|
|||
|
|
@ -49,15 +49,19 @@ struct DerivationStateOutput
|
|||
|
||||
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)
|
||||
|
||||
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")
|
||||
throw Error(format("shared '%1%' is not a correct type") % shared);
|
||||
if(synchronization != "none" && synchronization != "exclusive-lock" && synchronization != "recursive-exclusive-lock")
|
||||
throw Error(format("synchronization '%1%' is not a correct type") % synchronization);
|
||||
if(check){
|
||||
if(shared != "none" && shared != "full" && shared != "group")
|
||||
throw Error(format("shared '%1%' is not a correct type") % shared);
|
||||
if(synchronization != "none" && synchronization != "exclusive-lock" && synchronization != "recursive-exclusive-lock")
|
||||
throw Error(format("synchronization '%1%' is not a correct type") % synchronization);
|
||||
}
|
||||
|
||||
//TODO
|
||||
//commitReferences
|
||||
|
|
@ -81,6 +85,21 @@ struct DerivationStateOutput
|
|||
bool getCreateDirsBeforeInstall(){
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1282,7 +1282,7 @@ void updateAllStateDerivations()
|
|||
for (Strings::iterator i = unique_paths.begin(); i != unique_paths.end(); ++i)
|
||||
{
|
||||
string path = *i;
|
||||
printMsg(lvlError, format("Unique: %1%") % path);
|
||||
//printMsg(lvlError, format("Unique: %1%") % path);
|
||||
store->updateStateDerivation(txn, path); //TODO replace store->
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,21 +18,14 @@ namespace nix {
|
|||
|
||||
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"));
|
||||
|
||||
//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)
|
||||
|
|
@ -47,7 +40,7 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
|
||||
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){
|
||||
DerivationStateOutputDir d = i->second;
|
||||
|
|
@ -56,31 +49,33 @@ void createStateDirs(const DerivationStateOutputDirs & stateOutputDirs, const De
|
|||
string fullstatedir = stateDir + "/" + thisdir;
|
||||
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
|
||||
if(d.type == "none"){
|
||||
if(true){
|
||||
executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir");
|
||||
}
|
||||
executeAndPrintShellCommand("mkdir -p " + fullstatedir, "mkdir");
|
||||
continue;
|
||||
}
|
||||
|
||||
//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 ??
|
||||
// //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"){
|
||||
intervalPaths.insert(statePath);
|
||||
}
|
||||
|
||||
//TODO REPLACE TRUE INTO VAR OF CREATEING DIRS BEFORE OR AFTER INSTALL
|
||||
if(true){
|
||||
printMsg(lvlError, format("Adding state subdir: %1% to %2% from repository %3%") % thisdir % fullstatedir % repos);
|
||||
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;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
extern char * * environ;
|
||||
|
||||
|
||||
|
|
@ -1072,4 +1073,24 @@ string time_t2string(const time_t & t)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,11 @@ void executeAndPrintShellCommand(const string & command, const string & commandN
|
|||
//Convert time_t to a string
|
||||
string time_t2string(const time_t & t);
|
||||
|
||||
bool FileExist(const string FileName);
|
||||
|
||||
bool IsDirectory(const string FileName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* !__UTIL_H */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
//
|
||||
checkoutcommands.push_back(svnbin + " checkout file://" + repos + " " + fullstatedir);
|
||||
checkoutcommands.push_back(svnbin + " --ignore-externals checkout file://" + repos + " " + fullstatedir);
|
||||
subversionedpaths.push_back(fullstatedir);
|
||||
|
||||
if(d.type == "interval"){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue