Skip to content

Commit 202b92f

Browse files
committed
Merge pull request #1767 from nvazquez/userVmAndTemplatesDetails
CLOUDSTACK-9457: Allow retrieval and modification of VM and template details via API and UIJIRA TICKET: https://issues.apache.org/jira/browse/CLOUDSTACK-9457 ### Goal This PR proposes list/add/update/delete user vm and vm template details via API and UI. ### VM UI Screenshots Setting tab is added on Instances page. Actions allowed are: Add/Edit/Remove ![](https://issues.apache.org/jira/secure/attachment/12844858/VMDetails1.JPG "Screenshot 1 - VM Details") Settings tab is only shown if instance is Stopped: ![](https://issues.apache.org/jira/secure/attachment/12844859/VMDetailsRunning.JPG "Screenshot 2 - VM Details Hidden Running VM") ![](https://issues.apache.org/jira/secure/attachment/12844860/VMDetailsStopped.JPG "Screenshot 3 - VM Details Stopped VM") ### Templates UI Screenshots Setting tab is added on Templates page. Actions allowed are: Add/Edit/Remove: ![](https://issues.apache.org/jira/secure/attachment/12844857/TemplateDetails1.JPG "Screenshot 4 - Template Details") * pr/1767: CLOUDSTACK-9457: Allow retrieval and modification of VM and template details via API and UI Signed-off-by: Rajani Karuturi <rajani.karuturi@accelerite.com>
2 parents 30aef28 + e8049af commit 202b92f

12 files changed

Lines changed: 445 additions & 21 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ public class ApiConstants {
649649
public static final String OVM3_POOL = "ovm3pool";
650650
public static final String OVM3_CLUSTER = "ovm3cluster";
651651
public static final String OVM3_VIP = "ovm3vip";
652+
public static final String CLEAN_UP_DETAILS = "cleanupdetails";
652653

653654
public static final String ADMIN = "admin";
654655

api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.apache.cloudstack.api;
1818

1919
import org.apache.log4j.Logger;
20-
2120
import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
2221
import org.apache.cloudstack.api.response.GuestOSResponse;
2322
import org.apache.cloudstack.api.response.TemplateResponse;
@@ -73,6 +72,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
7372
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
7473
protected Map details;
7574

75+
@Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
76+
type = CommandType.BOOLEAN,
77+
description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
78+
private Boolean cleanupDetails;
79+
7680
/////////////////////////////////////////////////////
7781
/////////////////// Accessors ///////////////////////
7882
/////////////////////////////////////////////////////
@@ -129,4 +133,8 @@ public Map getDetails() {
129133
Collection paramsCollection = this.details.values();
130134
return (Map) (paramsCollection.toArray())[0];
131135
}
132-
}
136+
137+
public boolean isCleanupDetails(){
138+
return cleanupDetails == null ? false : cleanupDetails.booleanValue();
139+
}
140+
}

api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction
116116
)
117117
private List<String> securityGroupNameList;
118118

119+
@Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
120+
type = CommandType.BOOLEAN,
121+
description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
122+
private Boolean cleanupDetails;
123+
119124
/////////////////////////////////////////////////////
120125
/////////////////// Accessors ///////////////////////
121126
/////////////////////////////////////////////////////
@@ -173,6 +178,10 @@ public List<String> getSecurityGroupNameList() {
173178
return securityGroupNameList;
174179
}
175180

181+
public boolean isCleanupDetails(){
182+
return cleanupDetails == null ? false : cleanupDetails.booleanValue();
183+
}
184+
176185
/////////////////////////////////////////////////////
177186
/////////////// API Implementation///////////////////
178187
/////////////////////////////////////////////////////

engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java

100644100755
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,20 @@ public String getValue() {
7979
public boolean isDisplay() {
8080
return display;
8181
}
82+
83+
public void setId(long id) {
84+
this.id = id;
85+
}
86+
87+
public void setResourceId(long resourceId) {
88+
this.resourceId = resourceId;
89+
}
90+
91+
public void setName(String name) {
92+
this.name = name;
93+
}
94+
95+
public void setValue(String value) {
96+
this.value = value;
97+
}
8298
}

engine/schema/src/com/cloud/vm/UserVmDetailVO.java

100644100755
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,11 @@ public boolean isDisplay() {
8080
return display;
8181
}
8282

83+
public void setName(String name) {
84+
this.name = name;
85+
}
86+
87+
public void setValue(String value) {
88+
this.value = value;
89+
}
8390
}

server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import com.cloud.utils.db.SearchCriteria;
5252
import com.cloud.vm.UserVmDetailVO;
5353
import com.cloud.vm.VirtualMachine.State;
54-
import com.cloud.vm.VmDetailConstants;
5554
import com.cloud.vm.VmStats;
5655
import com.cloud.vm.dao.NicSecondaryIpVO;
5756
import com.cloud.vm.dao.UserVmDetailsDao;
@@ -292,11 +291,13 @@ public UserVmResponse newUserVmResponse(ResponseView view, String objectName, Us
292291
}
293292

