Skip to content

Commit a87c5c2

Browse files
authored
Create new Instance from VM backup (#10140)
This feature adds the ability to create a new instance from a VM backup for dummy, NAS and Veeam backup providers. It works even if the original instance used to create the backup was expunged or unmanaged. There are two parts to this functionality: Saving all configuration details that the VM had at the time of taking the backup. And using them to create an instance from backup. Enabling a user to expunge/unmanage an instance that has backups.
1 parent b9febe4 commit a87c5c2

File tree

141 files changed

+10868
-1787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+10868
-1787
lines changed

api/src/main/java/com/cloud/capacity/Capacity.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ public interface Capacity extends InternalIdentity, Identity {
3434
public static final short CAPACITY_TYPE_LOCAL_STORAGE = 9;
3535
public static final short CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = 10;
3636
public static final short CAPACITY_TYPE_GPU = 19;
37+
public static final short CAPACITY_TYPE_OBJECT_STORAGE = 20;
38+
public static final short CAPACITY_TYPE_BACKUP_STORAGE = 21;
3739

3840
public static final short CAPACITY_TYPE_CPU_CORE = 90;
3941

4042
public static final List<Short> STORAGE_CAPACITY_TYPES = List.of(CAPACITY_TYPE_STORAGE,
4143
CAPACITY_TYPE_STORAGE_ALLOCATED,
4244
CAPACITY_TYPE_SECONDARY_STORAGE,
43-
CAPACITY_TYPE_LOCAL_STORAGE);
45+
CAPACITY_TYPE_LOCAL_STORAGE,
46+
CAPACITY_TYPE_BACKUP_STORAGE,
47+
CAPACITY_TYPE_OBJECT_STORAGE);
4448

4549
public Long getHostOrPoolId();
4650

api/src/main/java/com/cloud/event/EventTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,11 +632,13 @@ public class EventTypes {
632632
public static final String EVENT_VM_BACKUP_CREATE = "BACKUP.CREATE";
633633
public static final String EVENT_VM_BACKUP_RESTORE = "BACKUP.RESTORE";
634634
public static final String EVENT_VM_BACKUP_DELETE = "BACKUP.DELETE";
635+
public static final String EVENT_VM_BACKUP_OFFERING_REMOVED_AND_BACKUPS_DELETED = "BACKUP.OFFERING.BACKUPS.DEL";
635636
public static final String EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM = "BACKUP.RESTORE.VOLUME.TO.VM";
636637
public static final String EVENT_VM_BACKUP_SCHEDULE_CONFIGURE = "BACKUP.SCHEDULE.CONFIGURE";
637638
public static final String EVENT_VM_BACKUP_SCHEDULE_DELETE = "BACKUP.SCHEDULE.DELETE";
638639
public static final String EVENT_VM_BACKUP_USAGE_METRIC = "BACKUP.USAGE.METRIC";
639640
public static final String EVENT_VM_BACKUP_EDIT = "BACKUP.OFFERING.EDIT";
641+
public static final String EVENT_VM_CREATE_FROM_BACKUP = "VM.CREATE.FROM.BACKUP";
640642

641643
// external network device events
642644
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";

api/src/main/java/com/cloud/network/NetworkService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,5 +272,7 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
272272

273273
boolean handleCksIsoOnNetworkVirtualRouter(Long virtualRouterId, boolean mount) throws ResourceUnavailableException;
274274

275+
IpAddresses getIpAddressesFromIps(String ipAddress, String ip6Address, String macAddress);
276+
275277
String getNicVlanValueForExternalVm(NicTO nic);
276278
}

api/src/main/java/com/cloud/offering/DiskOfferingInfo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ public DiskOfferingInfo(DiskOffering diskOffering) {
3131
_diskOffering = diskOffering;
3232
}
3333

34+
public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops) {
35+
_diskOffering = diskOffering;
36+
_size = size;
37+
_minIops = minIops;
38+
_maxIops = maxIops;
39+
}
40+
3441
public void setDiskOffering(DiskOffering diskOffering) {
3542
_diskOffering = diskOffering;
3643
}

