Skip to content

Instance lease: Allow deployment of instances with lease duration and leaseexpiry action #10560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d737cea
FR-248: Instance lease, WIP commit
sudo87 Feb 21, 2025
9bef279
insert lease expiry into db and use that to filter exiring vms, add a…
sudo87 Feb 22, 2025
759f1fa
Add leaseDuration and leaseExpiryAction in Service offering create flow
sudo87 Feb 24, 2025
8c7a9f2
Update listVM cmd to allow listing only leased instances
sudo87 Feb 24, 2025
1495b08
Add methods to fetch instances for which lease is expiring in next days
sudo87 Feb 24, 2025
e2da246
Changes included:
sudo87 Feb 25, 2025
0969bf0
Update UI screens for leased properties coming from config and servic…
sudo87 Feb 28, 2025
f239e92
use global lock before running scheduler
sudo87 Mar 1, 2025
e7ce8ae
Unit tests
sudo87 Mar 4, 2025
0cf2fe8
Flow changes done in UI based on discussion
sudo87 Mar 5, 2025
7bc5f2a
Include view changes in schema upgrade files and use feature in vario…
sudo87 Mar 5, 2025
aff544f
Added integration test for vm deployment, UI enhancements for user pe…
sudo87 Mar 6, 2025
62397cc
validate integration tests, minor ui changes and log messages
sudo87 Mar 13, 2025
faf484f
fix build: moving configkey from setup to test itself
sudo87 Mar 17, 2025
410a882
Disable testAlert to unblock build and trim whitespaces in integratio…
sudo87 Mar 17, 2025
f4aa2bc
Address review comments
sudo87 Mar 18, 2025
f77f3ab
Merge latest from main
sudo87 Mar 18, 2025
337401b
Minor changes in EditVM screen
sudo87 Mar 19, 2025
009e0b4
Use ExecutorService instead of Timer and TimerTask
sudo87 Mar 19, 2025
bd10721
Additional review comments
sudo87 Mar 22, 2025
78fc3e0
Incorporate following changes:
sudo87 Mar 27, 2025
b042167
Handle pr review comments
sudo87 Apr 7, 2025
89db8a2
merge latest changes from main
sudo87 Apr 7, 2025
5dbf822
address review comments
sudo87 Apr 24, 2025
aadc305
Merge latest from main
sudo87 Apr 24, 2025
7cd59df
move instance.lease.enabled config to VMLeaseManager interface
sudo87 Apr 24, 2025
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
3 changes: 3 additions & 0 deletions api/src/main/java/com/cloud/vm/VmDetailConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,7 @@ public interface VmDetailConstants {
String VMWARE_HOST_NAME = String.format("%s-host", VMWARE_TO_KVM_PREFIX);
String VMWARE_DISK = String.format("%s-disk", VMWARE_TO_KVM_PREFIX);
String VMWARE_MAC_ADDRESSES = String.format("%s-mac-addresses", VMWARE_TO_KVM_PREFIX);

String INSTANCE_LEASE_EXPIRY_DATE = "leaseexpirydate";
String INSTANCE_LEASE_EXPIRY_ACTION = "leaseexpiryaction";
}
5 changes: 5 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 @@ -269,6 +269,7 @@ public class ApiConstants {
public static final String INTERNAL_DNS2 = "internaldns2";
public static final String INTERNET_PROTOCOL = "internetprotocol";
public static final String INTERVAL_TYPE = "intervaltype";
public static final String INSTANCE_LEASE_ENABLED = "instanceleaseenabled";
public static final String LOCATION_TYPE = "locationtype";
public static final String IOPS_READ_RATE = "iopsreadrate";
public static final String IOPS_READ_RATE_MAX = "iopsreadratemax";
Expand Down Expand Up @@ -520,6 +521,10 @@ public class ApiConstants {
public static final String USED_SUBNETS = "usedsubnets";
public static final String USED_IOPS = "usediops";
public static final String USER_DATA = "userdata";
public static final String INSTANCE_LEASE_DURATION = "leaseduration";
public static final String INSTANCE_LEASE_EXPIRY_DATE= "leaseexpirydate";
public static final String INSTANCE_LEASE_EXPIRY_ACTION = "leaseexpiryaction";
public static final String LEASED = "leased";

public static final String USER_DATA_NAME = "userdataname";
public static final String USER_DATA_ID = "userdataid";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,14 @@ public class CreateServiceOfferingCmd extends BaseCmd {
since="4.20")
private Boolean purgeResources;

@Parameter(name = ApiConstants.INSTANCE_LEASE_DURATION, type = CommandType.LONG,
description = "Number of days instance is leased for.",
since = "4.21.0")
private Long leaseDuration;

@Parameter(name = ApiConstants.INSTANCE_LEASE_EXPIRY_ACTION, type = CommandType.STRING, since = "4.21.0",
description = "Lease expiry action, valid values are STOP and DESTROY")
private String leaseExpiryAction;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
Expand Down Expand Up @@ -487,6 +494,14 @@ public boolean getEncryptRoot() {
return false;
}

public String getLeaseExpiryAction() {
return leaseExpiryAction;
}

public Long getLeaseDuration() {
return leaseDuration;
}

public boolean isPurgeResources() {
return Boolean.TRUE.equals(purgeResources);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
response.setInstancesDisksStatsRetentionTime((Integer) capabilities.get(ApiConstants.INSTANCES_DISKS_STATS_RETENTION_TIME));
response.setSharedFsVmMinCpuCount((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_CPU_COUNT));
response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE));
response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED));

