Hack to get SSH error messages from build-remote
E.g. cannot build on 'ssh://mac1': cannot connect to 'mac1': bash: nix-store: command not found cannot build on 'ssh://mac2': cannot connect to 'mac2': Host key verification failed. cannot build on 'ssh://mac3': cannot connect to 'mac3': Received disconnect from 213... port 6001:2: Too many authentication failures Authentication failed.
This commit is contained in:
		
							parent
							
								
									78d0c72b52
								
							
						
					
					
						commit
						1aca195e52
					
				
					 4 changed files with 33 additions and 7 deletions
				
			
		|  | @ -191,8 +191,10 @@ int main (int argc, char * * argv) | ||||||
|                     storeUri = bestMachine->storeUri; |                     storeUri = bestMachine->storeUri; | ||||||
| 
 | 
 | ||||||
|                 } catch (std::exception & e) { |                 } catch (std::exception & e) { | ||||||
|                     printError("unable to open SSH connection to '%s': %s; trying other available machines...", |                     auto msg = chomp(drainFD(5, false)); | ||||||
|                         bestMachine->storeUri, e.what()); |                     printError("cannot build on '%s': %s%s", | ||||||
|  |                         bestMachine->storeUri, e.what(), | ||||||
|  |                         (msg.empty() ? "" : ": " + msg)); | ||||||
|                     bestMachine->enabled = false; |                     bestMachine->enabled = false; | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  | @ -202,6 +204,8 @@ int main (int argc, char * * argv) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| connected: | connected: | ||||||
|  |         close(5); | ||||||
|  | 
 | ||||||
|         std::cerr << "# accept\n" << storeUri << "\n"; |         std::cerr << "# accept\n" << storeUri << "\n"; | ||||||
| 
 | 
 | ||||||
|         auto inputs = readStrings<PathSet>(source); |         auto inputs = readStrings<PathSet>(source); | ||||||
|  |  | ||||||
|  | @ -652,6 +652,11 @@ HookInstance::HookInstance() | ||||||
|         if (dup2(builderOut.writeSide.get(), 4) == -1) |         if (dup2(builderOut.writeSide.get(), 4) == -1) | ||||||
|             throw SysError("dupping builder's stdout/stderr"); |             throw SysError("dupping builder's stdout/stderr"); | ||||||
| 
 | 
 | ||||||
|  |         /* Hack: pass the read side of that fd to allow build-remote
 | ||||||
|  |            to read SSH error messages. */ | ||||||
|  |         if (dup2(builderOut.readSide.get(), 5) == -1) | ||||||
|  |             throw SysError("dupping builder's stdout/stderr"); | ||||||
|  | 
 | ||||||
|         Strings args = { |         Strings args = { | ||||||
|             baseNameOf(settings.buildHook), |             baseNameOf(settings.buildHook), | ||||||
|             std::to_string(verbosity), |             std::to_string(verbosity), | ||||||
|  |  | ||||||
|  | @ -567,21 +567,38 @@ void writeFull(int fd, const string & s, bool allowInterrupts) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string drainFD(int fd) | string drainFD(int fd, bool block) | ||||||
| { | { | ||||||
|     StringSink sink; |     StringSink sink; | ||||||
|     drainFD(fd, sink); |     drainFD(fd, sink, block); | ||||||
|     return std::move(*sink.s); |     return std::move(*sink.s); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void drainFD(int fd, Sink & sink) | void drainFD(int fd, Sink & sink, bool block) | ||||||
| { | { | ||||||
|  |     int saved; | ||||||
|  | 
 | ||||||
|  |     Finally finally([&]() { | ||||||
|  |         if (!block) { | ||||||
|  |             if (fcntl(fd, F_SETFL, saved) == -1) | ||||||
|  |                 throw SysError("making file descriptor blocking"); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     if (!block) { | ||||||
|  |         saved = fcntl(fd, F_GETFL); | ||||||
|  |         if (fcntl(fd, F_SETFL, saved | O_NONBLOCK) == -1) | ||||||
|  |             throw SysError("making file descriptor non-blocking"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::vector<unsigned char> buf(4096); |     std::vector<unsigned char> buf(4096); | ||||||
|     while (1) { |     while (1) { | ||||||
|         checkInterrupt(); |         checkInterrupt(); | ||||||
|         ssize_t rd = read(fd, buf.data(), buf.size()); |         ssize_t rd = read(fd, buf.data(), buf.size()); | ||||||
|         if (rd == -1) { |         if (rd == -1) { | ||||||
|  |             if (!block && (errno == EAGAIN || errno == EWOULDBLOCK)) | ||||||
|  |                 break; | ||||||
|             if (errno != EINTR) |             if (errno != EINTR) | ||||||
|                 throw SysError("reading from file"); |                 throw SysError("reading from file"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -151,9 +151,9 @@ MakeError(EndOfFile, Error) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Read a file descriptor until EOF occurs. */ | /* Read a file descriptor until EOF occurs. */ | ||||||
| string drainFD(int fd); | string drainFD(int fd, bool block = true); | ||||||
| 
 | 
 | ||||||
| void drainFD(int fd, Sink & sink); | void drainFD(int fd, Sink & sink, bool block = true); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Automatic cleanup of resources. */ | /* Automatic cleanup of resources. */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue