Skip to content

Commit 3e6900a

Browse files
shwstpprweizhouapachesureshanaparti
authored
api,server: purge expunged resources (#8999)
This PR introduces the functionality of purging removed DB entries for CloudStack entities (currently only for VirtualMachine). There would be three mechanisms for purging removed resources: Background task - CloudStack will run a background task which runs at a defined interval. Other parameters for this task can be controlled with new global settings. API - New admin-only API purgeExpungedResources. It will allow passing the following parameters - resourcetype, batchsize, startdate, enddate. Currently, API is not supported in the UI. Config for service offering. Service offerings can be created with purgeresources parameter which would allow purging resources immediately on expunge. Following new global settings have been added: expunged.resources.purge.enabled: Default: false. Whether to run a background task to purge the expunged resources expunged.resources.purge.resources: Default: (empty). A comma-separated list of resource types that will be considered by the background task to purge the expunged resources. Currently only VirtualMachine is supported. An empty "value will result in considering all resource types for purging expunged.resources.purge.interval: Default: 86400. Interval (in seconds) for the background task to purge the expunged resources expunged.resources.purge.delay: Default: 300. Initial delay (in seconds) to start the background task to purge the expunged resources task. expunged.resources.purge.batch.size: Default: 50. Batch size to be used during expunged resources purging. expunged.resources.purge.start.time: Default: (empty). Start time to be used by the background task to purge the expunged resources. Use format yyyy-MM-dd or yyyy-MM-dd HH:mm:ss. expunged.resources.purge.keep.past.days: Default: 30. The number of days in the past from the execution time of the background task to purge the expunged resources for which the expunged resources must not be purged. To enable purging expunged resource till the execution of the background task, set the value to zero. expunged.resource.purge.job.delay: Default: 180. Delay (in seconds) to execute the purging of an expunged resource initiated by the configuration in the offering. Minimum value should be 180 seconds and if a lower value is set then the minimum value will be used. Documentation PR: apache/cloudstack-documentation#397 Signed-off-by: Abhishek Kumar <[email protected]> Co-authored-by: Wei Zhou <[email protected]> Co-authored-by: Suresh Kumar Anaparti <[email protected]>
1 parent 373f017 commit 3e6900a

File tree

100 files changed

+4054
-59
lines changed

Some content is hidden

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

100 files changed

+4054
-59
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ jobs:
8787
smoke/test_multipleips_per_nic
8888
smoke/test_nested_virtualization
8989
smoke/test_set_sourcenat
90-
smoke/test_webhook_lifecycle",
90+
smoke/test_webhook_lifecycle
91+
smoke/test_purge_expunged_vms",
9192
"smoke/test_network
9293
smoke/test_network_acl
9394
smoke/test_network_ipv6

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,8 @@ public class EventTypes {
721721

722722
// SystemVM
723723
public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM";
724+
//Purge resources
725+
public static final String EVENT_PURGE_EXPUNGED_RESOURCES = "PURGE.EXPUNGED.RESOURCES";
724726

725727
// OBJECT STORE
726728
public static final String EVENT_OBJECT_STORE_CREATE = "OBJECT.STORE.CREATE";

api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,7 @@ public interface LoadBalancingServiceProvider extends NetworkElement, IpDeployin
4848
List<LoadBalancerTO> updateHealthChecks(Network network, List<LoadBalancingRule> lbrules);
4949

5050
boolean handlesOnlyRulesInTransitionState();
51+
52+
default void expungeLbVmRefs(List<Long> vmIds, Long batchSize) {
53+
}
5154
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity,
3333
static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
3434
// leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
3535

36+
37+
static final String PURGE_DB_ENTITIES_KEY = "purge.db.entities";
38+
3639
enum State {
3740
Inactive, Active,
3841
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ public class ApiConstants {
388388
public static final String PUBLIC_START_PORT = "publicport";
389389
public static final String PUBLIC_END_PORT = "publicendport";
390390
public static final String PUBLIC_ZONE = "publiczone";
391+
public static final String PURGE_RESOURCES = "purgeresources";
391392
public static final String RECEIVED_BYTES = "receivedbytes";
392393
public static final String RECONNECT = "reconnect";
393394
public static final String RECOVER = "recover";
@@ -909,6 +910,7 @@ public class ApiConstants {
909910
public static final String AUTOSCALE_VMGROUP_NAME = "autoscalevmgroupname";
910911
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
911912
public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
913+
public static final String BATCH_SIZE = "batchsize";
912914
public static final String UCS_DN = "ucsdn";
913915
public static final String GSLB_PROVIDER = "gslbprovider";
914916
public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";

api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@ public class CreateServiceOfferingCmd extends BaseCmd {
246246
@Parameter(name = ApiConstants.ENCRYPT_ROOT, type = CommandType.BOOLEAN, description = "VMs using this offering require root volume encryption", since="4.18")
247247
private Boolean encryptRoot;
248248

249+
@Parameter(name = ApiConstants.PURGE_RESOURCES, type = CommandType.BOOLEAN,
250+
description = "Whether to cleanup instance and its associated resource from database upon expunge of the instance",
251+
since="4.20")
252+
private Boolean purgeResources;
253+
254+
249255

250256
/////////////////////////////////////////////////////
251257
/////////////////// Accessors ///////////////////////
@@ -273,7 +279,7 @@ public Integer getMemory() {
273279

274280
public String getServiceOfferingName() {
275281
if (StringUtils.isEmpty(serviceOfferingName)) {
276-
throw new InvalidParameterValueException("Failed to create service offering because offering name has not been spified.");
282+
throw new InvalidParameterValueException("Failed to create service offering because offering name has not been specified.");
277283
}
278284
return serviceOfferingName;
279285
}
@@ -481,6 +487,10 @@ public boolean getEncryptRoot() {
481487
return false;
482488
}
483489

490+
public boolean isPurgeResources() {
491+
return Boolean.TRUE.equals(purgeResources);
492+
}
493+
484494
/////////////////////////////////////////////////////
485495
/////////////// API Implementation///////////////////
486496
/////////////////////////////////////////////////////

api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ public class UpdateServiceOfferingCmd extends BaseCmd {
8989
description = "state of the service offering")
9090
private String serviceOfferingState;
9191

92+
@Parameter(name = ApiConstants.PURGE_RESOURCES, type = CommandType.BOOLEAN,
93+
description = "Whether to cleanup VM and its associated resource upon expunge",
94+
since="4.20")
95+
private Boolean purgeResources;
96+
9297
/////////////////////////////////////////////////////
9398
/////////////////// Accessors ///////////////////////
9499
/////////////////////////////////////////////////////
@@ -185,6 +190,10 @@ public State getState() {
185190
return state;
186191
}
187192

193+
public boolean isPurgeResources() {
194+
return Boolean.TRUE.equals(purgeResources);
195+
}
196+
188197
/////////////////////////////////////////////////////
189198
/////////////// API Implementation///////////////////
190199
/////////////////////////////////////////////////////
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.resource;
19+
20+
21+
import java.util.Date;
22+
23+
import javax.inject.Inject;
24+
25+
import org.apache.cloudstack.acl.RoleType;
26+
import org.apache.cloudstack.api.APICommand;
27+
import org.apache.cloudstack.api.ApiConstants;
28+
import org.apache.cloudstack.api.ApiErrorCode;
29+
import org.apache.cloudstack.api.BaseAsyncCmd;
30+
import org.apache.cloudstack.api.BaseCmd;
31+
import org.apache.cloudstack.api.Parameter;
32+
import org.apache.cloudstack.api.ResponseObject;
33+
import org.apache.cloudstack.api.ServerApiException;
34+
import org.apache.cloudstack.api.response.PurgeExpungedResourcesResponse;
35+
import org.apache.cloudstack.api.response.SuccessResponse;
36+
import org.apache.cloudstack.context.CallContext;
37+
import org.apache.cloudstack.resource.ResourceCleanupService;
38+
39+
import com.cloud.event.EventTypes;
40+
41+
@APICommand(name = "purgeExpungedResources",
42+
description = "Purge expunged resources",
43+
responseObject = SuccessResponse.class,
44+
responseView = ResponseObject.ResponseView.Full,
45+
requestHasSensitiveInfo = false,
46+
responseHasSensitiveInfo = false,
47+
authorized = {RoleType.Admin},
48+
since = "4.20")
49+
public class PurgeExpungedResourcesCmd extends BaseAsyncCmd {
50+
51+
@Inject
52+
ResourceCleanupService resourceCleanupService;
53+
54+
/////////////////////////////////////////////////////
55+
//////////////// API parameters /////////////////////
56+
/////////////////////////////////////////////////////
57+
58+
@Parameter(name = ApiConstants.RESOURCE_TYPE, type = BaseCmd.CommandType.STRING,
59+
description = "The type of the resource which need to be purged. Supported types: " +
60+
"VirtualMachine")
61+
private String resourceType;
62+
63+
@Parameter(name = ApiConstants.BATCH_SIZE, type = CommandType.LONG,
64+
description = "The size of batch used during purging")
65+
private Long batchSize;
66+
67+
@Parameter(name = ApiConstants.START_DATE,
68+
type = CommandType.DATE,
69+
description = "The start date range of the expunged resources used for purging " +
70+
"(use format \"yyyy-MM-dd\" or \"yyyy-MM-dd HH:mm:ss\")")
71+
private Date startDate;
72+
73+
@Parameter(name = ApiConstants.END_DATE,
74+
type = CommandType.DATE,
75+
description = "The end date range of the expunged resources used for purging " +
76+
"(use format \"yyyy-MM-dd\" or \"yyyy-MM-dd HH:mm:ss\")")
77+
private Date endDate;
78+
79+
/////////////////////////////////////////////////////
80+
/////////////////// Accessors ///////////////////////
81+
/////////////////////////////////////////////////////
82+
83+
84+
public String getResourceType() {
85+
return resourceType;
86+
}
87+
88+
public Long getBatchSize() {
89+
return batchSize;
90+
}
91+
92+
public Date getStartDate() {
93+
return startDate;
94+
}
95+
96+
public Date getEndDate() {
97+
return endDate;
98+
}
99+
100+
@Override
101+
public long getEntityOwnerId() {
102+
return CallContext.current().getCallingAccount().getId();
103+
}
104+
105+
@Override
106+
public String getEventType() {
107+
return EventTypes.EVENT_PURGE_EXPUNGED_RESOURCES;
108+
}
109+
110+
@Override
111+
public String getEventDescription() {
112+
return "Purging expunged resources";
113+
}
114+
115+
/////////////////////////////////////////////////////
116+
/////////////// API Implementation///////////////////
117+
/////////////////////////////////////////////////////
118+
119+
@Override
120+
public void execute() {
121+
try {
122+
long result = resourceCleanupService.purgeExpungedResources(this);
123+
PurgeExpungedResourcesResponse response = new PurgeExpungedResourcesResponse();
124+
response.setResourceCount(result);
125+
response.setObjectName(getCommandName().toLowerCase());
126+
setResponseObject(response);
127+
} catch (Exception e) {
128+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getLocalizedMessage());
129+
}
130+
}
131+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.response;
19+
20+
import org.apache.cloudstack.api.ApiConstants;
21+
import org.apache.cloudstack.api.BaseResponse;
22+
23+
import com.cloud.serializer.Param;
24+
import com.google.gson.annotations.SerializedName;
25+
26+
public class PurgeExpungedResourcesResponse extends BaseResponse {
27+
28+
@SerializedName(ApiConstants.RESOURCE_COUNT)
29+
@Param(description = "The count of the purged expunged resources")
30+
private Long resourceCount;
31+
32+
public Long getResourceCount() {
33+
return resourceCount;
34+
}
35+
36+
public void setResourceCount(Long resourceCount) {
37+
this.resourceCount = resourceCount;
38+
}
39+
}

api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ public class ServiceOfferingResponse extends BaseResponseWithAnnotations {
234234
@Param(description = "true if virtual machine root disk will be encrypted on storage", since = "4.18")
235235
private Boolean encryptRoot;
236236

237+
@SerializedName(ApiConstants.PURGE_RESOURCES)
238+
@Param(description = "Whether to cleanup VM and its associated resource upon expunge", since = "4.20")
239+
private Boolean purgeResources;
240+
237241
public ServiceOfferingResponse() {
238242
}
239243

@@ -555,4 +559,8 @@ public String getDiskOfferingDisplayText() {
555559
}
556560

557561
public void setEncryptRoot(Boolean encrypt) { this.encryptRoot = encrypt; }
562+
563+
public void setPurgeResources(Boolean purgeResources) {
564+
this.purgeResources = purgeResources;
565+
}
558566
}

0 commit comments

Comments
 (0)