Check warning on line 75 in api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java#L75

Added line #L75 was not covered by tests
response.setObjectName("capability");
response.setResponseName(getCommandName());
this.setResponseObject(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,14 @@
description = "Enable packed virtqueues or not.")
private Boolean nicPackedVirtQueues;

@Parameter(name = ApiConstants.INSTANCE_LEASE_DURATION, type = CommandType.LONG, since = "4.21.0",
description = "Number of days instance is leased for.")
private Long leaseDuration;

@Parameter(name = ApiConstants.INSTANCE_LEASE_EXPIRY_ACTION, type = CommandType.STRING, since = "4.21.0",
description = "Lease expiry action, valid values are STOP and DESTROY")
private String leaseExpiryAction;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -475,6 +483,14 @@
return password;
}

public Long getLeaseDuration() {

Check warning on line 486 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java#L486

Added line #L486 was not covered by tests
return leaseDuration;
}

Check warning on line 488 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java#L488

Added line #L488 was not covered by tests

public String getLeaseExpiryAction() {

Check warning on line 490 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java#L490

Added line #L490 was not covered by tests
return leaseExpiryAction;
}

Check warning on line 492 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java#L492

Added line #L492 was not covered by tests

public List<Long> getNetworkIds() {
if (MapUtils.isNotEmpty(vAppNetworks)) {
if (CollectionUtils.isNotEmpty(networkIds) || ipAddress != null || getIp6Address() != null || MapUtils.isNotEmpty(ipToNetworkList)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@
@Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, required = false, description = "the instances by userdata", since = "4.20.1")
private Long userdataId;

@Parameter(name = ApiConstants.LEASED, type = CommandType.BOOLEAN,

Check warning on line 156 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java#L156

Added line #L156 was not covered by tests
description = "Whether to return only leased instances",
since = "4.21.0")
private Boolean onlyLeasedInstances = false;

Check warning on line 159 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java#L159

Added line #L159 was not covered by tests

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -330,4 +335,8 @@
vmResponse.setResourceIconResponse(iconResponse);
}
}

public Boolean getOnlyLeasedInstances() {
return onlyLeasedInstances;
}

Check warning on line 341 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java#L339-L341

Added lines #L339 - L341 were not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@
" autoscaling groups or CKS, delete protection will be ignored.")
private Boolean deleteProtection;

@Parameter(name = ApiConstants.INSTANCE_LEASE_DURATION, type = CommandType.LONG, since = "4.21.0",
description = "Number of days instance is leased for.")
private Long leaseDuration;

@Parameter(name = ApiConstants.INSTANCE_LEASE_EXPIRY_ACTION, type = CommandType.STRING, since = "4.21.0",
description = "Lease expiry action, valid values are STOP and DESTROY")
private String leaseExpiryAction;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -324,4 +332,13 @@
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
}

public Long getLeaseDuration() {
return leaseDuration;
}

Check warning on line 338 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java#L336-L338

Added lines #L336 - L338 were not covered by tests

public String getLeaseExpiryAction() {
return leaseExpiryAction;
}

Check warning on line 342 in api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java#L340-L342

Added lines #L340 - L342 were not covered by tests

}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@
@Param(description = "the min Ram size for the service offering used by the shared filesystem instance", since = "4.20.0")
private Integer sharedFsVmMinRamSize;

@SerializedName(ApiConstants.INSTANCE_LEASE_ENABLED)
@Param(description = "true if instance lease feature is enabled", since = "4.21.0")
private Boolean instanceLeaseEnabled;

public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
this.securityGroupsEnabled = securityGroupsEnabled;
}
Expand Down Expand Up @@ -247,4 +251,8 @@
public void setSharedFsVmMinRamSize(Integer sharedFsVmMinRamSize) {
this.sharedFsVmMinRamSize = sharedFsVmMinRamSize;
}

public void setInstanceLeaseEnabled(Boolean instanceLeaseEnabled) {
this.instanceLeaseEnabled = instanceLeaseEnabled;
}

Check warning on line 257 in api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java#L255-L257

