* 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
 | /* Initialize and reorder arguments, then call the actual argument
 | ||||||
|    processor. */ |    processor. */ | ||||||
| static void initAndRun(int argc, char * * argv) | 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
 |     /* Obtain locks on all output paths.  The locks are automatically
 | ||||||
|        released when we exit this function or Nix crashes. */ |        released when we exit this function or Nix crashes. */ | ||||||
|  |     /* !!! BUG: this could block, which is not allowed. */ | ||||||
|     goal.outputLocks.lockPaths(goal.expr.derivation.outputs); |     goal.outputLocks.lockPaths(goal.expr.derivation.outputs); | ||||||
| 
 | 
 | ||||||
|     /* Now check again whether there is a successor.  This is because
 |     /* Now check again whether there is a successor.  This is because
 | ||||||
|  | @ -364,6 +365,25 @@ bool Normaliser::startBuild(Path nePath) | ||||||
|         return true; |         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. */ |     /* Otherwise, start the build in a child process. */ | ||||||
|     startBuildChild(goal); |     startBuildChild(goal); | ||||||
| 
 | 
 | ||||||
|  | @ -660,7 +680,7 @@ void Normaliser::finishGoal(Goal & goal) | ||||||
|     { |     { | ||||||
|         Path path = *i; |         Path path = *i; | ||||||
|         if (!pathExists(path)) |         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); |         nf.closure.roots.insert(path); | ||||||
| 
 | 
 | ||||||
| 	makePathReadOnly(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) | Path absPath(Path path, Path dir) | ||||||
| { | { | ||||||
|     if (path[0] != '/') { |     if (path[0] != '/') { | ||||||
|  | @ -206,8 +213,7 @@ void makePathReadOnly(const Path & path) | ||||||
| static Path tempName() | static Path tempName() | ||||||
| { | { | ||||||
|     static int counter = 0; |     static int counter = 0; | ||||||
|     char * s = getenv("TMPDIR"); |     Path tmpRoot = canonPath(getEnv("TMPDIR", "/tmp")); | ||||||
|     Path tmpRoot = s ? canonPath(Path(s)) : "/tmp"; |  | ||||||
|     return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str(); |     return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -55,6 +55,9 @@ typedef set<Path> PathSet; | ||||||
| extern string thisSystem; | extern string thisSystem; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /* Return an environment variable. */ | ||||||
|  | string getEnv(const string & key, const string & def = ""); | ||||||
|  | 
 | ||||||
| /* Return an absolutized path, resolving paths relative to the
 | /* Return an absolutized path, resolving paths relative to the
 | ||||||
|    specified directory, or the current directory otherwise.  The path |    specified directory, or the current directory otherwise.  The path | ||||||
|    is also canonicalised. */ |    is also canonicalised. */ | ||||||
|  |  | ||||||
|  | @ -118,7 +118,7 @@ void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs) | ||||||
| 
 | 
 | ||||||
| static Path getHomeDir() | static Path getHomeDir() | ||||||
| { | { | ||||||
|     Path homeDir(getenv("HOME")); |     Path homeDir(getEnv("HOME", "")); | ||||||
|     if (homeDir == "") throw Error("HOME environment variable not set"); |     if (homeDir == "") throw Error("HOME environment variable not set"); | ||||||
|     return homeDir; |     return homeDir; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,8 +16,10 @@ simple.sh: simple.nix | ||||||
| dependencies.sh: dependencies.nix | dependencies.sh: dependencies.nix | ||||||
| locking.sh: locking.nix | locking.sh: locking.nix | ||||||
| parallel.sh: parallel.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 = | XFAIL_TESTS = | ||||||
| 
 | 
 | ||||||
|  | @ -27,4 +29,5 @@ EXTRA_DIST = $(TESTS) \ | ||||||
|   simple.nix.in simple.builder.sh \ |   simple.nix.in simple.builder.sh \ | ||||||
|   dependencies.nix.in dependencies.builder*.sh \ |   dependencies.nix.in dependencies.builder*.sh \ | ||||||
|   locking.nix.in locking.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