mirror of
https://github.com/apache/cloudstack
synced 2026-08-02 05:26:35 +00:00
Introduce new backup provider (KBOSS) (#12758)
Co-authored-by: João Jandre <joao@scclouds.com.br> Co-authored-by: Bernardo De Marco Gonçalves <bernardomg2004@gmail.com> Co-authored-by: Fabricio Duarte <fabricio.duarte.jr@gmail.com> Co-authored-by: GaOrtiga <49285692+GaOrtiga@users.noreply.github.com>
This commit is contained in:
parent
0e43c6a818
commit
66132f83ea
@ -488,3 +488,15 @@ iscsi.session.cleanup.enabled=false
|
||||
# Optional vCenter SHA1 thumbprint for VMware to KVM conversion via VDDK, passed as
|
||||
# -io vddk-thumbprint=<value>. If unset, CloudStack computes it on the KVM host via openssl.
|
||||
#vddk.thumbprint=
|
||||
|
||||
# Timeout (in seconds) for QCOW2 delta merge operations, mainly used for classic volume snapshots, disk-only VM snapshots on file-based storage, and the KBOSS plugin.
|
||||
# If a value of 0 or less is informed, the default will be used.
|
||||
# qcow2.delta.merge.timeout=259200
|
||||
|
||||
# Maximum number of backup validation jobs that can be executed at the same time. Values lower than 0 remove the limit, meaning that as many validations as possible will be done at
|
||||
# the same time.
|
||||
# backup.validation.max.concurrent.operations.per.host=
|
||||
|
||||
# Maximum number of backup compression jobs that can be executed at the same time. Values lower than 0 remove the limit, meaning that as many compressions as possible will be
|
||||
# done at the same time.
|
||||
# backup.compression.max.concurrent.operations.per.host=
|
||||
|
||||
@ -170,7 +170,8 @@ public class AgentProperties{
|
||||
public static final Property<Integer> CMDS_TIMEOUT = new Property<>("cmds.timeout", 7200);
|
||||
|
||||
/**
|
||||
* The timeout (in seconds) for the snapshot merge operation, mainly used for classic volume snapshots and disk-only VM snapshots on file-based storage.<br>
|
||||
* The timeout (in seconds) for QCOW2 delta merge operations, mainly used for classic volume snapshots, disk-only VM snapshots on file-based storage, and the KBOSS plugin.
|
||||
* If a value of 0 or less is informed, the default will be used.<br>
|
||||
* This configuration is only considered if libvirt.events.enabled is also true. <br>
|
||||
* Data type: Integer.<br>
|
||||
* Default value: <code>259200</code>
|
||||
@ -953,6 +954,18 @@ public class AgentProperties{
|
||||
public static final Property<Boolean> VM_NETWORK_MACIP_STATIC = new Property<>("vm.network.macip.static", false, Boolean.class);
|
||||
|
||||
|
||||
/**
|
||||
* Maximum number of backup validation jobs that can be executed at the same time. Values lower than 0 remove the limit, meaning that as many validations as possible will be done at
|
||||
* the same time.
|
||||
*/
|
||||
public static final Property<Integer> BACKUP_VALIDATION_MAX_CONCURRENT_OPERATIONS_PER_HOST = new Property<>("backup.validation.max.concurrent.operations.per.host", null, Integer.class);
|
||||
|
||||
/**
|
||||
* Maximum number of backup compression jobs that can be executed at the same time. Values lower than 0 remove the limit, meaning that as many compressions as possible will be
|
||||
* done at the same time.
|
||||
*/
|
||||
public static final Property<Integer> BACKUP_COMPRESSION_MAX_CONCURRENT_OPERATIONS_PER_HOST = new Property<>("backup.compression.max.concurrent.operations.per.host", null, Integer.class);
|
||||
|
||||
public static class Property <T>{
|
||||
private String name;
|
||||
private T defaultValue;
|
||||
|
||||
@ -19,5 +19,5 @@
|
||||
package com.cloud.agent.api.to;
|
||||
|
||||
public enum DataObjectType {
|
||||
VOLUME, SNAPSHOT, TEMPLATE, ARCHIVE
|
||||
VOLUME, SNAPSHOT, TEMPLATE, ARCHIVE, BACKUP
|
||||
}
|
||||
|
||||
@ -668,6 +668,7 @@ public class EventTypes {
|
||||
public static final String EVENT_VM_BACKUP_USAGE_METRIC = "BACKUP.USAGE.METRIC";
|
||||
public static final String EVENT_VM_BACKUP_EDIT = "BACKUP.OFFERING.EDIT";
|
||||
public static final String EVENT_VM_CREATE_FROM_BACKUP = "VM.CREATE.FROM.BACKUP";
|
||||
public static final String EVENT_SCREENSHOT_DOWNLOAD = "BACKUP.VALIDATION.SCREENSHOT.DOWNLOAD";
|
||||
|
||||
// external network device events
|
||||
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
|
||||
|
||||
@ -20,6 +20,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupProvider;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
@ -94,10 +95,10 @@ public interface HypervisorGuru extends Adapter {
|
||||
Map<String, String> getClusterSettings(long vmId);
|
||||
|
||||
VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId,
|
||||
String vmInternalName, Backup backup) throws Exception;
|
||||
String vmInternalName, Backup backup, BackupProvider backupProvider) throws Exception;
|
||||
|
||||
boolean attachRestoredVolumeToVirtualMachine(long zoneId, String location, Backup.VolumeInfo volumeInfo,
|
||||
VirtualMachine vm, long poolId, Backup backup) throws Exception;
|
||||
VirtualMachine vm, long poolId, Backup backup, BackupProvider backupProvider) throws Exception;
|
||||
/**
|
||||
* Will generate commands to migrate a vm to a pool. For now this will only work for stopped VMs on Vmware.
|
||||
*
|
||||
|
||||
@ -35,7 +35,8 @@ public class Storage {
|
||||
VDI(true, true, false, "vdi"),
|
||||
TAR(false, false, false, "tar"),
|
||||
ZIP(false, false, false, "zip"),
|
||||
DIR(false, false, false, "dir");
|
||||
DIR(false, false, false, "dir"),
|
||||
PNG(false, false, false, "png");
|
||||
|
||||
private final boolean supportThinProvisioning;
|
||||
private final boolean supportSparse;
|
||||
|
||||
@ -60,7 +60,9 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
||||
UploadError(false, "Volume upload encountered some error"),
|
||||
UploadAbandoned(false, "Volume upload is abandoned since the upload was never initiated within a specified time"),
|
||||
Attaching(true, "The volume is attaching to a VM from Ready state."),
|
||||
Restoring(true, "The volume is being restored from backup.");
|
||||
Restoring(true, "The volume is being restored from backup."),
|
||||
Consolidating(true, "The volume is being flattened."),
|
||||
RestoreError(false, "The volume restore encountered an error.");
|
||||
|
||||
boolean _transitional;
|
||||
|
||||
@ -153,6 +155,10 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Destroy, Event.RestoreRequested, Restoring, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Restoring, Event.RestoreSucceeded, Ready, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Restoring, Event.RestoreFailed, Ready, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<>(Ready, Event.ConsolidationRequested, Consolidating, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<>(Consolidating, Event.OperationSucceeded, Ready, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<>(Consolidating, Event.OperationFailed, RestoreError, null));
|
||||
s_fsm.addTransition(new StateMachine2.Transition<>(RestoreError, Event.RestoreFailed, RestoreError, null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +185,8 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
||||
OperationTimeout,
|
||||
RestoreRequested,
|
||||
RestoreSucceeded,
|
||||
RestoreFailed;
|
||||
RestoreFailed,
|
||||
ConsolidationRequested
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -114,7 +114,7 @@ public interface VolumeApiService {
|
||||
|
||||
Volume attachVolumeToVM(AttachVolumeCmd command);
|
||||
|
||||
Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId, Boolean allowAttachForSharedFS);
|
||||
Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId, Boolean allowAttachForSharedFS, boolean allowAttachOnRestoring);
|
||||
|
||||
Volume detachVolumeViaDestroyVM(long vmId, long volumeId);
|
||||
|
||||
@ -189,7 +189,7 @@ public interface VolumeApiService {
|
||||
|
||||
boolean validateConditionsToReplaceDiskOfferingOfVolume(Volume volume, DiskOffering newDiskOffering, StoragePool destPool);
|
||||
|
||||
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
|
||||
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge, Boolean countDisplayFalseInResourceCount);
|
||||
|
||||
void destroyVolume(long volumeId);
|
||||
|
||||
|
||||
@ -254,14 +254,14 @@ public interface ResourceLimitService {
|
||||
void updateTaggedResourceLimitsAndCountsForAccounts(List<AccountResponse> responses, String tag);
|
||||
void updateTaggedResourceLimitsAndCountsForDomains(List<DomainResponse> responses, String tag);
|
||||
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
List<String> getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering);
|
||||
List<String> getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering, Boolean enforceResourceLimitOnDisplayFalse);
|
||||
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
|
||||
DiskOffering currentOffering, DiskOffering newOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering, Boolean countDisplayFalseInResourceCount);
|
||||
|
||||
void updateVmResourceCountForTemplateChange(long accountId, Boolean display, ServiceOffering offering, VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate);
|
||||
|
||||
@ -276,8 +276,8 @@ public interface ResourceLimitService {
|
||||
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
|
||||
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
|
||||
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Boolean countDisplayFalseInResourceLimit);
|
||||
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Boolean countDisplayFalseInResourceCount);
|
||||
|
||||
void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
|
||||
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List<Reserver> reservations) throws ResourceAllocationException;
|
||||
|
||||
@ -75,10 +75,11 @@ public interface UserVmService {
|
||||
* Destroys one virtual machine
|
||||
*
|
||||
* @param cmd the API Command Object containg the parameters to use for this service action
|
||||
* @param checkExpunge
|
||||
* @throws ConcurrentOperationException
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException;
|
||||
UserVm destroyVm(DestroyVMCmd cmd, boolean checkExpunge) throws ResourceUnavailableException, ConcurrentOperationException;
|
||||
|
||||
/**
|
||||
* Destroys one virtual machine
|
||||
|
||||
@ -58,7 +58,10 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
||||
Error(false, "VM is in error"),
|
||||
Unknown(false, "VM state is unknown."),
|
||||
Shutdown(false, "VM state is shutdown from inside"),
|
||||
Restoring(true, "VM is being restored from backup");
|
||||
Restoring(true, "VM is being restored from backup"),
|
||||
BackingUp(true, "VM is being backed up"),
|
||||
BackupError(false, "VM backup is in an inconsistent state. Operator should analyse the logs and restore the VM"),
|
||||
RestoreError(false, "VM restore left the VM in an inconsistent state. Operator should analyse the logs and restore the VM");
|
||||
|
||||
private final boolean _transitional;
|
||||
String _description;
|
||||
@ -134,6 +137,14 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, Event.RestoringRequested, State.Restoring, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Restoring, Event.RestoringSuccess, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Restoring, Event.RestoringFailed, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<>(State.Running, Event.BackupRequested, State.BackingUp, null));
|
||||
s_fsm.addTransition(new Transition<>(State.Stopped, Event.BackupRequested, State.BackingUp, null));
|
||||
s_fsm.addTransition(new Transition<>(State.BackingUp, Event.BackupSucceededRunning, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<>(State.BackingUp, Event.BackupSucceededStopped, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToError, State.BackupError, null));
|
||||
s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToRunning, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToStopped, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.RestoreError, Event.RestoringFailed, State.RestoreError, null));
|
||||
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
|
||||
@ -212,6 +223,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
||||
ExpungeOperation,
|
||||
OperationSucceeded,
|
||||
OperationFailed,
|
||||
OperationFailedToRunning,
|
||||
OperationFailedToStopped,
|
||||
OperationFailedToError,
|
||||
OperationRetry,
|
||||
AgentReportShutdowned,
|
||||
@ -221,6 +234,10 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
||||
RestoringRequested,
|
||||
RestoringFailed,
|
||||
RestoringSuccess,
|
||||
BackupRequested,
|
||||
BackupSucceededStopped,
|
||||
BackupSucceededRunning,
|
||||
FinalizedBackupChain,
|
||||
|
||||
// added for new VMSync logic
|
||||
FollowAgentPowerOnReport,
|
||||
|
||||
@ -136,4 +136,14 @@ public interface VmDetailConstants {
|
||||
String ACTIVE_CHECKPOINT_CREATE_TIME = "active.checkpoint.create.time";
|
||||
String LAST_CHECKPOINT_ID = "last.checkpoint.id";
|
||||
String LAST_CHECKPOINT_CREATE_TIME = "last.checkpoint.create.time";
|
||||
|
||||
// KBOSS specific
|
||||
String LINKED_VOLUMES_SECONDARY_STORAGE_UUIDS = "linkedVolumesSecondaryStorageUuids";
|
||||
String VALIDATION_COMMAND = "backupValidationCommand";
|
||||
String VALIDATION_COMMAND_ARGUMENTS = "backupValidationCommandArguments";
|
||||
String VALIDATION_COMMAND_EXPECTED_RESULT = "backupValidationCommandExpectedResult";
|
||||
String VALIDATION_COMMAND_TIMEOUT = "backupValidationCommandTimeout";
|
||||
String VALIDATION_SCREENSHOT_WAIT = "backupValidationScreenshotWait";
|
||||
String VALIDATION_BOOT_TIMEOUT = "backupValidationBootTimeout";
|
||||
String LAST_KNOWN_STATE = "last_known_state";
|
||||
}
|
||||
|
||||
@ -83,6 +83,9 @@ public interface AlertService {
|
||||
public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true, true);
|
||||
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
|
||||
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
|
||||
public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_FAILED = new AlertType((short)35, "ALERT.BACKUP.VALIDATION.FAILED", true, true);
|
||||
public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_UNABLE_TO_VALIDATE = new AlertType((short)36, "ALERT.BACKUP.VALIDATION.UNABLE.TO.VALIDATE", true, true);
|
||||
public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_CLEANUP_FAILED = new AlertType((short)37, "ALERT.BACKUP.VALIDATION.CLEANUP_FAILED", true, true);
|
||||
|
||||
public short getType() {
|
||||
return type;
|
||||
|
||||
@ -63,6 +63,7 @@ public class ApiConstants {
|
||||
public static final String BACKUP_LIMIT = "backuplimit";
|
||||
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
|
||||
public static final String BACKUP_OFFERING_ID = "backupofferingid";
|
||||
public static final String BACKUP_OFFERING_DETAILS = "backupofferingdetails";
|
||||
public static final String BACKUP_STORAGE_AVAILABLE = "backupstorageavailable";
|
||||
public static final String BACKUP_STORAGE_LIMIT = "backupstoragelimit";
|
||||
public static final String BACKUP_STORAGE_TOTAL = "backupstoragetotal";
|
||||
@ -534,6 +535,7 @@ public class ApiConstants {
|
||||
public static final String QUALIFIERS = "qualifiers";
|
||||
public static final String QUERY_FILTER = "queryfilter";
|
||||
public static final String QUIESCE_VM = "quiescevm";
|
||||
public static final String QUICK_RESTORE = "quickrestore";
|
||||
public static final String SCHEDULE = "schedule";
|
||||
public static final String SCHEDULE_ID = "scheduleid";
|
||||
public static final String SCOPE = "scope";
|
||||
@ -584,6 +586,8 @@ public class ApiConstants {
|
||||
public static final String STATE = "state";
|
||||
public static final String STATS = "stats";
|
||||
public static final String STATUS = "status";
|
||||
public static final String COMPRESSION_STATUS = "compressionstatus";
|
||||
public static final String VALIDATION_STATUS = "validationstatus";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
@ -682,6 +686,7 @@ public class ApiConstants {
|
||||
public static final String ETCD_SERVICE_OFFERING_NAME = "etcdofferingname";
|
||||
public static final String REMOVE_VLAN = "removevlan";
|
||||
public static final String VLAN_ID = "vlanid";
|
||||
public static final String ISOLATED = "isolated";
|
||||
public static final String ISOLATED_PVLAN = "isolatedpvlan";
|
||||
public static final String ISOLATED_PVLAN_TYPE = "isolatedpvlantype";
|
||||
public static final String ISOLATION_URI = "isolationuri";
|
||||
@ -1206,6 +1211,7 @@ public class ApiConstants {
|
||||
public static final String CLEAN_UP_EXTRA_CONFIG = "cleanupextraconfig";
|
||||
public static final String CLEAN_UP_PARAMETERS = "cleanupparameters";
|
||||
public static final String VIRTUAL_SIZE = "virtualsize";
|
||||
public static final String UNCOMPRESSED_SIZE = "uncompressedsize";
|
||||
public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
|
||||
public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid";
|
||||
public static final String FETCH_ROUTER_HEALTH_CHECK_RESULTS = "fetchhealthcheckresults";
|
||||
@ -1342,7 +1348,7 @@ public class ApiConstants {
|
||||
public static final String IMPORT_SOURCE = "importsource";
|
||||
public static final String TEMP_PATH = "temppath";
|
||||
public static final String HEURISTIC_RULE = "heuristicrule";
|
||||
public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, TEMPLATE and VOLUME.";
|
||||
public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, BACKUP, TEMPLATE and VOLUME.";
|
||||
public static final String MANAGEMENT = "management";
|
||||
public static final String IS_VNF = "isvnf";
|
||||
public static final String VNF_NICS = "vnfnics";
|
||||
@ -1438,6 +1444,10 @@ public class ApiConstants {
|
||||
|
||||
public static final String VMWARE_DC = "vmwaredc";
|
||||
|
||||
public static final String PARAMETER_DESCRIPTION_ISOLATED_BACKUPS = "Whether the backup will be isolated, defaults to false. " +
|
||||
"Isolated backups are always created as full backups in independent chains. Therefore, they will never depend on any existing backup chain " +
|
||||
"and no backup chain will depend on them. Currently only supported for the KBOSS provider.";
|
||||
|
||||
public static final String CSS = "css";
|
||||
|
||||
public static final String JSON_CONFIGURATION = "jsonconfiguration";
|
||||
@ -1459,6 +1469,27 @@ public class ApiConstants {
|
||||
public static final String OBSOLETE_PARAMETERS = "obsoleteparameters";
|
||||
public static final String EXCLUDED_PARAMETERS = "excludedparameters";
|
||||
|
||||
public static final String COMPRESS = "compress";
|
||||
|
||||
public static final String VALIDATE = "validate";
|
||||
|
||||
public static final String VALIDATION_STEPS = "validationsteps";
|
||||
|
||||
public static final String ALLOW_QUICK_RESTORE = "allowquickrestore";
|
||||
|
||||
public static final String ALLOW_EXTRACT_FILE = "allowextractfile";
|
||||
|
||||
public static final String BACKUP_CHAIN_SIZE = "backupchainsize";
|
||||
|
||||
public static final String COMPRESSION_LIBRARY = "compressionlibrary";
|
||||
public static final String ATTEMPTS = "attempts";
|
||||
|
||||
public static final String EXECUTING = "executing";
|
||||
|
||||
public static final String SCHEDULED = "scheduled";
|
||||
public static final String SCHEDULED_DATE = "scheduleddate";
|
||||
public static final String BACKUP_PROVIDER = "backupprovider";
|
||||
|
||||
/**
|
||||
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
||||
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
|
||||
|
||||
@ -45,6 +45,8 @@ public class CreateVMFromBackupCmdByAdmin extends CreateVMFromBackupCmd implemen
|
||||
@Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "destination Cluster ID to deploy the VM to - parameter available for root admin only", since = "4.21")
|
||||
private Long clusterId;
|
||||
|
||||
private String instanceType;
|
||||
|
||||
public Long getPodId() {
|
||||
return podId;
|
||||
}
|
||||
@ -52,4 +54,17 @@ public class CreateVMFromBackupCmdByAdmin extends CreateVMFromBackupCmd implemen
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceType() {
|
||||
return instanceType;
|
||||
}
|
||||
|
||||
public CreateVMFromBackupCmdByAdmin(){}
|
||||
|
||||
public CreateVMFromBackupCmdByAdmin(String hypervisor, String instanceType) {
|
||||
this.displayVm = false;
|
||||
this.hypervisor = hypervisor;
|
||||
this.instanceType = instanceType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class DestroyVolumeCmdByAdmin extends DestroyVolumeCmd implements AdminCm
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Volume Id: " + getId());
|
||||
Volume result = _volumeService.destroyVolume(getId(), CallContext.current().getCallingAccount(), getExpunge(), false);
|
||||
Volume result = _volumeService.destroyVolume(getId(), CallContext.current().getCallingAccount(), getExpunge(), false, null);
|
||||
if (result != null) {
|
||||
VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -81,6 +81,12 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
||||
since = "4.21.0")
|
||||
private Boolean quiesceVM;
|
||||
|
||||
@Parameter(name = ApiConstants.ISOLATED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = ApiConstants.PARAMETER_DESCRIPTION_ISOLATED_BACKUPS,
|
||||
since = "4.23.0")
|
||||
private boolean isolated;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -101,6 +107,10 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
||||
return quiesceVM;
|
||||
}
|
||||
|
||||
public boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -0,0 +1,185 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.backup;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "createBackupOffering", description = "Creates a backup offering", responseObject = BackupOfferingResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin}, since = "4.23.0")
|
||||
public class CreateBackupOfferingCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
protected BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Backup offering name.", required = true)
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true,
|
||||
description = "The description of the backup offering")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.COMPRESS, type = CommandType.BOOLEAN, description = "Whether the backups should be compressed or not.")
|
||||
private Boolean compress;
|
||||
|
||||
@Parameter(name = ApiConstants.VALIDATE, type = CommandType.BOOLEAN, description = "Whether the backups should be validated or not.")
|
||||
private Boolean validate;
|
||||
|
||||
@Parameter(name = ApiConstants.VALIDATION_STEPS, type = CommandType.STRING, description = "Which validation steps should be performed. Accepts a comma-separated list of " +
|
||||
"steps. Accepted values are: wait_for_boot, screenshot and execute_command.")
|
||||
private String validationSteps;
|
||||
|
||||
@Parameter(name = ApiConstants.ALLOW_QUICK_RESTORE, type = CommandType.BOOLEAN, description = "Whether quick restore is enabled for the backups or not.")
|
||||
private Boolean allowQuickRestore;
|
||||
|
||||
@Parameter(name = ApiConstants.ALLOW_EXTRACT_FILE, type = CommandType.BOOLEAN, description = "Whether files may be extracted from backups or not.")
|
||||
private Boolean allowExtractFile;
|
||||
|
||||
@Parameter(name = ApiConstants.BACKUP_CHAIN_SIZE, type = CommandType.INTEGER, description = "Backup chain size for backups created with this offering.")
|
||||
private Integer backupChainSize;
|
||||
|
||||
@Parameter(name = ApiConstants.COMPRESSION_LIBRARY, type = CommandType.STRING, description = "Compression library, for offerings that support compression. Accepted values " +
|
||||
"are zstd and zlib. By default, zstd is used for images that support it. If the image only supports zlib, it will be used regardless of this parameter.")
|
||||
private String compressionLibrary;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "Restrict the backup offering to the Zone identified by this ID.", required = true)
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = CommandType.BOOLEAN,
|
||||
description = "Whether users are allowed to create ad-hoc backups and backup schedules when using this offering.", required = true)
|
||||
private Boolean userDrivenBackups;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = DomainResponse.class,
|
||||
description = "Restrict the backup offering to the Domains identified by these IDs.")
|
||||
private List<Long> domainIds;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isCompress() {
|
||||
return Boolean.TRUE.equals(compress);
|
||||
}
|
||||
|
||||
public boolean isValidate() {
|
||||
return Boolean.TRUE.equals(validate);
|
||||
}
|
||||
|
||||
public boolean isAllowQuickRestore() {
|
||||
return Boolean.TRUE.equals(allowQuickRestore);
|
||||
}
|
||||
|
||||
public boolean isAllowExtractFile() {
|
||||
return Boolean.TRUE.equals(allowExtractFile);
|
||||
}
|
||||
|
||||
public Integer getBackupChainSize() {
|
||||
return backupChainSize;
|
||||
}
|
||||
|
||||
public Backup.CompressionLibrary getCompressionLibrary() {
|
||||
if (compressionLibrary == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Backup.CompressionLibrary.valueOf(compressionLibrary);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidParameterValueException(String.format("Invalid compression library, accepted values are zstd and zlib, received [%s].", compressionLibrary));
|
||||
}
|
||||
}
|
||||
|
||||
public String getValidationSteps() {
|
||||
if (validationSteps == null) {
|
||||
return Backup.ValidationSteps.screenshot.name();
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String step : validationSteps.strip().split(",")) {
|
||||
try {
|
||||
Backup.ValidationSteps enumStep = Backup.ValidationSteps.valueOf(step);
|
||||
sb.append(enumStep.name());
|
||||
sb.append(",");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
logger.error("Invalid validation step informed [{}].", step, ex);
|
||||
throw new InvalidParameterValueException(String.format("Invalid validation step [%s] informed. Accepted values are: wait_for_boot, screenshot and execute_command.", step));
|
||||
}
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public List<Long> getDomainIds() {
|
||||
return domainIds;
|
||||
}
|
||||
|
||||
public Boolean getUserDrivenBackups() {
|
||||
return userDrivenBackups;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
|
||||
NetworkRuleConflictException {
|
||||
BackupOffering offering = backupManager.createBackupOffering(this);
|
||||
BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(offering);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -88,6 +88,12 @@ public class CreateBackupScheduleCmd extends BaseCmd {
|
||||
since = "4.21.0")
|
||||
private Boolean quiesceVM;
|
||||
|
||||
@Parameter(name = ApiConstants.ISOLATED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = ApiConstants.PARAMETER_DESCRIPTION_ISOLATED_BACKUPS,
|
||||
since = "4.23.0")
|
||||
private boolean isolated;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -116,6 +122,10 @@ public class CreateBackupScheduleCmd extends BaseCmd {
|
||||
return quiesceVM;
|
||||
}
|
||||
|
||||
public boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.backup;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.ExtractResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.InternalBackupService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "downloadValidationScreenshot", description = "Download validation screenshot of given backup.",
|
||||
responseObject = ExtractResponse.class, since = "4.23.0", requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class DownloadValidationScreenshotCmd extends BaseAsyncCmd {
|
||||
|
||||
@Inject
|
||||
private InternalBackupService internalBackupService;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.BACKUP_ID, type = CommandType.UUID, entityType = BackupResponse.class, required = true,
|
||||
description = "ID of the backup.")
|
||||
private Long backupId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_SCREENSHOT_DOWNLOAD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
Backup backup = _entityMgr.findById(Backup.class, getBackupId());
|
||||
if (backup == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find backup with ID [%s].", getBackupId()));
|
||||
}
|
||||
return "Downloading validation screenshot of backup " + backup.getUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ExtractResponse response = internalBackupService.downloadScreenshot(getBackupId());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Backup backup = _entityMgr.findById(Backup.class, getBackupId());
|
||||
if (backup != null) {
|
||||
return backup.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.backup;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
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.VirtualMachineResponse;
|
||||
import org.apache.cloudstack.backup.InternalBackupService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "finishBackupChain", description = "Finish the backup chain of VM. Currently only has effect on VMs with KBOSS backup offerings.",
|
||||
responseObject = SuccessResponse.class, since = "4.23.0", requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false)
|
||||
public class FinishBackupChainCmd extends BaseCmd {
|
||||
@Inject
|
||||
private InternalBackupService internalBackupService;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = VirtualMachineResponse.class, required = true,
|
||||
description = "ID of the VM to finish the chain.")
|
||||
private Long vmId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
|
||||
NetworkRuleConflictException {
|
||||
boolean result = internalBackupService.finishBackupChain(getVmId());
|
||||
SuccessResponse response = new SuccessResponse();
|
||||
response.setSuccess(result);
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, getVmId());
|
||||
if (vm != null) {
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.backup;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupServiceJobResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
||||
@APICommand(name = "listBackupServiceJobs", description = "List backup service jobs", responseObject = BackupServiceJobResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin}, since = "4.23.0")
|
||||
public class ListBackupServiceJobsCmd extends BaseListCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.LONG, entityType = BackupServiceJobResponse.class, description = "List only job with given ID.")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.BACKUP_ID, type = CommandType.UUID, entityType = BackupResponse.class, description = "List jobs for the given backup.")
|
||||
private Long backupId;
|
||||
|
||||
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "List jobs in the given host. When passing this parameter, only jobs that are currently executing will be returned.")
|
||||
private Long hostId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "List jobs in the given zone.")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "List jobs with the given type. Accepted values are StartCompression, FinalizeCompression and " +
|
||||
"BackupValidation.")
|
||||
private String type;
|
||||
|
||||
@Parameter(name = ApiConstants.EXECUTING, type = CommandType.BOOLEAN, description = "List executing jobs.")
|
||||
private Boolean executing;
|
||||
|
||||
@Parameter(name = ApiConstants.SCHEDULED, type = CommandType.BOOLEAN, description = "List scheduled jobs.")
|
||||
private Boolean scheduled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean getExecuting() {
|
||||
return Boolean.TRUE.equals(executing);
|
||||
}
|
||||
|
||||
public boolean getScheduled() {
|
||||
return Boolean.TRUE.equals(scheduled);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
|
||||
NetworkRuleConflictException {
|
||||
ListResponse<BackupServiceJobResponse> response = _queryService.listBackupServiceJobs(this);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,7 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
@ -38,6 +39,7 @@ import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
@APICommand(name = "restoreBackup",
|
||||
description = "Restores an existing stopped or deleted Instance using an Instance backup",
|
||||
@ -59,6 +61,14 @@ public class RestoreBackupCmd extends BaseAsyncCmd {
|
||||
description = "ID of the backup")
|
||||
private Long backupId;
|
||||
|
||||
@Parameter(name = ApiConstants.QUICK_RESTORE, type = CommandType.BOOLEAN, entityType = BackupResponse.class, description = "Whether to use the quick restore process or not. " +
|
||||
"Currently this parameter is only supported by the KBOSS provider.", since = "4.23.0")
|
||||
private Boolean quickRestore;
|
||||
|
||||
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "If quickrestore is true, which host to start the VM on;" +
|
||||
" otherwise, ignored. Currently this parameter is only supported by the KBOSS provider.", since = "4.23.0", authorized = {RoleType.Admin})
|
||||
private Long hostId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -67,6 +77,14 @@ public class RestoreBackupCmd extends BaseAsyncCmd {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public boolean isQuickRestore() {
|
||||
return BooleanUtils.isTrue(quickRestore);
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -74,7 +92,7 @@ public class RestoreBackupCmd extends BaseAsyncCmd {
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackup(backupId);
|
||||
boolean result = backupManager.restoreBackup(backupId, isQuickRestore(), getHostId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -28,6 +28,7 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
@ -78,6 +79,14 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
||||
description = "ID of the Instance where to attach the restored volume")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.QUICK_RESTORE, type = CommandType.BOOLEAN, description = "Whether to use the quick restore process or not. " +
|
||||
"Currently this parameter is only supported by the KBOSS provider.", since = "4.23.0")
|
||||
private Boolean quickRestore;
|
||||
|
||||
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "If quickrestore is true, which host to start the VM on;" +
|
||||
" otherwise, ignored. Currently this parameter is only supported by the KBOSS provider.", since = "4.23.0", authorized = {RoleType.Admin})
|
||||
private Long hostId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -94,6 +103,14 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public boolean isQuickRestore() {
|
||||
return org.apache.commons.lang3.BooleanUtils.isTrue(quickRestore);
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
@ -106,7 +123,7 @@ public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackupVolumeAndAttachToVM(volumeUuid, backupId, vmId);
|
||||
boolean result = backupManager.restoreBackupVolumeAndAttachToVM(volumeUuid, backupId, vmId, isQuickRestore(), getHostId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -419,6 +419,27 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public CreateNetworkCmd() {
|
||||
}
|
||||
|
||||
public CreateNetworkCmd(long networkOfferingId, String name, String displayText, String gateway, String netmask, String startIp, String endIp, long domainId,
|
||||
String accountName, long zoneId, String aclType, boolean subdomainAccess, boolean displayNetwork) {
|
||||
this.networkOfferingId = networkOfferingId;
|
||||
this.name = name;
|
||||
this.displayText = displayText;
|
||||
this.gateway = gateway;
|
||||
this.netmask = netmask;
|
||||
this.startIp = startIp;
|
||||
this.endIp = endIp;
|
||||
this.domainId = domainId;
|
||||
this.accountName = accountName;
|
||||
this.zoneId = zoneId;
|
||||
this.aclType = aclType;
|
||||
this.subdomainAccess = subdomainAccess;
|
||||
this.displayNetwork = displayNetwork;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
|
||||
@ -36,6 +36,7 @@ import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
@APICommand(name = "createVMFromBackup",
|
||||
description = "Creates and automatically starts a VM from a backup.",
|
||||
@ -70,6 +71,10 @@ public class CreateVMFromBackupCmd extends BaseDeployVMCmd {
|
||||
@Parameter(name = ApiConstants.PRESERVE_IP, type = CommandType.BOOLEAN, description = "Use the same IP/MAC addresses as stored in the backup metadata. Works only if the original Instance is deleted and the IP/MAC address is available.")
|
||||
private Boolean preserveIp;
|
||||
|
||||
@Parameter(name = ApiConstants.QUICK_RESTORE, type = CommandType.BOOLEAN, entityType = BackupResponse.class, description = "Whether to use the quick restore process or not. " +
|
||||
"Currently this parameter is only supported by the KBOSS provider.", since = "4.23.0")
|
||||
private Boolean quickRestore;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -90,6 +95,10 @@ public class CreateVMFromBackupCmd extends BaseDeployVMCmd {
|
||||
return (preserveIp != null) ? preserveIp : false;
|
||||
}
|
||||
|
||||
public Boolean getQuickRestore() {
|
||||
return ObjectUtils.defaultIfNull(this.quickRestore, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
UserVm vm;
|
||||
|
||||
@ -98,6 +98,14 @@ public class DestroyVMCmd extends BaseAsyncCmd implements UserCmd {
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public DestroyVMCmd() {
|
||||
}
|
||||
|
||||
public DestroyVMCmd(Long id, Boolean expunge) {
|
||||
this.id = id;
|
||||
this.expunge = expunge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
@ -136,7 +144,7 @@ public class DestroyVMCmd extends BaseAsyncCmd implements UserCmd {
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
|
||||
CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID));
|
||||
UserVm result = _userVmService.destroyVm(this);
|
||||
UserVm result = _userVmService.destroyVm(this, true);
|
||||
|
||||
UserVmResponse response = new UserVmResponse();
|
||||
if (result != null) {
|
||||
|
||||
@ -85,7 +85,7 @@ public class DeleteVolumeCmd extends BaseCmd {
|
||||
@Override
|
||||
public void execute() throws ConcurrentOperationException {
|
||||
CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID));
|
||||
Volume result = _volumeService.destroyVolume(id, CallContext.current().getCallingAccount(), true, false);
|
||||
Volume result = _volumeService.destroyVolume(id, CallContext.current().getCallingAccount(), true, false, null);
|
||||
if (result != null) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
||||
@ -116,7 +116,7 @@ public class DestroyVolumeCmd extends BaseAsyncCmd {
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID));
|
||||
Volume result = _volumeService.destroyVolume(getId(), CallContext.current().getCallingAccount(), getExpunge(), false);
|
||||
Volume result = _volumeService.destroyVolume(getId(), CallContext.current().getCallingAccount(), getExpunge(), false, null);
|
||||
if (result != null) {
|
||||
VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
@ -79,6 +80,10 @@ public class BackupOfferingResponse extends BaseResponse {
|
||||
@Param(description = "The date this backup offering was created")
|
||||
private Date created;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_OFFERING_DETAILS)
|
||||
@Param(description = "Details for the backup offering", since = "4.23.0")
|
||||
private Map<String, String> details;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
@ -127,4 +132,7 @@ public class BackupOfferingResponse extends BaseResponse {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,10 +71,22 @@ public class BackupResponse extends BaseResponse {
|
||||
@Param(description = "Backup protected (virtual) size in bytes")
|
||||
private Long protectedSize;
|
||||
|
||||
@SerializedName(ApiConstants.UNCOMPRESSED_SIZE)
|
||||
@Param(description = "Backup uncompressed size in bytes. Only defined if backup is compressed.")
|
||||
private Long uncompressedSize;
|
||||
|
||||
@SerializedName(ApiConstants.STATUS)
|
||||
@Param(description = "Backup status")
|
||||
private Backup.Status status;
|
||||
|
||||
@SerializedName(ApiConstants.COMPRESSION_STATUS)
|
||||
@Param(description = "Backup compression status.")
|
||||
private Backup.CompressionStatus compressionStatus;
|
||||
|
||||
@SerializedName(ApiConstants.VALIDATION_STATUS)
|
||||
@Param(description = "Backup validation status.")
|
||||
private Backup.ValidationStatus validationStatus;
|
||||
|
||||
@SerializedName(ApiConstants.VOLUMES)
|
||||
@Param(description = "Backed up volumes")
|
||||
private String volumes;
|
||||
@ -219,6 +231,14 @@ public class BackupResponse extends BaseResponse {
|
||||
this.protectedSize = protectedSize;
|
||||
}
|
||||
|
||||
public Long getUncompressedSize() {
|
||||
return uncompressedSize;
|
||||
}
|
||||
|
||||
public void setUncompressedSize(Long uncompressedSize) {
|
||||
this.uncompressedSize = uncompressedSize;
|
||||
}
|
||||
|
||||
public Backup.Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
@ -227,6 +247,22 @@ public class BackupResponse extends BaseResponse {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Backup.CompressionStatus getCompressionStatus() {
|
||||
return compressionStatus;
|
||||
}
|
||||
|
||||
public void setCompressionStatus(Backup.CompressionStatus compressionStatus) {
|
||||
this.compressionStatus = compressionStatus;
|
||||
}
|
||||
|
||||
public Backup.ValidationStatus getValidationStatus() {
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
public void setValidationStatus(Backup.ValidationStatus validationStatus) {
|
||||
this.validationStatus = validationStatus;
|
||||
}
|
||||
|
||||
public String getVolumes() {
|
||||
return volumes;
|
||||
}
|
||||
|
||||
@ -56,6 +56,10 @@ public class BackupScheduleResponse extends BaseResponse {
|
||||
@Param(description = "maximum number of backups retained")
|
||||
private Integer maxBackups;
|
||||
|
||||
@SerializedName(ApiConstants.ISOLATED)
|
||||
@Param(description = ApiConstants.PARAMETER_DESCRIPTION_ISOLATED_BACKUPS)
|
||||
private boolean isolated;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
@ -111,4 +115,8 @@ public class BackupScheduleResponse extends BaseResponse {
|
||||
public void setQuiesceVM(Boolean quiesceVM) {
|
||||
this.quiesceVM = quiesceVM;
|
||||
}
|
||||
|
||||
public void setIsolated(boolean isolated) {
|
||||
this.isolated = isolated;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class BackupServiceJobResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "Compression job ID.")
|
||||
private Long id;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_ID)
|
||||
@Param(description = "Backup ID.")
|
||||
private String backupId;
|
||||
|
||||
@SerializedName(ApiConstants.HOST_ID)
|
||||
@Param(description = "Host where the job is being executed.")
|
||||
private String hostId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "Zone where the job is being executed.")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ATTEMPTS)
|
||||
@Param(description = "Number of attempts already made to complete this job.")
|
||||
private Integer attempts;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "Compression job type.")
|
||||
private String type;
|
||||
|
||||
@SerializedName(ApiConstants.START_DATE)
|
||||
@Param(description = "Compression job start date.")
|
||||
private Date startDate;
|
||||
|
||||
@SerializedName(ApiConstants.SCHEDULED_DATE)
|
||||
@Param(description = "Compression job scheduled start date.")
|
||||
private Date scheduledDate;
|
||||
|
||||
@SerializedName(ApiConstants.REMOVED)
|
||||
@Param(description = "Compression job scheduled removed date.")
|
||||
private Date removed;
|
||||
|
||||
public BackupServiceJobResponse(Long id, String backupId, String zoneId, Integer attempts, String type, Date startDate, Date scheduledDate, Date removed) {
|
||||
super("backupservicejob");
|
||||
this.id = id;
|
||||
this.backupId = backupId;
|
||||
this.zoneId = zoneId;
|
||||
this.attempts = attempts;
|
||||
this.type = type;
|
||||
this.startDate = startDate;
|
||||
this.scheduledDate = scheduledDate;
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public void setHostId(String hostId) {
|
||||
this.hostId = hostId;
|
||||
}
|
||||
}
|
||||
@ -234,6 +234,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
@Param(description = "The name of the backup offering of the Instance", since = "4.14")
|
||||
private String backupOfferingName;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_PROVIDER)
|
||||
@Param(description = "The name of the backup provider of the offering attached to the Instance", since = "4.23.0")
|
||||
private String backupProvider;
|
||||
|
||||
@SerializedName("forvirtualnetwork")
|
||||
@Param(description = "The virtual Network for the service offering")
|
||||
private Boolean forVirtualNetwork;
|
||||
@ -1362,4 +1366,11 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
this.leaseExpiryDate = leaseExpiryDate;
|
||||
}
|
||||
|
||||
public String getBackupProvider() {
|
||||
return backupProvider;
|
||||
}
|
||||
|
||||
public void setBackupProvider(String backupProvider) {
|
||||
this.backupProvider = backupProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -46,6 +47,22 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
||||
Hidden
|
||||
}
|
||||
|
||||
enum CompressionStatus {
|
||||
Uncompressed, Compressing, FinalizingCompression, Compressed, CompressionError
|
||||
}
|
||||
|
||||
enum ValidationStatus {
|
||||
NotValidated, Validating, Valid, UnableToValidate, NotValid
|
||||
}
|
||||
|
||||
enum ValidationSteps {
|
||||
wait_for_boot, screenshot, execute_command
|
||||
}
|
||||
|
||||
enum CompressionLibrary {
|
||||
zstd, zlib
|
||||
}
|
||||
|
||||
class Metric {
|
||||
private Long backupSize = 0L;
|
||||
private Long dataSize = 0L;
|
||||
@ -132,7 +149,7 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
||||
}
|
||||
}
|
||||
|
||||
class VolumeInfo {
|
||||
class VolumeInfo implements Serializable {
|
||||
private String uuid;
|
||||
private Volume.Type type;
|
||||
private Long size;
|
||||
@ -201,11 +218,14 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
||||
String getType();
|
||||
Date getDate();
|
||||
Backup.Status getStatus();
|
||||
Backup.CompressionStatus getCompressionStatus();
|
||||
Backup.ValidationStatus getValidationStatus();
|
||||
Long getSize();
|
||||
Long getProtectedSize();
|
||||
void setName(String name);
|
||||
String getDescription();
|
||||
void setDescription(String description);
|
||||
Long getUncompressedSize();
|
||||
List<VolumeInfo> getBackedUpVolumes();
|
||||
long getZoneId();
|
||||
Map<String, String> getDetails();
|
||||
|
||||
@ -20,6 +20,8 @@ package org.apache.cloudstack.backup;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.capacity.Capacity;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.api.command.admin.backup.CloneBackupOfferingCmd;
|
||||
@ -31,17 +33,16 @@ import org.apache.cloudstack.api.command.user.backup.DeleteBackupScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.CreateBackupOfferingCmd;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VmDiskInfo;
|
||||
|
||||
/**
|
||||
@ -138,6 +139,12 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
||||
*/
|
||||
BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd);
|
||||
|
||||
/**
|
||||
* Create a new Backup and Recovery policy to CloudStack. Currently only supported for KBOSS.
|
||||
* @param cmd create backup offering cmd
|
||||
*/
|
||||
BackupOffering createBackupOffering(final CreateBackupOfferingCmd cmd);
|
||||
|
||||
List<Long> getBackupOfferingDomains(final Long offeringId);
|
||||
|
||||
/**
|
||||
@ -210,7 +217,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
||||
/**
|
||||
* Restore a full VM from backup
|
||||
*/
|
||||
boolean restoreBackup(final Long backupId);
|
||||
boolean restoreBackup(final Long backupId, boolean quickRestore, Long hostId);
|
||||
|
||||
Map<Long, Network.IpAddresses> getIpToNetworkMapFromBackup(Backup backup, boolean preserveIps, List<Long> networkIds);
|
||||
|
||||
@ -221,12 +228,12 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
||||
/**
|
||||
* Restore a backup to a new Instance
|
||||
*/
|
||||
boolean restoreBackupToVM(Long backupId, Long vmId) throws ResourceUnavailableException;
|
||||
boolean restoreBackupToVM(Long backupId, Long vmId, boolean quickrestore) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Restore a backed up volume and attach it to a VM
|
||||
*/
|
||||
boolean restoreBackupVolumeAndAttachToVM(final String backedUpVolumeUuid, final Long backupId, final Long vmId) throws Exception;
|
||||
boolean restoreBackupVolumeAndAttachToVM(final String backedUpVolumeUuid, final Long backupId, final Long vmId, boolean isQuickRestore, Long hostId) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes a backup
|
||||
|
||||
@ -63,6 +63,17 @@ public interface BackupProvider {
|
||||
*/
|
||||
boolean removeVMFromBackupOffering(VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Removes the specified backup schedule from a virtual machine.
|
||||
*
|
||||
* @param vm the virtual machine from which the schedule will be removed.
|
||||
* @param backupSchedule the backup schedule to be removed.
|
||||
* @return {@code true} if the operation was successful; {@code false} otherwise.
|
||||
*/
|
||||
default boolean removeVMBackupSchedule(VirtualMachine vm, BackupSchedule backupSchedule) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the provider will delete backups on removal of VM from the offering
|
||||
* @return boolean result
|
||||
@ -73,11 +84,14 @@ public interface BackupProvider {
|
||||
* Starts and creates an adhoc backup process
|
||||
* for a previously registered VM backup
|
||||
*
|
||||
* @param vm the machine to make a backup of
|
||||
* @param quiesceVM instance will be quiesced for checkpointing for backup. Applicable only to NAS plugin.
|
||||
* @param vm
|
||||
* the machine to make a backup of
|
||||
* @param quiesceVM
|
||||
* instance will be quiesced for checkpointing for backup. Applicable only to NAS plugin.
|
||||
* @param isolated
|
||||
* @return the result and {code}Backup{code} {code}Object{code}
|
||||
*/
|
||||
Pair<Boolean, Backup> takeBackup(VirtualMachine vm, Boolean quiesceVM);
|
||||
Pair<Boolean, Backup> takeBackup(VirtualMachine vm, Boolean quiesceVM, boolean isolated, Long backupScheduleId);
|
||||
|
||||
/**
|
||||
* Delete an existing backup
|
||||
@ -99,17 +113,18 @@ public interface BackupProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
Pair<Boolean, String> restoreBackupToVM(VirtualMachine vm, Backup backup, String hostIp, String dataStoreUuid);
|
||||
Pair<Boolean, String> restoreBackupToVM(VirtualMachine vm, Backup backup, String hostIp, String dataStoreUuid, boolean quickrestore);
|
||||
|
||||
/**
|
||||
* Restore VM from backup
|
||||
*/
|
||||
boolean restoreVMFromBackup(VirtualMachine vm, Backup backup);
|
||||
boolean restoreVMFromBackup(VirtualMachine vm, Backup backup, boolean quickRestore, Long hostId);
|
||||
|
||||
/**
|
||||
* Restore a volume from a backup
|
||||
*/
|
||||
Pair<Boolean, String> restoreBackedUpVolume(Backup backup, Backup.VolumeInfo backupVolumeInfo, String hostIp, String dataStoreUuid, Pair<String, VirtualMachine.State> vmNameAndState);
|
||||
Pair<Boolean, String> restoreBackedUpVolume(Backup backup, Backup.VolumeInfo backupVolumeInfo, String hostIp, String dataStoreUuid,
|
||||
Pair<String, VirtualMachine.State> vmNameAndState, VirtualMachine vm, boolean quickRestore);
|
||||
|
||||
/**
|
||||
* Syncs backup metrics (backup size, protected size) from the plugin and stores it within the provider
|
||||
@ -152,5 +167,4 @@ public interface BackupProvider {
|
||||
* @param zoneId the zone for which to return metrics
|
||||
*/
|
||||
void syncBackupStorageStats(Long zoneId);
|
||||
|
||||
}
|
||||
|
||||
@ -34,4 +34,5 @@ public interface BackupSchedule extends ControlledEntity, InternalIdentity {
|
||||
Boolean getQuiesceVM();
|
||||
int getMaxBackups();
|
||||
String getUuid();
|
||||
boolean isIsolated();
|
||||
}
|
||||
|
||||
@ -0,0 +1,142 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface InternalBackupProvider extends BackupProvider {
|
||||
String VM_WORK_JOB_HANDLER = InternalBackupService.class.getSimpleName();
|
||||
|
||||
ConfigKey<Integer> backupCompressionTimeout = new ConfigKey<>("Advanced", Integer.class, "backup.compression.timeout", "28800", "Backup compression timeout (in " +
|
||||
"seconds). Will only start counting once the backup compression async job actually starts. This setting is currently only applicable to KBOSS.", true,
|
||||
ConfigKey.Scope.Cluster);
|
||||
|
||||
ConfigKey<Double> backupCompressionMinimumFreeStorage = new ConfigKey<>("Advanced", Double.class, "backup.compression.minimum.free.storage", "1", "The minimum " +
|
||||
"amount of free storage that should be available to start the compression. This configuration uses a multiplier on the backup size, by default, it needs the same " +
|
||||
"amount of free storage as the backup uses while uncompressed. This setting is currently only applicable to KBOSS.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<Integer> backupCompressionCoroutines = new ConfigKey<>("Advanced", Integer.class, "backup.compression.coroutines", "1", "Number of parallel coroutines " +
|
||||
"for the compression process. This is translated to qemu-img '-m' parameter. This setting is currently only applicable to KBOSS.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
ConfigKey<Integer> backupCompressionRateLimit = new ConfigKey<>("Advanced", Integer.class, "backup.compression.rate.limit", "0", "Limit the compression rate to " +
|
||||
"this configuration's value (in MB/s). Values lower than 1 disable the limit. This setting is currently only applicable to KBOSS.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
ConfigKey<Integer> backupValidationTimeout = new ConfigKey<>("Advanced", Integer.class, "backup.validation.timeout", "3600", "Backup validation job timeout (in " +
|
||||
"seconds). Will only start counting once the backup validation async job actually starts. This setting is currently only applicable to KBOSS.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
/**
|
||||
* Actually execute the backup after being queued.
|
||||
* */
|
||||
default Pair<Boolean, Long> orchestrateTakeBackup(Backup backup, boolean quiesceVm, boolean isolated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually delete the backup after being queued.
|
||||
* */
|
||||
default Boolean orchestrateDeleteBackup(Backup backup, boolean forced) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually restore the backup after being queued.
|
||||
* */
|
||||
default Boolean orchestrateRestoreVMFromBackup(Backup backup, VirtualMachine vm, boolean quickRestore, Long hostId, boolean sameVmAsBackup) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any backup providers that want to schedule their backup restore jobs in the same queue as the VM jobs.
|
||||
* Otherwise, just use the restoreBackedUpVolume method.
|
||||
* */
|
||||
default Pair<Boolean, String> orchestrateRestoreBackedUpVolume(Backup backup, VirtualMachine vm, Backup.VolumeInfo backupVolumeInfo, String hostIp, boolean quickRestore) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that want to allow backup compression through ACS.<br/>
|
||||
* The compression is done in two steps:<br/>
|
||||
* 1) Compress the backup to a different file;<br/>
|
||||
* 2) Switch the old file for the newly compressed one.<br/>
|
||||
* <br/> <br/>
|
||||
* This method is supposed to execute step 1.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
default boolean startBackupCompression(long backupId, long hostId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that want to allow backup compression through ACS.<br/>
|
||||
* The compression is done in two steps:<br/>
|
||||
* 1) Compress the backup to a different file;<br/>
|
||||
* 2) Switch the old file for the newly compressed one.<br/>
|
||||
* <br/> <br/>
|
||||
* This method is supposed to execute step 2.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
default boolean finalizeBackupCompression(long backupId, long hostId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean validateBackup(long backupId, long hostId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that allow volume detach but need to prepare it beforehand.
|
||||
* */
|
||||
default void prepareVolumeForDetach(Volume volume, VirtualMachine virtualMachine) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that allow volume migration but need to prepare it beforehand.
|
||||
* */
|
||||
default void prepareVolumeForMigration(Volume volume, VirtualMachine virtualMachine) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that must update metadata regarding a volume after certain operations (such as after a volume migration).
|
||||
* */
|
||||
default void updateVolumeId(VirtualMachine virtualMachine, long oldVolumeId, long newVolumeId) {
|
||||
}
|
||||
|
||||
default Set<String> getSecondaryStorageUrls(UserVm userVm) {
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten by any native backup providers that are compatible with VM Snapshots but need to prepare the VM to be reverted.
|
||||
* Currently, the only strategy that calls this method is the {@code KvmFileBasedStorageVmSnapshotStrategy}.
|
||||
* */
|
||||
default void prepareVmForSnapshotRevert(VMSnapshot vmSnapshot, VirtualMachine virtualMachine) {
|
||||
}
|
||||
|
||||
default boolean finishBackupChains(VirtualMachine virtualMachine) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import org.apache.cloudstack.api.response.ExtractResponse;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface InternalBackupService {
|
||||
|
||||
void configureChainInfo(DataTO volumeTo, Command cmd);
|
||||
|
||||
void cleanupBackupMetadata(long volumeId);
|
||||
|
||||
void prepareVolumeForDetach(Volume volume, VirtualMachine virtualMachine);
|
||||
|
||||
void prepareVolumeForMigration(Volume volume);
|
||||
|
||||
void prepareVmForSnapshotRevert(VMSnapshot vmSnapshot);
|
||||
|
||||
void updateVolumeId(long oldVolumeId, long newVolumeId);
|
||||
|
||||
Set<String> getSecondaryStorageUrls(UserVm userVm);
|
||||
|
||||
boolean startBackupCompression(long backupId, long hostId, long zoneId);
|
||||
|
||||
boolean finalizeBackupCompression(long backupId, long hostId, long zoneId);
|
||||
|
||||
boolean validateBackup(long backupId, long hostId, long zoneId);
|
||||
|
||||
ExtractResponse downloadScreenshot(long backupId);
|
||||
|
||||
boolean finishBackupChain(long vmId);
|
||||
}
|
||||
@ -41,6 +41,7 @@ import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.address.ListQuarantinedIpsCmd;
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupServiceJobsCmd;
|
||||
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
|
||||
@ -63,6 +64,7 @@ import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
||||
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.api.response.BackupServiceJobResponse;
|
||||
import org.apache.cloudstack.api.response.BucketResponse;
|
||||
import org.apache.cloudstack.api.response.DetailOptionsResponse;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
@ -119,7 +121,7 @@ public interface QueryService {
|
||||
"Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null);
|
||||
|
||||
ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<>(String.class,
|
||||
"user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController",
|
||||
"user.vm.readonly.details", "Advanced", "dataDiskController, rootDiskController, backupValidationCommandTimeout, backupValidationScreenshotWait, backupValidationBootTimeout",
|
||||
"List of read-only VM settings/details as comma separated string", true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.CSV, null, "");
|
||||
|
||||
ConfigKey<Boolean> SortKeyAscending = new ConfigKey<>("Advanced", Boolean.class, "sortkey.algorithm", "true",
|
||||
@ -224,4 +226,6 @@ public interface QueryService {
|
||||
ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd listObjectStoragePoolsCmd);
|
||||
|
||||
ListResponse<BucketResponse> searchForBuckets(ListBucketsCmd listBucketsCmd);
|
||||
|
||||
ListResponse<BackupServiceJobResponse> listBackupServiceJobs(ListBackupServiceJobsCmd cmd);
|
||||
}
|
||||
|
||||
@ -18,8 +18,8 @@ package org.apache.cloudstack.secstorage.heuristics;
|
||||
|
||||
/**
|
||||
* The type of the heuristic used in the allocation process of secondary storage resources.
|
||||
* Valid options are: {@link #ISO}, {@link #SNAPSHOT}, {@link #TEMPLATE} and {@link #VOLUME}
|
||||
* Valid options are: {@link #ISO}, {@link #SNAPSHOT}, {@link #TEMPLATE}, {@link #VOLUME} and {@link #BACKUP}
|
||||
*/
|
||||
public enum HeuristicType {
|
||||
ISO, SNAPSHOT, TEMPLATE, VOLUME
|
||||
ISO, SNAPSHOT, TEMPLATE, VOLUME, BACKUP
|
||||
}
|
||||
|
||||
@ -627,6 +627,11 @@
|
||||
<artifactId>cloud-plugin-integrations-veeam-control-service</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-backup-kvm-backup-on-secondary-storage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-integrations-kubernetes-service</artifactId>
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MigrateBackupsBetweenSecondaryStoragesCommand extends MigrateBetweenSecondaryStoragesCommand {
|
||||
|
||||
List<List<DataTO>> backupChain;
|
||||
|
||||
public MigrateBackupsBetweenSecondaryStoragesCommand() {
|
||||
}
|
||||
|
||||
public MigrateBackupsBetweenSecondaryStoragesCommand(List<List<DataTO>> backupChain, DataStoreTO srcDataStore, DataStoreTO destDataStore) {
|
||||
super(srcDataStore, destDataStore);
|
||||
this.backupChain = backupChain;
|
||||
}
|
||||
|
||||
public List<List<DataTO>> getBackupChain() {
|
||||
return backupChain;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
|
||||
public abstract class MigrateBetweenSecondaryStoragesCommand extends Command {
|
||||
|
||||
DataStoreTO srcDataStore;
|
||||
DataStoreTO destDataStore;
|
||||
|
||||
public MigrateBetweenSecondaryStoragesCommand() {
|
||||
}
|
||||
|
||||
public MigrateBetweenSecondaryStoragesCommand(DataStoreTO srcDataStore, DataStoreTO destDataStore) {
|
||||
this.srcDataStore = srcDataStore;
|
||||
this.destDataStore = destDataStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DataStoreTO getSrcDataStore() {
|
||||
return srcDataStore;
|
||||
}
|
||||
|
||||
public DataStoreTO getDestDataStore() {
|
||||
return destDataStore;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MigrateBetweenSecondaryStoragesCommandAnswer extends Answer {
|
||||
|
||||
List<Pair<Long, String>> migratedResourcesIdAndCheckpointPath;
|
||||
|
||||
public MigrateBetweenSecondaryStoragesCommandAnswer() {
|
||||
}
|
||||
|
||||
public MigrateBetweenSecondaryStoragesCommandAnswer(MigrateBetweenSecondaryStoragesCommand cmd, boolean success, String result, List<Pair<Long, String>> migratedResourcesIdAndCheckpointPath) {
|
||||
super(cmd, success, result);
|
||||
this.migratedResourcesIdAndCheckpointPath = migratedResourcesIdAndCheckpointPath;
|
||||
}
|
||||
|
||||
public List<Pair<Long, String>> getMigratedResources() {
|
||||
return migratedResourcesIdAndCheckpointPath;
|
||||
}
|
||||
}
|
||||
@ -22,13 +22,15 @@ package com.cloud.agent.api;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.host.Host;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class StartCommand extends Command {
|
||||
VirtualMachineTO vm;
|
||||
String hostIp;
|
||||
boolean executeInSequence = false;
|
||||
String secondaryStorage;
|
||||
private List<String> secondaryStorages;
|
||||
|
||||
public VirtualMachineTO getVirtualMachine() {
|
||||
return vm;
|
||||
@ -50,18 +52,18 @@ public class StartCommand extends Command {
|
||||
this.vm = vm;
|
||||
this.hostIp = host.getPrivateIpAddress();
|
||||
this.executeInSequence = executeInSequence;
|
||||
this.secondaryStorage = null;
|
||||
this.secondaryStorages = null;
|
||||
}
|
||||
|
||||
public String getHostIp() {
|
||||
return this.hostIp;
|
||||
}
|
||||
|
||||
public String getSecondaryStorage() {
|
||||
return this.secondaryStorage;
|
||||
public List<String> getSecondaryStorages() {
|
||||
return this.secondaryStorages;
|
||||
}
|
||||
|
||||
public void setSecondaryStorage(String secondary) {
|
||||
this.secondaryStorage = secondary;
|
||||
public void setSecondaryStorages(List<String> secondary) {
|
||||
this.secondaryStorages = secondary;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,20 +20,19 @@ package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateDiskOnlyVmSnapshotAnswer extends Answer {
|
||||
|
||||
protected Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath;
|
||||
protected Map<String, Long> mapVolumeToSnapshotSize;
|
||||
|
||||
public CreateDiskOnlyVmSnapshotAnswer(Command command, boolean success, String details, Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath) {
|
||||
public CreateDiskOnlyVmSnapshotAnswer(Command command, boolean success, String details, Map<String, Long> mapVolumeToSnapshotSize) {
|
||||
super(command, success, details);
|
||||
this.mapVolumeToSnapshotSizeAndNewVolumePath = mapVolumeToSnapshotSizeAndNewVolumePath;
|
||||
this.mapVolumeToSnapshotSize = mapVolumeToSnapshotSize;
|
||||
}
|
||||
|
||||
public Map<String, Pair<Long, String>> getMapVolumeToSnapshotSizeAndNewVolumePath() {
|
||||
return mapVolumeToSnapshotSizeAndNewVolumePath;
|
||||
public Map<String, Long> getMapVolumeToSnapshotSize() {
|
||||
return mapVolumeToSnapshotSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.VMSnapshotBaseCommand;
|
||||
import com.cloud.agent.api.VMSnapshotTO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
|
||||
@ -30,12 +31,19 @@ public class CreateDiskOnlyVmSnapshotCommand extends VMSnapshotBaseCommand {
|
||||
|
||||
protected VirtualMachine.State vmState;
|
||||
|
||||
public CreateDiskOnlyVmSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) {
|
||||
super(vmName, snapshot, volumeTOs, guestOSType);
|
||||
List<Pair<VolumeObjectTO, String>> volumeTosAndNewPaths;
|
||||
|
||||
public CreateDiskOnlyVmSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<Pair<VolumeObjectTO, String>> volumeTosAndNewPaths, String guestOSType, VirtualMachine.State vmState) {
|
||||
super(vmName, snapshot, null, guestOSType);
|
||||
this.vmState = vmState;
|
||||
this.volumeTosAndNewPaths = volumeTosAndNewPaths;
|
||||
}
|
||||
|
||||
public VirtualMachine.State getVmState() {
|
||||
return vmState;
|
||||
}
|
||||
|
||||
public List<Pair<VolumeObjectTO, String>> getVolumeTosAndNewPaths() {
|
||||
return volumeTosAndNewPaths;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,28 +19,28 @@
|
||||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.storage.to.DeltaMergeTreeTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MergeDiskOnlyVmSnapshotCommand extends Command {
|
||||
|
||||
private List<SnapshotMergeTreeTO> snapshotMergeTreeToList;
|
||||
private VirtualMachine.State vmState;
|
||||
private List<DeltaMergeTreeTO> snapshotMergeTreeToList;
|
||||
private boolean isVmRunning;
|
||||
private String vmName;
|
||||
|
||||
public MergeDiskOnlyVmSnapshotCommand(List<SnapshotMergeTreeTO> snapshotMergeTreeToList, VirtualMachine.State vmState, String vmName) {
|
||||
public MergeDiskOnlyVmSnapshotCommand(List<DeltaMergeTreeTO> snapshotMergeTreeToList, boolean isVmRunning, String vmName) {
|
||||
this.snapshotMergeTreeToList = snapshotMergeTreeToList;
|
||||
this.vmState = vmState;
|
||||
this.isVmRunning = isVmRunning;
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public List<SnapshotMergeTreeTO> getSnapshotMergeTreeToList() {
|
||||
public List<DeltaMergeTreeTO> getDeltaMergeTreeToList() {
|
||||
return snapshotMergeTreeToList;
|
||||
}
|
||||
|
||||
public VirtualMachine.State getVmState() {
|
||||
return vmState;
|
||||
public boolean isVmRunning() {
|
||||
return isVmRunning;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
|
||||
@ -85,4 +85,8 @@ public interface StorageProcessor {
|
||||
public Answer checkDataStoreStoragePolicyCompliance(CheckDataStoreStoragePolicyComplianceCommand cmd);
|
||||
|
||||
public Answer syncVolumePath(SyncVolumePathCommand cmd);
|
||||
|
||||
default Answer deleteBackup(DeleteCommand cmd) {
|
||||
return new Answer(cmd, false, "Operation not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,6 +154,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
|
||||
answer = processor.deleteVolume(cmd);
|
||||
} else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
|
||||
answer = processor.deleteSnapshot(cmd);
|
||||
} else if (data.getObjectType() == DataObjectType.BACKUP) {
|
||||
answer = processor.deleteBackup(cmd);
|
||||
} else {
|
||||
answer = new Answer(cmd, false, "unsupported type");
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
public class CleanupKbossBackupErrorAnswer extends Answer {
|
||||
private Map<String, Pair<String, Boolean>> volumeIdToPathAndChainEnded;
|
||||
private boolean vmRunning;
|
||||
|
||||
public CleanupKbossBackupErrorAnswer(Command cmd, Map<String, Pair<String, Boolean>> volumeIdToPathAndChainEnded, boolean vmRunning) {
|
||||
super(cmd, MapUtils.isNotEmpty(volumeIdToPathAndChainEnded), null);
|
||||
this.volumeIdToPathAndChainEnded = volumeIdToPathAndChainEnded;
|
||||
this.vmRunning = vmRunning;
|
||||
}
|
||||
|
||||
public Map<String, Pair<String, Boolean>> getVolumeIdToPathAndChainEnded() {
|
||||
return volumeIdToPathAndChainEnded;
|
||||
}
|
||||
|
||||
public boolean isVmRunning() {
|
||||
return vmRunning;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.KbossTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CleanupKbossBackupErrorCommand extends Command {
|
||||
|
||||
private boolean runningVM;
|
||||
|
||||
private boolean errorOnCreate;
|
||||
|
||||
private boolean endOfChain;
|
||||
|
||||
private boolean isTopDelta;
|
||||
|
||||
private String vmName;
|
||||
|
||||
private String imageStoreUrl;
|
||||
|
||||
private List<KbossTO> kbossTOS;
|
||||
|
||||
public CleanupKbossBackupErrorCommand(boolean runningVM, boolean errorOnCreate, boolean endOfChain, boolean isTopDelta, String vmName, String imageStoreUrl, List<KbossTO> kbossTOS) {
|
||||
this.errorOnCreate = errorOnCreate;
|
||||
this.runningVM = runningVM;
|
||||
this.endOfChain = endOfChain;
|
||||
this.isTopDelta = isTopDelta;
|
||||
this.vmName = vmName;
|
||||
this.imageStoreUrl = imageStoreUrl;
|
||||
this.kbossTOS = kbossTOS;
|
||||
}
|
||||
|
||||
public boolean isErrorOnCreate() {
|
||||
return errorOnCreate;
|
||||
}
|
||||
|
||||
public boolean isEndOfChain() {
|
||||
return endOfChain;
|
||||
}
|
||||
|
||||
public boolean isTopDelta() {
|
||||
return isTopDelta;
|
||||
}
|
||||
|
||||
public boolean isRunningVM() {
|
||||
return runningVM;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public String getImageStoreUrl() {
|
||||
return imageStoreUrl;
|
||||
}
|
||||
|
||||
public List<KbossTO> getKbossTOs() {
|
||||
return kbossTOS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CleanupKbossValidationCommand extends Command {
|
||||
|
||||
private String vmName;
|
||||
|
||||
private Set<String> secondaryStorages;
|
||||
|
||||
public CleanupKbossValidationCommand(String vmName, Set<String> secondaryStorages) {
|
||||
this.vmName = vmName;
|
||||
this.secondaryStorages = secondaryStorages;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public Set<String> getSecondaryStorages() {
|
||||
return secondaryStorages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.DeltaMergeTreeTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CompressBackupCommand extends Command {
|
||||
|
||||
private List<DeltaMergeTreeTO> backupDeltasToCompress;
|
||||
|
||||
private List<String> backupChainImageStoreUrls;
|
||||
|
||||
private long minFreeStorage;
|
||||
|
||||
private Backup.CompressionLibrary compressionLib;
|
||||
|
||||
private int coroutines;
|
||||
|
||||
private int rateLimit;
|
||||
|
||||
public CompressBackupCommand(List<DeltaMergeTreeTO> backupDeltasToCompress, List<String> backupChainImageStoreUrls, long minFreeStorage, Backup.CompressionLibrary compressionLib, int coroutines, int rateLimit) {
|
||||
this.backupChainImageStoreUrls = backupChainImageStoreUrls;
|
||||
this.backupDeltasToCompress = backupDeltasToCompress;
|
||||
this.minFreeStorage = minFreeStorage;
|
||||
this.compressionLib = compressionLib;
|
||||
this.coroutines = coroutines;
|
||||
this.rateLimit = rateLimit;
|
||||
}
|
||||
|
||||
public List<DeltaMergeTreeTO> getBackupDeltasToCompress() {
|
||||
return backupDeltasToCompress;
|
||||
}
|
||||
|
||||
public List<String> getBackupChainImageStoreUrls() {
|
||||
return backupChainImageStoreUrls;
|
||||
}
|
||||
|
||||
public long getMinFreeStorage() {
|
||||
return minFreeStorage;
|
||||
}
|
||||
|
||||
public Backup.CompressionLibrary getCompressionLib() {
|
||||
return compressionLib;
|
||||
}
|
||||
|
||||
public int getCoroutines() {
|
||||
return coroutines;
|
||||
}
|
||||
|
||||
public int getRateLimit() {
|
||||
return rateLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConsolidateVolumesAnswer extends Answer {
|
||||
|
||||
private List<VolumeObjectTO> successfullyConsolidatedVolumes;
|
||||
|
||||
public ConsolidateVolumesAnswer(Command command, boolean success, String details, List<VolumeObjectTO> successfullyConsolidatedVolumes) {
|
||||
super(command, success, details);
|
||||
this.successfullyConsolidatedVolumes = successfullyConsolidatedVolumes;
|
||||
}
|
||||
|
||||
public List<VolumeObjectTO> getSuccessfullyConsolidatedVolumes() {
|
||||
return successfullyConsolidatedVolumes;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConsolidateVolumesCommand extends Command {
|
||||
|
||||
private List<VolumeObjectTO> volumesToConsolidate;
|
||||
|
||||
private List<String> secondaryStorageUuids;
|
||||
|
||||
private String vmName;
|
||||
|
||||
public ConsolidateVolumesCommand(List<VolumeInfo> volumesToConsolidate, List<String> secondaryStorageUuids, String vmName) {
|
||||
this.volumesToConsolidate = volumesToConsolidate.stream().map(vol -> (VolumeObjectTO)vol.getTO()).collect(Collectors.toList());
|
||||
this.secondaryStorageUuids = secondaryStorageUuids;
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public List<VolumeObjectTO> getVolumesToConsolidate() {
|
||||
return volumesToConsolidate;
|
||||
}
|
||||
|
||||
public List<String> getSecondaryStorageUuids() {
|
||||
return secondaryStorageUuids;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.BackupDeltaTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FinalizeBackupCompressionCommand extends Command {
|
||||
private boolean cleanup;
|
||||
|
||||
private List<BackupDeltaTO> backupDeltaTO;
|
||||
|
||||
public FinalizeBackupCompressionCommand(boolean cleanup, List<BackupDeltaTO> backupDeltaTO) {
|
||||
this.cleanup = cleanup;
|
||||
this.backupDeltaTO = backupDeltaTO;
|
||||
}
|
||||
|
||||
public boolean isCleanup() {
|
||||
return cleanup;
|
||||
}
|
||||
|
||||
public List<BackupDeltaTO> getBackupDeltaTOList() {
|
||||
return backupDeltaTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.cloudstack.storage.to.BackupDeltaTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PrepareValidationCommand extends Command {
|
||||
|
||||
private List<Pair<BackupDeltaTO, VolumeObjectTO>> backupToVolumeList;
|
||||
|
||||
private Set<String> imageStoreSet;
|
||||
|
||||
public PrepareValidationCommand(List<Pair<BackupDeltaTO, VolumeObjectTO>> backupToVolumeList, Set<String> imageStoreSet) {
|
||||
this.backupToVolumeList = backupToVolumeList;
|
||||
this.imageStoreSet = imageStoreSet;
|
||||
}
|
||||
|
||||
public List<Pair<BackupDeltaTO, VolumeObjectTO>> getBackupToVolumeList() {
|
||||
return backupToVolumeList;
|
||||
}
|
||||
|
||||
public Set<String> getImageStoreSet() {
|
||||
return imageStoreSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class RestoreKbossBackupAnswer extends Answer {
|
||||
|
||||
private Set<String> secondaryStorageUuids;
|
||||
|
||||
public RestoreKbossBackupAnswer(Command command, Set<String> secondaryStorageUuids) {
|
||||
super(command);
|
||||
this.secondaryStorageUuids = secondaryStorageUuids;
|
||||
}
|
||||
|
||||
public RestoreKbossBackupAnswer(Command command, Exception e, Set<String> secondaryStorageUuids) {
|
||||
super(command, e);
|
||||
this.secondaryStorageUuids = secondaryStorageUuids;
|
||||
}
|
||||
|
||||
public Set<String> getSecondaryStorageUuids() {
|
||||
return secondaryStorageUuids;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.cloudstack.storage.to.BackupDeltaTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class RestoreKbossBackupCommand extends Command {
|
||||
|
||||
private Set<BackupDeltaTO> deltasToRemove;
|
||||
|
||||
private Set<Pair<BackupDeltaTO, VolumeObjectTO>> backupAndVolumePairs;
|
||||
|
||||
private Set<String> secondaryStorageUrls;
|
||||
|
||||
private boolean quickRestore;
|
||||
|
||||
public RestoreKbossBackupCommand(Set<BackupDeltaTO> deltasToRemove, Set<Pair<BackupDeltaTO, VolumeObjectTO>> backupAndVolumePairs, Set<String> secondaryStorageUrls,
|
||||
boolean quickRestore) {
|
||||
this.deltasToRemove = deltasToRemove;
|
||||
this.backupAndVolumePairs = backupAndVolumePairs;
|
||||
this.secondaryStorageUrls = secondaryStorageUrls;
|
||||
this.quickRestore = quickRestore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<BackupDeltaTO> getDeltasToRemove() {
|
||||
return deltasToRemove;
|
||||
}
|
||||
|
||||
public Set<Pair<BackupDeltaTO, VolumeObjectTO>> getBackupAndVolumePairs() {
|
||||
return backupAndVolumePairs;
|
||||
}
|
||||
|
||||
public Set<String> getSecondaryStorageUrls() {
|
||||
return secondaryStorageUrls;
|
||||
}
|
||||
|
||||
public boolean isQuickRestore() {
|
||||
return quickRestore;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.BackupDeltaTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TakeBackupHashCommand extends Command {
|
||||
|
||||
private List<BackupDeltaTO> backupDeltaTOList;
|
||||
|
||||
private String backupUuid;
|
||||
|
||||
public TakeBackupHashCommand(List<BackupDeltaTO> backupDeltaTOList, String backupUuid) {
|
||||
this.backupDeltaTOList = backupDeltaTOList;
|
||||
this.backupUuid = backupUuid;
|
||||
}
|
||||
|
||||
public List<BackupDeltaTO> getBackupDeltaTOList() {
|
||||
return backupDeltaTOList;
|
||||
}
|
||||
|
||||
public String getBackupUuid() {
|
||||
return backupUuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.BackupException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TakeKbossBackupAnswer extends Answer {
|
||||
|
||||
private Map<String, String> mapVolumeUuidToNewVolumePath;
|
||||
private Map<String, Pair<String, Long>> mapVolumeUuidToDeltaPathOnSecondaryAndSize;
|
||||
private boolean isVmConsistent = true;
|
||||
|
||||
public TakeKbossBackupAnswer(Command command, boolean success, Map<String, String> mapVolumeUuidToNewVolumePath,
|
||||
Map<String, Pair<String, Long>> mapVolumeUuidToDeltaPathOnSecondaryAndSize) {
|
||||
super(command, success, null);
|
||||
this.mapVolumeUuidToNewVolumePath = mapVolumeUuidToNewVolumePath;
|
||||
this.mapVolumeUuidToDeltaPathOnSecondaryAndSize = mapVolumeUuidToDeltaPathOnSecondaryAndSize;
|
||||
}
|
||||
|
||||
public TakeKbossBackupAnswer(Command command, Exception e) {
|
||||
super(command, e);
|
||||
if (e instanceof BackupException) {
|
||||
this.isVmConsistent = ((BackupException)e).isVmConsistent();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getMapVolumeUuidToNewVolumePath() {
|
||||
return mapVolumeUuidToNewVolumePath;
|
||||
}
|
||||
|
||||
public Map<String, Pair<String, Long>> getMapVolumeUuidToDeltaPathOnSecondaryAndSize() {
|
||||
return mapVolumeUuidToDeltaPathOnSecondaryAndSize;
|
||||
}
|
||||
|
||||
public boolean isVmConsistent() {
|
||||
return isVmConsistent;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import org.apache.cloudstack.storage.to.KbossTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TakeKbossBackupCommand extends Command {
|
||||
|
||||
private boolean quiesceVm;
|
||||
|
||||
private boolean runningVM;
|
||||
|
||||
private boolean endChain;
|
||||
|
||||
private String vmName;
|
||||
|
||||
private String imageStoreUrl;
|
||||
|
||||
private List<String> backupChainImageStoreUrls;
|
||||
|
||||
private List<KbossTO> kbossTOS;
|
||||
|
||||
private boolean isolated;
|
||||
|
||||
public TakeKbossBackupCommand(boolean quiesceVm, boolean runningVM, boolean endChain, String vmName, String imageStoreUrl, List<String> backupChainImageStoreUrls, List<KbossTO> kbossTOS, boolean isolated) {
|
||||
this.quiesceVm = quiesceVm;
|
||||
this.runningVM = runningVM;
|
||||
this.endChain = endChain;
|
||||
this.vmName = vmName;
|
||||
this.imageStoreUrl = imageStoreUrl;
|
||||
this.backupChainImageStoreUrls = backupChainImageStoreUrls;
|
||||
this.kbossTOS = kbossTOS;
|
||||
this.isolated = isolated;
|
||||
}
|
||||
|
||||
public boolean isQuiesceVm() {
|
||||
return quiesceVm;
|
||||
}
|
||||
|
||||
public boolean isRunningVM() {
|
||||
return runningVM;
|
||||
}
|
||||
|
||||
public boolean isEndChain() {
|
||||
return endChain;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public String getImageStoreUrl() {
|
||||
return imageStoreUrl;
|
||||
}
|
||||
|
||||
public List<String> getBackupChainImageStoreUrls() {
|
||||
return backupChainImageStoreUrls;
|
||||
}
|
||||
|
||||
public List<KbossTO> getKbossTOs() {
|
||||
return kbossTOS;
|
||||
}
|
||||
|
||||
public boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class ValidateKbossVmAnswer extends Answer {
|
||||
|
||||
private boolean bootValidated;
|
||||
private String screenshotPath;
|
||||
private String scriptResult;
|
||||
|
||||
public ValidateKbossVmAnswer(Command command, boolean bootValidated, String screenshotPath, String scriptResult) {
|
||||
super(command);
|
||||
this.bootValidated = bootValidated;
|
||||
this.screenshotPath = screenshotPath;
|
||||
this.scriptResult = scriptResult;
|
||||
}
|
||||
|
||||
public boolean isBootValidated() {
|
||||
return bootValidated;
|
||||
}
|
||||
|
||||
public String getScreenshotPath() {
|
||||
return screenshotPath;
|
||||
}
|
||||
|
||||
public String getScriptResult() {
|
||||
return scriptResult;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import org.apache.cloudstack.storage.to.BackupDeltaTO;
|
||||
|
||||
public class ValidateKbossVmCommand extends Command {
|
||||
|
||||
private VirtualMachineTO vm;
|
||||
private BackupDeltaTO backupDeltaTO;
|
||||
|
||||
private String scriptToExecute;
|
||||
|
||||
private String scriptArguments;
|
||||
private String expectedResult;
|
||||
|
||||
private Integer scriptTimeout;
|
||||
private Integer bootTimeout;
|
||||
private Integer screenshotWait;
|
||||
|
||||
private boolean takeScreenshot;
|
||||
private boolean waitForBoot;
|
||||
private boolean executeScript;
|
||||
|
||||
public ValidateKbossVmCommand(VirtualMachineTO vm, BackupDeltaTO backupDeltaTO) {
|
||||
this.vm = vm;
|
||||
this.backupDeltaTO = backupDeltaTO;
|
||||
}
|
||||
|
||||
public void setScriptToExecute(String scriptToExecute) {
|
||||
this.scriptToExecute = scriptToExecute;
|
||||
}
|
||||
|
||||
public void setScriptArguments(String scriptArguments) {
|
||||
this.scriptArguments = scriptArguments;
|
||||
}
|
||||
|
||||
public void setExpectedResult(String expectedResult) {
|
||||
this.expectedResult = expectedResult;
|
||||
}
|
||||
|
||||
public void setScriptTimeout(Integer scriptTimeout) {
|
||||
this.scriptTimeout = scriptTimeout;
|
||||
}
|
||||
|
||||
public void setTakeScreenshot(boolean takeScreenshot) {
|
||||
this.takeScreenshot = takeScreenshot;
|
||||
}
|
||||
|
||||
public void setWaitForBoot(boolean waitForBoot) {
|
||||
this.waitForBoot = waitForBoot;
|
||||
}
|
||||
|
||||
public void setExecuteScript(boolean executeScript) {
|
||||
this.executeScript = executeScript;
|
||||
}
|
||||
|
||||
public void setBootTimeout(Integer bootTimeout) {
|
||||
this.bootTimeout = bootTimeout;
|
||||
}
|
||||
|
||||
public void setScreenshotWait(Integer screenshotWait) {
|
||||
this.screenshotWait = screenshotWait;
|
||||
}
|
||||
|
||||
public VirtualMachineTO getVm() {
|
||||
return vm;
|
||||
}
|
||||
|
||||
public BackupDeltaTO getBackupDeltaTO() {
|
||||
return backupDeltaTO;
|
||||
}
|
||||
|
||||
public String getScriptToExecute() {
|
||||
return scriptToExecute;
|
||||
}
|
||||
|
||||
public String getScriptArguments() {
|
||||
return scriptArguments;
|
||||
}
|
||||
|
||||
public String getExpectedResult() {
|
||||
return expectedResult;
|
||||
}
|
||||
|
||||
public Integer getScriptTimeout() {
|
||||
return scriptTimeout;
|
||||
}
|
||||
|
||||
public Integer getBootTimeout() {
|
||||
return bootTimeout;
|
||||
}
|
||||
|
||||
public Integer getScreenshotWait() {
|
||||
return screenshotWait;
|
||||
}
|
||||
|
||||
public boolean isTakeScreenshot() {
|
||||
return takeScreenshot;
|
||||
}
|
||||
|
||||
public boolean isWaitForBoot() {
|
||||
return waitForBoot;
|
||||
}
|
||||
|
||||
public boolean isExecuteScript() {
|
||||
return executeScript;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
package org.apache.cloudstack.storage.command;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class BackupDeleteAnswer extends Answer {
|
||||
|
||||
private long backupId;
|
||||
|
||||
public BackupDeleteAnswer(Command command, boolean success, String details) {
|
||||
super(command, success, details);
|
||||
backupId = ((DeleteCommand) command).getData().getId();
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,8 @@ import com.cloud.agent.api.to.DataTO;
|
||||
public final class DeleteCommand extends StorageSubSystemCommand {
|
||||
private DataTO data;
|
||||
|
||||
private boolean deleteChain;
|
||||
|
||||
public DeleteCommand(final DataTO data) {
|
||||
super();
|
||||
this.data = data;
|
||||
@ -42,6 +44,14 @@ public final class DeleteCommand extends StorageSubSystemCommand {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setDeleteChain(boolean deleteChain) {
|
||||
this.deleteChain = deleteChain;
|
||||
}
|
||||
|
||||
public boolean isDeleteChain() {
|
||||
return deleteChain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExecuteInSequence(final boolean inSeq) {
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@ public final class RevertSnapshotCommand extends StorageSubSystemCommand {
|
||||
private SnapshotObjectTO dataOnPrimaryStorage;
|
||||
private boolean _executeInSequence = false;
|
||||
|
||||
private boolean deleteChain;
|
||||
|
||||
public RevertSnapshotCommand(SnapshotObjectTO data, SnapshotObjectTO dataOnPrimaryStorage) {
|
||||
super();
|
||||
this.data = data;
|
||||
@ -43,6 +45,14 @@ public final class RevertSnapshotCommand extends StorageSubSystemCommand {
|
||||
return dataOnPrimaryStorage;
|
||||
}
|
||||
|
||||
public boolean isDeleteChain() {
|
||||
return deleteChain;
|
||||
}
|
||||
|
||||
public void setDeleteChain(boolean deleteChain) {
|
||||
this.deleteChain = deleteChain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExecuteInSequence(final boolean executeInSequence) {
|
||||
_executeInSequence = executeInSequence;
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.storage.to;
|
||||
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.Storage;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class BackupDeltaTO implements DataTO {
|
||||
private DataStoreTO dataStoreTO;
|
||||
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
|
||||
private String path;
|
||||
|
||||
private String screenshotPath;
|
||||
|
||||
private Storage.ImageFormat format;
|
||||
|
||||
// When set, represents the Backup ID, not the delta ID.
|
||||
private long id = 0;
|
||||
|
||||
public BackupDeltaTO(DataStoreTO dataStoreTO, Hypervisor.HypervisorType hypervisorType, String path) {
|
||||
this.dataStoreTO = dataStoreTO;
|
||||
this.hypervisorType = hypervisorType;
|
||||
this.path = path;
|
||||
this.format = Storage.ImageFormat.QCOW2;
|
||||
}
|
||||
|
||||
public BackupDeltaTO(long id, DataStoreTO dataStoreTO, Hypervisor.HypervisorType hypervisorType, String path) {
|
||||
this(dataStoreTO, hypervisorType, path);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataObjectType getObjectType() {
|
||||
return DataObjectType.BACKUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreTO getDataStore() {
|
||||
return dataStoreTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Storage.ImageFormat getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public void setScreenshotPath(String screenshotPath) {
|
||||
this.screenshotPath = screenshotPath;
|
||||
}
|
||||
|
||||
public String getScreenshotPath() {
|
||||
return screenshotPath;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ReflectionToStringBuilder(this, ToStringStyle.JSON_STYLE).setExcludeFieldNames("id").toString();
|
||||
}
|
||||
}
|
||||
@ -16,28 +16,40 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package com.cloud.agent.api.storage;
|
||||
package org.apache.cloudstack.storage.to;
|
||||
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SnapshotMergeTreeTO {
|
||||
public class DeltaMergeTreeTO {
|
||||
|
||||
VolumeObjectTO volumeObjectTO;
|
||||
DataTO parent;
|
||||
DataTO child;
|
||||
List<DataTO> grandChildren;
|
||||
|
||||
public SnapshotMergeTreeTO(DataTO parent, DataTO child, List<DataTO> grandChildren) {
|
||||
public DeltaMergeTreeTO(VolumeObjectTO volumeObjectTO, DataTO parent, DataTO child, List<DataTO> grandChildren) {
|
||||
this.volumeObjectTO = volumeObjectTO;
|
||||
this.parent = parent;
|
||||
this.child = child;
|
||||
this.grandChildren = grandChildren;
|
||||
}
|
||||
|
||||
public VolumeObjectTO getVolumeObjectTO() {
|
||||
return volumeObjectTO;
|
||||
}
|
||||
|
||||
public DataTO getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(DataTO parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public DataTO getChild() {
|
||||
return child;
|
||||
}
|
||||
@ -52,6 +64,6 @@ public class SnapshotMergeTreeTO {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this);
|
||||
return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
110
core/src/main/java/org/apache/cloudstack/storage/to/KbossTO.java
Normal file
110
core/src/main/java/org/apache/cloudstack/storage/to/KbossTO.java
Normal file
@ -0,0 +1,110 @@
|
||||
package org.apache.cloudstack.storage.to;
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class KbossTO {
|
||||
|
||||
private String pathBackupParentOnSecondary;
|
||||
private VolumeObjectTO volumeObjectTO;
|
||||
private String deltaPathOnPrimary;
|
||||
private String parentDeltaPathOnPrimary;
|
||||
private String deltaPathOnSecondary;
|
||||
private String oldVolumePath;
|
||||
|
||||
private DeltaMergeTreeTO deltaMergeTreeTO;
|
||||
|
||||
private List<String> deltaPaths;
|
||||
|
||||
public KbossTO(VolumeObjectTO volumeObjectTO, LinkedList<String> deltaPaths) {
|
||||
this.volumeObjectTO = volumeObjectTO;
|
||||
this.deltaPaths = deltaPaths;
|
||||
}
|
||||
|
||||
public KbossTO(VolumeObjectTO volumeObjectTO, String deltaPathOnPrimary, String deltaPathOnSecondary, LinkedList<String> deltaPaths) {
|
||||
this.volumeObjectTO = volumeObjectTO;
|
||||
this.deltaPathOnPrimary = deltaPathOnPrimary;
|
||||
this.deltaPathOnSecondary = deltaPathOnSecondary;
|
||||
this.deltaPaths = deltaPaths;
|
||||
}
|
||||
|
||||
public String getPathBackupParentOnSecondary() {
|
||||
return pathBackupParentOnSecondary;
|
||||
}
|
||||
|
||||
public VolumeObjectTO getVolumeObjectTO() {
|
||||
return volumeObjectTO;
|
||||
}
|
||||
|
||||
public DeltaMergeTreeTO getDeltaMergeTreeTO() {
|
||||
return deltaMergeTreeTO;
|
||||
}
|
||||
|
||||
public List<String> getDeltaPaths() {
|
||||
return deltaPaths;
|
||||
}
|
||||
|
||||
public String getDeltaPathOnPrimary() {
|
||||
return deltaPathOnPrimary;
|
||||
}
|
||||
|
||||
public String getDeltaPathOnSecondary() {
|
||||
return deltaPathOnSecondary;
|
||||
}
|
||||
|
||||
public String getParentDeltaPathOnPrimary() {
|
||||
return parentDeltaPathOnPrimary;
|
||||
}
|
||||
|
||||
public void setParentDeltaPathOnPrimary(String parentDeltaPathOnPrimary) {
|
||||
this.parentDeltaPathOnPrimary = parentDeltaPathOnPrimary;
|
||||
}
|
||||
|
||||
public void setPathBackupParentOnSecondary(String pathBackupParentOnSecondary) {
|
||||
this.pathBackupParentOnSecondary = pathBackupParentOnSecondary;
|
||||
}
|
||||
|
||||
public void setDeltaMergeTreeTO(DeltaMergeTreeTO deltaMergeTreeTO) {
|
||||
this.deltaMergeTreeTO = deltaMergeTreeTO;
|
||||
}
|
||||
|
||||
public void setDeltaPathOnPrimary(String deltaPathOnPrimary) {
|
||||
this.deltaPathOnPrimary = deltaPathOnPrimary;
|
||||
}
|
||||
|
||||
public void setDeltaPathOnSecondary(String deltaPathOnSecondary) {
|
||||
this.deltaPathOnSecondary = deltaPathOnSecondary;
|
||||
}
|
||||
|
||||
public String getOldVolumePath() {
|
||||
return oldVolumePath;
|
||||
}
|
||||
|
||||
public void setOldVolumePath(String oldVolumePath) {
|
||||
this.oldVolumePath = oldVolumePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
@ -32,11 +32,12 @@ import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Volume;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class VolumeObjectTO extends DownloadableObjectTO implements DataTO {
|
||||
public class VolumeObjectTO extends DownloadableObjectTO implements DataTO, Serializable {
|
||||
private String uuid;
|
||||
private Volume.Type volumeType;
|
||||
private DataStoreTO dataStore;
|
||||
@ -80,6 +81,7 @@ public class VolumeObjectTO extends DownloadableObjectTO implements DataTO {
|
||||
private String encryptFormat;
|
||||
private List<String> checkpointPaths;
|
||||
private Set<String> checkpointImageStoreUrls;
|
||||
private Set<String> deltasToRemove;
|
||||
|
||||
public VolumeObjectTO() {
|
||||
|
||||
@ -424,4 +426,12 @@ public class VolumeObjectTO extends DownloadableObjectTO implements DataTO {
|
||||
public void setCheckpointImageStoreUrls(Set<String> checkpointImageStoreUrls) {
|
||||
this.checkpointImageStoreUrls = checkpointImageStoreUrls;
|
||||
}
|
||||
|
||||
public Set<String> getDeltasToRemove() {
|
||||
return deltasToRemove;
|
||||
}
|
||||
|
||||
public void setDeltasToRemove(Set<String> deltasToRemove) {
|
||||
this.deltasToRemove = deltasToRemove;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,4 +29,9 @@
|
||||
<property name="typeClass" value="org.apache.cloudstack.backup.BackupProvider" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
|
||||
<property name="registry" ref="internalBackupProvidersRegistry" />
|
||||
<property name="typeClass" value="org.apache.cloudstack.backup.InternalBackupProvider" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@ -339,6 +339,10 @@
|
||||
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
<bean id="internalBackupProvidersRegistry"
|
||||
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
<bean id="kubernetesServiceHelperRegistry"
|
||||
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
@ -122,7 +122,7 @@ public interface VolumeOrchestrationService {
|
||||
DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template,
|
||||
Account owner, Long deviceId, Long kmsKeyId, boolean incrementResourceCount);
|
||||
|
||||
VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException;
|
||||
VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool, Long clusterId, Long podId) throws NoTransitionException;
|
||||
|
||||
void release(VirtualMachineProfile profile);
|
||||
|
||||
|
||||
@ -241,6 +241,9 @@ public interface StorageManager extends StorageService {
|
||||
"while adding a new Secondary Storage. If the copy operation fails, the system falls back to downloading the template from the source URL.",
|
||||
true, ConfigKey.Scope.Zone, null);
|
||||
|
||||
ConfigKey<Integer> AgentMaxDataMigrationWaitTime = new ConfigKey<>("Advanced", Integer.class, "agent.max.data.migration.wait.time", "3600",
|
||||
"The maximum time (in seconds) that the secondary storage data migration command sent to the KVM Agent will be executed before a timeout occurs.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
/**
|
||||
* should we execute in sequence not involving any storages?
|
||||
* @return true if commands should execute in sequence
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
public class VmWorkDeleteBackup extends VmWork {
|
||||
|
||||
private long backupId;
|
||||
|
||||
private boolean forced;
|
||||
|
||||
public VmWorkDeleteBackup(long userId, long accountId, long vmId, String handlerName, long backupId, boolean forced) {
|
||||
super(userId, accountId, vmId, handlerName);
|
||||
this.backupId = backupId;
|
||||
this.forced = forced;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public boolean isForced() {
|
||||
return forced;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
public class VmWorkRestoreBackup extends VmWork {
|
||||
|
||||
private long backupId;
|
||||
|
||||
private boolean quickRestore;
|
||||
|
||||
private Long hostId;
|
||||
|
||||
public VmWorkRestoreBackup(long userId, long accountId, long vmId, String handlerName, long backupId, boolean quickRestore, Long hostId) {
|
||||
super(userId, accountId, vmId, handlerName);
|
||||
this.backupId = backupId;
|
||||
this.quickRestore = quickRestore;
|
||||
this.hostId = hostId;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public boolean isQuickRestore() {
|
||||
return quickRestore;
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
public class VmWorkRestoreVolumeBackupAndAttach extends VmWork {
|
||||
|
||||
private long backupId;
|
||||
|
||||
private Backup.VolumeInfo backupVolumeInfo;
|
||||
|
||||
private String hostIp;
|
||||
|
||||
private boolean quickRestore;
|
||||
|
||||
public VmWorkRestoreVolumeBackupAndAttach(long userId, long accountId, long vmId, String handlerName, long backupId, Backup.VolumeInfo backupVolumeInfo,
|
||||
String hostIp, boolean quickRestore) {
|
||||
super(userId, accountId, vmId, handlerName);
|
||||
this.backupId = backupId;
|
||||
this.backupVolumeInfo = backupVolumeInfo;
|
||||
this.hostIp = hostIp;
|
||||
this.quickRestore = quickRestore;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public Backup.VolumeInfo getBackupVolumeInfo() {
|
||||
return backupVolumeInfo;
|
||||
}
|
||||
|
||||
public String getHostIp() {
|
||||
return hostIp;
|
||||
}
|
||||
|
||||
public boolean isQuickRestore() {
|
||||
return quickRestore;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
public class VmWorkTakeBackup extends VmWork {
|
||||
|
||||
private long backupId;
|
||||
|
||||
private boolean quiesceVm;
|
||||
|
||||
private boolean isolated;
|
||||
|
||||
public VmWorkTakeBackup(long userId, long accountId, long vmId, long backupId, String handlerName, boolean quiesceVm, boolean isolated) {
|
||||
super(userId, accountId, vmId, handlerName);
|
||||
this.quiesceVm = quiesceVm;
|
||||
this.backupId = backupId;
|
||||
this.isolated = isolated;
|
||||
}
|
||||
|
||||
public boolean isQuiesceVm() {
|
||||
return quiesceVm;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toStringAfterRemoveParams(null, null);
|
||||
}
|
||||
}
|
||||
@ -499,7 +499,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
static final ConfigKey<Integer> ClusterVMMetaDataSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vmmetadata.sync.interval", "180", "Cluster VM metadata sync interval in seconds",
|
||||
false);
|
||||
|
||||
static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced",
|
||||
public static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced",
|
||||
Long.class, "vm.job.check.interval", "3000",
|
||||
"Interval in milliseconds to check if the job is complete", false);
|
||||
static final ConfigKey<Long> VmJobTimeout = new ConfigKey<Long>("Advanced",
|
||||
@ -1029,7 +1029,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) {
|
||||
logger.debug("Successfully transitioned to start state for {} reservation id = {}", vm, work.getId());
|
||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||
_resourceLimitMgr.incrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template);
|
||||
_resourceLimitMgr.incrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template, null);
|
||||
}
|
||||
return new Ternary<>(vm, context, work);
|
||||
}
|
||||
@ -1396,6 +1396,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
Throwable lastKnownError = null;
|
||||
boolean canRetry = true;
|
||||
ExcludeList avoids = null;
|
||||
long deployedHostId = -1;
|
||||
try {
|
||||
final Journal journal = start.second().getJournal();
|
||||
|
||||
@ -1527,6 +1528,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (params != null) {
|
||||
Boolean returnAfterVolumePrepare = (Boolean) params.get(VirtualMachineProfile.Param.ReturnAfterVolumePrepare);
|
||||
if (Boolean.TRUE.equals(returnAfterVolumePrepare)) {
|
||||
deployedHostId = vm.getHostId();
|
||||
logger.info("Returning from VM start command execution for VM {} as requested. Volumes are prepared and ready.", vm.getUuid());
|
||||
|
||||
if (!changeState(vm, Event.AgentReportStopped, destHostId, work, Step.Done)) {
|
||||
@ -1715,7 +1717,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
} finally {
|
||||
if (startedVm == null) {
|
||||
if (VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||
_resourceLimitMgr.decrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template);
|
||||
_resourceLimitMgr.decrementVmResourceCount(owner.getAccountId(), vm.isDisplay(), offering, template, null);
|
||||
}
|
||||
if (canRetry) {
|
||||
try {
|
||||
@ -1730,6 +1732,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (planToDeploy != null) {
|
||||
planToDeploy.setAvoids(avoids);
|
||||
}
|
||||
|
||||
if (params != null && Boolean.TRUE.equals(params.get(VirtualMachineProfile.Param.ReturnAfterVolumePrepare))) {
|
||||
vm.setHostId(null);
|
||||
vm.setLastHostId(deployedHostId);
|
||||
_vmDao.update(vm.getId(), vm);
|
||||
}
|
||||
}
|
||||
|
||||
if (startedVm == null) {
|
||||
@ -2646,7 +2654,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (result && VirtualMachine.Type.User.equals(vm.type) && ResourceCountRunningVMsonly.value()) {
|
||||
ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||
_resourceLimitMgr.decrementVmResourceCount(vm.getAccountId(), vm.isDisplay(), offering, template);
|
||||
_resourceLimitMgr.decrementVmResourceCount(vm.getAccountId(), vm.isDisplay(), offering, template, null);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -28,9 +28,13 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.InternalBackupJoinVO;
|
||||
import org.apache.cloudstack.backup.dao.InternalBackupJoinDao;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
@ -42,6 +46,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.storage.ImageStoreService;
|
||||
import org.apache.cloudstack.storage.backup.BackupObject;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
@ -89,12 +94,15 @@ public class DataMigrationUtility {
|
||||
HostDao hostDao;
|
||||
@Inject
|
||||
SnapshotDao snapshotDao;
|
||||
|
||||
@Inject
|
||||
InternalBackupJoinDao internalBackupJoinDao;
|
||||
/**
|
||||
* This function verifies if the given image store contains data objects that are not in any of the following states:
|
||||
* "Ready" "Allocated", "Destroying", "Destroyed", "Failed". If this is the case, and if the migration policy is complete,
|
||||
* the migration is terminated.
|
||||
*/
|
||||
public boolean filesReadyToMigrate(Long srcDataStoreId, List<TemplateDataStoreVO> templates, List<SnapshotDataStoreVO> snapshots, List<VolumeDataStoreVO> volumes) {
|
||||
public boolean filesReadyToMigrate(Long srcDataStoreId, List<TemplateDataStoreVO> templates, List<SnapshotDataStoreVO> snapshots, List<VolumeDataStoreVO> volumes, List<InternalBackupJoinVO> backups) {
|
||||
State[] validStates = {State.Ready, State.Allocated, State.Destroying, State.Destroyed, State.Failed};
|
||||
boolean isReady = true;
|
||||
for (TemplateDataStoreVO template : templates) {
|
||||
@ -109,14 +117,48 @@ public class DataMigrationUtility {
|
||||
isReady &= (Arrays.asList(validStates).contains(volume.getState()));
|
||||
logger.trace("volume state: {}", volume.getState());
|
||||
}
|
||||
isReady &= checkIfBackupsMigrationIsPossible(backups);
|
||||
return isReady;
|
||||
}
|
||||
|
||||
private boolean checkIfBackupsMigrationIsPossible(List<InternalBackupJoinVO> backups) {
|
||||
List<Backup.Status> invalidBackupStates = Arrays.asList(Backup.Status.BackingUp, Backup.Status.Restoring);
|
||||
List<Backup.CompressionStatus> invalidBackupCompressionStatus = Arrays.asList(Backup.CompressionStatus.Compressing, Backup.CompressionStatus.FinalizingCompression);
|
||||
|
||||
List<List<BackupObject>> backupChains;
|
||||
Set<Long> backupIdsAlreadyInChain = new HashSet<>();
|
||||
|
||||
for (InternalBackupJoinVO backup : backups) {
|
||||
if (backup.getStatus() == Backup.Status.BackedUp && !backupIdsAlreadyInChain.contains(backup.getId())) {
|
||||
backupChains = createBackupChain(backup);
|
||||
backupChains.forEach(list -> backupIdsAlreadyInChain.add(list.stream().map(BackupObject::getId).findFirst().get()));
|
||||
|
||||
for (List<BackupObject> backupVolumeChain : backupChains) {
|
||||
BackupObject backupObject = backupVolumeChain.get(0);
|
||||
|
||||
if (invalidBackupStates.contains(backupObject.getStatus())) {
|
||||
logger.debug("Migration is not possible because backup {} is in {} state.", backupObject.getUuid(), backupObject.getStatus());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (invalidBackupCompressionStatus.contains(backupObject.getCompressionStatus())) {
|
||||
logger.debug("Migration is not possible because backup {} is currently being compressed. Current compression status: {}.", backupObject.getUuid(), backupObject.getCompressionStatus());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean filesReadyToMigrate(Long srcDataStoreId) {
|
||||
List<TemplateDataStoreVO> templates = templateDataStoreDao.listByStoreId(srcDataStoreId);
|
||||
List<SnapshotDataStoreVO> snapshots = snapshotDataStoreDao.listByStoreId(srcDataStoreId, DataStoreRole.Image);
|
||||
List<VolumeDataStoreVO> volumes = volumeDataStoreDao.listByStoreId(srcDataStoreId);
|
||||
return filesReadyToMigrate(srcDataStoreId, templates, snapshots, volumes);
|
||||
List<InternalBackupJoinVO> backups = internalBackupJoinDao.listByImageStoreId(srcDataStoreId);
|
||||
|
||||
return filesReadyToMigrate(srcDataStoreId, templates, snapshots, volumes, backups);
|
||||
}
|
||||
|
||||
protected void checkIfCompleteMigrationPossible(ImageStoreService.MigrationPolicy policy, Long srcDataStoreId) {
|
||||
@ -175,19 +217,58 @@ public class DataMigrationUtility {
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
protected List<DataObject> getSortedValidSourcesList(DataStore srcDataStore, Map<DataObject, Pair<List<SnapshotInfo>, Long>> snapshotChains,
|
||||
Map<DataObject, Pair<List<TemplateInfo>, Long>> childTemplates) {
|
||||
Map<DataObject, Pair<List<TemplateInfo>, Long>> childTemplates, Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains) {
|
||||
List<DataObject> files = new ArrayList<>();
|
||||
files.addAll(getAllReadyTemplates(srcDataStore, childTemplates));
|
||||
files.addAll(getAllReadySnapshotsAndChains(srcDataStore, snapshotChains));
|
||||
files.addAll(getAllReadyVolumes(srcDataStore));
|
||||
files.addAll(getAllReadyBackupsAndChains(srcDataStore, backupChains));
|
||||
|
||||
files = sortFilesOnSize(files, snapshotChains);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
protected List<DataObject> getAllReadyBackupsAndChains(DataStore srcDataStore, Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains) {
|
||||
List<InternalBackupJoinVO> backups = internalBackupJoinDao.listByImageStoreId(srcDataStore.getId());
|
||||
return getAllReadyBackupsAndChains(backupChains, backups);
|
||||
}
|
||||
|
||||
private List<DataObject> getAllReadyBackupsAndChains(Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupsChains, List<InternalBackupJoinVO> backups) {
|
||||
Set<Long> backupIdsToMigrate = backups.stream().map(InternalBackupJoinVO::getId).collect(Collectors.toSet());
|
||||
List<List<BackupObject>> backupChains;
|
||||
Set<Long> backupIdsAlreadyInChain = new HashSet<>();
|
||||
List<BackupObject> files = new LinkedList<>();
|
||||
|
||||
for (InternalBackupJoinVO backup : backups) {
|
||||
long backupId = backup.getId();
|
||||
|
||||
if (backup.getStatus() == Backup.Status.BackedUp && !backupIdsAlreadyInChain.contains(backupId)) {
|
||||
backupChains = createBackupChain(backup);
|
||||
backupChains.forEach(list -> backupIdsAlreadyInChain.add(list.stream().map(BackupObject::getId).findFirst().get()));
|
||||
BackupObject parent = backupChains.get(0).get(0);
|
||||
files.add(parent);
|
||||
backupsChains.put(parent, new Pair<>(backupChains, backupChains.stream().map(list -> getTotalChainSize(list.stream()
|
||||
.filter(back -> backupIdsToMigrate.contains(parent.getId())).collect(Collectors.toList()))
|
||||
).reduce(Long::sum).get()));
|
||||
}
|
||||
}
|
||||
|
||||
return (List<DataObject>) (List<?>) files;
|
||||
}
|
||||
|
||||
private List<List<BackupObject>> createBackupChain(InternalBackupJoinVO backup) {
|
||||
List<List<BackupObject>> chain = new LinkedList<>();
|
||||
BackupObject backupObject = BackupObject.getBackupObject(backup);
|
||||
|
||||
chain.addAll(backupObject.getParents(backup.getParentId()));
|
||||
chain.add(internalBackupJoinDao.listById(backup.getId()).stream().map(BackupObject::getBackupObject).collect(Collectors.toList()));
|
||||
chain.addAll(backupObject.getChildren());
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
protected List<DataObject> sortFilesOnSize(List<DataObject> files, Map<DataObject, Pair<List<SnapshotInfo>, Long>> snapshotChains) {
|
||||
Collections.sort(files, new Comparator<DataObject>() {
|
||||
@Override
|
||||
|
||||
@ -25,9 +25,13 @@ import java.util.Hashtable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -36,10 +40,22 @@ import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.MigrateBackupsBetweenSecondaryStoragesCommand;
|
||||
import com.cloud.agent.api.MigrateBetweenSecondaryStoragesCommandAnswer;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import org.apache.cloudstack.api.response.MigrationResponse;
|
||||
import org.apache.cloudstack.backup.BackupDetailVO;
|
||||
import org.apache.cloudstack.backup.dao.BackupDetailsDao;
|
||||
import org.apache.cloudstack.engine.orchestration.service.StorageOrchestrationService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
@ -57,6 +73,7 @@ import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.ImageStoreService.MigrationPolicy;
|
||||
import org.apache.cloudstack.storage.backup.BackupObject;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
@ -115,6 +132,12 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
TemplateDataFactory templateDataFactory;
|
||||
@Inject
|
||||
DataCenterDao dcDao;
|
||||
@Inject
|
||||
AgentManager agentManager;
|
||||
@Inject
|
||||
HostDao hostDao;
|
||||
@Inject
|
||||
BackupDetailsDao backupDetailDao;
|
||||
|
||||
|
||||
ConfigKey<Double> ImageStoreImbalanceThreshold = new ConfigKey<>("Advanced", Double.class,
|
||||
@ -128,6 +151,7 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
|
||||
private final Map<Long, ThreadPoolExecutor> zoneExecutorMap = new HashMap<>();
|
||||
private final Map<Long, Integer> zonePendingWorkCountMap = new HashMap<>();
|
||||
private final Map<Long, ExecutorService> zoneKvmIncrementalExecutorMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
@ -171,7 +195,9 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
DataStore srcDatastore = dataStoreManager.getDataStore(srcDataStoreId, DataStoreRole.Image);
|
||||
Map<DataObject, Pair<List<SnapshotInfo>, Long>> snapshotChains = new HashMap<>();
|
||||
Map<DataObject, Pair<List<TemplateInfo>, Long>> childTemplates = new HashMap<>();
|
||||
files = migrationHelper.getSortedValidSourcesList(srcDatastore, snapshotChains, childTemplates);
|
||||
Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains = new HashMap<>();
|
||||
files = migrationHelper.getSortedValidSourcesList(srcDatastore, snapshotChains, childTemplates, backupChains);
|
||||
|
||||
|
||||
if (files.isEmpty()) {
|
||||
return new MigrationResponse(String.format("No files in Image store: %s to migrate", srcDatastore), migrationPolicy.toString(), true);
|
||||
@ -227,7 +253,7 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
}
|
||||
|
||||
if (shouldMigrate(chosenFileForMigration, srcDatastore.getId(), destDatastoreId, storageCapacities, snapshotChains, childTemplates, migrationPolicy)) {
|
||||
storageCapacities = migrateAway(chosenFileForMigration, storageCapacities, snapshotChains, childTemplates, srcDatastore, destDatastoreId, futures);
|
||||
storageCapacities = migrateAway(chosenFileForMigration, storageCapacities, snapshotChains, childTemplates, backupChains, srcDatastore, destDatastoreId, futures);
|
||||
} else {
|
||||
if (migrationPolicy == MigrationPolicy.BALANCE) {
|
||||
continue;
|
||||
@ -256,7 +282,7 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
List<TemplateDataStoreVO> templates = templateDataStoreDao.listByStoreIdAndTemplateIds(srcImgStoreId, templateIdList);
|
||||
List<SnapshotDataStoreVO> snapshots = snapshotDataStoreDao.listByStoreAndSnapshotIds(srcImgStoreId, DataStoreRole.Image, snapshotIdList);
|
||||
|
||||
if (!migrationHelper.filesReadyToMigrate(srcImgStoreId, templates, snapshots, Collections.emptyList())) {
|
||||
if (!migrationHelper.filesReadyToMigrate(srcImgStoreId, templates, snapshots, Collections.emptyList(), Collections.emptyList())) {
|
||||
throw new CloudRuntimeException("Migration failed as there are data objects which are not Ready - i.e, they may be in Migrating, creating, copying, etc. states");
|
||||
}
|
||||
files = migrationHelper.getSortedValidSourcesList(srcDatastore, snapshotChains, childTemplates, templates, snapshots);
|
||||
@ -291,7 +317,7 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
}
|
||||
|
||||
if (storageCapacityBelowThreshold(storageCapacities, destImgStoreId)) {
|
||||
storageCapacities = migrateAway(chosenFileForMigration, storageCapacities, snapshotChains, childTemplates, srcDatastore, destImgStoreId, futures);
|
||||
storageCapacities = migrateAway(chosenFileForMigration, storageCapacities, snapshotChains, childTemplates, null, srcDatastore, destImgStoreId, futures);
|
||||
} else {
|
||||
message = "Migration failed. Destination store doesn't have enough capacity for migration";
|
||||
success = false;
|
||||
@ -355,15 +381,89 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
Map<DataObject,
|
||||
Pair<List<SnapshotInfo>, Long>> snapshotChains,
|
||||
Map<DataObject, Pair<List<TemplateInfo>, Long>> templateChains,
|
||||
Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains,
|
||||
DataStore srcDatastore,
|
||||
Long destDatastoreId,
|
||||
List<Future<DataObjectResult>> futures) {
|
||||
|
||||
Long fileSize = migrationHelper.getFileSize(chosenFileForMigration, snapshotChains, templateChains);
|
||||
storageCapacities = assumeMigrate(storageCapacities, srcDatastore.getId(), destDatastoreId, fileSize);
|
||||
DataStore destDataStore = dataStoreManager.getDataStore(destDatastoreId, DataStoreRole.Image);
|
||||
|
||||
MigrateDataTask task = new MigrateDataTask(chosenFileForMigration, srcDatastore, dataStoreManager.getDataStore(destDatastoreId, DataStoreRole.Image));
|
||||
if (chosenFileForMigration instanceof SnapshotInfo ) {
|
||||
boolean isKvmIncrementalBackup = backupChains != null && chosenFileForMigration instanceof BackupObject && backupChains.containsKey(chosenFileForMigration);
|
||||
|
||||
if (isKvmIncrementalBackup) {
|
||||
MigrateKvmIncrementalBackupTask task = new MigrateKvmIncrementalBackupTask(chosenFileForMigration, backupChains, srcDatastore, destDataStore);
|
||||
futures.add(submitKvmIncrementalMigration(srcDatastore.getScope().getScopeId(), task));
|
||||
logger.debug("Incremental backup migration {} submitted to incremental pool.", chosenFileForMigration.getUuid());
|
||||
} else {
|
||||
createMigrateDataTask(chosenFileForMigration, snapshotChains, templateChains, srcDatastore, destDataStore, futures);
|
||||
}
|
||||
|
||||
return storageCapacities;
|
||||
}
|
||||
|
||||
private void migrateKvmIncrementalBackupChain(DataObject chosenFileForMigration, Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains, DataStore srcDatastore, DataStore destDataStore) {
|
||||
Transaction.execute((TransactionCallback<Boolean>) status -> {
|
||||
MigrateBetweenSecondaryStoragesCommandAnswer answer = null;
|
||||
|
||||
try {
|
||||
List<List<BackupObject>> backupChain = backupChains.get(chosenFileForMigration).first();
|
||||
MigrateBackupsBetweenSecondaryStoragesCommand migrateBetweenSecondaryStoragesCmd = new MigrateBackupsBetweenSecondaryStoragesCommand(backupChain.stream().map(list -> list.stream().map(BackupObject::getTO).collect(Collectors.toList()))
|
||||
.collect(Collectors.toList()), srcDatastore.getTO(), destDataStore.getTO());
|
||||
|
||||
HostVO host = getAvailableHost(((BackupObject) chosenFileForMigration).getZoneId());
|
||||
if (host == null) {
|
||||
throw new CloudRuntimeException("No hosts found to send migrate command.");
|
||||
}
|
||||
|
||||
migrateBetweenSecondaryStoragesCmd.setWait(StorageManager.AgentMaxDataMigrationWaitTime.valueIn(host.getClusterId()));
|
||||
answer = (MigrateBetweenSecondaryStoragesCommandAnswer) agentManager.send(host.getId(), migrateBetweenSecondaryStoragesCmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
logger.warn("Unable to migrate backups [{}].", backupChain);
|
||||
throw new CloudRuntimeException("Unable to migrate KVM incremental backups to another secondary storage");
|
||||
}
|
||||
|
||||
} catch (final OperationTimedoutException | AgentUnavailableException e) {
|
||||
throw new CloudRuntimeException("Error while migrating KVM incremental backup chain. Check the logs for more information.", e);
|
||||
} finally {
|
||||
if (answer != null) {
|
||||
updateBackupsReference(destDataStore, answer);
|
||||
}
|
||||
}
|
||||
return answer.getResult();
|
||||
});
|
||||
}
|
||||
|
||||
private void updateBackupsReference(DataStore destDataStore, MigrateBetweenSecondaryStoragesCommandAnswer answer) {
|
||||
for (Pair<Long, String> backupIdAndUpdatedCheckpointPath : answer.getMigratedResources()) {
|
||||
Long backupId = backupIdAndUpdatedCheckpointPath.first();
|
||||
BackupDetailVO backupDetail = backupDetailDao.findDetail(backupId, BackupDetailsDao.IMAGE_STORE_ID);
|
||||
String destDataStoreId = String.valueOf(destDataStore.getId());
|
||||
|
||||
if (backupDetail == null) {
|
||||
logger.warn("No details found for backup [{}]. Creating new entry with image store ID [{}].", backupId, destDataStoreId);
|
||||
backupDetailDao.addDetail(backupId, BackupDetailsDao.IMAGE_STORE_ID, destDataStoreId, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
backupDetail.setValue(destDataStoreId);
|
||||
backupDetailDao.update(backupDetail.getId(), backupDetail);
|
||||
}
|
||||
}
|
||||
|
||||
private HostVO getAvailableHost(long zoneId) throws AgentUnavailableException, OperationTimedoutException {
|
||||
List<HostVO> hosts = hostDao.listByDataCenterIdAndHypervisorType(zoneId, Hypervisor.HypervisorType.KVM);
|
||||
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||
return hosts.get(new Random().nextInt(hosts.size()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createMigrateDataTask(DataObject chosenFileForMigration, Map<DataObject, Pair<List<SnapshotInfo>, Long>> snapshotChains, Map<DataObject, Pair<List<TemplateInfo>, Long>> templateChains, DataStore srcDatastore, DataStore destDataStore, List<Future<DataObjectResult>> futures) {
|
||||
MigrateDataTask task = new MigrateDataTask(chosenFileForMigration, srcDatastore, destDataStore);
|
||||
if (chosenFileForMigration instanceof SnapshotInfo) {
|
||||
task.setSnapshotChains(snapshotChains);
|
||||
}
|
||||
if (chosenFileForMigration instanceof TemplateInfo) {
|
||||
@ -371,7 +471,6 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
}
|
||||
futures.add(submit(srcDatastore.getScope().getScopeId(), task));
|
||||
logger.debug("Migration of {}: {} is initiated.", chosenFileForMigration.getType().name(), chosenFileForMigration.getUuid());
|
||||
return storageCapacities;
|
||||
}
|
||||
|
||||
protected <T> Future<T> submit(Long zoneId, Callable<T> task) {
|
||||
@ -390,6 +489,13 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
|
||||
}
|
||||
|
||||
protected synchronized <T> Future<T> submitKvmIncrementalMigration(Long zoneId, Callable<T> task) {
|
||||
if (!zoneKvmIncrementalExecutorMap.containsKey(zoneId)) {
|
||||
zoneKvmIncrementalExecutorMap.put(zoneId, Executors.newSingleThreadExecutor());
|
||||
}
|
||||
return zoneKvmIncrementalExecutorMap.get(zoneId).submit(task);
|
||||
}
|
||||
|
||||
protected void scaleExecutorIfNecessary(Long zoneId) {
|
||||
long activeSsvms = migrationHelper.activeSSVMCount(zoneId);
|
||||
long totalJobs = activeSsvms * numConcurrentCopyTasksPerSSVM;
|
||||
@ -666,4 +772,32 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private class MigrateKvmIncrementalBackupTask implements Callable<DataObjectResult> {
|
||||
private final DataObject chosenFile;
|
||||
private final Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains;
|
||||
private final DataStore srcDataStore;
|
||||
private final DataStore destDataStore;
|
||||
|
||||
public MigrateKvmIncrementalBackupTask(DataObject chosenFile, Map<DataObject, Pair<List<List<BackupObject>>, Long>> backupChains, DataStore srcDataStore, DataStore destDataStore) {
|
||||
this.chosenFile = chosenFile;
|
||||
this.backupChains = backupChains;
|
||||
this.srcDataStore = srcDataStore;
|
||||
this.destDataStore = destDataStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataObjectResult call() {
|
||||
try {
|
||||
migrateKvmIncrementalBackupChain(chosenFile, backupChains, srcDataStore, destDataStore);
|
||||
return new DataObjectResult(chosenFile);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed migrating incremental backup {} due to {}.", chosenFile.getUuid(), e);
|
||||
DataObjectResult result = new DataObjectResult(chosenFile);
|
||||
result.setResult(e.toString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy;
|
||||
import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
|
||||
import org.apache.cloudstack.backup.InternalBackupService;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
|
||||
@ -301,6 +302,9 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
@Inject
|
||||
private KMSWrappedKeyDao kmsWrappedKeyDao;
|
||||
|
||||
@Inject
|
||||
private InternalBackupService internalBackupService;
|
||||
|
||||
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
|
||||
protected List<StoragePoolAllocator> _storagePoolAllocators;
|
||||
|
||||
@ -1358,21 +1362,27 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volumeInfo, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException {
|
||||
public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volumeInfo, HypervisorType rootDiskHyperType, StoragePool storagePool, Long clusterId, Long podId)
|
||||
throws NoTransitionException {
|
||||
String volumeToString = getReflectOnlySelectedFields(volumeInfo.getVolume());
|
||||
|
||||
VirtualMachineTemplate rootDiskTmplt = _entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
|
||||
DataCenter dcVO = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
|
||||
logger.trace("storage-pool {}/{} is associated with pod {}",storagePool.getName(), storagePool.getUuid(), storagePool.getPodId());
|
||||
Long podId = storagePool.getPodId() != null ? storagePool.getPodId() : vm.getPodIdToDeployIn();
|
||||
|
||||
if (storagePool != null) {
|
||||
logger.trace("storage-pool {}/{} is associated with pod {}", storagePool.getName(), storagePool.getUuid(), storagePool.getPodId());
|
||||
podId = storagePool.getPodId() != null ? storagePool.getPodId() : vm.getPodIdToDeployIn();
|
||||
clusterId = storagePool.getClusterId();
|
||||
logger.trace("storage-pool {}/{} is associated with cluster {}",storagePool.getName(), storagePool.getUuid(), clusterId);
|
||||
}
|
||||
|
||||
Pod pod = _entityMgr.findById(Pod.class, podId);
|
||||
|
||||
ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
|
||||
DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volumeInfo.getDiskOfferingId());
|
||||
Long clusterId = storagePool.getClusterId();
|
||||
logger.trace("storage-pool {}/{} is associated with cluster {}",storagePool.getName(), storagePool.getUuid(), clusterId);
|
||||
|
||||
Long hostId = vm.getHostId();
|
||||
if (hostId == null && (storagePool.isLocal() || ClvmPoolManager.isClvmPoolType(storagePool.getPoolType()))) {
|
||||
if (hostId == null && storagePool != null && (storagePool.isLocal() || ClvmPoolManager.isClvmPoolType(storagePool.getPoolType()))) {
|
||||
if (ClvmPoolManager.isClvmPoolType(storagePool.getPoolType())) {
|
||||
hostId = getClvmLockHostFromVmVolumes(vm.getId());
|
||||
if (hostId != null) {
|
||||
@ -1632,6 +1642,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
_snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
|
||||
_snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
|
||||
}
|
||||
internalBackupService.updateVolumeId(vol.getId(), result.getVolume().getId());
|
||||
|
||||
// For CLVM volumes attached to a VM, update the CLVM_LOCK_HOST_ID after migration
|
||||
updateClvmLockHostAfterMigration(result.getVolume(), destPool, "migrated");
|
||||
@ -1695,6 +1706,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
throw new CloudRuntimeException(String.format("Failed to find the destination storage pool [%s] to migrate the volume [%s] to.", storagePoolToString, volumeToString));
|
||||
}
|
||||
|
||||
internalBackupService.prepareVolumeForMigration(volume);
|
||||
|
||||
volumeMap.put(volFactory.getVolume(volume.getId()), (DataStore)destPool);
|
||||
}
|
||||
|
||||
@ -2531,7 +2544,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
if (volume.getState() == Volume.State.Allocated) {
|
||||
_volsDao.remove(volume.getId());
|
||||
stateTransitTo(volume, Volume.Event.DestroyRequested);
|
||||
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
|
||||
_resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), volume.isDisplay(), volume.getSize(), diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()),
|
||||
null);
|
||||
} else {
|
||||
destroyVolumeInContext(volume);
|
||||
}
|
||||
|
||||
@ -91,6 +91,7 @@
|
||||
<entry key="VolumeApiServiceImpl" value-ref="volumeApiServiceImpl" />
|
||||
<entry key="VMSnapshotManagerImpl" value-ref="vMSnapshotManagerImpl" />
|
||||
<entry key="KVMBackupExportServiceImpl" value-ref="kvmBackupExportService" />
|
||||
<entry key="InternalBackupService" value-ref="internalBackupServiceImpl" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
@ -121,6 +121,8 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
||||
|
||||
List<Long> listIdsForUpEnabledByZoneAndHypervisor(Long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
List<HostVO> findRoutingByClusterId(Long clusterId);
|
||||
|
||||
List<HostVO> findByClusterIdAndEncryptionSupport(Long clusterId);
|
||||
|
||||
/**
|
||||
@ -139,6 +141,8 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
||||
|
||||
List<HostVO> listAllHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
List<HostVO> listAllRoutingHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
List<HostVO> listAllHostsThatHaveNoRuleTag(Host.Type type, Long clusterId, Long podId, Long dcId);
|
||||
|
||||
HostVO findByPublicIp(String publicIp);
|
||||
|
||||
@ -1341,6 +1341,14 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
||||
return listIdsBy(null, Status.Up, ResourceState.Enabled, hypervisorType, zoneId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findRoutingByClusterId(Long clusterId) {
|
||||
SearchCriteria<HostVO> sc = ClusterSearch.create();
|
||||
sc.setParameters("clusterId", clusterId);
|
||||
sc.setParameters("type", Type.Routing);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findByClusterIdAndEncryptionSupport(Long clusterId) {
|
||||
SearchBuilder<DetailVO> hostCapabilitySearch = _detailsDao.createSearchBuilder();
|
||||
@ -1456,6 +1464,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listAllRoutingHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType) {
|
||||
SearchCriteria<HostVO> sc = DcSearch.create();
|
||||
sc.setParameters("dc", zoneId);
|
||||
sc.setParameters("hypervisorType", hypervisorType.toString());
|
||||
sc.setParameters("type", Type.Routing);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listAllHostsThatHaveNoRuleTag(Type type, Long clusterId, Long podId, Long dcId) {
|
||||
SearchCriteria<HostVO> sc = searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.create();
|
||||
|
||||
@ -141,4 +141,6 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
|
||||
List<NetworkVO> listByPhysicalNetworkPvlan(long physicalNetworkId, String broadcastUri);
|
||||
|
||||
List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId);
|
||||
|
||||
NetworkVO findByZoneIdAndAccountIdAndGuestTypeAndName(long zoneId, long accountId, GuestType guestType, String name);
|
||||
}
|
||||
|
||||
@ -943,4 +943,16 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
|
||||
|
||||
return overlappingNetworks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkVO findByZoneIdAndAccountIdAndGuestTypeAndName(long zoneId, long accountId, GuestType guestType, String name) {
|
||||
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
|
||||
|
||||
sc.setParameters("datacenter", zoneId);
|
||||
sc.setParameters("account", accountId);
|
||||
sc.setParameters("guestType", guestType);
|
||||
sc.setParameters("name", name);
|
||||
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,6 +248,10 @@ public class SnapshotVO implements Snapshot {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return state;
|
||||
|
||||
@ -56,10 +56,18 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
// TODO: we should remove these direct sqls
|
||||
private static final String GET_LAST_SNAPSHOT =
|
||||
"SELECT snapshots.id FROM snapshot_store_ref, snapshots where snapshots.id = snapshot_store_ref.snapshot_id AND snapshosts.volume_id = ? AND snapshot_store_ref.role = ? ORDER BY created DESC";
|
||||
|
||||
private static final String VOLUME_ID = "volumeId";
|
||||
private static final String NOT_TYPE = "notType";
|
||||
private static final String TYPE = "type";
|
||||
private static final String STATUS = "status";
|
||||
private static final String VERSION = "version";
|
||||
private static final String ACCOUNT_ID = "accountId";
|
||||
private static final String REMOVED = "removed";
|
||||
private static final String NOT_TYPE = "notType";
|
||||
private static final String ID = "id";
|
||||
private static final String INSTANCE_ID = "instanceId";
|
||||
private static final String STATE = "state";
|
||||
private static final String INSTANCE_VOLUMES = "instanceVolumes";
|
||||
private static final String INSTANCE_SNAPSHOTS = "instanceSnapshots";
|
||||
|
||||
private SearchBuilder<SnapshotVO> snapshotIdsSearch;
|
||||
private SearchBuilder<SnapshotVO> VolumeIdSearch;
|
||||
@ -83,9 +91,9 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public List<SnapshotVO> listByVolumeIdTypeNotDestroyed(long volumeId, Type type) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdTypeNotDestroyedSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("type", type.ordinal());
|
||||
sc.setParameters("status", State.Destroyed);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
sc.setParameters(TYPE, type.ordinal());
|
||||
sc.setParameters(STATUS, State.Destroyed);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@ -102,28 +110,28 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public List<SnapshotVO> listByVolumeId(Filter filter, long volumeId) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
return listIncludingRemovedBy(sc, null);
|
||||
}
|
||||
|
||||
public List<SnapshotVO> listByVolumeIdType(Filter filter, long volumeId, Type type) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdTypeSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("type", type.ordinal());
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
sc.setParameters(TYPE, type.ordinal());
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
public List<SnapshotVO> listByVolumeIdVersion(Filter filter, long volumeId, String version) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdVersionSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("version", version);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
sc.setParameters(VERSION, version);
|
||||
return listBy(sc, filter);
|
||||
}
|
||||
|
||||
@ -133,61 +141,61 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
VolumeIdSearch = createSearchBuilder();
|
||||
VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdSearch.and(VOLUME_ID, VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdSearch.done();
|
||||
|
||||
VolumeIdTypeSearch = createSearchBuilder();
|
||||
VolumeIdTypeSearch.and("volumeId", VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getSnapshotType(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.and(VOLUME_ID, VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.and(TYPE, VolumeIdTypeSearch.entity().getSnapshotType(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeSearch.done();
|
||||
|
||||
VolumeIdTypeNotDestroyedSearch = createSearchBuilder();
|
||||
VolumeIdTypeNotDestroyedSearch.and("volumeId", VolumeIdTypeNotDestroyedSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeNotDestroyedSearch.and("type", VolumeIdTypeNotDestroyedSearch.entity().getSnapshotType(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeNotDestroyedSearch.and("status", VolumeIdTypeNotDestroyedSearch.entity().getState(), SearchCriteria.Op.NEQ);
|
||||
VolumeIdTypeNotDestroyedSearch.and(VOLUME_ID, VolumeIdTypeNotDestroyedSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeNotDestroyedSearch.and(TYPE, VolumeIdTypeNotDestroyedSearch.entity().getSnapshotType(), SearchCriteria.Op.EQ);
|
||||
VolumeIdTypeNotDestroyedSearch.and(STATUS, VolumeIdTypeNotDestroyedSearch.entity().getState(), SearchCriteria.Op.NEQ);
|
||||
VolumeIdTypeNotDestroyedSearch.done();
|
||||
|
||||
VolumeIdVersionSearch = createSearchBuilder();
|
||||
VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ);
|
||||
VolumeIdVersionSearch.and(VOLUME_ID, VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
VolumeIdVersionSearch.and(VERSION, VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ);
|
||||
VolumeIdVersionSearch.done();
|
||||
|
||||
AccountIdSearch = createSearchBuilder();
|
||||
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
AccountIdSearch.and(ACCOUNT_ID, AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
AccountIdSearch.done();
|
||||
|
||||
StatusSearch = createSearchBuilder();
|
||||
StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
StatusSearch.and(VOLUME_ID, StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
StatusSearch.and(STATUS, StatusSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
StatusSearch.done();
|
||||
|
||||
notInStatusSearch = createSearchBuilder();
|
||||
notInStatusSearch.and("volumeId", notInStatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
notInStatusSearch.and("status", notInStatusSearch.entity().getState(), SearchCriteria.Op.NOTIN);
|
||||
notInStatusSearch.and(VOLUME_ID, notInStatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
|
||||
notInStatusSearch.and(STATUS, notInStatusSearch.entity().getState(), SearchCriteria.Op.NOTIN);
|
||||
notInStatusSearch.done();
|
||||
|
||||
CountSnapshotsByAccount = createSearchBuilder(Long.class);
|
||||
CountSnapshotsByAccount.select(null, Func.COUNT, null);
|
||||
CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
CountSnapshotsByAccount.and("status", CountSnapshotsByAccount.entity().getState(), SearchCriteria.Op.NIN);
|
||||
CountSnapshotsByAccount.and(ACCOUNT_ID, CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
CountSnapshotsByAccount.and(STATUS, CountSnapshotsByAccount.entity().getState(), SearchCriteria.Op.NIN);
|
||||
CountSnapshotsByAccount.and("snapshotTypeNEQ", CountSnapshotsByAccount.entity().getSnapshotType(), SearchCriteria.Op.NIN);
|
||||
CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
CountSnapshotsByAccount.and(REMOVED, CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
CountSnapshotsByAccount.done();
|
||||
|
||||
InstanceIdSearch = createSearchBuilder();
|
||||
InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
InstanceIdSearch.and(STATUS, InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
|
||||
snapshotIdsSearch = createSearchBuilder();
|
||||
snapshotIdsSearch.and("id", snapshotIdsSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
snapshotIdsSearch.and(ID, snapshotIdsSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
|
||||
SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
|
||||
instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
instanceSearch.and(INSTANCE_ID, instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
|
||||
SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
|
||||
volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
|
||||
volumeSearch.and(STATE, volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
volumeSearch.join(INSTANCE_VOLUMES, instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
|
||||
|
||||
InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
|
||||
InstanceIdSearch.join(INSTANCE_SNAPSHOTS, volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
|
||||
InstanceIdSearch.done();
|
||||
|
||||
volumeIdAndTypeNotInSearch = createSearchBuilder();
|
||||
@ -219,8 +227,8 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public Long countSnapshotsForAccount(long accountId) {
|
||||
SearchCriteria<Long> sc = CountSnapshotsByAccount.create();
|
||||
sc.setParameters("account", accountId);
|
||||
sc.setParameters("status", State.Error, State.Destroyed);
|
||||
sc.setParameters(ACCOUNT_ID, accountId);
|
||||
sc.setParameters(STATUS, State.Error, State.Destroyed);
|
||||
sc.setParameters("snapshotTypeNEQ", Snapshot.Type.GROUP.ordinal());
|
||||
return customSearch(sc, null).get(0);
|
||||
}
|
||||
@ -230,19 +238,19 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
SearchCriteria<SnapshotVO> sc = InstanceIdSearch.create();
|
||||
|
||||
if (status != null && status.length != 0) {
|
||||
sc.setParameters("status", (Object[])status);
|
||||
sc.setParameters(STATUS, (Object[])status);
|
||||
}
|
||||
|
||||
sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready);
|
||||
sc.setJoinParameters("instanceVolumes", "instanceId", instanceId);
|
||||
sc.setJoinParameters(INSTANCE_SNAPSHOTS, STATE, Volume.State.Ready);
|
||||
sc.setJoinParameters(INSTANCE_VOLUMES, INSTANCE_ID, instanceId);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status) {
|
||||
SearchCriteria<SnapshotVO> sc = StatusSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("status", (Object[])status);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
sc.setParameters(STATUS, (Object[])status);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@ -263,7 +271,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public List<SnapshotVO> listAllByStatus(Snapshot.State... status) {
|
||||
SearchCriteria<SnapshotVO> sc = StatusSearch.create();
|
||||
sc.setParameters("status", (Object[])status);
|
||||
sc.setParameters(STATUS, (Object[])status);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@ -277,7 +285,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public List<SnapshotVO> listByIds(Object... ids) {
|
||||
SearchCriteria<SnapshotVO> sc = snapshotIdsSearch.create();
|
||||
sc.setParameters("id", ids);
|
||||
sc.setParameters(ID, ids);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@ -295,7 +303,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public void updateVolumeIds(long oldVolId, long newVolId) {
|
||||
SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
|
||||
sc.setParameters("volumeId", oldVolId);
|
||||
sc.setParameters(VOLUME_ID, oldVolId);
|
||||
SnapshotVO snapshot = createForUpdate();
|
||||
snapshot.setVolumeId(newVolId);
|
||||
UpdateBuilder ub = getUpdateBuilder(snapshot);
|
||||
@ -305,8 +313,8 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
|
||||
@Override
|
||||
public List<SnapshotVO> listByStatusNotIn(long volumeId, Snapshot.State... status) {
|
||||
SearchCriteria<SnapshotVO> sc = this.notInStatusSearch.create();
|
||||
sc.setParameters("volumeId", volumeId);
|
||||
sc.setParameters("status", (Object[]) status);
|
||||
sc.setParameters(VOLUME_ID, volumeId);
|
||||
sc.setParameters(STATUS, (Object[]) status);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +83,11 @@ public class BackupOfferingVO implements BackupOffering {
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
public BackupOfferingVO(final long zoneId, final String provider, final String name, final String description, final boolean userDrivenBackupAllowed) {
|
||||
this(zoneId, null, provider, name, description, userDrivenBackupAllowed);
|
||||
this.externalId = this.uuid;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@ -74,10 +74,14 @@ public class BackupScheduleVO implements BackupSchedule {
|
||||
@Column(name = "domain_id")
|
||||
Long domainId;
|
||||
|
||||
@Column(name = "isolated")
|
||||
private boolean isolated;
|
||||
|
||||
public BackupScheduleVO() {
|
||||
}
|
||||
|
||||
public BackupScheduleVO(Long vmId, DateUtil.IntervalType scheduleType, String schedule, String timezone, Date scheduledTimestamp, int maxBackups, Boolean quiesceVM, Long accountId, Long domainId) {
|
||||
public BackupScheduleVO(Long vmId, DateUtil.IntervalType scheduleType, String schedule, String timezone, Date scheduledTimestamp, int maxBackups, Boolean quiesceVM,
|
||||
Long accountId, Long domainId, boolean isolated) {
|
||||
this.vmId = vmId;
|
||||
this.scheduleType = (short) scheduleType.ordinal();
|
||||
this.schedule = schedule;
|
||||
@ -87,6 +91,7 @@ public class BackupScheduleVO implements BackupSchedule {
|
||||
this.quiesceVM = quiesceVM;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.isolated = isolated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -197,4 +202,13 @@ public class BackupScheduleVO implements BackupSchedule {
|
||||
public void setDomainId(Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
public void setIsolated(boolean isolated) {
|
||||
this.isolated = isolated;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -81,6 +80,9 @@ public class BackupVO implements Backup {
|
||||
@Column(name = "protected_size")
|
||||
private Long protectedSize;
|
||||
|
||||
@Column(name = "uncompressed_size")
|
||||
private Long uncompressedSize;
|
||||
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private Backup.Status status;
|
||||
@ -103,6 +105,12 @@ public class BackupVO implements Backup {
|
||||
@Column(name = "backup_schedule_id")
|
||||
private Long backupScheduleId;
|
||||
|
||||
@Column(name = "compression_status")
|
||||
private CompressionStatus compressionStatus;
|
||||
|
||||
@Column(name = "validation_status")
|
||||
private ValidationStatus validationStatus;
|
||||
|
||||
@Column(name = "from_checkpoint_id")
|
||||
private String fromCheckpointId;
|
||||
|
||||
@ -120,6 +128,24 @@ public class BackupVO implements Backup {
|
||||
|
||||
public BackupVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.compressionStatus = CompressionStatus.Uncompressed;
|
||||
this.validationStatus = ValidationStatus.NotValidated;
|
||||
}
|
||||
|
||||
public BackupVO(String name, long vmId, long backupOfferingId, long accountId, long domainId, long zoneId, long virtualSize, Status status, Long backupScheduleId) {
|
||||
this.name = name;
|
||||
this.vmId = vmId;
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.zoneId = zoneId;
|
||||
this.protectedSize = virtualSize;
|
||||
this.status = status;
|
||||
this.setType("FULL");
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.backupScheduleId = backupScheduleId;
|
||||
this.compressionStatus = CompressionStatus.Uncompressed;
|
||||
this.validationStatus = ValidationStatus.NotValidated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -156,6 +182,7 @@ public class BackupVO implements Backup {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
@ -301,6 +328,32 @@ public class BackupVO implements Backup {
|
||||
this.backupScheduleId = backupScheduleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompressionStatus getCompressionStatus() {
|
||||
return compressionStatus;
|
||||
}
|
||||
|
||||
public void setCompressionStatus(CompressionStatus compressionStatus) {
|
||||
this.compressionStatus = compressionStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationStatus getValidationStatus() {
|
||||
return validationStatus;
|
||||
}
|
||||
|
||||
public void setValidationStatus(ValidationStatus validationStatus) {
|
||||
this.validationStatus = validationStatus;
|
||||
}
|
||||
|
||||
public Long getUncompressedSize() {
|
||||
return uncompressedSize;
|
||||
}
|
||||
|
||||
public void setUncompressedSize(Long uncompressedSize) {
|
||||
this.uncompressedSize = uncompressedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFromCheckpointId() {
|
||||
return fromCheckpointId;
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "internal_backup_store_ref")
|
||||
public class InternalBackupDataStoreVO implements InternalIdentity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "backup_id")
|
||||
private long backupId;
|
||||
|
||||
@Column(name = "volume_id")
|
||||
private long volumeId;
|
||||
|
||||
@Column (name = "device_id")
|
||||
private long deviceId;
|
||||
|
||||
@Column(name = "path")
|
||||
private String backupPath;
|
||||
|
||||
public InternalBackupDataStoreVO() {
|
||||
}
|
||||
|
||||
public InternalBackupDataStoreVO(long backupId, long volumeId, long deviceId, String backupPath) {
|
||||
this.backupId = backupId;
|
||||
this.volumeId = volumeId;
|
||||
this.deviceId = deviceId;
|
||||
this.backupPath = backupPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public long getVolumeId() {
|
||||
return volumeId;
|
||||
}
|
||||
|
||||
public long getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public String getBackupPath() {
|
||||
return backupPath;
|
||||
}
|
||||
|
||||
public void setVolumeId(long volumeId) {
|
||||
this.volumeId = volumeId;
|
||||
}
|
||||
|
||||
public void setBackupPath(String backupPath) {
|
||||
this.backupPath = backupPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,211 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "internal_backup_view")
|
||||
public class InternalBackupJoinVO {
|
||||
|
||||
@Id
|
||||
@Column(name="id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
|
||||
@Column(name = "backed_volumes", length = 65535)
|
||||
private String backedUpVolumes;
|
||||
|
||||
@Column(name = "backup_offering_id")
|
||||
private long backupOfferingId;
|
||||
|
||||
@Column(name = "image_store_id")
|
||||
private long imageStoreId;
|
||||
|
||||
@Column(name = "parent_id")
|
||||
private long parentId;
|
||||
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
@Column(name = "date")
|
||||
@Temporal(value = TemporalType.DATE)
|
||||
private Date date;
|
||||
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private Backup.Status status;
|
||||
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
@Column(name = "compression_status")
|
||||
private Backup.CompressionStatus compressionStatus;
|
||||
|
||||
@Column(name = "end_of_chain")
|
||||
private Boolean endOfChain;
|
||||
|
||||
@Column(name = "current")
|
||||
private Boolean current;
|
||||
|
||||
@Column(name = "image_store_path")
|
||||
private String imageStorePath;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private long zoneId;
|
||||
|
||||
@Column(name = "size")
|
||||
private long size;
|
||||
|
||||
@Column(name = "protected_size")
|
||||
private long protectedSize;
|
||||
|
||||
@Column(name = "volume_id")
|
||||
private long volumeId;
|
||||
|
||||
@Column(name = "isolated")
|
||||
private Boolean isolated;
|
||||
|
||||
@Column(name = "storage_pool_delta_path")
|
||||
private String storagePoolDeltaPath;
|
||||
|
||||
@Column(name = "storage_pool_parent_path")
|
||||
private String storagePoolParentPath;
|
||||
|
||||
@Column(name = "schedule_id")
|
||||
private Long scheduleId;
|
||||
|
||||
public InternalBackupJoinVO() {
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public List<Backup.VolumeInfo> getBackedUpVolumes() {
|
||||
if (StringUtils.isEmpty(this.backedUpVolumes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(new Gson().fromJson(this.backedUpVolumes, Backup.VolumeInfo[].class));
|
||||
}
|
||||
|
||||
public long getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public long getImageStoreId() {
|
||||
return imageStoreId;
|
||||
}
|
||||
|
||||
public long getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public Backup.Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Boolean getEndOfChain() {
|
||||
return BooleanUtils.isTrue(endOfChain);
|
||||
}
|
||||
|
||||
public Boolean getCurrent() {
|
||||
return BooleanUtils.isTrue(current);
|
||||
}
|
||||
|
||||
public String getImageStorePath() {
|
||||
return imageStorePath;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public long getProtectedSize() {
|
||||
return protectedSize;
|
||||
}
|
||||
|
||||
public long getVolumeId() {
|
||||
return volumeId;
|
||||
}
|
||||
|
||||
public Boolean getIsolated() {
|
||||
return BooleanUtils.isTrue(isolated);
|
||||
}
|
||||
|
||||
public Backup.CompressionStatus getCompressionStatus() {
|
||||
return compressionStatus;
|
||||
}
|
||||
|
||||
public String getStoragePoolDeltaPath() {
|
||||
return storagePoolDeltaPath;
|
||||
}
|
||||
|
||||
public String getStoragePoolParentPath() {
|
||||
return storagePoolParentPath;
|
||||
}
|
||||
|
||||
public Long getScheduleId() {
|
||||
return scheduleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
public enum InternalBackupServiceJobType {
|
||||
StartCompression, FinalizeCompression, BackupValidation
|
||||
}
|
||||
@ -0,0 +1,179 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "internal_backup_service_job")
|
||||
public class InternalBackupServiceJobVO implements InternalIdentity, Comparable<InternalBackupServiceJobVO> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "backup_id")
|
||||
private long backupId;
|
||||
|
||||
@Column(name = "instance_id")
|
||||
private long instanceId;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name = "host_id")
|
||||
private Long hostId;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private long zoneId;
|
||||
|
||||
@Column(name = "attempts")
|
||||
private int attempts;
|
||||
|
||||
@Column (name = "type")
|
||||
private InternalBackupServiceJobType type;
|
||||
|
||||
@Column(name = GenericDao.CREATED_COLUMN)
|
||||
private Date created;
|
||||
|
||||
@Column(name = "scheduled_start_time")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date scheduledStartTime;
|
||||
|
||||
@Column(name = "start_time")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date startTime;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public InternalBackupServiceJobVO() {
|
||||
}
|
||||
|
||||
public InternalBackupServiceJobVO(long backupId, long zoneId, long instanceId, long accountId, InternalBackupServiceJobType type) {
|
||||
this.created = new Date();
|
||||
this.backupId = backupId;
|
||||
this.zoneId = zoneId;
|
||||
this.instanceId = instanceId;
|
||||
this.accountId = accountId;
|
||||
this.type = type;
|
||||
this.scheduledStartTime = this.created;
|
||||
}
|
||||
|
||||
public InternalBackupServiceJobVO(long backupId, long zoneId, long instanceId, long accountId, InternalBackupServiceJobType type, Date scheduledStartTime) {
|
||||
this(backupId, zoneId, instanceId, accountId, type);
|
||||
this.scheduledStartTime = scheduledStartTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
public long getInstanceId() {
|
||||
return instanceId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
public void setHostId(Long hostId) {
|
||||
this.hostId = hostId;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(Long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public int getAttempts() {
|
||||
return attempts;
|
||||
}
|
||||
|
||||
public void setAttempts(int attempts) {
|
||||
this.attempts = attempts;
|
||||
}
|
||||
|
||||
public InternalBackupServiceJobType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public Date getScheduledStartTime() {
|
||||
return scheduledStartTime;
|
||||
}
|
||||
|
||||
public void setScheduledStartTime(Date scheduledStartTime) {
|
||||
this.scheduledStartTime = scheduledStartTime;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Date startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public Date getRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(InternalBackupServiceJobVO that) {
|
||||
return this.created.compareTo(that.created);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "backupId", "zoneId", "hostId", "created", "scheduledStartTime", "startTime", "attempts",
|
||||
"type");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user