|
19 | 19 | import java.util.ArrayList; |
20 | 20 | import java.util.Arrays; |
21 | 21 | import java.util.Collections; |
| 22 | +import java.util.Comparator; |
22 | 23 | import java.util.Date; |
23 | 24 | import java.util.HashMap; |
24 | 25 | import java.util.List; |
25 | 26 | import java.util.Map; |
| 27 | +import java.util.Objects; |
26 | 28 | import java.util.TimeZone; |
27 | 29 | import java.util.Timer; |
28 | 30 | import java.util.TimerTask; |
29 | 31 | import java.util.stream.Collectors; |
30 | 32 |
|
31 | 33 | import com.amazonaws.util.CollectionUtils; |
| 34 | +import com.cloud.network.dao.NetworkDao; |
| 35 | +import com.cloud.network.dao.NetworkVO; |
| 36 | +import com.cloud.storage.VMTemplateVO; |
32 | 37 | import com.cloud.storage.VolumeApiService; |
| 38 | +import com.cloud.storage.dao.VMTemplateDao; |
33 | 39 | import com.cloud.utils.fsm.NoTransitionException; |
| 40 | +import com.cloud.vm.NicVO; |
34 | 41 | import com.cloud.vm.UserVmManager; |
| 42 | +import com.cloud.vm.UserVmService; |
35 | 43 | import com.cloud.vm.UserVmVO; |
36 | 44 | import com.cloud.vm.VirtualMachineManager; |
37 | 45 | import javax.inject.Inject; |
38 | 46 | import javax.naming.ConfigurationException; |
39 | 47 |
|
| 48 | +import com.cloud.vm.dao.NicDao; |
40 | 49 | import org.apache.cloudstack.api.ApiCommandResourceType; |
41 | 50 | import org.apache.cloudstack.api.ApiConstants; |
42 | 51 | import org.apache.cloudstack.api.command.admin.backup.DeleteBackupOfferingCmd; |
@@ -166,6 +175,14 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { |
166 | 175 | private VolumeApiService volumeApiService; |
167 | 176 | @Inject |
168 | 177 | private VolumeOrchestrationService volumeOrchestrationService; |
| 178 | + @Inject |
| 179 | + private VMTemplateDao templateDao; |
| 180 | + @Inject |
| 181 | + private NicDao nicDao; |
| 182 | + @Inject |
| 183 | + private NetworkDao networkDao; |
| 184 | + @Inject |
| 185 | + protected UserVmService userVmService; |
169 | 186 |
|
170 | 187 | private AsyncJobDispatcher asyncJobDispatcher; |
171 | 188 | private Timer backupTimer; |
@@ -645,6 +662,9 @@ public boolean restoreBackup(final Long backupId) { |
645 | 662 | !vm.getState().equals(VirtualMachine.State.Destroyed)) { |
646 | 663 | throw new CloudRuntimeException("Existing VM should be stopped before being restored from backup"); |
647 | 664 | } |
| 665 | + if (VirtualMachine.State.Expunging.equals(vm.getState()) && vm.getRemoved() != null) { |
| 666 | + restoreExpungedVm(vm); |
| 667 | + } |
648 | 668 | // This is done to handle historic backups if any with Veeam / Networker plugins |
649 | 669 | List<Backup.VolumeInfo> backupVolumes = CollectionUtils.isNullOrEmpty(backup.getBackedUpVolumes()) ? |
650 | 670 | vm.getBackupVolumeList() : backup.getBackedUpVolumes(); |
@@ -705,6 +725,28 @@ protected void tryRestoreVM(BackupVO backup, VMInstanceVO vm, BackupOffering off |
705 | 725 | } |
706 | 726 | } |
707 | 727 |
|
| 728 | + private void restoreExpungedVm(VMInstanceVO vm) { |
| 729 | + VMTemplateVO template = templateDao.findById(vm.getTemplateId()); |
| 730 | + if (Objects.isNull(template)) { |
| 731 | + throw new CloudRuntimeException("Failed to find VM template to restore the VM"); |
| 732 | + } |
| 733 | + List<Long> networkIds = nicDao.listByVmId(vm.getId()).stream().sorted(Comparator.comparing(NicVO::getDeviceId)).map(NicVO::getNetworkId).collect(Collectors.toList()); |
| 734 | + for (Long networkId : networkIds) { |
| 735 | + NetworkVO networkVO = networkDao.findById(networkId); |
| 736 | + if (Objects.isNull(networkVO)) { |
| 737 | + throw new CloudRuntimeException("Failed to find network all networks the VM was previously attached to"); |
| 738 | + } |
| 739 | + } |
| 740 | + |
| 741 | + CallContext ctx = CallContext.current(); |
| 742 | + final Account owner = ctx.getCallingAccount(); |
| 743 | +// userVmService.createAdvancedVirtualMachine(vm.getDataCenterId(), vm.getServiceOfferingId(), template.getId(), networkIds, owner, |
| 744 | +// vm.getHostName(), vm.getHostName(), null, null, null, |
| 745 | +// Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, null, null, null, keypairs, |
| 746 | +// requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, true, null, null); |
| 747 | + |
| 748 | + } |
| 749 | + |
708 | 750 | /** |
709 | 751 | * Tries to update the state of given VM, given specified event |
710 | 752 | * @param vm The VM to update its state |
|
0 commit comments