api/src/main/java/com/cloud/storage/StorageService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public interface StorageService {
134134

135135
void removeSecondaryStorageHeuristic(RemoveSecondaryStorageSelectorCmd cmd);
136136

137-
ObjectStore discoverObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
137+
ObjectStore discoverObjectStore(String name, String url, Long size, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
138138

139139
boolean deleteObjectStore(DeleteObjectStoragePoolCmd cmd);
140140

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
2828
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
2929
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
30+
import org.apache.cloudstack.api.command.user.vm.CreateVMFromBackupCmd;
3031
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
3132
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
3233
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
@@ -220,7 +221,7 @@ void startVirtualMachineForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param
220221
* available.
221222
*/
222223
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
223-
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
224+
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
224225
String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
225226
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
226227
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
@@ -297,7 +298,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
297298
* available.
298299
*/
299300
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
300-
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
301+
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor,
301302
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
302303
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
303304
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
@@ -369,7 +370,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
369370
* available.
370371
*/
371372
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
372-
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
373+
String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
373374
Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
374375
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
375376
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot)
@@ -516,4 +517,8 @@ UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemp
516517
* @return true if the VM is successfully unmanaged, false if not.
517518
*/
518519
boolean unmanageUserVM(Long vmId);
520+
521+
UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException;
522+
523+
UserVm restoreVMFromBackup(CreateVMFromBackupCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
519524
}

api/src/main/java/com/cloud/vm/VirtualMachine.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ public static StateMachine2<State, VirtualMachine.Event, VirtualMachine> getStat
128128
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
129129
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
130130
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, Event.RestoringRequested, State.Restoring, null));
131-
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, Event.RestoringRequested, State.Restoring, null));
132131
s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, Event.RestoringRequested, State.Restoring, null));
133132
s_fsm.addTransition(new Transition<State, Event>(State.Restoring, Event.RestoringSuccess, State.Stopped, null));
134133
s_fsm.addTransition(new Transition<State, Event>(State.Restoring, Event.RestoringFailed, State.Stopped, null));
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package com.cloud.vm;
20+
21+
import com.cloud.offering.DiskOffering;
22+
import com.cloud.offering.DiskOfferingInfo;
23+
24+
public class VmDiskInfo extends DiskOfferingInfo {
25+
private Long _deviceId;
26+
27+
public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops) {
28+
super(diskOffering, size, minIops, maxIops);
29+
}
30+
31+
public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long deviceId) {
32+
super(diskOffering, size, minIops, maxIops);
33+
_deviceId = deviceId;
34+
}
35+
36+
public Long getDeviceId() {
37+
return _deviceId;
38+
}
39+
}

api/src/main/java/org/apache/cloudstack/alert/AlertService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ private AlertType(short type, String name, boolean isDefault) {
7474
public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true);
7575
public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true);
7676
public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true);
77+
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
78+
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
7779

