Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
9913be6
kvm: restore backups into the volume they were taken from
calvix Aug 18, 2026
4722bd4
kvm: add regression tests for backup restore volume mapping
calvix Aug 18, 2026
2e7d20e
kvm: keep create-instance-from-backup working when mapping volumes by…
calvix Aug 21, 2026
7ea1dca
Add NULL check during restoreVM operation when host is removed (#13779)
nvazquez Aug 24, 2026
5b49d6a
Errorprone static analysis tool integration and fixes of reported iss…
Pearl1594 Sep 2, 2026
7d45dcb
Migrations triggered by Maintenance (system) not reported on VM event…
abh1sar Sep 2, 2026
b09005f
UI: make serviceofferingid optional when add network offering (#13502)
weizhouapache Sep 2, 2026
3dc2305
server: fix lastpinged of hosts (#13030)
weizhouapache Sep 2, 2026
f2dec38
Merge branch '4.20' into 4.22
Sep 2, 2026
c760568
ui: label instance volume sizes as GiB (#13831)
Dogface2k Sep 2, 2026
a5954f9
fix domain cleanup when a removed account owns templates (#13630)
Damans227 Sep 2, 2026
167320e
Propagate StopAnswer error details up the call chain when stopping a …
Damans227 Sep 2, 2026
6434ff2
make sure virtual machine params exist (#12771)
DaanHoogland Sep 2, 2026
8d26cb3
Support for migration of system VMs with volumes in the GUI (#13144)
Tonitzpp Sep 2, 2026
042ec7e
UI: fix usage records end date with local timezone (#13769)
Dogface2k Sep 2, 2026
2cd8c5e
Create bridge on dest host during SSVM migration when using storage n…
Pearl1594 Sep 2, 2026
e3c7b76
Merge remote-tracking branch 'origin/4.20' into 4.22
Pearl1594 Sep 2, 2026
2b3cca6
SAML SLO does not clear session cookies on logout (#14017)
DaanHoogland Sep 4, 2026
2327e83
UI: Fix listing of resources for ASG belonging to a project (#13187)
vishesh92 Sep 7, 2026
c2c74c5
api: fix ProjectResponse.setVpcLimit assigning the network limit (#14…
rootnomad Sep 7, 2026
ac45be4
Change 2FA Field Type From Password to Text (#13723)
daviftorres Sep 7, 2026
3a79799
Make `domainid` optional in `assignVirtualMachine` (#13213)
winterhazel Sep 7, 2026
6ad0d75
volume: reset pool_id on failed volume create for zone-wide storage (…
nikolauseppinger Sep 8, 2026
f725211
fix label key for gpudisplay (#13272)
sudo87 Sep 8, 2026
6a2e033
apply the restored volume max IOPS to the max IOPS field (#14024)
rootnomad Sep 8, 2026
cdbda0a
engine: key removeNic work job lookup on nic uuid to fix concurrent r…
Andr0human Sep 8, 2026
bbf8c1a
server: do not NPE when a VPN provider returns no per-user result (#1…
rootnomad Sep 8, 2026
c860e0c
kvm: fix RBD exclusive-lock leak that breaks revertSnapshot on Ceph (…
calvix Sep 8, 2026
f493d99
sharedfs: skip hypervisors without system templates (#13830)
Dogface2k Sep 8, 2026
223351c
Add VR's system offering to network listing (#12862)
erikbocks Sep 8, 2026
74e7105
ui: show selected template hypervisor in deploy form (#13813)
Dogface2k Sep 8, 2026
215ef98
Allow cleaning up of networks stuck in Implementing state (#12409)
Pearl1594 Sep 9, 2026
245bbd9
server: null-check public IP before the DNS/Source NAT guard in creat…
rootnomad Sep 9, 2026
c7f2efa
kvm: fix restore-and-attach of a backed up volume (#14007)
abh1sar Sep 9, 2026
a9b2f33
ui: filter accessible pools on live migration with storage wizard (#1…
winterhazel Sep 9, 2026
9c8bdf3
config: persist config subgroups with their name and group id (#14050)
rootnomad Sep 9, 2026
10d3e11
KVM: fix UEFI disk-only instance snapshot NVRAM handling (#13020)
Kunalbehbud Sep 9, 2026
4ea3d0b
Merge branch '4.22' into fix/nas-backup-restore-volume-mapping
weizhouapache Sep 9, 2026
1f761f0
Update pmd config to make it pmd 7 compatible (#13168)
vishesh92 Sep 9, 2026
6e4413d
engine: do not stall the host command queue on a failed send in Agent…
rootnomad Sep 9, 2026
b93f603
api: fix inverted value comparison in ImageStoreDetailResponse.equals…
rootnomad Sep 10, 2026
c467686
[ConsoleProxy] Performance fixes on concurrency and closing console s…
nvazquez Sep 10, 2026
af8691c
Routed: get vm network statistics on Routed network (#13105)
weizhouapache Sep 10, 2026
17098c1
Fix lscpu speed checking order (#12190)
guillemtp Sep 10, 2026
02da97d
Merge remote-tracking branch 'apache/4.20' into 4.22
shwstppr Sep 10, 2026
d0d49bc
ui: fix build
shwstppr Sep 10, 2026
b9a5977
fix: use auth_client_required instead of removed auth_supported for R…
waterWang Sep 10, 2026
9018034
Add basic `.editorconfig` file to help maintain consistent coding sty…
jbampton Sep 11, 2026
a4d3c66
KVM: assign the hot-plugged NIC the next PCI slot above existing NICs…
jmsperu Sep 11, 2026
8261bec
ui: fix info card showing invalid template, iso link (#13199)
shwstppr Sep 11, 2026
9030443
SharedFS: fix NPE when accessing systemvm templates for unsupported h…
abh1sar Sep 11, 2026
2e450cb
marvin: use pycryptodome instead of PyCrypt (#13594)
weizhouapache Jul 13, 2026
a01fb0b
server: copy template details to vm instance details when import VM (…
weizhouapache Sep 14, 2026
8eeccdb
UI: don’t continue with session with an expired userid (#13969)
DaanHoogland Sep 14, 2026
e38b7a7
kvm: apply rbd_default_data_pool when creating volumes from templates…
bhouse-nexthop Sep 14, 2026
10037c8
Nas backup: Fix mount/unmount error handling and timeout in LibvirtRe…
abh1sar Sep 15, 2026
bb8f0cb
Merge branch '4.22' into fix/nas-backup-restore-volume-mapping
calvix Sep 16, 2026
1ba78e1
kvm: adapt the restore volume mapping tests to the backup command tim…
calvix Sep 16, 2026
cffa6e3
backport: Incremental NAS backup support for KVM (#13074) (#13877)
abh1sar Sep 17, 2026
a8c8c18
xenserver/xcpng: do not bypass secondary storage when copy volumes be…
weizhouapache Sep 17, 2026
273b2ea
Fix importVM for use with dummy template (#14195)
abh1sar Sep 19, 2026
ac8d69c
importVM improvements: RBD support, volume format, and cluster select…
abh1sar Sep 19, 2026
b0b7d11
kvm: keep the restore volume mapping tests on the rsync path
calvix Sep 22, 2026
f23766d
core: introduce a set of type adapters (#13624)
weizhouapache Sep 24, 2026
51c5249
Add schema upgrade path for 4.22.2 (#14179)
nvazquez Sep 28, 2026
31b6855
linstor: escape dashes in the LVM volume group name of snapshot paths…
rp- Sep 29, 2026
250695e
Escape snapshot names in libvirt XML (#14201)
sureshanaparti Sep 29, 2026
730d11f
[4.22] Fix CI Pre-commit failure (#14268)
nvazquez Sep 30, 2026
a772e8d
CKS/CSI: fix PVC deletion script to avoid '(standard input)' and use …
Pearl1594 Sep 30, 2026
2e63c60
Clarify KVM import template requirement (#13126)
andrijapanicsb Sep 30, 2026
5deb6a9
Improve date/timestamp handling performance in GenericDaoBase and Dat…
sudo87 Sep 30, 2026
4b2d387
server: null-check requested IP in assignSourceNatPublicIpAddress (#1…
rootnomad Oct 1, 2026
cdd03d7
Merge branch '4.20' into 4.22
Oct 5, 2026
d4f5dff
Fix overly broad classpath scanning in ReflectUtil.getClassesWithAnno…
vishesh92 Oct 6, 2026
4e679ad
Ensure the detail value is not null when updating the vnc access deta…
sureshanaparti Oct 6, 2026
cc2f74f
Ensure compliance with storage access groups when mounting disabled s…
sureshanaparti Oct 6, 2026
2974af8
Make worker and API thread pool size configurable (#13565)
Damans227 Oct 6, 2026
437adc8
ui: add the missing label for the backup resource limit (#14163)
stag7824 Oct 8, 2026
1805dde
kvm: look RBD volumes up through librbd instead of refreshing the poo…
bhouse-nexthop Oct 9, 2026
0931cf8
usage: widen usage_volume unique key to include vm_id (#13933)
Alpha162 Oct 9, 2026
0883185
Nasbackup quiesce fixes (#14305)
MitchDrage Oct 12, 2026
dfff32e
Netris: Improvements and fixes to the Netris plugin (#13591)
Pearl1594 Oct 12, 2026
8753579
backup: match restored volumes by uuid on the management server
calvix Oct 13, 2026
bc8e476
Merge remote-tracking branch 'upstream/4.22' into fix/nas-backup-rest…
calvix Oct 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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.
root = true

[*]
charset = utf-8
end_of_line = lf
# indent_size = 4
indent_style = space
insert_final_newline = true
# max_line_length = 120
# tab_width = 4
1 change: 1 addition & 0 deletions .github/linters/codespell.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ environmnet
equivalant
erro
erronous
errorprone
everthing
everytime
excute
Expand Down
14 changes: 14 additions & 0 deletions PendingReleaseNotes
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ example.ver.1 > example.ver.2:
which can now be attached to Instances. This is to prevent the Secondary
Storage to grow to enormous sizes as Linux Distributions keep growing in
size while a stripped down Linux should fit on a 2.88MB floppy.

4.22.0.0 > 4.22.0.1:
* Disk-only instance snapshots for KVM UEFI VMs now include a sidecar copy of
the active NVRAM state so revert operations restore both disk and firmware
boot state consistently.

* UEFI disk-only instance snapshots taken before this change do not contain an
NVRAM sidecar and cannot be safely reverted. Take a new snapshot after
upgrading before relying on revert for UEFI VMs.

* Taking a disk-only instance snapshot for KVM UEFI VMs now briefly suspends
the guest while the NVRAM sidecar is copied, so that the captured firmware
state is consistent with the disk snapshot. Non-UEFI VMs are unaffected and
continue to snapshot live.
2 changes: 1 addition & 1 deletion agent/src/main/java/com/cloud/agent/mockvm/MockVmMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public void freeVncPort(int port) {
public MockVm createVmFromSpec(VirtualMachineTO vmSpec) {
String vmName = vmSpec.getName();
long ramSize = vmSpec.getMinRam();
int utilizationPercent = randSeed.nextInt() % 100;
int utilizationPercent = randSeed.nextInt(100);
MockVm vm = null;

synchronized (this) {
Expand Down
1 change: 1 addition & 0 deletions api/src/main/java/com/cloud/host/Host.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public static String[] toStrings(Host.Type... types) {
}

String HOST_UEFI_ENABLE = "host.uefi.enable";
String HOST_KVM_DISK_ONLY_VM_SNAPSHOT_NVRAM = "host.kvm.diskonlyvmsnapshot.nvram";
String HOST_VOLUME_ENCRYPTION = "host.volume.encryption";
String HOST_INSTANCE_CONVERSION = "host.instance.conversion";
String HOST_VDDK_SUPPORT = "host.vddk.support";
Expand Down
30 changes: 18 additions & 12 deletions api/src/main/java/com/cloud/network/netris/NetrisService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.cloud.network.SDNProviderNetworkRule;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.Vpc;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.net.NetUtils;

import java.util.List;

Expand Down Expand Up @@ -81,18 +83,20 @@ public interface NetrisService {
/**
* Creates a virtual network (vNet) resource.
*
* @param zoneId the ID of the zone
* @param accountId the ID of the account
* @param domainId the ID of the domain
* @param vpcName the name of the VPC
* @param vpcId the ID of the VPC
* @param networkName the name of the network
* @param networkId the ID of the network
* @param cidr the CIDR of the network
* @param globalRouting true if global routing is enabled
* @param zoneId the ID of the zone
* @param accountId the ID of the account
* @param domainId the ID of the domain
* @param vpcName the name of the VPC
* @param vpcId the ID of the VPC
* @param networkName the name of the network
* @param networkId the ID of the network
* @param cidr the CIDR of the network
* @param networkMode the network mode
* @param internetProtocol the internet protocol
* @param isL2 true if it is an L2 network
* @return true if the operation is successful, false otherwise
*/
boolean createVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr, Boolean globalRouting);
boolean createVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr, NetworkOffering.NetworkMode networkMode, NetUtils.InternetProtocol internetProtocol, boolean isL2);

/**
* Updates an existing vNet resource.
Expand All @@ -105,9 +109,10 @@ public interface NetrisService {
* @param networkName the new name of the network
* @param networkId the ID of the network
* @param prevNetworkName the previous name of the network
* @param isL2 true if it is an L2 network
* @return true if the operation is successful, false otherwise
*/
boolean updateVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String prevNetworkName);
boolean updateVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String prevNetworkName, boolean isL2);

/**
* Deletes an existing vNet resource.
Expand All @@ -120,9 +125,10 @@ public interface NetrisService {
* @param networkName the name of the network
* @param networkId the ID of the network
* @param cidr the CIDR of the network
* @param isL2 true if it is an L2 network
* @return true if the operation is successful, false otherwise
*/
boolean deleteVnetResource(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
boolean deleteVnetResource(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr, boolean isL2);

/**
* Creates a source NAT rule for a VPC or network.
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/resource/ResourceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public interface ResourceService {

DataCenter getZone(Long zoneId);

List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forSystemVm, Long podId);

boolean releaseHostReservation(Long hostId);

Expand Down
1 change: 1 addition & 0 deletions api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public static class Param {
public static final Param PreserveNics = new Param("PreserveNics");
public static final Param ConsiderLastHost = new Param("ConsiderLastHost");
public static final Param ReturnAfterVolumePrepare = new Param("ReturnAfterVolumePrepare");
public static final Param ResetPasswordOnRestore = new Param("ResetPasswordOnRestore");

private String name;

Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ public class ApiConstants {
public static final String CURRENT_PASSWORD = "currentpassword";
public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
public static final String PASSWORD_ENABLED = "passwordenabled";
public static final String RESET_PASSWORD = "resetpassword";
public static final String SSHKEY_ENABLED = "sshkeyenabled";
public static final String PATH = "path";
public static final String PATH_READY = "pathready";
Expand Down Expand Up @@ -1288,6 +1289,7 @@ public class ApiConstants {
public static final String HAS_RULES = "hasrules";
public static final String NSX_DETAIL_KEY = "forNsx";
public static final String NETRIS_DETAIL_KEY = "forNetris";
public static final String NETRIS_NAT_PUBLIC_IP_ID = "netrisnatpublicipid";
public static final String NETRIS_TAG = "netristag";
public static final String NETRIS_VXLAN_ID = "netrisvxlanid";
public static final String NETRIS_URL = "netrisurl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ public Boolean getAllowUserDrivenBackups() {
public void execute() {
try {
if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null) {
throw new InvalidParameterValueException(String.format("Can't update Backup Offering [id: %s] because there are no parameters to be updated, at least one of the",
"following should be informed: name, description or allowUserDrivenBackups.", id));
throw new InvalidParameterValueException(String.format("Can't update Backup Offering [id: %s] because there are no parameters to be updated," +
" at least one of the following should be passed: name, description or allowUserDrivenBackups.", id));
}

BackupOffering result = backupManager.updateBackupOffering(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import static com.cloud.network.Network.Service.NetworkACL;
import static com.cloud.network.Network.Service.UserData;
import static com.cloud.network.Network.Service.Firewall;
import static com.cloud.network.Network.Service.Vpn;

import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
Expand Down Expand Up @@ -309,6 +310,10 @@ public List<String> getSupportedServices() {
} else {
services.add(Firewall.getName());
}

if (isNetrisNatted(getProvider(), getNetworkMode())) {
services.add(Vpn.getName());
}
return services;
}
}
Expand Down Expand Up @@ -418,6 +423,9 @@ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMo
serviceProviderMap.remove(Lb.getName());
}
}
if (isNetrisNatted(getProvider(), getNetworkMode())) {
serviceProviderMap.put(Vpn.getName(), List.of(routerProvider));
}
}

public Map<Capability, String> getServiceCapabilities(Service service) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.TEMPLATE_ID,
type = CommandType.UUID,
entityType = TemplateResponse.class,
description = "The ID of the Template for the Instance")
description = "The ID of the Template for the Instance. Required when the instance to import is an unmanaged KVM Instance.")
private Long templateId;

@Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public class ImportVmCmd extends ImportUnmanagedInstanceCmd {

@Parameter(name = ApiConstants.DISK_PATH,
type = CommandType.STRING,
description = "path of the disk image")
description = "path of the disk image. It is the file name on file based storage pools (NFS, Local, SharedMountPoint), and the image name on RBD storage pools")
private String diskPath;

@Parameter(name = ApiConstants.IMPORT_SOURCE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class ImportVolumeCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.PATH,
type = BaseCmd.CommandType.STRING,
required = true,
description = "the path of the volume")
description = "the path of the volume. It is the file name on file based storage pools (NFS, Local, SharedMountPoint), and the image name on RBD storage pools")
private String path;

@Parameter(name = ApiConstants.NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -61,7 +62,9 @@
import static com.cloud.network.Network.Service.NetworkACL;
import static com.cloud.network.Network.Service.UserData;
import static com.cloud.network.Network.Service.Gateway;
import static com.cloud.network.Network.Service.Vpn;

import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetris;
import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNsxWithoutLb;
Expand Down Expand Up @@ -189,7 +192,7 @@ public List<String> getSupportedServices() {
NetworkACL.getName(),
UserData.getName()
));
if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
if (isNetrisNatted(getProvider(), getNetworkMode())) {
supportedServices.addAll(Arrays.asList(
StaticNat.getName(),
SourceNat.getName(),
Expand All @@ -198,9 +201,13 @@ public List<String> getSupportedServices() {
if (NetworkOffering.NetworkMode.ROUTED.name().equalsIgnoreCase(getNetworkMode())) {
supportedServices.add(Gateway.getName());
}

if (getNsxSupportsLbService() || isNetrisNatted(getProvider(), getNetworkMode())) {
supportedServices.add(Lb.getName());
}
if (isNetrisNatted(getProvider(), getNetworkMode())) {
supportedServices.add(Vpn.getName());
}
}
return supportedServices;
}
Expand All @@ -210,7 +217,7 @@ public String getProvider() {
}

public String getNetworkMode() {
return networkMode;
return isNetris(getProvider()) && Objects.isNull(networkMode) ? NetworkOffering.NetworkMode.NATTED.name() : networkMode;
}

public boolean getNsxSupportsLbService() {
Expand Down Expand Up @@ -248,7 +255,7 @@ public Map<String, List<String>> getServiceProviders() {

private void getServiceProviderMapForExternalProvider(Map<String, List<String>> serviceProviderMap, String provider) {
List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity", "Firewall"));
if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
if (isNetrisNatted(getProvider(), getNetworkMode())) {
unsupportedServices.add("Gateway");
}
List<String> routerSupported = List.of("Dhcp", "Dns", "UserData");
Expand All @@ -258,7 +265,7 @@ private void getServiceProviderMapForExternalProvider(Map<String, List<String>>
continue;
if (routerSupported.contains(service))
serviceProviderMap.put(service, List.of(VirtualRouterProvider.Type.VPCVirtualRouter.name()));
else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) ||
else if (isNetrisNatted(getProvider(), getNetworkMode()) ||
Stream.of(NetworkACL.getName(), Gateway.getName()).anyMatch(s -> s.equalsIgnoreCase(service))) {
serviceProviderMap.put(service, List.of(provider));
}
Expand All @@ -268,7 +275,20 @@ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMo
}
}

@SuppressWarnings("unchecked")
public Map<String, List<String>> getServiceCapabilityList() {
// For Netris NATTED, Gateway service is excluded so the redundant-router capability
// must reference SourceNat (not Gateway).
if (serviceCapabilityList != null
&& isNetrisNatted(getProvider(), getNetworkMode())) {
for (Object capEntry : serviceCapabilityList.values()) {
Map<String, String> cap = (Map<String, String>) capEntry;
if (Network.Capability.RedundantRouter.getName().equalsIgnoreCase(cap.get("capabilitytype"))
&& Gateway.getName().equalsIgnoreCase(cap.get("service"))) {
cap.put("service", SourceNat.getName());
}
}
}
return serviceCapabilityList;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ 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.RESET_PASSWORD, type = CommandType.BOOLEAN,
description = "For a password enabled template, whether to generate a new password for the created Instance and return it in the response. " +
"If not specified, the zone setting `restore.vm.from.backup.reset.password` decides.", since = "4.22.1.0")
private Boolean resetPassword;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -90,6 +95,10 @@ public boolean getPreserveIp() {
return (preserveIp != null) ? preserveIp : false;
}

public Boolean getResetPassword() {
return resetPassword;
}

@Override
public void create() {
UserVm vm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;

@APICommand(name = "createVMSnapshot", description = "Creates Snapshot for an Instance.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
@APICommand(name = "createVMSnapshot", description = "Creates Snapshot for an Instance. Running KVM UEFI disk-only snapshots briefly suspend the Instance while copying NVRAM state.",
responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ public class OfferingUtils {
private OfferingUtils() {
}

public static boolean isNetris(String provider) {
return "Netris".equalsIgnoreCase(provider);
}

public static boolean isNetrisNatted(String provider, String networkMode) {
return "Netris".equalsIgnoreCase(provider) &&
return isNetris(provider) &&
NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(networkMode);
}

Expand All @@ -33,6 +37,6 @@ public static boolean isNsxWithoutLb(String provider, boolean nsxSupportsLbServi
}

public static boolean isNetrisRouted(String provider, String networkMode) {
return "Netris".equalsIgnoreCase(provider) && NetworkOffering.NetworkMode.ROUTED.name().equalsIgnoreCase(networkMode);
return isNetris(provider) && NetworkOffering.NetworkMode.ROUTED.name().equalsIgnoreCase(networkMode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.response;

import java.util.Objects;

import com.google.gson.annotations.SerializedName;

import org.apache.cloudstack.api.BaseResponse;
Expand Down Expand Up @@ -81,7 +83,7 @@ public boolean equals(Object obj) {
return false;
} else if (!oid.equals(other.getName()))
return false;
else if (this.getValue().equals(other.getValue()))
else if (!Objects.equals(this.getValue(), other.getValue()))
return false;
return true;
}
Expand Down
Loading
Loading