294293
// set resource details map
295-
// only hypervisortoolsversion can be returned to the end user
296-
UserVmDetailVO hypervisorToolsVersion = _userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.HYPERVISOR_TOOLS_VERSION);
297-
if (hypervisorToolsVersion != null) {
294+
// Allow passing details to end user
295+
List<UserVmDetailVO> vmDetails = _userVmDetailsDao.listDetails(userVm.getId());
296+
if (vmDetails != null) {
298297
Map<String, String> resourceDetails = new HashMap<String, String>();
299-
resourceDetails.put(hypervisorToolsVersion.getName(), hypervisorToolsVersion.getValue());
298+
for (UserVmDetailVO userVmDetailVO : vmDetails) {
299+
resourceDetails.put(userVmDetailVO.getName(), userVmDetailVO.getValue());
300+
}
300301
userVmResponse.setDetails(resourceDetails);
301302
}
302303

server/src/com/cloud/template/TemplateManagerImpl.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
import com.cloud.storage.dao.SnapshotDao;
162162
import com.cloud.storage.dao.StoragePoolHostDao;
163163
import com.cloud.storage.dao.VMTemplateDao;
164+
import com.cloud.storage.dao.VMTemplateDetailsDao;
164165
import com.cloud.storage.dao.VMTemplatePoolDao;
165166
import com.cloud.storage.dao.VMTemplateZoneDao;
166167
import com.cloud.storage.dao.VolumeDao;
@@ -269,6 +270,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
269270
private ImageStoreDao _imgStoreDao;
270271
@Inject
271272
MessageBus _messageBus;
273+
@Inject
274+
private VMTemplateDetailsDao _tmpltDetailsDao;
272275

273276
private boolean _disableExtraction = false;
274277
private List<TemplateAdapter> _adapters;
@@ -1880,6 +1883,7 @@ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
18801883
Integer sortKey = cmd.getSortKey();
18811884
Map details = cmd.getDetails();
18821885
Account account = CallContext.current().getCallingAccount();
1886+
boolean cleanupDetails = cmd.isCleanupDetails();
18831887

18841888
// verify that template exists
18851889
VMTemplateVO template = _tmpltDao.findById(id);
@@ -1911,7 +1915,8 @@ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
19111915
sortKey == null &&
19121916
isDynamicallyScalable == null &&
19131917
isRoutingTemplate == null &&
1914-
details == null);
1918+
(! cleanupDetails && details == null) //update details in every case except this one
1919+
);
19151920
if (!updateNeeded) {
19161921
return template;
19171922
}
@@ -1989,7 +1994,11 @@ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
19891994
}
19901995
}
19911996

1992-
if (details != null && !details.isEmpty()) {
1997+
if (cleanupDetails) {
1998+
template.setDetails(null);
1999+
_tmpltDetailsDao.removeDetails(id);
2000+
}
2001+
else if (details != null && !details.isEmpty()) {
19932002
template.setDetails(details);
19942003
_tmpltDao.saveDetails(template);
19952004
}

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,6 +2309,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
23092309
Map<String,String> details = cmd.getDetails();
23102310
Account caller = CallContext.current().getCallingAccount();
23112311
List<Long> securityGroupIdList = getSecurityGroupIdList(cmd);
2312+
boolean cleanupDetails = cmd.isCleanupDetails();
23122313

23132314
// Input validation and permission checks
23142315
UserVmVO vmInstance = _vmDao.findById(id);
@@ -2347,14 +2348,11 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
23472348

23482349
}
23492350

2350-
if (details != null && !details.isEmpty()) {
2351-
_vmDao.loadDetails(vmInstance);
2352-
2353-
for(Map.Entry<String,String> entry : details.entrySet()) {
2354-
if(entry instanceof Map.Entry) {
2355-
vmInstance.setDetail(entry.getKey(), entry.getValue());
2356-
}
2357-
}
2351+
if (cleanupDetails){
2352+
_vmDetailsDao.removeDetails(id);
2353+
}
2354+
else if (details != null && !details.isEmpty()) {
2355+
vmInstance.setDetails(details);
23582356
_vmDao.saveDetails(vmInstance);
23592357
}
23602358

server/test/com/cloud/template/TemplateManagerImplTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.cloud.storage.dao.SnapshotDao;
4646
import com.cloud.storage.dao.StoragePoolHostDao;
4747
import com.cloud.storage.dao.VMTemplateDao;
48+
import com.cloud.storage.dao.VMTemplateDetailsDao;
4849
import com.cloud.storage.dao.VMTemplatePoolDao;
4950
import com.cloud.storage.dao.VMTemplateZoneDao;
5051
import com.cloud.storage.dao.VolumeDao;
@@ -161,6 +162,9 @@ public class TemplateManagerImplTest {
161162
@Inject
162163
SnapshotDao snapshotDao;
163164

165+
@Inject
166+
VMTemplateDetailsDao tmpltDetailsDao;
167+
164168
public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
165169
AtomicInteger ai = new AtomicInteger(0);
166170
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
@@ -623,6 +627,11 @@ public TemplateAdapter templateAdapter() {
623627
return Mockito.mock(TemplateAdapter.class);
624628
}
625629

630+
@Bean
631+
public VMTemplateDetailsDao vmTemplateDetailsDao() {
632+
return Mockito.mock(VMTemplateDetailsDao.class);
633+
}
634+
626635
public static class Library implements TypeFilter {
627636
@Override
628637
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {

0 commit comments

Comments
 (0)