7880
public short getType() {
7981
return type;

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class ApiConstants {
2929
public static final String ADDRESS = "address";
3030
public static final String ALGORITHM = "algorithm";
3131
public static final String ALIAS = "alias";
32+
public static final String ALLOCATED = "allocated";
3233
public static final String ALLOCATED_DATE = "allocateddate";
3334
public static final String ALLOCATED_ONLY = "allocatedonly";
3435
public static final String ALLOCATED_TIME = "allocated";
@@ -60,6 +61,7 @@ public class ApiConstants {
6061
public static final String BACKUP_STORAGE_AVAILABLE = "backupstorageavailable";
6162
public static final String BACKUP_STORAGE_LIMIT = "backupstoragelimit";
6263
public static final String BACKUP_STORAGE_TOTAL = "backupstoragetotal";
64+
public static final String BACKUP_VM_OFFERING_REMOVED = "vmbackupofferingremoved";
6365
public static final String BACKUP_TOTAL = "backuptotal";
6466
public static final String BASE64_IMAGE = "base64image";
6567
public static final String BGP_PEERS = "bgppeers";
@@ -155,6 +157,7 @@ public class ApiConstants {
155157
public static final String MAX_IOPS = "maxiops";
156158
public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
157159
public static final String DATACENTER_NAME = "datacentername";
160+
public static final String DATADISKS_DETAILS = "datadisksdetails";
158161
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
159162
public static final String DEFAULT_VALUE = "defaultvalue";
160163
public static final String DELETE_PROTECTION = "deleteprotection";
@@ -163,6 +166,7 @@ public class ApiConstants {
163166
public static final String DESTINATION_ZONE_ID = "destzoneid";
164167
public static final String DETAILS = "details";
165168
public static final String DEVICE_ID = "deviceid";
169+
public static final String DEVICE_IDS = "deviceids";
166170
public static final String DEVICE_NAME = "devicename";
167171
public static final String DIRECT_DOWNLOAD = "directdownload";
168172
public static final String DISK = "disk";
@@ -305,6 +309,7 @@ public class ApiConstants {
305309
public static final String IP_ADDRESS = "ipaddress";
306310
public static final String IP_ADDRESSES = "ipaddresses";
307311
public static final String IP6_ADDRESS = "ip6address";
312+
public static final String IP6_ADDRESSES = "ip6addresses";
308313
public static final String IP_ADDRESS_ID = "ipaddressid";
309314
public static final String IS_2FA_ENABLED = "is2faenabled";
310315
public static final String IS_2FA_VERIFIED = "is2faverified";
@@ -356,6 +361,7 @@ public class ApiConstants {
356361
public static final String LBID = "lbruleid";
357362
public static final String LB_PROVIDER = "lbprovider";
358363
public static final String MAC_ADDRESS = "macaddress";
364+
public static final String MAC_ADDRESSES = "macaddresses";
359365
public static final String MANUAL_UPGRADE = "manualupgrade";
360366
public static final String MAX = "max";
361367
public static final String MAX_SNAPS = "maxsnaps";
@@ -383,6 +389,7 @@ public class ApiConstants {
383389
public static final String NETMASK = "netmask";
384390
public static final String NEW_NAME = "newname";
385391
public static final String NIC = "nic";
392+
public static final String NICS = "nics";
386393
public static final String NIC_NETWORK_LIST = "nicnetworklist";
387394
public static final String NIC_IP_ADDRESS_LIST = "nicipaddresslist";
388395
public static final String NIC_MULTIQUEUE_NUMBER = "nicmultiqueuenumber";
@@ -459,6 +466,7 @@ public class ApiConstants {
459466
public static final String POWER_STATE = "powerstate";
460467
public static final String PRECEDENCE = "precedence";
461468
public static final String PREPARE_VM = "preparevm";
469+
public static final String PRESERVE_IP = "preserveip";
462470
public static final String PRIVATE_INTERFACE = "privateinterface";
463471
public static final String PRIVATE_IP = "privateip";
464472
public static final String PRIVATE_PORT = "privateport";
@@ -494,6 +502,7 @@ public class ApiConstants {
494502
public static final String REGISTERED = "registered";
495503
public static final String QUALIFIERS = "qualifiers";
496504
public static final String QUERY_FILTER = "queryfilter";
505+
public static final String QUIESCE_VM = "quiescevm";
497506
public static final String SCHEDULE = "schedule";
498507
public static final String SCHEDULE_ID = "scheduleid";
499508
public static final String SCOPE = "scope";
@@ -509,6 +518,7 @@ public class ApiConstants {
509518
public static final String SERIAL = "serial";
510519
public static final String SERVICE_IP = "serviceip";
511520
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
521+
public static final String SERVICE_OFFERING_NAME = "serviceofferingname";
512522
public static final String SESSIONKEY = "sessionkey";
513523
public static final String SHOW_CAPACITIES = "showcapacities";
514524
public static final String SHOW_REMOVED = "showremoved";
@@ -576,6 +586,7 @@ public class ApiConstants {
576586
public static final String TRUST_STORE_PASSWORD = "truststorepass";
577587
public static final String URL = "url";
578588
public static final String USAGE_INTERFACE = "usageinterface";
589+
public static final String USED = "used";
579590
public static final String USED_SUBNETS = "usedsubnets";
580591
public static final String USED_IOPS = "usediops";
581592
public static final String USER_DATA = "userdata";
@@ -634,8 +645,10 @@ public class ApiConstants {
634645
public static final String IS_DEDICATED = "isdedicated";
635646
public static final String TAKEN = "taken";
636647
public static final String VM_AVAILABLE = "vmavailable";
648+
public static final String VM_DETAILS = "vmdetails";
637649
public static final String VM_LIMIT = "vmlimit";
638650
public static final String VM_TOTAL = "vmtotal";
651+
public static final String VM_SETTINGS = "vmsettings";
639652
public static final String VM_TYPE = "vmtype";
640653
public static final String VNET = "vnet";
641654
public static final String IS_VOLATILE = "isvolatile";
@@ -817,6 +830,7 @@ public class ApiConstants {
817830
public static final String LIST_ALL = "listall";
818831
public static final String LIST_ONLY_REMOVED = "listonlyremoved";
819832
public static final String LIST_SYSTEM_VMS = "listsystemvms";
833+
public static final String LIST_VM_DETAILS = "listvmdetails";
820834
public static final String IP_RANGES = "ipranges";
821835
public static final String IPV4_ROUTING = "ip4routing";
822836
public static final String IPV4_ROUTES = "ip4routes";

0 commit comments

Comments
 (0)