Skip to content

Commit 6feaadf

Browse files
author
Fabrício Duarte
committed
Merge branch 'Issues3122' into '4.20.0.0-scclouds'
Correção no estado da VM ao criar um _backup_ com o host `Down` ou `Disconnected` Closes #3122 See merge request scclouds/scclouds!1314
2 parents 9c691f5 + aaba494 commit 6feaadf

2 files changed

Lines changed: 54 additions & 7 deletions

File tree

plugins/backup/knib/src/main/java/org/apache/cloudstack/backup/KnibBackupProvider.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.cloud.exception.InvalidParameterValueException;
3232
import com.cloud.exception.OperationTimedoutException;
3333
import com.cloud.host.HostVO;
34+
import com.cloud.host.Status;
3435
import com.cloud.host.dao.HostDao;
3536
import com.cloud.hypervisor.Hypervisor;
3637
import com.cloud.resource.ResourceState;
@@ -126,6 +127,7 @@
126127
import java.util.Objects;
127128
import java.util.Optional;
128129
import java.util.Set;
130+
import java.util.concurrent.ExecutionException;
129131
import java.util.stream.Collectors;
130132

131133
import static org.apache.cloudstack.backup.dao.BackupDetailDao.CURRENT;
@@ -311,7 +313,7 @@ public boolean takeBackup(VirtualMachine vm, boolean quiesceVm, Long backupSched
311313

312314
try {
313315
outcome.get();
314-
} catch (InterruptedException | java.util.concurrent.ExecutionException e) {
316+
} catch (InterruptedException | ExecutionException e) {
315317
throw new CloudRuntimeException(String.format("Unable to retrieve result from job takeBackup due to [%s]. VM [%s].", e.getMessage(), vm.getUuid()), e);
316318
}
317319

@@ -331,6 +333,16 @@ public Boolean orchestrateTakeBackup(Backup backup, boolean quiesceVm) {
331333
BackupVO backupVO = (BackupVO) backup;
332334
long vmId = backup.getVmId();
333335
VirtualMachine userVm = virtualMachineManager.findById(vmId);
336+
Long hostId = vmSnapshotHelper.pickRunningHost(vmId);
337+
HostVO hostVO = hostDao.findById(hostId);
338+
339+
if (hostVO.getStatus() == Status.Down || hostVO.getStatus() == Status.Disconnected) {
340+
backupVO.setStatus(Backup.Status.Failed);
341+
backupDao.update(backupVO.getId(), backupVO);
342+
343+
logger.error("No available host found to create backup [{}] of VM [{}]. Setting the backup as Failed.", backupVO.getUuid(), userVm.getUuid());
344+
return false;
345+
}
334346

335347
validateVmState(userVm, "take backup");
336348
List<VolumeObjectTO> volumeTOs;
@@ -346,7 +358,6 @@ public Boolean orchestrateTakeBackup(Backup backup, boolean quiesceVm) {
346358

347359
logger.info("Starting VM backup process for VM [{}].", userVm.getUuid());
348360

349-
Long hostId = vmSnapshotHelper.pickRunningHost(vmId);
350361
BackupOfferingVO backupOfferingVO = backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
351362
NativeBackupOfferingVO nativeBackupOfferingVO = nativeBackupOfferingDao.findByUuidIncludingRemoved(backupOfferingVO.getExternalId());
352363

@@ -412,7 +423,7 @@ public boolean deleteBackup(Backup backup, boolean forced) {
412423

413424
try {
414425
outcome.get();
415-
} catch (InterruptedException | java.util.concurrent.ExecutionException e) {
426+
} catch (InterruptedException | ExecutionException e) {
416427
throw new CloudRuntimeException(String.format("Unable to retrieve result from job deleteBackup due to [%s]. Backup [%s].", e.getMessage(), backup.getUuid()), e);
417428
}
418429

@@ -509,7 +520,7 @@ public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup, boolean qui
509520

510521
try {
511522
outcome.get();
512-
} catch (InterruptedException | java.util.concurrent.ExecutionException e) {
523+
} catch (InterruptedException | ExecutionException e) {
513524
throw new CloudRuntimeException(String.format("Unable to retrieve result from job restoreVMFromBackup due to [%s]. Backup [%s].", e.getMessage(), backup.getUuid()), e);
514525
}
515526

@@ -602,7 +613,7 @@ public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeU
602613

603614
try {
604615
outcome.get();
605-
} catch (InterruptedException | java.util.concurrent.ExecutionException e) {
616+
} catch (InterruptedException | ExecutionException e) {
606617
throw new CloudRuntimeException(String.format("Unable to retrieve result from job restoreBackedUpVolume due to [%s]. Backup [%s].", e.getMessage(), backup.getUuid()), e);
607618
}
608619

@@ -833,7 +844,6 @@ private boolean finalizeQuickRestore(VirtualMachine vm, List<VolumeInfo> volumes
833844
return consolidateVolumes(vm, hostId, volumesToConsolidate);
834845
}
835846

836-
837847
private List<VolumeInfo> getVolumesToConsolidate(VirtualMachine vm, List<NativeBackupDataStoreVO> deltasOnSecondary, List<VolumeObjectTO> volumeObjectTOS, long hostId) {
838848
List<VolumeInfo> volumesToConsolidate = new ArrayList<>();
839849

@@ -1001,7 +1011,7 @@ private HostVO getHostToRestore(VirtualMachine vm, boolean quickRestore, Long ho
10011011
throw new AgentUnavailableException(String.format("No host found to quick restore VM [%s]. Please check the logs.", vm.getUuid()), -1);
10021012
}
10031013
host = hostDao.findByIdIncludingRemoved(hostId);
1004-
if (host.getStatus() != com.cloud.host.Status.Up || host.isInMaintenanceStates() || host.getResourceState() != ResourceState.Enabled) {
1014+
if (host.getStatus() != Status.Up || host.isInMaintenanceStates() || host.getResourceState() != ResourceState.Enabled) {
10051015
logger.error("Cannot quick restore if the VM's last host is in maintenance, not Up, or disabled. You may try to start it in an available host and stop it before quick" +
10061016
" restoring. Otherwise, use the normal restore.");
10071017
throw new AgentUnavailableException(String.format("No host found to quick restore VM [%s]. Please check the logs.", vm.getUuid()), -1);

plugins/backup/knib/src/test/java/org/apache/cloudstack/backup/KnibBackupProviderTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717

1818
package org.apache.cloudstack.backup;
1919

20+
import com.cloud.host.HostVO;
21+
import com.cloud.host.Status;
22+
import com.cloud.host.dao.HostDao;
2023
import com.cloud.hypervisor.Hypervisor;
2124
import com.cloud.storage.VolumeApiServiceImpl;
2225
import com.cloud.storage.VolumeVO;
2326
import com.cloud.storage.dao.VolumeDao;
2427
import com.cloud.utils.DateUtil;
2528
import com.cloud.utils.exception.CloudRuntimeException;
2629
import com.cloud.vm.VirtualMachine;
30+
import com.cloud.vm.VirtualMachineManager;
2731
import com.cloud.vm.snapshot.VMSnapshot;
2832
import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
2933
import com.cloud.vm.snapshot.VMSnapshotVO;
@@ -142,6 +146,15 @@ public class KnibBackupProviderTest {
142146
@Mock
143147
private VolumeObjectTO volumeObjectToMock;
144148

149+
@Mock
150+
private VirtualMachineManager virtualMachineManagerMock;
151+
152+
@Mock
153+
private HostDao hostDaoMock;
154+
155+
@Mock
156+
private HostVO hostVOMock;
157+
145158
@Spy
146159
@InjectMocks
147160
private KnibBackupProvider knibBackupProviderSpy;
@@ -567,4 +580,28 @@ public void createDeltaReferencesTestFullBackupNotEndOfChainDoesNotHaveVmSnapsho
567580

568581
verify(nativeBackupDataStoreDaoMock, Mockito.times(1)).persist(Mockito.any());
569582
}
583+
584+
@Test
585+
public void orchestrateTakeBackupTestHostIsDownReturnFalse() {
586+
587+
Mockito.when(virtualMachineManagerMock.findById(Mockito.anyLong())).thenReturn(virtualMachineMock);
588+
Mockito.when(vmSnapshotHelperMock.pickRunningHost(Mockito.anyLong())).thenReturn(1L);
589+
Mockito.when(hostDaoMock.findById(Mockito.anyLong())).thenReturn(hostVOMock);
590+
Mockito.when(hostVOMock.getStatus()).thenReturn(Status.Down);
591+
592+
boolean result = knibBackupProviderSpy.orchestrateTakeBackup(backupVoMock, false);
593+
assertFalse(result);
594+
}
595+
596+
@Test
597+
public void orchestrateTakeBackupTestHostIsDisconnectedReturnFalse() {
598+
599+
Mockito.when(virtualMachineManagerMock.findById(Mockito.anyLong())).thenReturn(virtualMachineMock);
600+
Mockito.when(vmSnapshotHelperMock.pickRunningHost(Mockito.anyLong())).thenReturn(1L);
601+
Mockito.when(hostDaoMock.findById(Mockito.anyLong())).thenReturn(hostVOMock);
602+
Mockito.when(hostVOMock.getStatus()).thenReturn(Status.Disconnected);
603+
604+
boolean result = knibBackupProviderSpy.orchestrateTakeBackup(backupVoMock, false);
605+
assertFalse(result);
606+
}
570607
}

0 commit comments

Comments
 (0)