Added lines #L255 - L257 were not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@
@Param(description = "Whether to cleanup VM and its associated resource upon expunge", since = "4.20")
private Boolean purgeResources;

@SerializedName(ApiConstants.INSTANCE_LEASE_DURATION)
@Param(description = "Instance lease duration for service offering", since = "4.21.0")
private Long leaseDuration;

@SerializedName(ApiConstants.INSTANCE_LEASE_EXPIRY_ACTION)
@Param(description = "Action to be taken once lease is over", since = "4.21.0")
private String leaseExpiryAction;

public ServiceOfferingResponse() {
}

Expand Down Expand Up @@ -505,6 +513,22 @@
this.cacheMode = cacheMode;
}

public Long getLeaseDuration() {
return leaseDuration;
}

Check warning on line 518 in api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java#L516-L518

Added lines #L516 - L518 were not covered by tests

public void setLeaseDuration(Long leaseDuration) {
this.leaseDuration = leaseDuration;
}

Check warning on line 522 in api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java#L520-L522

Added lines #L520 - L522 were not covered by tests

public String getLeaseExpiryAction() {
return leaseExpiryAction;
}

Check warning on line 526 in api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java#L524-L526

Added lines #L524 - L526 were not covered by tests

public void setLeaseExpiryAction(String leaseExpiryAction) {
this.leaseExpiryAction = leaseExpiryAction;
}

Check warning on line 530 in api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java#L528-L530

Added lines #L528 - L530 were not covered by tests

public String getVsphereStoragePolicy() {
return vsphereStoragePolicy;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
// under the License.
package org.apache.cloudstack.api.response;

import com.cloud.network.router.VirtualRouter;
import com.cloud.serializer.Param;
import com.cloud.uservm.UserVm;
import com.cloud.vm.VirtualMachine;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import org.apache.cloudstack.api.EntityReference;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
Expand All @@ -26,19 +38,6 @@
import java.util.Set;
import java.util.TreeSet;

import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import org.apache.cloudstack.api.EntityReference;

import com.cloud.network.router.VirtualRouter;
import com.cloud.serializer.Param;
import com.cloud.uservm.UserVm;
import com.cloud.vm.VirtualMachine;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.collections.CollectionUtils;

@SuppressWarnings("unused")
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
public class UserVmResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse, SetResourceIconResponse {
Expand Down Expand Up @@ -392,10 +391,22 @@
@Param(description = "VNF details", since = "4.19.0")
private Map<String, String> vnfDetails;

@SerializedName((ApiConstants.VM_TYPE))
@SerializedName(ApiConstants.VM_TYPE)
@Param(description = "User VM type", since = "4.20.0")
private String vmType;

@SerializedName(ApiConstants.INSTANCE_LEASE_DURATION)
@Param(description = "Instance lease duration in days", since = "4.21.0")
private Long leaseDuration;

@SerializedName(ApiConstants.INSTANCE_LEASE_EXPIRY_DATE)
@Param(description = "Instance lease expiry date", since = "4.21.0")
private Date leaseExpiryDate;

@SerializedName(ApiConstants.INSTANCE_LEASE_EXPIRY_ACTION)
@Param(description = "Instance lease expiry action", since = "4.21.0")
private String leaseExpiryAction;

public UserVmResponse() {
securityGroupList = new LinkedHashSet<>();
nics = new TreeSet<>(Comparator.comparingInt(x -> Integer.parseInt(x.getDeviceId())));
Expand Down Expand Up @@ -1169,4 +1180,29 @@
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}

public Long getLeaseDuration() {
return leaseDuration;
}

Check warning on line 1186 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1184-L1186

Added lines #L1184 - L1186 were not covered by tests

public void setLeaseDuration(Long leaseDuration) {
this.leaseDuration = leaseDuration;
}

Check warning on line 1190 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1188-L1190

Added lines #L1188 - L1190 were not covered by tests

public String getLeaseExpiryAction() {
return leaseExpiryAction;
}

Check warning on line 1194 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1192-L1194

Added lines #L1192 - L1194 were not covered by tests

public void setLeaseExpiryAction(String leaseExpiryAction) {
this.leaseExpiryAction = leaseExpiryAction;
}

Check warning on line 1198 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1196-L1198

Added lines #L1196 - L1198 were not covered by tests

public Date getLeaseExpiryDate() {
return leaseExpiryDate;
}

Check warning on line 1202 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1200-L1202

Added lines #L1200 - L1202 were not covered by tests

public void setLeaseExpiryDate(Date leaseExpiryDate) {
this.leaseExpiryDate = leaseExpiryDate;
}

Check warning on line 1206 in api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java#L1204-L1206

Added lines #L1204 - L1206 were not covered by tests

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,19 @@ public void testIsPurgeResourcesTrue() {
ReflectionTestUtils.setField(createServiceOfferingCmd, "purgeResources", true);
Assert.assertTrue(createServiceOfferingCmd.isPurgeResources());
}

@Test
public void testGetLeaseDuration() {
ReflectionTestUtils.setField(createServiceOfferingCmd, "leaseDuration", 10L);
Assert.assertEquals(10, createServiceOfferingCmd.getLeaseDuration().longValue());
}

@Test
public void testGetLeaseExpiryAction() {
ReflectionTestUtils.setField(createServiceOfferingCmd, "leaseExpiryAction", "stop");
Assert.assertEquals("stop", createServiceOfferingCmd.getLeaseExpiryAction());

ReflectionTestUtils.setField(createServiceOfferingCmd, "leaseExpiryAction", "DESTROY");
Assert.assertEquals("DESTROY", createServiceOfferingCmd.getLeaseExpiryAction());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ SELECT
`service_offering`.`dynamic_scaling_enabled` AS `dynamic_scaling_enabled`,
`service_offering`.`disk_offering_strictness` AS `disk_offering_strictness`,
`vsphere_storage_policy`.`value` AS `vsphere_storage_policy`,
`lease_duration_details`.`value` AS `lease_duration`,
`lease_expiry_action_details`.`value` AS `lease_expiry_action`,
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
Expand Down Expand Up @@ -109,5 +111,11 @@ FROM
LEFT JOIN
`cloud`.`service_offering_details` AS `vsphere_storage_policy` ON `vsphere_storage_policy`.`service_offering_id` = `service_offering`.`id`
AND `vsphere_storage_policy`.`name` = 'storagepolicy'
LEFT JOIN
`cloud`.`service_offering_details` AS `lease_duration_details` ON `lease_duration_details`.`service_offering_id` = `service_offering`.`id`
AND `lease_duration_details`.`name` = 'leaseduration'
LEFT JOIN
`cloud`.`service_offering_details` AS `lease_expiry_action_details` ON `lease_expiry_action_details`.`service_offering_id` = `service_offering`.`id`
AND `lease_expiry_action_details`.`name` = 'leaseexpiryaction'
GROUP BY
`service_offering`.`id`;
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ SELECT
`user_data`.`uuid` AS `user_data_uuid`,
`user_data`.`name` AS `user_data_name`,
`user_vm`.`user_data_details` AS `user_data_details`,
`vm_template`.`user_data_link_policy` AS `user_data_policy`
`vm_template`.`user_data_link_policy` AS `user_data_policy`,
`lease_expiry_date`.`value` AS `lease_expiry_date`,
`lease_expiry_action`.`value` AS `lease_expiry_action`
FROM
(((((((((((((((((((((((((((((((((((`user_vm`
JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`)
Expand Down Expand Up @@ -215,4 +217,8 @@ FROM
LEFT JOIN `user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `vm_instance`.`id`)
AND (`custom_speed`.`name` = 'CpuSpeed'))))
LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`)
AND (`custom_ram_size`.`name` = 'memory'))));
AND (`custom_ram_size`.`name` = 'memory')))
LEFT JOIN `user_vm_details` `lease_expiry_date` ON ((`lease_expiry_date`.`vm_id` = `vm_instance`.`id`)
AND (`lease_expiry_date`.`name` = 'leaseexpirydate'))
LEFT JOIN `user_vm_details` `lease_expiry_action` ON (((`lease_expiry_action`.`vm_id` = `vm_instance`.`id`)
AND (`lease_expiry_action`.`name` = 'leaseexpiryaction'))));
18 changes: 18 additions & 0 deletions framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,24 @@
return (J)this;
}

/**
* Adds an AND NOT condition to the search. Normally you should use this to
* perform an 'AND NOT' with a big conditional in parenthesis. For example,
*
* search.andNot().op(entity.getId(), Op.Eq, "abc").cp()
*
* The above fragment produces something similar to
*
* "AND NOT (id = $abc) where abc is the token to be replaced by a value later.
*
* @return this
*/
@SuppressWarnings("unchecked")
public J andNot() {

Check warning on line 375 in framework/db/src/main/java/com/cloud/utils/db/SearchBase.java

View check run for this annotation

Codecov / codecov/patch

framework/db/src/main/java/com/cloud/utils/db/SearchBase.java#L375

Added line #L375 was not covered by tests
constructCondition(null, " AND NOT ", null, null);
return (J)this;
}

Check warning on line 378 in framework/db/src/main/java/com/cloud/utils/db/SearchBase.java

View check run for this annotation

Codecov / codecov/patch

framework/db/src/main/java/com/cloud/utils/db/SearchBase.java#L378

Added line #L378 was not covered by tests

/**
* Closes a parenthesis that's started by op()
* @return this
Expand Down
Loading
Loading