* An quick and dirty hack to support distributed builds.
This commit is contained in:
		
							parent
							
								
									c8d3882cdc
								
							
						
					
					
						commit
						8c0b42f857
					
				
					 9 changed files with 92 additions and 13 deletions
				
			
		|  | @ -52,13 +52,6 @@ void checkStoreNotSymlink(Path path) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static string getEnv(const string & key, const string & def = "") | ||||
| { | ||||
|     char * value = getenv(key.c_str()); | ||||
|     return value ? string(value) : def; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Initialize and reorder arguments, then call the actual argument
 | ||||
|    processor. */ | ||||
| static void initAndRun(int argc, char * * argv) | ||||
|  |  | |||
|  | @ -302,6 +302,7 @@ bool Normaliser::startBuild(Path nePath) | |||
| 
 | ||||
|     /* Obtain locks on all output paths.  The locks are automatically
 | ||||
|        released when we exit this function or Nix crashes. */ | ||||
|     /* !!! BUG: this could block, which is not allowed. */ | ||||
|     goal.outputLocks.lockPaths(goal.expr.derivation.outputs); | ||||
| 
 | ||||
|     /* Now check again whether there is a successor.  This is because
 | ||||
|  | @ -364,6 +365,25 @@ bool Normaliser::startBuild(Path nePath) | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /* !!! Hack */ | ||||
|     Path buildHook = getEnv("NIX_BUILD_HOOK"); | ||||
|     if (buildHook != "") { | ||||
|         printMsg(lvlChatty, format("using build hook `%1%'") % buildHook); | ||||
|         int status = system((buildHook + " " + goal.nePath + " 1>&2").c_str()); | ||||
|         if (WIFEXITED(status)) { | ||||
|             int code = WEXITSTATUS(status); | ||||
|             if (code == 100) { /* == accepted */ | ||||
|                 printMsg(lvlChatty, | ||||
|                     format("build hook succesfully realised output paths")); | ||||
|                 finishGoal(goal); | ||||
|                 return true; | ||||
|             } else if (code != 101) /* != declined */ | ||||
|                 throw Error( | ||||
|                     format("build hook returned exit code %1%") % code); | ||||
|         } else throw Error( | ||||
|             format("build hook died with status %1%") % status); | ||||
|     } | ||||
| 
 | ||||
|     /* Otherwise, start the build in a child process. */ | ||||
|     startBuildChild(goal); | ||||
| 
 | ||||
|  | @ -660,7 +680,7 @@ void Normaliser::finishGoal(Goal & goal) | |||
|     { | ||||
|         Path path = *i; | ||||
|         if (!pathExists(path)) | ||||
|             throw Error(format("path `%1%' does not exist") % path); | ||||
|             throw Error(format("output path `%1%' does not exist") % path); | ||||
|         nf.closure.roots.insert(path); | ||||
| 
 | ||||
| 	makePathReadOnly(path); | ||||
|  |  | |||
|  | @ -29,6 +29,13 @@ SysError::SysError(const format & f) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| string getEnv(const string & key, const string & def) | ||||
| { | ||||
|     char * value = getenv(key.c_str()); | ||||
|     return value ? string(value) : def; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Path absPath(Path path, Path dir) | ||||
| { | ||||
|     if (path[0] != '/') { | ||||
|  | @ -206,8 +213,7 @@ void makePathReadOnly(const Path & path) | |||
| static Path tempName() | ||||
| { | ||||
|     static int counter = 0; | ||||
|     char * s = getenv("TMPDIR"); | ||||
|     Path tmpRoot = s ? canonPath(Path(s)) : "/tmp"; | ||||
|     Path tmpRoot = canonPath(getEnv("TMPDIR", "/tmp")); | ||||
|     return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -55,6 +55,9 @@ typedef set<Path> PathSet; | |||
| extern string thisSystem; | ||||
| 
 | ||||
| 
 | ||||
| /* Return an environment variable. */ | ||||
| string getEnv(const string & key, const string & def = ""); | ||||
| 
 | ||||
| /* Return an absolutized path, resolving paths relative to the
 | ||||
|    specified directory, or the current directory otherwise.  The path | ||||
|    is also canonicalised. */ | ||||
|  |  | |||
|  | @ -118,7 +118,7 @@ void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs) | |||
| 
 | ||||
| static Path getHomeDir() | ||||
| { | ||||
|     Path homeDir(getenv("HOME")); | ||||
|     Path homeDir(getEnv("HOME", "")); | ||||
|     if (homeDir == "") throw Error("HOME environment variable not set"); | ||||
|     return homeDir; | ||||
| } | ||||
|  |  | |||
|  | @ -16,8 +16,10 @@ simple.sh: simple.nix | |||
| dependencies.sh: dependencies.nix | ||||
| locking.sh: locking.nix | ||||
| parallel.sh: parallel.nix | ||||
| build-hook.sh: build-hook.nix | ||||
| 
 | ||||
| TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh | ||||
| TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh \ | ||||
|   build-hook.sh | ||||
| 
 | ||||
| XFAIL_TESTS = | ||||
| 
 | ||||
|  | @ -27,4 +29,5 @@ EXTRA_DIST = $(TESTS) \ | |||
|   simple.nix.in simple.builder.sh \ | ||||
|   dependencies.nix.in dependencies.builder*.sh \ | ||||
|   locking.nix.in locking.builder.sh \ | ||||
|   parallel.nix.in parallel.builder.sh | ||||
|   parallel.nix.in parallel.builder.sh \ | ||||
|   build-hook.nix.in | ||||
|  |  | |||
							
								
								
									
										17
									
								
								tests/build-hook.hook.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/build-hook.hook.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| set -x | ||||
| 
 | ||||
| drv=$1 | ||||
| 
 | ||||
| echo "HOOK for $drv" | ||||
| 
 | ||||
| outPath=$(sed 's/Derive(\[\"\([^\"]*\)\".*/\1/' $drv) | ||||
| 
 | ||||
| echo "output path is $outPath" | ||||
| 
 | ||||
| if $(echo $outPath | grep -q input-1); then | ||||
|     mkdir $outPath | ||||
|     echo "BAR" > $outPath/foo | ||||
|     exit 100 | ||||
| fi | ||||
| 
 | ||||
| exit 101 | ||||
							
								
								
									
										25
									
								
								tests/build-hook.nix.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tests/build-hook.nix.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| let { | ||||
| 
 | ||||
|   input1 = derivation { | ||||
|     name = "dependencies-input-1"; | ||||
|     system = "@system@"; | ||||
|     builder = "@shell@"; | ||||
|     args = ["-e" "-x" ./dependencies.builder1.sh]; | ||||
|   }; | ||||
| 
 | ||||
|   input2 = derivation { | ||||
|     name = "dependencies-input-2"; | ||||
|     system = "@system@"; | ||||
|     builder = "@shell@"; | ||||
|     args = ["-e" "-x" ./dependencies.builder2.sh]; | ||||
|   }; | ||||
| 
 | ||||
|   body = derivation { | ||||
|     name = "dependencies"; | ||||
|     system = "@system@"; | ||||
|     builder = "@shell@"; | ||||
|     args = ["-e" "-x" ./dependencies.builder0.sh]; | ||||
|     inherit input1 input2; | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										12
									
								
								tests/build-hook.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/build-hook.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| export NIX_BUILD_HOOK="sh build-hook.hook.sh" | ||||
| 
 | ||||
| storeExpr=$($TOP/src/nix-instantiate/nix-instantiate build-hook.nix) | ||||
| 
 | ||||
| echo "store expr is $storeExpr" | ||||
| 
 | ||||
| outPath=$($TOP/src/nix-store/nix-store -qnfvvvvv "$storeExpr") | ||||
| 
 | ||||
| echo "output path is $outPath" | ||||
| 
 | ||||
| text=$(cat "$outPath"/foobar) | ||||
| if test "$text" != "BARBAR"; then exit 1; fi | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue