4343
4444import org .apache .cloudstack .utils .security .KeyStoreUtils ;
4545import org .apache .commons .io .IOUtils ;
46+ import org .apache .commons .lang3 .ArrayUtils ;
4647import org .apache .logging .log4j .LogManager ;
4748import org .apache .logging .log4j .Logger ;
4849import org .joda .time .Duration ;
@@ -236,6 +237,14 @@ static String stackTraceAsString(Throwable throwable) {
236237 }
237238
238239 public String execute (OutputInterpreter interpreter ) {
240+ return execute (interpreter , null );
241+ }
242+
243+ public String execute (OutputInterpreter interpreter , String [] environment ) {
244+ return executeInternal (interpreter , environment );
245+ }
246+
247+ public String executeInternal (OutputInterpreter interpreter , String [] environment ) {
239248 String [] command = _command .toArray (new String [_command .size ()]);
240249 String commandLine = buildCommandLine (command );
241250 if (_logger .isDebugEnabled () && !avoidLoggingCommand ) {
@@ -245,13 +254,23 @@ public String execute(OutputInterpreter interpreter) {
245254 try {
246255 _logger .trace (String .format ("Creating process for command [%s]." , commandLine ));
247256
248- ProcessBuilder pb = new ProcessBuilder (command );
249- pb .redirectErrorStream (true );
250- if (_workDir != null )
251- pb .directory (new File (_workDir ));
257+ if (ArrayUtils .isEmpty (environment )) {
258+ ProcessBuilder pb = new ProcessBuilder (command );
259+ pb .redirectErrorStream (true );
260+ if (_workDir != null )
261+ pb .directory (new File (_workDir ));
262+
263+ _logger .trace (String .format ("Starting process for command [%s]." , commandLine ));
264+ _process = pb .start ();
265+ } else {
266+ // Since Runtime.exec() does not support redirecting the error stream, then append 2>&1 to the command
267+ String [] commands = new String [] {"sh" , "-c" , String .format ("%s 2>&1" , commandLine )};
268+ // The PATH variable must be added for indirect calls within the running command
269+ // Example: virt-v2v invokes qemu-img, which cannot be found if PATH is not set
270+ String [] env = ArrayUtils .add (environment , String .format ("PATH=%s" , System .getenv ("PATH" )));
271+ _process = Runtime .getRuntime ().exec (commands , env , _workDir != null ? new File (_workDir ) : null );
272+ }
252273
253- _logger .trace (String .format ("Starting process for command [%s]." , commandLine ));
254- _process = pb .start ();
255274 if (_process == null ) {
256275 _logger .warn (String .format ("Unable to execute command [%s] because no process was created." , commandLine ));
257276 return "Unable to execute the command: " + command [0 ];
0 commit comments