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