forked from ungleich-public/cdist
		
	Merge pull request #439 from darko-poljak/better-remote-err-reporting
Improve error reporting for remote exec.
This commit is contained in:
		
				commit
				
					
						b37b31e234
					
				
			
		
					 5 changed files with 58 additions and 12 deletions
				
			
		|  | @ -41,8 +41,8 @@ BANNER = """ | ||||||
|    "P'        ""         "" |    "P'        ""         "" | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| REMOTE_COPY = "scp -o User=root -q" | REMOTE_COPY = "scp -o User=root" | ||||||
| REMOTE_EXEC = "ssh -o User=root -q" | REMOTE_EXEC = "ssh -o User=root" | ||||||
| 
 | 
 | ||||||
| class Error(Exception): | class Error(Exception): | ||||||
|     """Base exception class for this project""" |     """Base exception class for this project""" | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ import tempfile | ||||||
| import cdist | import cdist | ||||||
| import cdist.message | import cdist.message | ||||||
| from cdist import core | from cdist import core | ||||||
|  | import cdist.exec.util as exec_util | ||||||
| 
 | 
 | ||||||
| class Local(object): | class Local(object): | ||||||
|     """Execute commands locally. |     """Execute commands locally. | ||||||
|  | @ -203,12 +204,14 @@ class Local(object): | ||||||
|             env.update(message.env) |             env.update(message.env) | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|  |             output = exec_util.call_get_output(command, env=env) | ||||||
|  |             self.log.debug("Local output: {}".format(output)) | ||||||
|             if return_output: |             if return_output: | ||||||
|                 return subprocess.check_output(command, env=env).decode() |                 return output.decode() | ||||||
|             else: |         except subprocess.CalledProcessError as e: | ||||||
|                 subprocess.check_call(command, env=env) |             raise cdist.Error("Command failed: " + " ".join(command) | ||||||
|         except subprocess.CalledProcessError: |                     + " with returncode: {} and output: {}".format( | ||||||
|             raise cdist.Error("Command failed: " + " ".join(command)) |                         e.returncode, e.output)) | ||||||
|         except OSError as error: |         except OSError as error: | ||||||
|             raise cdist.Error(" ".join(command) + ": " + error.args[1]) |             raise cdist.Error(" ".join(command) + ": " + error.args[1]) | ||||||
|         finally: |         finally: | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import sys | ||||||
| import glob | import glob | ||||||
| import subprocess | import subprocess | ||||||
| import logging | import logging | ||||||
|  | import cdist.exec.util as exec_util | ||||||
| 
 | 
 | ||||||
| import cdist | import cdist | ||||||
| 
 | 
 | ||||||
|  | @ -167,12 +168,14 @@ class Remote(object): | ||||||
| 
 | 
 | ||||||
|         self.log.debug("Remote run: %s", command) |         self.log.debug("Remote run: %s", command) | ||||||
|         try: |         try: | ||||||
|  |             output = exec_util.call_get_output(command, env=os_environ) | ||||||
|  |             self.log.debug("Remote output: {}".format(output)) | ||||||
|             if return_output: |             if return_output: | ||||||
|                 return subprocess.check_output(command, env=os_environ).decode() |                 return output.decode() | ||||||
|             else: |         except subprocess.CalledProcessError as e: | ||||||
|                 subprocess.check_call(command, env=os_environ) |             raise cdist.Error("Command failed: " + " ".join(command) | ||||||
|         except subprocess.CalledProcessError: |                     + " with returncode: {} and output: {}".format( | ||||||
|             raise cdist.Error("Command failed: " + " ".join(command)) |                         e.returncode, e.output)) | ||||||
|         except OSError as error: |         except OSError as error: | ||||||
|             raise cdist.Error(" ".join(command) + ": " + error.args[1]) |             raise cdist.Error(" ".join(command) + ": " + error.args[1]) | ||||||
|         except UnicodeDecodeError: |         except UnicodeDecodeError: | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								cdist/exec/util.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								cdist/exec/util.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | # | ||||||
|  | # 2016 Darko Poljak (darko.poljak at gmail.com) | ||||||
|  | # | ||||||
|  | # This file is part of cdist. | ||||||
|  | # | ||||||
|  | # cdist is free software: you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation, either version 3 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # cdist is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with cdist. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | import subprocess | ||||||
|  | from tempfile import TemporaryFile | ||||||
|  | 
 | ||||||
|  | import cdist | ||||||
|  | 
 | ||||||
|  | def call_get_output(command, env=None): | ||||||
|  |     """Run the given command with the given environment. | ||||||
|  |     Return the stdout and stderr output as a byte string. | ||||||
|  |     """ | ||||||
|  |     assert isinstance(command, (list, tuple)), "list or tuple argument expected, got: {}".format(command) | ||||||
|  | 
 | ||||||
|  |     with TemporaryFile() as fout: | ||||||
|  |         subprocess.check_call(command, env=env, | ||||||
|  |                 stdout=fout, stderr=subprocess.STDOUT) | ||||||
|  |         fout.seek(0) | ||||||
|  |         output = fout.read() | ||||||
|  | 
 | ||||||
|  |     return output | ||||||
|  | @ -2,6 +2,7 @@ Changelog | ||||||
| --------- | --------- | ||||||
| 
 | 
 | ||||||
| next: | next: | ||||||
|  | 	* Core: Improve error reporting for local and remote run command (Darko Poljak) | ||||||
| 	* New type: __jail_freebsd9: Handle jail management on FreeBSD <= 9.X (Jake Guffey) | 	* New type: __jail_freebsd9: Handle jail management on FreeBSD <= 9.X (Jake Guffey) | ||||||
| 	* New type: __jail_freebsd10: Handle jail management on FreeBSD >= 10.0 (Jake Guffey) | 	* New type: __jail_freebsd10: Handle jail management on FreeBSD >= 10.0 (Jake Guffey) | ||||||
| 	* Type __jail: Dynamically select the correct jail subtype based on target host OS (Jake Guffey) | 	* Type __jail: Dynamically select the correct jail subtype based on target host OS (Jake Guffey) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue