Fix Instance Backup related events (#13180)

This commit is contained in:
Abhisar Sinha 2026-05-26 13:42:03 +05:30 committed by GitHub
parent a0aafe2fa7
commit ea771a7013
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 104 additions and 60 deletions

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -102,6 +103,16 @@ public class AssignVirtualMachineToBackupOfferingCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public Long getApiResourceId() {
return vmId;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
}
@Override
public String getEventType() {
return EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN;

View File

@ -123,7 +123,12 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.Backup;
return ApiCommandResourceType.VirtualMachine;
}
@Override
public Long getApiResourceId() {
return vmId;
}
@Override

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
@ -81,7 +82,7 @@ public class CreateBackupScheduleCmd extends BaseCmd {
@Parameter(name = ApiConstants.QUIESCE_VM,
type = CommandType.BOOLEAN,
required = false,
description = "Quiesce the instance before checkpointing the disks for backup. Applicable only to NAS backup provider. " +
description = "Quiesce the Instance before checkpointing the disks for backup. Applicable only to NAS backup provider. " +
"The filesystem is frozen before the backup starts and thawed immediately after. " +
"Requires the instance to have the QEMU Guest Agent installed and running.",
since = "4.21.0")
@ -139,4 +140,14 @@ public class CreateBackupScheduleCmd extends BaseCmd {
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
@Override
public Long getApiResourceId() {
return vmId;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
}
}

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -99,6 +100,16 @@ public class RemoveVirtualMachineFromBackupOfferingCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public Long getApiResourceId() {
return vmId;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
}
@Override
public String getEventType() {
return EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE;

View File

@ -22,6 +22,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -127,4 +128,14 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
public String getEventDescription() {
return "Restoring volume "+ volumeUuid + " from backup " + getResourceUuid(ApiConstants.BACKUP_ID) + " and attaching it to Instance " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID);
}
@Override
public Long getApiResourceId() {
return vmId;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
}
}

View File

@ -226,12 +226,12 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
} catch (AgentUnavailableException e) {
logger.error("Unable to contact backend control plane to initiate backup for VM {}", vm.getInstanceName());
backupVO.setStatus(Backup.Status.Failed);
backupDao.remove(backupVO.getId());
backupDao.update(backupVO.getId(), backupVO);
throw new CloudRuntimeException("Unable to contact backend control plane to initiate backup");
} catch (OperationTimedoutException e) {
logger.error("Operation to initiate backup timed out for VM {}", vm.getInstanceName());
backupVO.setStatus(Backup.Status.Failed);
backupDao.remove(backupVO.getId());
backupDao.update(backupVO.getId(), backupVO);
throw new CloudRuntimeException("Operation to initiate backup timed out, please try again");
}
@ -249,12 +249,12 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
} else {
logger.error("Failed to take backup for VM {}: {}", vm.getInstanceName(), answer != null ? answer.getDetails() : "No answer received");
if (answer.getNeedsCleanup()) {
logger.error("Backup cleanup failed for VM {}. Leaving the backup in Error state.", vm.getInstanceName());
logger.error("Backup cleanup failed for VM {}. Leaving the backup in Error state. Backup should be manually deleted to free up the space", vm.getInstanceName());
backupVO.setStatus(Backup.Status.Error);
backupDao.update(backupVO.getId(), backupVO);
} else {
backupVO.setStatus(Backup.Status.Failed);
backupDao.remove(backupVO.getId());
backupDao.update(backupVO.getId(), backupVO);
}
return new Pair<>(false, null);
}

View File

@ -576,12 +576,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN, eventDescription = "assign VM to backup offering", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN, eventDescription = "assign Instance to Backup Offering", async = true)
public boolean assignVMToBackupOffering(Long vmId, Long offeringId) {
final VMInstanceVO vm = findVmById(vmId);
if (!Arrays.asList(VirtualMachine.State.Running, VirtualMachine.State.Stopped, VirtualMachine.State.Shutdown).contains(vm.getState())) {
throw new CloudRuntimeException("VM is not in running or stopped state");
throw new CloudRuntimeException("Instance is not in running or stopped state");
}
validateBackupForZone(vm.getDataCenterId());
@ -589,7 +589,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
if (vm.getBackupOfferingId() != null) {
throw new CloudRuntimeException("VM already is assigned to a backup offering, please remove the VM from its previous offering");
throw new CloudRuntimeException("Instance already is assigned to a backup offering, please remove the Instance from its previous offering");
}
final BackupOfferingVO offering = backupOfferingDao.findById(offeringId);
@ -621,12 +621,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
vm.setBackupVolumes(createVolumeInfoFromVolumes(new ArrayList<>(volumeDao.findByInstance(vmId))));
if (!backupProvider.assignVMToBackupOffering(vm, offering)) {
throw new CloudRuntimeException("Failed to assign the VM to the backup offering, please try removing the assignment and try again.");
throw new CloudRuntimeException("Failed to assign the Instance to the Backup Offering, please try removing the assignment and try again.");
}
if (!vmInstanceDao.update(vmId, vm)) {
backupProvider.removeVMFromBackupOffering(vm);
throw new CloudRuntimeException("Failed to update VM assignment to the backup offering in the DB, please try again.");
throw new CloudRuntimeException("Failed to update Instance assignment to the Backup Offering in the DB, please try again.");
}
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vmId,
@ -635,7 +635,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
"uuid", "instanceName", "backupOfferingId", "backupVolumes"), ReflectionToStringBuilderUtils.reflectOnlySelectedFields(offering,
"uuid", "name", "externalId", "provider")));
} catch (Exception e) {
String msg = String.format("Failed to assign VM [%s] to the Backup Offering [%s], using provider [name: %s, class: %s], due to: [%s].",
String msg = String.format("Failed to assign Instance [%s] to the Backup Offering [%s], using provider [name: %s, class: %s], due to: [%s].",
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(vm, "uuid", "instanceName", "backupOfferingId", "backupVolumes"),
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(offering, "uuid", "name", "externalId", "provider"),
backupProvider.getName(), backupProvider.getClass().getSimpleName(), e.getMessage());
@ -649,11 +649,11 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE, eventDescription = "remove VM from backup offering", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE, eventDescription = "remove Instance from Backup Offering", async = true)
public boolean removeVMFromBackupOffering(final Long vmId, final boolean forced) {
final VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(vmId);
if (vm == null) {
throw new CloudRuntimeException(String.format("Can't find any VM with ID: [%s].", vmId));
throw new CloudRuntimeException(String.format("Can't find any Instance with ID: [%s].", vmId));
}
validateBackupForZone(vm.getDataCenterId());
@ -670,8 +670,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
if (!forced && backupProvider.willDeleteBackupsOnOfferingRemoval()) {
String message = String.format("To remove VM [id: %s, name: %s] from Backup Offering [id: %s, name: %s] using the provider [%s], please specify the "
+ "forced:true option to allow the deletion of all jobs and backups for this VM or remove the backups that this VM has with the backup "
String message = String.format("To remove Instance [id: %s, name: %s] from Backup Offering [id: %s, name: %s] using the provider [%s], please specify the "
+ "forced:true option to allow the deletion of all jobs and backups for this Instance or remove the backups that this Instance has with the backup "
+ "offering.", vm.getUuid(), vm.getInstanceName(), offering.getUuid(), offering.getName(), backupProvider.getClass().getSimpleName());
throw new CloudRuntimeException(message);
}
@ -709,7 +709,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_SCHEDULE_CONFIGURE, eventDescription = "configuring VM backup schedule")
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_SCHEDULE_CONFIGURE, eventDescription = "configuring Instance Backup Schedule")
public BackupSchedule configureBackupSchedule(CreateBackupScheduleCmd cmd) {
final Long vmId = cmd.getVmId();
final DateUtil.IntervalType intervalType = cmd.getIntervalType();
@ -725,7 +725,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
if (vm.getBackupOfferingId() == null) {
throw new CloudRuntimeException("Cannot configure backup schedule for the VM without having any backup offering");
throw new CloudRuntimeException("Cannot configure Backup Schedule for the Instance as it is not assigned any Backup Offering");
}
final BackupOffering offering = backupOfferingDao.findById(vm.getBackupOfferingId());
@ -859,7 +859,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_SCHEDULE_DELETE, eventDescription = "deleting VM backup schedule")
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_SCHEDULE_DELETE, eventDescription = "deleting Instance Backup Schedule")
public boolean deleteBackupSchedule(DeleteBackupScheduleCmd cmd) {
Long vmId = cmd.getVmId();
Long id = cmd.getId();
@ -910,7 +910,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_CREATE, eventDescription = "creating VM backup", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_CREATE, eventDescription = "creating Instance Backup", async = true)
public boolean createBackup(CreateBackupCmd cmd, Object job) throws ResourceAllocationException {
Long vmId = cmd.getVmId();
Account caller = CallContext.current().getCallingAccount();
@ -920,17 +920,17 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
accountManager.checkAccess(caller, null, true, vm);
if (vm.getBackupOfferingId() == null) {
throw new CloudRuntimeException("VM has not backup offering configured, cannot create backup before assigning it to a backup offering");
throw new CloudRuntimeException("Cannot create backup as the Instance doesn't have a Backup Offering assigned");
}
final BackupOffering offering = backupOfferingDao.findById(vm.getBackupOfferingId());
if (offering == null) {
throw new CloudRuntimeException("VM backup offering not found");
throw new CloudRuntimeException("Instance Backup Offering not found");
}
final BackupProvider backupProvider = getBackupProvider(offering.getProvider());
if (backupProvider == null) {
throw new CloudRuntimeException("VM backup provider not found for the offering");
throw new CloudRuntimeException("Instance backup provider not found for the Offering");
}
if (!offering.isUserDrivenBackupAllowed()) {
@ -970,14 +970,9 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
CheckedReservation backupStorageReservation = new CheckedReservation(owner,
Resource.ResourceType.backup_storage, backupSize, reservationDao, resourceLimitMgr)) {
ActionEventUtils.onStartedActionEvent(User.UID_SYSTEM, vm.getAccountId(),
EventTypes.EVENT_VM_BACKUP_CREATE, "creating backup for VM ID:" + vm.getUuid(),
vmId, ApiCommandResourceType.VirtualMachine.toString(),
true, 0);
Pair<Boolean, Backup> result = backupProvider.takeBackup(vm, cmd.getQuiesceVM());
if (!result.first()) {
throw new CloudRuntimeException("Failed to create VM backup");
throw new CloudRuntimeException("Failed to create Instance Backup");
}
Backup backup = result.second();
if (backup != null) {
@ -1079,7 +1074,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
for (int i = 0; i < amountOfBackupsToDelete; i++) {
BackupVO backup = backups.get(i);
if (deleteBackup(backup.getId(), false)) {
String eventDescription = String.format("Successfully deleted backup for VM [ID: %s], suiting the retention specified in the backup schedule [ID: %s]", backup.getVmId(), backupScheduleId);
String eventDescription = String.format("Successfully deleted Backup for Instance [ID: %s], suiting the retention specified in the Backup Schedule [ID: %s]", backup.getVmId(), backupScheduleId);
logger.info(eventDescription);
ActionEventUtils.onCompletedActionEvent(
User.UID_SYSTEM, backup.getAccountId(), EventVO.LEVEL_INFO,
@ -1176,9 +1171,9 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
logger.error(String.format("Failed to import VM [vmInternalName: %s] from backup restoration [%s] with hypervisor [type: %s] due to: [%s].", vmInternalName,
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(backup, "id", "uuid", "vmId", "externalId", "backupType"), hypervisorType, e.getMessage()), e);
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_BACKUP_RESTORE,
String.format("Failed to import VM %s from backup %s with hypervisor [type: %s]", vmInternalName, backup.getUuid(), hypervisorType),
String.format("Failed to import Instance %s from Backup %s with hypervisor [type: %s]", vmInternalName, backup.getUuid(), hypervisorType),
vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),0);
throw new CloudRuntimeException("Error during vm backup restoration and import: " + e.getMessage());
throw new CloudRuntimeException("Error during Instance Backup restoration and import: " + e.getMessage());
}
if (vm == null) {
String message = String.format("Failed to import restored VM %s with hypervisor type %s using backup of VM ID %s",
@ -1188,14 +1183,14 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
message, vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),0);
} else {
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_BACKUP_RESTORE,
String.format("Restored VM %s from backup %s", vm.getUuid(), backup.getUuid()),
String.format("Restored Instance %s from Backup %s", vm.getUuid(), backup.getUuid()),
vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),0);
}
return vm != null;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_RESTORE, eventDescription = "restoring VM from backup", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_RESTORE, eventDescription = "restoring Instance from Backup", async = true)
public boolean restoreBackup(final Long backupId) {
final BackupVO backup = backupDao.findById(backupId);
if (backup == null) {
@ -1214,7 +1209,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
if (vm.getRemoved() == null && !vm.getState().equals(VirtualMachine.State.Stopped) &&
!vm.getState().equals(VirtualMachine.State.Destroyed)) {
throw new CloudRuntimeException("Existing VM should be stopped before being restored from backup");
throw new CloudRuntimeException("Existing Instance should be stopped before being restored from Backup");
}
// This is done to handle historic backups if any with Veeam / Networker plugins
@ -1222,7 +1217,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
vm.getBackupVolumeList() : backup.getBackedUpVolumes();
List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId());
if (vmVolumes.size() != backupVolumes.size()) {
throw new CloudRuntimeException("Unable to restore VM with the current backup as the backup has different number of disks as the VM");
throw new CloudRuntimeException("Unable to restore Instance with the current Backup as the Backup has different number of disks to the Instance");
}
BackupOffering offering = backupOfferingDao.findByIdIncludingRemoved(vm.getBackupOfferingId());
@ -1256,16 +1251,16 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
updateVmState(vm, VirtualMachine.Event.RestoringRequested, VirtualMachine.State.Restoring);
updateVolumeState(vm, Volume.Event.RestoreRequested, Volume.State.Restoring);
ActionEventUtils.onStartedActionEvent(User.UID_SYSTEM, vm.getAccountId(), EventTypes.EVENT_VM_BACKUP_RESTORE,
String.format("Restoring VM %s from backup %s", vm.getUuid(), backup.getUuid()),
String.format("Restoring Instance %s from Backup %s", vm.getUuid(), backup.getUuid()),
vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),
true, 0);
final BackupProvider backupProvider = getBackupProvider(offering.getProvider());
if (!backupProvider.restoreVMFromBackup(vm, backup)) {
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_BACKUP_RESTORE,
String.format("Failed to restore VM %s from backup %s", vm.getInstanceName(), backup.getUuid()),
String.format("Failed to restore Instance %s from Backup %s", vm.getInstanceName(), backup.getUuid()),
vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),0);
throw new CloudRuntimeException("Error restoring VM from backup with uuid " + backup.getUuid());
throw new CloudRuntimeException("Error restoring Instance from Backup with uuid " + backup.getUuid());
}
// The restore process is executed by a backup provider outside of ACS, I am using the catch-all (Exception) to
// ensure that no provider-side exception is missed. Therefore, we have a proper handling of exceptions, and rollbacks if needed.
@ -1273,7 +1268,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
logger.error(String.format("Failed to restore backup [%s] due to: [%s].", backupDetailsInMessage, e.getMessage()), e);
updateVolumeState(vm, Volume.Event.RestoreFailed, Volume.State.Ready);
updateVmState(vm, VirtualMachine.Event.RestoringFailed, VirtualMachine.State.Stopped);
throw new CloudRuntimeException(String.format("Error restoring VM from backup [%s].", backupDetailsInMessage));
throw new CloudRuntimeException(String.format("Error restoring Instance from Backup [%s].", backupDetailsInMessage));
}
}
@ -1288,10 +1283,10 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
Transaction.execute(TransactionLegacy.CLOUD_DB, (TransactionCallback<VMInstanceVO>) status -> {
try {
if (!virtualMachineManager.stateTransitTo(vm, event, vm.getHostId())) {
throw new CloudRuntimeException(String.format("Unable to change state of VM [%s] to [%s].", vm, next));
throw new CloudRuntimeException(String.format("Unable to change state of Instance [%s] to [%s].", vm, next));
}
} catch (NoTransitionException e) {
String errMsg = String.format("Failed to update state of VM [%s] with event [%s] due to [%s].", vm, event, e.getMessage());
String errMsg = String.format("Failed to update state of Instance [%s] with event [%s] due to [%s].", vm, event, e.getMessage());
logger.error(errMsg, e);
throw new RuntimeException(errMsg);
}
@ -1503,7 +1498,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
throw new CloudRuntimeException("Instance with ID " + backup.getVmId() + " couldn't be found.");
}
if (!vm.getState().equals(VirtualMachine.State.Stopped)) {
throw new CloudRuntimeException("The VM should be in stopped state");
throw new CloudRuntimeException("The Instance should be in stopped state");
}
List<Backup.VolumeInfo> backupVolumes = backup.getBackedUpVolumes();
@ -1567,7 +1562,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_RESTORE, eventDescription = "restoring VM from backup", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM, eventDescription = "restoring Volume from Backup to Instance", async = true)
public boolean restoreBackupVolumeAndAttachToVM(final String backedUpVolumeUuid, final Long backupId, final Long vmId) throws Exception {
if (StringUtils.isEmpty(backedUpVolumeUuid)) {
throw new CloudRuntimeException("Invalid volume ID passed");
@ -1585,7 +1580,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
if (vm.getBackupOfferingId() != null && !BackupEnableAttachDetachVolumes.value()) {
throw new CloudRuntimeException("The selected VM has backups, cannot restore and attach volume to the VM.");
throw new CloudRuntimeException("The selected Instance has backups, cannot restore and attach Volume to the Instance.");
}
if (backup.getZoneId() != vm.getDataCenterId()) {
@ -1596,7 +1591,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
if (volumeInfoList == null) {
final VMInstanceVO vmFromBackup = vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
if (vmFromBackup == null) {
throw new CloudRuntimeException("VM reference for the provided VM backup not found");
throw new CloudRuntimeException("Instance reference for the provided Instance backup not found");
} else if (vmFromBackup == null || vmFromBackup.getBackupVolumeList() == null) {
throw new CloudRuntimeException("Volumes metadata not found in the backup");
}
@ -1610,7 +1605,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
final BackupOffering offering = backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
if (offering == null) {
throw new CloudRuntimeException("Failed to find VM backup offering");
throw new CloudRuntimeException("Failed to find Instance Backup Offering");
}
BackupProvider backupProvider = getBackupProvider(offering.getProvider());
@ -1636,12 +1631,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
Pair<Boolean, String> result = restoreBackedUpVolume(backupVolumeInfo, backup, backupProvider, hostPossibleValues, datastoresPossibleValues, vm);
if (BooleanUtils.isFalse(result.first())) {
throw new CloudRuntimeException(String.format("Error restoring volume [%s] of VM [%s] to host [%s] using backup provider [%s] due to: [%s].",
throw new CloudRuntimeException(String.format("Error restoring Volume [%s] of Instance [%s] to host [%s] using backup provider [%s] due to: [%s].",
backedUpVolumeUuid, vm.getUuid(), host.getUuid(), backupProvider.getName(), result.second()));
}
if (!attachVolumeToVM(vm.getDataCenterId(), result.second(), backupVolumeInfo,
backedUpVolumeUuid, vm, datastore.getUuid(), backup)) {
throw new CloudRuntimeException(String.format("Error attaching volume [%s] to VM [%s].", backedUpVolumeUuid, vm.getUuid()));
throw new CloudRuntimeException(String.format("Error attaching Volume [%s] to Instance [%s].", backedUpVolumeUuid, vm.getUuid()));
}
return true;
}
@ -1670,7 +1665,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_DELETE, eventDescription = "deleting VM backup", async = true)
@ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_DELETE, eventDescription = "deleting Instance backup", async = true)
public boolean deleteBackup(final Long backupId, final Boolean forced) throws ResourceAllocationException {
final BackupVO backup = backupDao.findByIdIncludingRemoved(backupId);
if (backup == null) {
@ -1776,12 +1771,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
HypervisorGuru guru = hypervisorGuruManager.getGuru(vm.getHypervisorType());
backupVolumeInfo.setType(Volume.Type.DATADISK);
logger.info("Attaching the restored volume {} to VM {}.", () -> ReflectionToStringBuilder.toString(backupVolumeInfo, ToStringStyle.JSON_STYLE), () -> vm);
logger.info("Attaching the restored Volume {} to Instance {}.", () -> ReflectionToStringBuilder.toString(backupVolumeInfo, ToStringStyle.JSON_STYLE), () -> vm);
StoragePoolVO pool = primaryDataStoreDao.findByUuid(datastoreUuid);
try {
return guru.attachRestoredVolumeToVirtualMachine(zoneId, restoredVolumeLocation, backupVolumeInfo, vm, pool.getId(), backup);
} catch (Exception e) {
throw new CloudRuntimeException("Error attach restored volume to VM " + vm.getUuid() + " due to: " + e.getMessage());
throw new CloudRuntimeException("Error attach restored Volume to Instance " + vm.getUuid() + " due to: " + e.getMessage());
}
}
@ -1964,7 +1959,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
case FAILED:
final Date nextDateTime = scheduleNextBackupJob(backupSchedule);
final String nextScheduledTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, nextDateTime);
logger.debug("Next backup scheduled time for VM ID " + backupSchedule.getVmId() + " is " + nextScheduledTime);
logger.debug("Next backup scheduled time for Instance ID " + backupSchedule.getVmId() + " is " + nextScheduledTime);
break;
default:
logger.debug("Found async backup job [id: {}, uuid: {}, vmId: {}] with " +
@ -2004,7 +1999,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
final Account backupAccount = accountService.getAccount(vm.getAccountId());
if (backupAccount == null || backupAccount.getState() == Account.State.DISABLED) {
logger.debug("Skip backup for VM ({}) since its account has been removed or disabled.", vm);
logger.debug("Skip backup for Instance ({}) since its account has been removed or disabled.", vm);
continue;
}
@ -2021,7 +2016,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
tmpBackupScheduleVO = backupScheduleDao.acquireInLockTable(backupScheduleId);
final Long eventId = ActionEventUtils.onScheduledActionEvent(User.UID_SYSTEM, vm.getAccountId(),
EventTypes.EVENT_VM_BACKUP_CREATE, "creating backup for VM ID:" + vm.getUuid(),
EventTypes.EVENT_VM_BACKUP_CREATE, "creating Backup for Instance ID:" + vm.getUuid(),
vmId, ApiCommandResourceType.VirtualMachine.toString(),
true, 0);
final Map<String, String> params = new HashMap<String, String>();
@ -2085,7 +2080,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
private VMInstanceVO findVmById(final Long vmId) {
final VMInstanceVO vm = vmInstanceDao.findById(vmId);
if (vm == null) {
throw new CloudRuntimeException(String.format("Can't find any VM with ID: [%s].", vmId));
throw new CloudRuntimeException(String.format("Can't find any Instance with ID: [%s].", vmId));
}
return vm;
}
@ -2269,7 +2264,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
backup.getBackupOfferingId(), backup.getAccountId(), backup.getDomainId(), backup.getZoneId()));
ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_BACKUP_CREATE,
String.format("Created backup %s for VM ID: %s", backup.getUuid(), vm.getUuid()),
String.format("Created Backup %s for Instance ID: %s", backup.getUuid(), vm.getUuid()),
vm.getId(), ApiCommandResourceType.VirtualMachine.toString(),0);
}
}

View File

@ -578,7 +578,7 @@ public class BackupManagerTest {
backupManager.tryRestoreVM(backup, vm, offering, "Checking message error.");
fail("An exception is needed.");
} catch (CloudRuntimeException e) {
assertEquals("Error restoring VM from backup [Checking message error.].", e.getMessage());
assertEquals("Error restoring Instance from Backup [Checking message error.].", e.getMessage());
}
}
}
@ -2215,7 +2215,7 @@ public class BackupManagerTest {
CloudRuntimeException exception = Assert.assertThrows(CloudRuntimeException.class,
() -> backupManager.restoreBackup(backupId));
assertEquals("Existing VM should be stopped before being restored from backup", exception.getMessage());
assertEquals("Existing Instance should be stopped before being restored from Backup", exception.getMessage());
verify(backupDao, times(1)).findById(backupId);
verify(vmInstanceDao, times(1)).findByIdIncludingRemoved(vmId);
}
@ -2252,7 +2252,7 @@ public class BackupManagerTest {
CloudRuntimeException exception = Assert.assertThrows(CloudRuntimeException.class,
() -> backupManager.restoreBackup(backupId));
assertEquals("Unable to restore VM with the current backup as the backup has different number of disks as the VM", exception.getMessage());
assertEquals("Unable to restore Instance with the current Backup as the Backup has different number of disks to the Instance", exception.getMessage());
}
verify(backupDao, times(1)).findById(backupId);
verify(vmInstanceDao, times(1)).findByIdIncludingRemoved(vmId);