mirror of https://github.com/apache/cloudstack.git
Refactor and marvin tests stabilization
This commit is contained in:
parent
279bc68706
commit
1caa1173c7
|
|
@ -584,6 +584,15 @@ public class EventTypes {
|
|||
public static final String EVENT_TEMPLATE_DIRECT_DOWNLOAD_FAILURE = "TEMPLATE.DIRECT.DOWNLOAD.FAILURE";
|
||||
public static final String EVENT_ISO_DIRECT_DOWNLOAD_FAILURE = "ISO.DIRECT.DOWNLOAD.FAILURE";
|
||||
|
||||
// Backup and Recovery events
|
||||
public static final String EVENT_ADD_VM_TO_BACKUP_POLICY = "ADD.VM.TO.BACKUP.POLICY";
|
||||
public static final String EVENT_REMOVE_VM_FROM_BACKUP_POLICY = "REMOVE.VM.FROM.BACKUP.POLICY";
|
||||
public static final String EVENT_IMPORT_BACKUP_POLICY = "IMPORT.BACKUP.POLICY";
|
||||
public static final String EVENT_CREATE_VM_BACKUP = "CREATE.VM.BACKUP";
|
||||
public static final String EVENT_DELETE_VM_BACKUP = "DELETE.VM.BACKUP";
|
||||
public static final String EVENT_RESTORE_VM_FROM_BACKUP = "RESTORE.VM.FROM.BACKUP";
|
||||
public static final String EVENT_RESTORE_VOLUME_FROM_BACKUP_AND_ATTACH_TO_VM = "RESTORE.VOLUME.FROM.BACKUP.AND.ATTACH.TO.VM";
|
||||
|
||||
static {
|
||||
|
||||
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ package org.apache.cloudstack.api.command.admin.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
|
|
@ -43,7 +45,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
description = "Imports a backup policy from the backup provider",
|
||||
responseObject = BackupPolicyResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class ImportBackupPolicyCmd extends BaseCmd {
|
||||
public class ImportBackupPolicyCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "importBackupPolicy";
|
||||
|
||||
@Inject
|
||||
|
|
@ -122,4 +124,14 @@ public class ImportBackupPolicyCmd extends BaseCmd {
|
|||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_IMPORT_BACKUP_POLICY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Importing backup policy: " + policyName + " (externalId=" + policyExternalId + ") on zone " + zoneId ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupPolicyResponse;
|
||||
|
|
@ -41,7 +42,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
description = "Assigns a VM to an existing backup policy",
|
||||
responseObject = SuccessResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class AddVMToBackupPolicyCmd extends BaseCmd {
|
||||
public class AddVMToBackupPolicyCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "addVMToBackupPolicy";
|
||||
|
||||
@Inject
|
||||
|
|
@ -106,4 +107,14 @@ public class AddVMToBackupPolicyCmd extends BaseCmd {
|
|||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_ADD_VM_TO_BACKUP_POLICY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Adding VM " + vmId + " to backup policy " + policyId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,15 +19,18 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
|
|
@ -40,9 +43,9 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
|
||||
@APICommand(name = CreateVMBackupCmd.APINAME,
|
||||
description = "Create VM backup",
|
||||
responseObject = SuccessResponse.class, since = "4.12.0",
|
||||
responseObject = BackupResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateVMBackupCmd extends BaseCmd {
|
||||
public class CreateVMBackupCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "createVMBackup";
|
||||
|
||||
@Inject
|
||||
|
|
@ -76,10 +79,9 @@ public class CreateVMBackupCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.createBackup(vmId);
|
||||
// FIXME: the response type
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
Backup backup = backupManager.createBackup(vmId);
|
||||
if (backup != null) {
|
||||
BackupResponse response = _responseGenerator.createBackupResponse(backup);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
|
|
@ -99,4 +101,14 @@ public class CreateVMBackupCmd extends BaseCmd {
|
|||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_CREATE_VM_BACKUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Creating backup for VM " + vmId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
|||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
|
|
@ -52,19 +52,19 @@ public class DeleteVMBackupCmd extends BaseCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
entityType = BackupResponse.class,
|
||||
required = true,
|
||||
description = "id of the VM")
|
||||
private Long vmId;
|
||||
description = "id of backup")
|
||||
private Long backupId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
public Long getId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -74,7 +74,7 @@ public class DeleteVMBackupCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.deleteBackup(vmId);
|
||||
boolean result = backupManager.deleteBackup(backupId);
|
||||
// FIXME: the response type
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import org.apache.cloudstack.api.Parameter;
|
|||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
|
@ -62,10 +61,6 @@ public class ListVMBackupsCmd extends BaseBackupListCmd {
|
|||
description = "id of the VM")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "The zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -74,10 +69,6 @@ public class ListVMBackupsCmd extends BaseBackupListCmd {
|
|||
return vmId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -85,7 +76,7 @@ public class ListVMBackupsCmd extends BaseBackupListCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try{
|
||||
List<Backup> backups = backupManager.listVMBackups(getZoneId(), getVmId());
|
||||
List<Backup> backups = backupManager.listVMBackups(getVmId());
|
||||
setupResponseBackupList(backups);
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupPolicyResponse;
|
||||
|
|
@ -42,7 +43,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
description = "Removes a VM from an existing backup policy",
|
||||
responseObject = SuccessResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RemoveVMFromBackupPolicyCmd extends BaseCmd {
|
||||
public class RemoveVMFromBackupPolicyCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "removeVMFromBackupPolicy";
|
||||
|
||||
@Inject
|
||||
|
|
@ -108,4 +109,13 @@ public class RemoveVMFromBackupPolicyCmd extends BaseCmd {
|
|||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_REMOVE_VM_FROM_BACKUP_POLICY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Removing VM " + vmId + " from backup policy " + policyId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
|
|
@ -40,12 +40,12 @@ import com.cloud.exception.ResourceAllocationException;
|
|||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = RestoreVMBackupCmd.APINAME,
|
||||
description = "Restore VM backup",
|
||||
@APICommand(name = RestoreVMFromBackupCmd.APINAME,
|
||||
description = "Restore VM from backup",
|
||||
responseObject = SuccessResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RestoreVMBackupCmd extends BaseCmd {
|
||||
public static final String APINAME = "restoreVMBackup";
|
||||
public class RestoreVMFromBackupCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "restoreVMFromBackup";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
|
@ -61,34 +61,14 @@ public class RestoreVMBackupCmd extends BaseCmd {
|
|||
description = "id of the backup")
|
||||
private Long backupId;
|
||||
|
||||
//FIXME: is this necessary when backup id is known? unless we want to restore to a different VM?
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "id of the VM")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "The zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -96,7 +76,7 @@ public class RestoreVMBackupCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackup(zoneId, vmId, backupId);
|
||||
boolean result = backupManager.restoreVMFromBackup(backupId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
@ -119,4 +99,13 @@ public class RestoreVMBackupCmd extends BaseCmd {
|
|||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_RESTORE_VM_FROM_BACKUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Restoring VM from backup " + backupId;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,12 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
|
|
@ -30,7 +32,6 @@ import org.apache.cloudstack.api.response.BackupResponse;
|
|||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
|
|
@ -41,12 +42,12 @@ import com.cloud.exception.ResourceAllocationException;
|
|||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = RestoreBackupVolumeCmd.APINAME,
|
||||
@APICommand(name = RestoreVolumeFromBackupAndAttachToVMCmd.APINAME,
|
||||
description = "Restore and attach a backed up volume to VM",
|
||||
responseObject = SuccessResponse.class, since = "4.12.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RestoreBackupVolumeCmd extends BaseCmd {
|
||||
public static final String APINAME = "restoreBackupVolumeAndAttachToVM";
|
||||
public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "restoreVolumeFromBackupAndAttachToVM";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
|
@ -79,10 +80,6 @@ public class RestoreBackupVolumeCmd extends BaseCmd {
|
|||
description = "id of the VM where to attach the restored volume")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "The zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -99,10 +96,6 @@ public class RestoreBackupVolumeCmd extends BaseCmd {
|
|||
return backupId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
|
|
@ -120,7 +113,7 @@ public class RestoreBackupVolumeCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackupVolumeAndAttachToVM(zoneId, volumeId, vmId, backupId);
|
||||
boolean result = backupManager.restoreBackupVolumeAndAttachToVM(volumeId, vmId, backupId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
@ -132,4 +125,14 @@ public class RestoreBackupVolumeCmd extends BaseCmd {
|
|||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_RESTORE_VOLUME_FROM_BACKUP_AND_ATTACH_TO_VM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Restoring volume "+ volumeId + " from backup " + backupId + " and attaching it to VM " + vmId;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.BaseResponse;
|
|||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@EntityReference(value = Backup.class)
|
||||
|
|
@ -69,6 +70,10 @@ public class BackupResponse extends BaseResponse {
|
|||
@Param(description = "backup volume ids")
|
||||
private Backup.Status status;
|
||||
|
||||
@SerializedName(ApiConstants.START_DATE)
|
||||
@Param(description = "backup start date")
|
||||
private Date startDate;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
@ -148,4 +153,12 @@ public class BackupResponse extends BaseResponse {
|
|||
public void setVolumeIds(List<String> volumeIds) {
|
||||
this.volumeIds = volumeIds;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,5 @@ public interface Backup extends InternalIdentity, Identity {
|
|||
List<Long> getVolumeIds();
|
||||
Status getStatus();
|
||||
Date getStartTime();
|
||||
Date getRemoved();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
/**
|
||||
* List existing backups for a VM
|
||||
*/
|
||||
List<Backup> listVMBackups(Long zoneId, Long vmId);
|
||||
List<Backup> listVMBackups(Long vmId);
|
||||
|
||||
/**
|
||||
* List backup policies
|
||||
|
|
@ -82,24 +82,23 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
* @param vmId Virtual Machine ID
|
||||
* @return returns operation success
|
||||
*/
|
||||
boolean createBackup(Long vmId);
|
||||
Backup createBackup(Long vmId);
|
||||
|
||||
/**
|
||||
* Deletes backup of a VM
|
||||
* @param vmId Virtual Machine ID
|
||||
* Deletes a backup
|
||||
* @return returns operation success
|
||||
*/
|
||||
boolean deleteBackup(Long vmId);
|
||||
boolean deleteBackup(Long backupId);
|
||||
|
||||
/**
|
||||
* Restore a full backed up VM
|
||||
* Restore a full VM from backup
|
||||
*/
|
||||
boolean restoreBackup(Long zoneId, Long vmId, Long backupId);
|
||||
boolean restoreVMFromBackup(Long backupId);
|
||||
|
||||
/**
|
||||
* Restore a backed up volume and attach it to a VM
|
||||
*/
|
||||
boolean restoreBackupVolumeAndAttachToVM(Long zoneId, Long volumeId, Long vmId, Long backupId);
|
||||
boolean restoreBackupVolumeAndAttachToVM(Long volumeId, Long vmId, Long backupId);
|
||||
|
||||
/**
|
||||
* Deletes a backup policy
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public interface BackupProvider {
|
|||
* @param vm
|
||||
* @return true if backup successfully starts
|
||||
*/
|
||||
boolean startBackup(BackupPolicy policy, VirtualMachine vm);
|
||||
Backup createVMBackup(BackupPolicy policy, VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Restore VM from backup
|
||||
|
|
@ -79,4 +79,9 @@ public interface BackupProvider {
|
|||
* List VM Backups
|
||||
*/
|
||||
List<Backup> listVMBackups(Long zoneId, VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Remove a VM backup
|
||||
*/
|
||||
boolean removeVMBackup(VirtualMachine vm, String backupId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,11 @@ public class BackupTO implements Backup {
|
|||
return startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getRemoved() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setStartTime(Date startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class BackupVO implements Backup {
|
|||
private Long parentId;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
private Long vmId;
|
||||
|
||||
@Column(name = "volumes")
|
||||
private String volumes;
|
||||
|
|
@ -83,6 +83,10 @@ public class BackupVO implements Backup {
|
|||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date startTime;
|
||||
|
||||
@Column(name = "removed")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
@Transient
|
||||
private List<Long> volumeIds;
|
||||
|
||||
|
|
@ -173,7 +177,7 @@ public class BackupVO implements Backup {
|
|||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
public void setVmId(Long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
|
|
@ -224,6 +228,14 @@ public class BackupVO implements Backup {
|
|||
}
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
protected String getVolumes() {
|
||||
return volumes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public interface BackupDao extends GenericDao<BackupVO, Long> {
|
|||
List<Backup> syncVMBackups(Long zoneId, Long vmId, List<Backup> externalBackups);
|
||||
|
||||
BackupResponse newBackupResponse(Backup backup);
|
||||
BackupVO getBackupVO(Backup backup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements Bac
|
|||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
private BackupVO getBackupVO(Backup backup) {
|
||||
public BackupVO getBackupVO(Backup backup) {
|
||||
BackupVO backupVO = new BackupVO();
|
||||
backupVO.setZoneId(backup.getZoneId());
|
||||
backupVO.setAccountId(backup.getAccountId());
|
||||
|
|
@ -146,6 +146,7 @@ public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements Bac
|
|||
backupResponse.setVolumeIds(volIds);
|
||||
}
|
||||
backupResponse.setStatus(backup.getStatus());
|
||||
backupResponse.setStartDate(backup.getStartTime());
|
||||
backupResponse.setObjectName("backup");
|
||||
return backupResponse;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,14 +64,15 @@ CREATE TABLE IF NOT EXISTS `cloud`.`backup` (
|
|||
`uuid` varchar(40) NOT NULL,
|
||||
`account_id` bigint(20) unsigned NOT NULL,
|
||||
`zone_id` bigint(20) unsigned NOT NULL,
|
||||
`external_id` varchar(40) NOT NULL COMMENT 'backup ID on provider side',
|
||||
`external_id` varchar(80) NOT NULL COMMENT 'backup ID on provider side',
|
||||
`name` varchar(255) NOT NULL COMMENT 'backup name',
|
||||
`description` varchar(255) COMMENT 'backup description',
|
||||
`parent_id` bigint(20) unsigned COMMENT 'backup parent id',
|
||||
`vm_id` bigint(20) unsigned NOT NULL,
|
||||
`volumes` varchar(100),
|
||||
`status` varchar(20) NOT NULL,
|
||||
`start` timestamp,
|
||||
`start` datetime DEFAULT NULL,
|
||||
`removed` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_backup__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_backup__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@
|
|||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.backup.dao.BackupDao;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
|
@ -28,10 +30,15 @@ import com.cloud.storage.Volume;
|
|||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(DummyBackupProvider.class);
|
||||
|
||||
@Inject
|
||||
private BackupDao backupDao;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "dummy";
|
||||
|
|
@ -69,8 +76,24 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean startBackup(BackupPolicy policy, VirtualMachine vm) {
|
||||
return true;
|
||||
public Backup createVMBackup(BackupPolicy policy, VirtualMachine vm) {
|
||||
s_logger.debug("Creating VM backup for VM " + vm.getInstanceName() + " from backup policy " + policy.getName());
|
||||
|
||||
List<Backup> backups = backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
|
||||
String backupNumber = String.valueOf(backups.size() + 1);
|
||||
Backup lastBackup = null;
|
||||
if (backups.size() > 0) {
|
||||
backups.sort(Comparator.comparing(Backup::getStartTime));
|
||||
lastBackup = backups.get(backups.size() - 1);
|
||||
}
|
||||
BackupTO newBackup = new BackupTO(vm.getDataCenterId(), vm.getAccountId(),
|
||||
"xxxx-xxxx-" + vm.getUuid() + "-" + backupNumber, "Backup-" + vm.getUuid() + backupNumber,
|
||||
"VM-" + vm.getInstanceName() + "-backup-" + backupNumber,
|
||||
lastBackup != null ? lastBackup.getExternalId() : null, vm.getId(), null,
|
||||
Backup.Status.BackedUp, new Date());
|
||||
backups.add(newBackup);
|
||||
|
||||
return newBackup;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -89,15 +112,19 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
|||
@Override
|
||||
public List<Backup> listVMBackups(Long zoneId, VirtualMachine vm) {
|
||||
s_logger.debug("Listing VM " + vm.getInstanceName() + "backups on the Dummy Backup Provider");
|
||||
return backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
|
||||
}
|
||||
|
||||
BackupTO backup1 = new BackupTO(zoneId, vm.getAccountId(),
|
||||
"xxxx-xxxx", "Backup-1", "VM-" + vm.getInstanceName() + "-backup-1",
|
||||
null, vm.getId(), null, Backup.Status.BackedUp, new Date());
|
||||
@Override
|
||||
public boolean removeVMBackup(VirtualMachine vm, String backupId) {
|
||||
s_logger.debug("Removing VM backup " + backupId + " for VM " + vm.getInstanceName() + " on the Dummy Backup Provider");
|
||||
|
||||
BackupTO backup2 = new BackupTO(zoneId, vm.getAccountId(), "yyyy-yyyy",
|
||||
"Backup-2", "VM-" + vm.getInstanceName() + "-backup-2",
|
||||
backup1.getExternalId(), vm.getId(), null, Backup.Status.BackedUp, new Date());
|
||||
|
||||
return Arrays.asList(backup1, backup2);
|
||||
List<Backup> backups = backupDao.listByVmId(vm.getDataCenterId(), vm.getId());
|
||||
for (Backup backup : backups) {
|
||||
if (backup.getExternalId().equals(backupId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,10 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean startBackup(BackupPolicy policy, VirtualMachine vm) {
|
||||
return getClient(vm.getDataCenterId()).startBackupJob(policy.getExternalId());
|
||||
public Backup createVMBackup(BackupPolicy policy, VirtualMachine vm) {
|
||||
//TODO: Return backup
|
||||
getClient(vm.getDataCenterId()).startBackupJob(policy.getExternalId());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -150,6 +152,12 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVMBackup(VirtualMachine vm, String backupId) {
|
||||
//TODO: Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return BackupService.class.getSimpleName();
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ public class VeeamBackup implements Backup {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getRemoved() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uid;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import java.util.Map;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.api.command.admin.backup.DeleteBackupPolicyCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.ImportBackupPolicyCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.ListBackupProvidersCmd;
|
||||
|
|
@ -35,14 +37,13 @@ import org.apache.cloudstack.api.command.user.backup.ListBackupPoliciesCmd;
|
|||
import org.apache.cloudstack.api.command.user.backup.ListBackupPolicyVMMappingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListVMBackupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.RemoveVMFromBackupPolicyCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.RestoreBackupVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.RestoreVMBackupCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.RestoreVolumeFromBackupAndAttachToVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.RestoreVMFromBackupCmd;
|
||||
import org.apache.cloudstack.backup.dao.BackupDao;
|
||||
import org.apache.cloudstack.backup.dao.BackupPolicyDao;
|
||||
import org.apache.cloudstack.backup.dao.BackupPolicyVMMapDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
|
@ -89,6 +90,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
private List<BackupProvider> backupProviders;
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_IMPORT_BACKUP_POLICY, eventDescription = "importing backup policy", async = true)
|
||||
public BackupPolicy importBackupPolicy(Long zoneId, String policyExternalId, String policyName, String policyDescription) {
|
||||
final BackupProvider provider = getBackupProvider(zoneId);
|
||||
if (!provider.isBackupPolicy(zoneId, policyExternalId)) {
|
||||
|
|
@ -105,6 +107,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ADD_VM_TO_BACKUP_POLICY, eventDescription = "adding VM to backup policy", async = true)
|
||||
public boolean addVMToBackupPolicy(Long policyId, Long virtualMachineId) {
|
||||
VMInstanceVO vm = vmInstanceDao.findById(virtualMachineId);
|
||||
if (vm == null) {
|
||||
|
|
@ -132,6 +135,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_REMOVE_VM_FROM_BACKUP_POLICY, eventDescription = "removing VM from backup policy", async = true)
|
||||
public boolean removeVMFromBackupPolicy(Long policyId, Long vmId) {
|
||||
BackupPolicyVO policy = backupPolicyDao.findById(policyId);
|
||||
if (policy == null) {
|
||||
|
|
@ -171,19 +175,15 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Backup> listVMBackups(Long zoneId, Long vmId) {
|
||||
BackupProvider backupProvider = getBackupProvider(zoneId);
|
||||
//TODO: Add background job to sync VM backups from the provider
|
||||
public List<Backup> listVMBackups(Long vmId) {
|
||||
VMInstanceVO vm = vmInstanceDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("VM " + vmId + " does not exist");
|
||||
}
|
||||
List<Backup> existingBackups = backupDao.listByVmId(zoneId, vmId);
|
||||
if (CollectionUtils.isNotEmpty(existingBackups)) {
|
||||
return existingBackups;
|
||||
} else {
|
||||
List<Backup> externalBackups = backupProvider.listVMBackups(zoneId, vm);
|
||||
return backupDao.syncVMBackups(zoneId, vmId, externalBackups);
|
||||
}
|
||||
Long zoneId = vm.getDataCenterId();
|
||||
BackupProvider backupProvider = getBackupProvider(zoneId);
|
||||
return backupDao.listByVmId(zoneId, vmId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -229,48 +229,76 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean createBackup(Long vmId) {
|
||||
@ActionEvent(eventType = EventTypes.EVENT_CREATE_VM_BACKUP, eventDescription = "creating VM backup", async = true)
|
||||
public Backup createBackup(Long vmId) {
|
||||
VMInstanceVO vm = vmInstanceDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("VM does not exist");
|
||||
}
|
||||
BackupPolicyVMMap vmMap = backupPolicyVMMapDao.findByVMId(vmId);
|
||||
if (vmMap == null) {
|
||||
throw new CloudRuntimeException("VM " + vmId + " is not assigned to any backup policy");
|
||||
}
|
||||
BackupPolicyVO policy = backupPolicyDao.findById(vmMap.getPolicyId());
|
||||
if (policy == null) {
|
||||
throw new CloudRuntimeException("Policy does not exist");
|
||||
}
|
||||
BackupProvider backupProvider = getBackupProvider(vm.getDataCenterId());
|
||||
// FIXME: on successfully started, add an entry in DB?
|
||||
return backupProvider.startBackup(policy, vm);
|
||||
|
||||
Backup vmBackup = backupProvider.createVMBackup(policy, vm);
|
||||
if (vmBackup == null) {
|
||||
return null;
|
||||
}
|
||||
BackupVO backupVO = backupDao.getBackupVO(vmBackup);
|
||||
return backupDao.persist(backupVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteBackup(Long vmId) {
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreBackup(Long zoneId, Long vmId, Long backupId) {
|
||||
BackupProvider backupProvider = getBackupProvider(zoneId);
|
||||
@ActionEvent(eventType = EventTypes.EVENT_DELETE_VM_BACKUP, eventDescription = "deleting VM backup", async = true)
|
||||
public boolean deleteBackup(Long backupId) {
|
||||
BackupVO backup = backupDao.findById(backupId);
|
||||
if (backup == null) {
|
||||
throw new CloudRuntimeException("Backup " + backupId + " does not exist");
|
||||
}
|
||||
Long zoneId = backup.getZoneId();
|
||||
Long vmId = backup.getVmId();
|
||||
VMInstanceVO vm = vmInstanceDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("VM " + vmId + " does not exist");
|
||||
}
|
||||
BackupProvider backupProvider = getBackupProvider(backup.getZoneId());
|
||||
boolean result = backupProvider.removeVMBackup(vm, backup.getExternalId());
|
||||
if (result) {
|
||||
backupDao.remove(backupId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_RESTORE_VM_FROM_BACKUP, eventDescription = "restoring VM from backup", async = true)
|
||||
public boolean restoreVMFromBackup(Long backupId) {
|
||||
BackupVO backup = backupDao.findById(backupId);
|
||||
if (backup == null) {
|
||||
throw new CloudRuntimeException("Backup " + backupId + " does not exist");
|
||||
}
|
||||
Long vmId = backup.getVmId();
|
||||
BackupProvider backupProvider = getBackupProvider(backup.getZoneId());
|
||||
VMInstanceVO vm = vmInstanceDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("VM " + vmId + " does not exist");
|
||||
}
|
||||
return backupProvider.restoreVMFromBackup(vm.getUuid(), backup.getUuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreBackupVolumeAndAttachToVM(Long zoneId, Long volumeId, Long vmId, Long backupId) {
|
||||
BackupProvider backupProvider = getBackupProvider(zoneId);
|
||||
@ActionEvent(eventType = EventTypes.EVENT_RESTORE_VM_FROM_BACKUP, eventDescription = "restoring VM from backup", async = true)
|
||||
public boolean restoreBackupVolumeAndAttachToVM(Long volumeId, Long vmId, Long backupId) {
|
||||
BackupVO backup = backupDao.findById(backupId);
|
||||
if (backup == null) {
|
||||
throw new CloudRuntimeException("Backup " + backupId + " does not exist");
|
||||
}
|
||||
BackupProvider backupProvider = getBackupProvider(backup.getZoneId());
|
||||
|
||||
VMInstanceVO vm = vmInstanceDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("VM " + vmId + " does not exist");
|
||||
|
|
@ -346,8 +374,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
cmdList.add(ListVMBackupsCmd.class);
|
||||
cmdList.add(CreateVMBackupCmd.class);
|
||||
cmdList.add(DeleteVMBackupCmd.class);
|
||||
cmdList.add(RestoreVMBackupCmd.class);
|
||||
cmdList.add(RestoreBackupVolumeCmd.class);
|
||||
cmdList.add(RestoreVMFromBackupCmd.class);
|
||||
cmdList.add(RestoreVolumeFromBackupAndAttachToVMCmd.class);
|
||||
|
||||
return cmdList;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.utils import (cleanup_resources)
|
||||
from marvin.lib.base import (Account, ServiceOffering, VirtualMachine, BackupPolicy, Configurations)
|
||||
from marvin.lib.base import (Account, ServiceOffering, VirtualMachine, BackupPolicy, Configurations, VMBackup)
|
||||
from marvin.lib.common import (get_domain, get_zone, get_template)
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.codes import FAILED
|
||||
|
|
@ -50,8 +50,8 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
|
|||
|
||||
# Check backup configuration values, set them to enable the dummy provider
|
||||
|
||||
backup_enabled_cfg = Configurations.list(cls.api_client, name='backup.framework.enabled')
|
||||
backup_provider_cfg = Configurations.list(cls.api_client, name='backup.framework.provider.plugin')
|
||||
backup_enabled_cfg = Configurations.list(cls.api_client, name='backup.framework.enabled', zoneid=cls.zone.id)
|
||||
backup_provider_cfg = Configurations.list(cls.api_client, name='backup.framework.provider.plugin', zoneid=cls.zone.id)
|
||||
cls.backup_enabled = backup_enabled_cfg[0].value
|
||||
cls.backup_provider = backup_provider_cfg[0].value
|
||||
|
||||
|
|
@ -110,20 +110,24 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
|
|||
# 3. Delete backup policy
|
||||
# 4. List internal backup policies, policy id should not be listed
|
||||
|
||||
# Import backup policy
|
||||
ext_policy = self.external_policies[1]
|
||||
self.debug("Importing backup policy %s - %s" % (ext_policy.externalid, ext_policy.name))
|
||||
policy = BackupPolicy.importExisting(self.apiclient, self.zone.id, ext_policy.externalid,
|
||||
ext_policy.name, ext_policy.description)
|
||||
|
||||
# Verify policy is listed
|
||||
imported_policies = BackupPolicy.listInternal(self.apiclient, self.zone.id)
|
||||
self.assertIsInstance(imported_policies, list, "List Backup Policies should return a valid response")
|
||||
self.assertNotEqual(len(imported_policies), 0, "Check if the list API returns a non-empty response")
|
||||
matching_policies = [x for x in imported_policies if x.id == policy.id]
|
||||
self.assertNotEqual(len(matching_policies), 0, "Check if there is a matching policy")
|
||||
|
||||
# Delete backup policy
|
||||
self.debug("Deleting backup policy %s" % policy.id)
|
||||
policy.delete(self.apiclient)
|
||||
|
||||
# Verify policy is not listed
|
||||
imported_policies = BackupPolicy.listInternal(self.apiclient, self.zone.id)
|
||||
self.assertIsInstance(imported_policies, list, "List Backup Policies should return a valid response")
|
||||
matching_policies = [x for x in imported_policies if x.id == policy.id]
|
||||
|
|
@ -141,28 +145,58 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
|
|||
# 3. Remove VM from backup policy
|
||||
# 4. Verify there is no mapping between the VM and the backup policy
|
||||
|
||||
# Add VM to backup policy
|
||||
self.debug("Adding VM %s to backup policy %s" % (self.vm.id, self.policy.id))
|
||||
self.policy.addVM(self.apiclient, self.vm.id, self.zone.id)
|
||||
self.policy.addVM(self.apiclient, self.vm.id)
|
||||
|
||||
# Verify a mapping between backup policy and VM is created on DB
|
||||
qresultset = self.dbclient.execute("select id from vm_instance where uuid='%s';" % self.vm.id)
|
||||
vm_id = qresultset[0][0]
|
||||
|
||||
qresultset = self.dbclient.execute("select id from backup_policy where uuid='%s';" % self.policy.id)
|
||||
policy_id = qresultset[0][0]
|
||||
|
||||
qresultset = self.dbclient.execute("select id from backup_policy_vm_map where policy_id='%d' and vm_id = '%d';"
|
||||
% (policy_id, vm_id))
|
||||
|
||||
map = qresultset[0]
|
||||
self.assertNotEqual(len(map), 0, "A mapping between VM and backup policy should exist on DB")
|
||||
self.assertNotEqual(map[0], None, "A mapping between VM and backup policy should exist on DB")
|
||||
mappings = BackupPolicy.listVMMappings(self.apiclient, self.policy.id, self.vm.id, self.zone.id)
|
||||
self.assertNotEqual(len(mappings), 0, "A mapping between VM and backup policy should exist")
|
||||
self.assertNotEqual(mappings[0], None, "A mapping between VM and backup policy should exist")
|
||||
|
||||
# Remove VM from backup policy
|
||||
self.debug("Removing VM %s from backup policy %s" % (self.vm.id, self.policy.id))
|
||||
self.policy.removeVM(self.apiclient, self.vm.id, self.zone.id)
|
||||
self.policy.removeVM(self.apiclient, self.vm.id)
|
||||
|
||||
# Verify mapping is removed from DB
|
||||
qresultset = self.dbclient.execute("select id from backup_policy_vm_map where policy_id='%d' and vm_id = '%d';"
|
||||
% (policy_id, vm_id))
|
||||
# Verify mapping is removed
|
||||
zone_mappings = BackupPolicy.listVMMappings(self.apiclient, zoneid=self.zone.id)
|
||||
matching_mappings = [x for x in zone_mappings if x.policyid == self.policy.id and x.virtualmachineid == self.vm.id]
|
||||
self.assertEqual(len(matching_mappings), 0, "The mapping between VM and backup policy should be removed")
|
||||
|
||||
self.assertEqual(len(qresultset), 0, "The mapping between VM and backup policy should be removed from DB")
|
||||
@attr(tags=["advanced", "backup"], required_hardware="false")
|
||||
def test_vm_backup_lifecycle(self):
|
||||
"""
|
||||
Test VM backup lifecycle
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. List VM backups, verify no backups are created
|
||||
# 2. Add VM to policy
|
||||
# 3. Create VM backup
|
||||
# 4. List VM backups, verify backup is created
|
||||
# 5. Delete VM backup
|
||||
# 6. List VM backups, verify backup is deleted
|
||||
# 7. Remove VM from policy
|
||||
|
||||
# Verify there are no backups for the VM
|
||||
backups = VMBackup.list(self.apiclient, self.vm.id)
|
||||
self.assertEqual(backups, None, "There should not exist any backup for the VM")
|
||||
|
||||
# Create a VM backup
|
||||
self.policy.addVM(self.apiclient, self.vm.id)
|
||||
VMBackup.create(self.apiclient, self.vm.id)
|
||||
|
||||
# Verify backup is created for the VM
|
||||
backups = VMBackup.list(self.apiclient, self.vm.id)
|
||||
self.assertEqual(len(backups), 1, "There should exist only one backup for the VM")
|
||||
backup = backups[0]
|
||||
|
||||
# Delete backup
|
||||
VMBackup.delete(self.apiclient, backup.id)
|
||||
|
||||
# Verify backup is deleted
|
||||
backups = VMBackup.list(self.apiclient, self.vm.id)
|
||||
self.assertEqual(backups, None, "There should not exist any backup for the VM")
|
||||
|
||||
# Remove VM from policy
|
||||
self.policy.removeVM(self.apiclient, self.vm.id)
|
||||
|
|
@ -5426,20 +5426,76 @@ class BackupPolicy:
|
|||
cmd.id = self.id
|
||||
return (apiclient.deleteBackupPolicy(cmd))
|
||||
|
||||
def addVM(self, apiclient, vmid, zoneid):
|
||||
def addVM(self, apiclient, vmid):
|
||||
"""Add a VM to a backup policy"""
|
||||
|
||||
cmd = addVirtualMachineToBackupPolicy.addVirtualMachineToBackupPolicyCmd()
|
||||
cmd.backuppolicyid = self.id
|
||||
cmd = addVMToBackupPolicy.addVMToBackupPolicyCmd()
|
||||
cmd.policyid = self.id
|
||||
cmd.virtualmachineid = vmid
|
||||
cmd.zoneid = zoneid
|
||||
return (apiclient.addVirtualMachineToBackupPolicy(cmd))
|
||||
return (apiclient.addVMToBackupPolicy(cmd))
|
||||
|
||||
def removeVM(self, apiclient, vmid, zoneid):
|
||||
def removeVM(self, apiclient, vmid):
|
||||
"""Remove a VM from a backup policy"""
|
||||
|
||||
cmd = removeVirtualMachineFromBackupPolicy.removeVirtualMachineFromBackupPolicyCmd()
|
||||
cmd.backuppolicyid = self.id
|
||||
cmd = removeVMFromBackupPolicy.removeVMFromBackupPolicyCmd()
|
||||
cmd.policyid = self.id
|
||||
cmd.virtualmachineid = vmid
|
||||
cmd.zoneid = zoneid
|
||||
return (apiclient.removeVirtualMachineFromBackupPolicy(cmd))
|
||||
return (apiclient.removeVMFromBackupPolicy(cmd))
|
||||
|
||||
@classmethod
|
||||
def listVMMappings(self, apiclient, policyid=None, vmid=None, zoneid=None):
|
||||
"""List VM - Backup policies mappings"""
|
||||
|
||||
cmd = listBackupPolicyVMMappings.listBackupPolicyVMMappingsCmd()
|
||||
if vmid:
|
||||
cmd.virtualmachineid = vmid
|
||||
if zoneid:
|
||||
cmd.zoneid = zoneid
|
||||
if policyid:
|
||||
cmd.policyid = policyid
|
||||
return (apiclient.listBackupPolicyVMMappings(cmd))
|
||||
|
||||
class VMBackup:
|
||||
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(self, apiclient, vmid):
|
||||
"""Create VM backup"""
|
||||
|
||||
cmd = createVMBackup.createVMBackupCmd()
|
||||
cmd.virtualmachineid = vmid
|
||||
return (apiclient.createVMBackup(cmd))
|
||||
|
||||
@classmethod
|
||||
def delete(self, apiclient, id):
|
||||
"""Delete VM backup"""
|
||||
|
||||
cmd = deleteVMBackup.deleteVMBackupCmd()
|
||||
cmd.id = id
|
||||
return (apiclient.deleteVMBackup(cmd))
|
||||
|
||||
@classmethod
|
||||
def list(self, apiclient, vmid):
|
||||
"""List VM backups"""
|
||||
|
||||
cmd = listVMBackups.listVMBackupsCmd()
|
||||
cmd.virtualmachineid = vmid
|
||||
return (apiclient.listVMBackups(cmd))
|
||||
|
||||
def restoreVM(self, apiclient):
|
||||
"""Restore VM from backup"""
|
||||
|
||||
cmd = restoreVMFromBackup.restoreVMFromBackupCmd()
|
||||
cmd.id = self.id
|
||||
return (apiclient.restoreVMFromBackup(cmd))
|
||||
|
||||
def restoreVolumeAndAttachToVM(self, apiclient, volumeid, vmid):
|
||||
"""Restore volume from backup and attach it to VM"""
|
||||
|
||||
cmd = restoreVolumeFromBackupAndAttachToVM.restoreVolumeFromBackupAndAttachToVMCmd()
|
||||
cmd.id = self.id
|
||||
cmd.volumeid = volumeid
|
||||
cmd.virtualmachineid = vmid
|
||||
return (apiclient.restoreVolumeFromBackupAndAttachToVM(cmd))
|
||||
Loading…
Reference in New Issue