@@ -345,7 +345,7 @@ private boolean checkTaskStatus(final HttpResponse response) throws IOException
345345 String type = pair .second ();
346346 String path = url .replace (apiURI .toString (), "" );
347347 if (type .equals ("RestoreSession" )) {
348- return checkIfRestoreSessionFinished (type , path );
348+ checkIfRestoreSessionFinished (type , path );
349349 }
350350 }
351351 return true ;
@@ -361,17 +361,29 @@ private boolean checkTaskStatus(final HttpResponse response) throws IOException
361361 return false ;
362362 }
363363
364- protected boolean checkIfRestoreSessionFinished (String type , String path ) throws IOException {
365- for (int j = 0 ; j < this .restoreTimeout ; j ++) {
364+
365+ /**
366+ * Checks the status of the restore session. Checked states are "Success" and "Failure".<br/>
367+ * There is also a timeout defined in the global configuration, backup.plugin.veeam.restore.timeout,<br/>
368+ * that is used to wait for the restore to complete before throwing a {@link CloudRuntimeException}.
369+ */
370+ protected void checkIfRestoreSessionFinished (String type , String path ) throws IOException {
371+ for (int j = 0 ; j < restoreTimeout ; j ++) {
366372 HttpResponse relatedResponse = get (path );
367373 RestoreSession session = parseRestoreSessionResponse (relatedResponse );
368374 if (session .getResult ().equals ("Success" )) {
369- return true ;
375+ return ;
370376 }
377+
371378 if (session .getResult ().equalsIgnoreCase ("Failed" )) {
372379 String sessionUid = session .getUid ();
380+ LOG .error (String .format ("Failed to restore backup [%s] of VM [%s] due to [%s]." ,
381+ sessionUid , session .getVmDisplayName (),
382+ getRestoreVmErrorDescription (StringUtils .substringAfterLast (sessionUid , ":" ))));
373383 throw new CloudRuntimeException (String .format ("Restore job [%s] failed." , sessionUid ));
374384 }
385+ LOG .debug (String .format ("Waiting %s seconds, out of a total of %s seconds, for the restore backup process to finish." , j , restoreTimeout ));
386+
375387 try {
376388 Thread .sleep (1000 );
377389 } catch (InterruptedException ignored ) {
@@ -930,6 +942,29 @@ public Pair<Boolean, String> restoreVMToDifferentLocation(String restorePointId,
930942 return new Pair <>(result .first (), restoreLocation );
931943 }
932944
945+ /**
946+ * Tries to retrieve the error's description of the Veeam restore task that resulted in an error.
947+ * @param uid Session uid in Veeam of the restore process;
948+ * @return the description found in Veeam about the cause of error in the restore process.
949+ */
950+ protected String getRestoreVmErrorDescription (String uid ) {
951+ LOG .debug (String .format ("Trying to find the cause of error in the restore process [%s]." , uid ));
952+ List <String > cmds = Arrays .asList (
953+ String .format ("$restoreUid = '%s'" , uid ),
954+ "$restore = Get-VBRRestoreSession -Id $restoreUid" ,
955+ "if ($restore) {" ,
956+ "Write-Output $restore.Description" ,
957+ "} else {" ,
958+ "Write-Output 'Cannot find restore session with provided uid $restoreUid'" ,
959+ "}"
960+ );
961+ Pair <Boolean , String > result = executePowerShellCommands (cmds );
962+ if (result != null && result .first ()) {
963+ return result .second ();
964+ }
965+ return String .format ("Failed to get the description of the failed restore session [%s]. Please contact an administrator." , uid );
966+ }
967+
933968 private boolean isLegacyServer () {
934969 return this .veeamServerVersion != null && (this .veeamServerVersion > 0 && this .veeamServerVersion < 11 );
935970 }
0 commit comments