* Build hooks: use nix-store --import. This prevents a redundant
scan for runtime dependencies (i.e. the local machine shouldn't do a scan that the remote machine has already done). Also pipe directly into `nix-store --import': don't use a temporary file.
This commit is contained in:
		
							parent
							
								
									6f8c96d123
								
							
						
					
					
						commit
						b682fae9d9
					
				
					 3 changed files with 29 additions and 22 deletions
				
			
		|  | @ -192,7 +192,7 @@ my $buildFlags = "--max-silent-time $maxSilentTime"; | ||||||
| # connection dies.  Without it, the remote process might continue to | # connection dies.  Without it, the remote process might continue to | ||||||
| # run indefinitely (that is, until it next tries to write to | # run indefinitely (that is, until it next tries to write to | ||||||
| # stdout/stderr). | # stdout/stderr). | ||||||
| if (system("ssh -tt $sshOpts $hostName 'nix-store -rvvK $buildFlags $drvPath'") != 0) { | if (system("ssh -tt $sshOpts $hostName 'nix-store --realise -K $buildFlags $drvPath > /dev/null'") != 0) { | ||||||
|     # If we couldn't run ssh or there was an ssh problem (indicated by |     # If we couldn't run ssh or there was an ssh problem (indicated by | ||||||
|     # exit code 255), then we return exit code 1; otherwise we assume |     # exit code 255), then we return exit code 1; otherwise we assume | ||||||
|     # that the builder failed, which we indicated to Nix using exit |     # that the builder failed, which we indicated to Nix using exit | ||||||
|  | @ -209,17 +209,6 @@ foreach my $output (split '\n', $outputs) { | ||||||
|     my $maybeSignRemote = ""; |     my $maybeSignRemote = ""; | ||||||
|     $maybeSignRemote = "--sign" if $UID != 0; |     $maybeSignRemote = "--sign" if $UID != 0; | ||||||
|      |      | ||||||
|     system("ssh $sshOpts $hostName 'nix-store --export $maybeSignRemote $output' > dump") == 0 |     system("ssh $sshOpts $hostName 'nix-store --export $maybeSignRemote $output' | @bindir@/nix-store --import > /dev/null") == 0 | ||||||
| 	or die "cannot copy $output from $hostName: $?"; | 	or die "cannot copy $output from $hostName: $?"; | ||||||
| 
 |  | ||||||
|     # This doesn't work yet, since the caller has a lock on the output |  | ||||||
|     # path.  We should move towards lock-free invocation of build |  | ||||||
|     # hooks and substitutes. |  | ||||||
|     #system("nix-store --import < dump") == 0 |  | ||||||
|     #    or die "cannot import $output: $?"; |  | ||||||
| 
 |  | ||||||
|     # Hack: skip the first 8 bytes (the nix-store --export next |  | ||||||
|     # archive marker).  The archive follows. |  | ||||||
|     system("(dd bs=1 count=8 of=/dev/null && cat) < dump | nix-store --restore $output") == 0 |  | ||||||
| 	or die "cannot restore $output: $?"; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1240,6 +1240,12 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook() | ||||||
| 
 | 
 | ||||||
|             initChild(); |             initChild(); | ||||||
| 
 | 
 | ||||||
|  |             string s; | ||||||
|  |             foreach (DerivationOutputs::const_iterator, i, drv.outputs) | ||||||
|  |                 s += i->second.path + " "; | ||||||
|  |             if (setenv("NIX_HELD_LOCKS", s.c_str(), 1)) | ||||||
|  |                 throw SysError("setting an environment variable"); | ||||||
|  | 
 | ||||||
|             execl(buildHook.c_str(), buildHook.c_str(), |             execl(buildHook.c_str(), buildHook.c_str(), | ||||||
|                 (worker.canBuildMore() ? (string) "1" : "0").c_str(), |                 (worker.canBuildMore() ? (string) "1" : "0").c_str(), | ||||||
|                 thisSystem.c_str(), |                 thisSystem.c_str(), | ||||||
|  | @ -1946,12 +1952,20 @@ void DerivationGoal::computeClosure() | ||||||
|     map<Path, PathSet> allReferences; |     map<Path, PathSet> allReferences; | ||||||
|     map<Path, Hash> contentHashes; |     map<Path, Hash> contentHashes; | ||||||
| 
 | 
 | ||||||
|  |     /* When using a build hook, the build hook can register the output
 | ||||||
|  |        as valid (by doing `nix-store --import').  If so we don't have | ||||||
|  |        to do anything here. */ | ||||||
|  |     if (usingBuildHook) { | ||||||
|  |         bool allValid = true; | ||||||
|  |         foreach (DerivationOutputs::iterator, i, drv.outputs) | ||||||
|  |             if (!worker.store.isValidPath(i->second.path)) allValid = false; | ||||||
|  |         if (allValid) return; | ||||||
|  |     } | ||||||
|  |          | ||||||
|     /* Check whether the output paths were created, and grep each
 |     /* Check whether the output paths were created, and grep each
 | ||||||
|        output path to determine what other paths it references.  Also make all |        output path to determine what other paths it references.  Also make all | ||||||
|        output paths read-only. */ |        output paths read-only. */ | ||||||
|     for (DerivationOutputs::iterator i = drv.outputs.begin();  |     foreach (DerivationOutputs::iterator, i, drv.outputs) { | ||||||
|          i != drv.outputs.end(); ++i) |  | ||||||
|     { |  | ||||||
|         Path path = i->second.path; |         Path path = i->second.path; | ||||||
|         if (!pathExists(path)) { |         if (!pathExists(path)) { | ||||||
|             throw BuildError( |             throw BuildError( | ||||||
|  | @ -2043,14 +2057,11 @@ void DerivationGoal::computeClosure() | ||||||
|        paths referenced by each of them.  !!! this should be |        paths referenced by each of them.  !!! this should be | ||||||
|        atomic so that either all paths are registered as valid, or |        atomic so that either all paths are registered as valid, or | ||||||
|        none are. */ |        none are. */ | ||||||
|     for (DerivationOutputs::iterator i = drv.outputs.begin();  |     foreach (DerivationOutputs::iterator, i, drv.outputs) | ||||||
|          i != drv.outputs.end(); ++i) |  | ||||||
|     { |  | ||||||
|         worker.store.registerValidPath(i->second.path, |         worker.store.registerValidPath(i->second.path, | ||||||
|             contentHashes[i->second.path], |             contentHashes[i->second.path], | ||||||
|             allReferences[i->second.path], |             allReferences[i->second.path], | ||||||
|             drvPath); |             drvPath); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /* It is now safe to delete the lock files, since all future
 |     /* It is now safe to delete the lock files, since all future
 | ||||||
|        lockers will see that the output paths are valid; they will not |        lockers will see that the output paths are valid; they will not | ||||||
|  |  | ||||||
|  | @ -924,7 +924,14 @@ Path LocalStore::importPath(bool requireSignature, Source & source) | ||||||
| 
 | 
 | ||||||
|     if (!isValidPath(dstPath)) { |     if (!isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|         PathLocks outputLock(singleton<PathSet, Path>(dstPath)); |         PathLocks outputLock; | ||||||
|  | 
 | ||||||
|  |         /* Lock the output path.  But don't lock if we're being called
 | ||||||
|  |            from a build hook (whose parent process already acquired a | ||||||
|  |            lock on this path). */ | ||||||
|  |         Strings locksHeld = tokenizeString(getEnv("NIX_HELD_LOCKS")); | ||||||
|  |         if (find(locksHeld.begin(), locksHeld.end(), dstPath) == locksHeld.end()) | ||||||
|  |             outputLock.lockPaths(singleton<PathSet, Path>(dstPath)); | ||||||
| 
 | 
 | ||||||
|         if (!isValidPath(dstPath)) { |         if (!isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue