You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2017/02/08 06:43:41 UTC
[1/2] git commit: updated refs/heads/master to 202b92f
Repository: cloudstack
Updated Branches:
refs/heads/master 30aef2890 -> 202b92f24
CLOUDSTACK-9457: Allow retrieval and modification of VM and template details via API and UI
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e8049af1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e8049af1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e8049af1
Branch: refs/heads/master
Commit: e8049af1534f1ab2cc8335034c2fd76c67f9fdec
Parents: 0db4471
Author: nvazquez <ni...@gmail.com>
Authored: Tue Dec 27 23:33:50 2016 -0300
Committer: nvazquez <ni...@gmail.com>
Committed: Tue Dec 27 23:33:50 2016 -0300
----------------------------------------------------------------------
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
.../api/BaseUpdateTemplateOrIsoCmd.java | 12 +-
.../api/command/user/vm/UpdateVMCmd.java | 9 +
.../com/cloud/storage/VMTemplateDetailVO.java | 16 ++
.../schema/src/com/cloud/vm/UserVmDetailVO.java | 7 +
.../cloud/api/query/dao/UserVmJoinDaoImpl.java | 11 +-
.../com/cloud/template/TemplateManagerImpl.java | 13 +-
server/src/com/cloud/vm/UserVmManagerImpl.java | 14 +-
.../cloud/template/TemplateManagerImplTest.java | 9 +
ui/scripts/instances.js | 167 ++++++++++++++++++-
ui/scripts/templates.js | 121 +++++++++++++-
ui/scripts/ui-custom/granularSettings.js | 86 +++++++++-
12 files changed, 445 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 00e9d38..f7f2a37 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -648,6 +648,7 @@ public class ApiConstants {
public static final String OVM3_POOL = "ovm3pool";
public static final String OVM3_CLUSTER = "ovm3cluster";
public static final String OVM3_VIP = "ovm3vip";
+ public static final String CLEAN_UP_DETAILS = "cleanupdetails";
public static final String ADMIN = "admin";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
index 5dc2b06..3676734 100644
--- a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -17,7 +17,6 @@
package org.apache.cloudstack.api;
import org.apache.log4j.Logger;
-
import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
@@ -73,6 +72,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
protected Map details;
+ @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
+ type = CommandType.BOOLEAN,
+ 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)")
+ private Boolean cleanupDetails;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -129,4 +133,8 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
Collection paramsCollection = this.details.values();
return (Map) (paramsCollection.toArray())[0];
}
-}
\ No newline at end of file
+
+ public boolean isCleanupDetails(){
+ return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
index 4508f7e..eb03f08 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -116,6 +116,11 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction
)
private List<String> securityGroupNameList;
+ @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
+ type = CommandType.BOOLEAN,
+ 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)")
+ private Boolean cleanupDetails;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -173,6 +178,10 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction
return securityGroupNameList;
}
+ public boolean isCleanupDetails(){
+ return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java b/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java
old mode 100644
new mode 100755
index f988aba..5010edf
--- a/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java
+++ b/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java
@@ -79,4 +79,20 @@ public class VMTemplateDetailVO implements ResourceDetail {
public boolean isDisplay() {
return display;
}
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public void setResourceId(long resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/engine/schema/src/com/cloud/vm/UserVmDetailVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/vm/UserVmDetailVO.java b/engine/schema/src/com/cloud/vm/UserVmDetailVO.java
old mode 100644
new mode 100755
index 2b169a3..81bb6dd
--- a/engine/schema/src/com/cloud/vm/UserVmDetailVO.java
+++ b/engine/schema/src/com/cloud/vm/UserVmDetailVO.java
@@ -80,4 +80,11 @@ public class UserVmDetailVO implements ResourceDetail {
return display;
}
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
index 106cd25..75b42c2 100644
--- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
@@ -51,7 +51,6 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.VmStats;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDetailsDao;
@@ -292,11 +291,13 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
}
// set resource details map
- // only hypervisortoolsversion can be returned to the end user
- UserVmDetailVO hypervisorToolsVersion = _userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.HYPERVISOR_TOOLS_VERSION);
- if (hypervisorToolsVersion != null) {
+ // Allow passing details to end user
+ List<UserVmDetailVO> vmDetails = _userVmDetailsDao.listDetails(userVm.getId());
+ if (vmDetails != null) {
Map<String, String> resourceDetails = new HashMap<String, String>();
- resourceDetails.put(hypervisorToolsVersion.getName(), hypervisorToolsVersion.getValue());
+ for (UserVmDetailVO userVmDetailVO : vmDetails) {
+ resourceDetails.put(userVmDetailVO.getName(), userVmDetailVO.getValue());
+ }
userVmResponse.setDetails(resourceDetails);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 7130042..c20889e 100644
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -161,6 +161,7 @@ import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
@@ -269,6 +270,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
private ImageStoreDao _imgStoreDao;
@Inject
MessageBus _messageBus;
+ @Inject
+ private VMTemplateDetailsDao _tmpltDetailsDao;
private boolean _disableExtraction = false;
private List<TemplateAdapter> _adapters;
@@ -1880,6 +1883,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
Integer sortKey = cmd.getSortKey();
Map details = cmd.getDetails();
Account account = CallContext.current().getCallingAccount();
+ boolean cleanupDetails = cmd.isCleanupDetails();
// verify that template exists
VMTemplateVO template = _tmpltDao.findById(id);
@@ -1911,7 +1915,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
sortKey == null &&
isDynamicallyScalable == null &&
isRoutingTemplate == null &&
- details == null);
+ (! cleanupDetails && details == null) //update details in every case except this one
+ );
if (!updateNeeded) {
return template;
}
@@ -1989,7 +1994,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
}
- if (details != null && !details.isEmpty()) {
+ if (cleanupDetails) {
+ template.setDetails(null);
+ _tmpltDetailsDao.removeDetails(id);
+ }
+ else if (details != null && !details.isEmpty()) {
template.setDetails(details);
_tmpltDao.saveDetails(template);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 453800d..1db0956 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2307,6 +2307,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Map<String,String> details = cmd.getDetails();
Account caller = CallContext.current().getCallingAccount();
List<Long> securityGroupIdList = getSecurityGroupIdList(cmd);
+ boolean cleanupDetails = cmd.isCleanupDetails();
// Input validation and permission checks
UserVmVO vmInstance = _vmDao.findById(id);
@@ -2345,14 +2346,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
- if (details != null && !details.isEmpty()) {
- _vmDao.loadDetails(vmInstance);
-
- for(Map.Entry<String,String> entry : details.entrySet()) {
- if(entry instanceof Map.Entry) {
- vmInstance.setDetail(entry.getKey(), entry.getValue());
- }
- }
+ if (cleanupDetails){
+ _vmDetailsDao.removeDetails(id);
+ }
+ else if (details != null && !details.isEmpty()) {
+ vmInstance.setDetails(details);
_vmDao.saveDetails(vmInstance);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/server/test/com/cloud/template/TemplateManagerImplTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/template/TemplateManagerImplTest.java b/server/test/com/cloud/template/TemplateManagerImplTest.java
index 6e16938..61a8a4a 100644
--- a/server/test/com/cloud/template/TemplateManagerImplTest.java
+++ b/server/test/com/cloud/template/TemplateManagerImplTest.java
@@ -45,6 +45,7 @@ import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
@@ -161,6 +162,9 @@ public class TemplateManagerImplTest {
@Inject
SnapshotDao snapshotDao;
+ @Inject
+ VMTemplateDetailsDao tmpltDetailsDao;
+
public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
AtomicInteger ai = new AtomicInteger(0);
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
@@ -623,6 +627,11 @@ public class TemplateManagerImplTest {
return Mockito.mock(TemplateAdapter.class);
}
+ @Bean
+ public VMTemplateDetailsDao vmTemplateDetailsDao() {
+ return Mockito.mock(VMTemplateDetailsDao.class);
+ }
+
public static class Library implements TypeFilter {
@Override
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/ui/scripts/instances.js
----------------------------------------------------------------------
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index 19db257..ec10df8 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -497,6 +497,10 @@
if (includingSecurityGroupService == false) {
hiddenTabs.push("securityGroups");
}
+
+ if (args.context.instances[0].state == 'Running') {
+ hiddenTabs.push("settings");
+ }
return hiddenTabs;
},
@@ -2679,11 +2683,172 @@
}
});
}
- }
+ },
+
+ /**
+ * Settings tab
+ */
+ settings: {
+ title: 'label.settings',
+ custom: cloudStack.uiCustom.granularDetails({
+ dataProvider: function(args) {
+ $.ajax({
+ url: createURL('listVirtualMachines&id=' + args.context.instances[0].id),
+ success: function(json) {
+ var details = json.listvirtualmachinesresponse.virtualmachine[0].details;
+ args.response.success({
+ data: parseDetails(details)
+ });
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+
+ },
+ actions: {
+ edit: function(args) {
+ var data = {
+ name: args.data.jsonObj.name,
+ value: args.data.value
+ };
+ var existingDetails;
+ $.ajax({
+ url: createURL('listVirtualMachines&id=' + args.context.instances[0].id),
+ async:false,
+ success: function(json) {
+ var details = json.listvirtualmachinesresponse.virtualmachine[0].details;
+ console.log(details);
+ existingDetails = details;
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ console.log(existingDetails);
+ var newDetails = '';
+ for (d in existingDetails) {
+ if (d != data.name) {
+ newDetails += 'details[0].' + d + '=' + existingDetails[d] + '&';
+ }
+ }
+ newDetails += 'details[0].' + data.name + '=' + data.value;
+
+ $.ajax({
+ url: createURL('updateVirtualMachine&id=' + args.context.instances[0].id + '&' + newDetails),
+ async:false,
+ success: function(json) {
+ var items = json.updatevirtualmachineresponse.virtualmachine.details;
+ args.response.success({
+ data: parseDetails(items)
+ });
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ },
+ remove: function(args) {
+ var existingDetails;
+ $.ajax({
+ url: createURL('listVirtualMachines&id=' + args.context.instances[0].id),
+ async:false,
+ success: function(json) {
+ var details = json.listvirtualmachinesresponse.virtualmachine[0].details;
+ existingDetails = details;
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+
+ var detailToDelete = args.data.jsonObj.name;
+ var newDetails = ''
+ for (detail in existingDetails) {
+ if (detail != detailToDelete) {
+ newDetails += 'details[0].' + detail + '=' + existingDetails[detail] + '&';
+ }
+ }
+ if (newDetails != '') {
+ newDetails = newDetails.substring(0, newDetails.length - 1);
+ }
+ else {
+ newDetails += 'cleanupdetails=true'
+ }
+ $.ajax({
+ url: createURL('updateVirtualMachine&id=' + args.context.instances[0].id + '&' + newDetails),
+ async:false,
+ success: function(json) {
+ var items = json.updatevirtualmachineresponse.virtualmachine.details;
+ args.response.success({
+ data: parseDetails(items)
+ });
+ },
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ },
+ add: function(args) {
+ var name = args.data.name;
+ var value = args.data.value;
+
+ var details;
+ $.ajax({
+ url: createURL('listVirtualMachines&id=' + args.context.instances[0].id),
+ async:false,
+ success: function(json) {
+ var dets = json.listvirtualmachinesresponse.virtualmachine[0].details;
+ details = dets;
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+
+ var detailsFormat = '';
+ for (key in details) {
+ detailsFormat += "details[0]." + key + "=" + details[key] + "&";
+ }
+ // Add new detail to the existing ones
+ detailsFormat += "details[0]." + name + "=" + value;
+ $.ajax({
+ url: createURL('updateVirtualMachine&id=' + args.context.instances[0].id + "&" + detailsFormat),
+ async: false,
+ success: function(json) {
+ var items = json.updatevirtualmachineresponse.virtualmachine.details;
+ args.response.success({
+ data: parseDetails(items)
+ });
+ },
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ }
+ }
+ })
+ }
}
}
}
};
+
+ var parseDetails = function(details) {
+ var listDetails = [];
+ for (detail in details){
+ var det = {};
+ det["name"] = detail;
+ det["value"] = details[detail];
+ listDetails.push(det);
+ }
+ return listDetails;
+ }
var vmActionfilter = cloudStack.actionFilter.vmActionFilter = function(args) {
var jsonObj = args.context.item;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/ui/scripts/templates.js
----------------------------------------------------------------------
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
old mode 100644
new mode 100755
index 96ef43a..26f0fd1
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -1780,8 +1780,125 @@
}
}}
}
- }
- }
+ },
+ /**
+ * Settings tab
+ */
+ settings: {
+ title: 'label.settings',
+ custom: cloudStack.uiCustom.granularDetails({
+ dataProvider: function(args) {
+ $.ajax({
+ url: createURL('listTemplates'),
+ data: {
+ templatefilter: "self",
+ id: args.context.templates[0].id
+ },
+ success: function(json) {
+ var details = json.listtemplatesresponse.template[0].details;
+ var listDetails = [];
+ for (detail in details){
+ var det = {};
+ det["name"] = detail;
+ det["value"] = details[detail];
+ listDetails.push(det);
+ }
+ args.response.success({
+ data: listDetails
+ });
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+
+ },
+ actions: {
+ edit: function(args) {
+ var data = {
+ name: args.data.jsonObj.name,
+ value: args.data.value
+ };
+ var existingDetails = args.context.templates[0].details;
+ var newDetails = '';
+ for (d in existingDetails) {
+ if (d != data.name) {
+ newDetails += 'details[0].' + d + '=' + existingDetails[d] + '&';
+ }
+ }
+ newDetails += 'details[0].' + data.name + '=' + data.value;
+
+ $.ajax({
+ url: createURL('updateTemplate&id=' + args.context.templates[0].id + '&' + newDetails),
+ success: function(json) {
+ var template = json.updatetemplateresponse.template;
+ args.context.templates[0].details = template.details;
+ args.response.success({
+ data: template.details
+ });
+ },
+
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ },
+ remove: function(args) {
+ var existingDetails = args.context.templates[0].details;
+ var detailToDelete = args.data.jsonObj.name;
+ var newDetails = ''
+ for (detail in existingDetails) {
+ if (detail != detailToDelete) {
+ newDetails += 'details[0].' + detail + '=' + existingDetails[detail] + '&';
+ }
+ }
+ if (newDetails != '') {
+ newDetails = newDetails.substring(0, newDetails.length - 1);
+ }
+ else {
+ newDetails += 'cleanupdetails=true';
+ }
+ $.ajax({
+ url: createURL('updateTemplate&id=' + args.context.templates[0].id + '&' + newDetails),
+ success: function(json) {
+ var template = json.updatetemplateresponse.template;
+ args.context.templates[0].details = template.details;
+ args.response.success({
+ data: template.details
+ });
+ },
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ },
+ add: function(args) {
+ var name = args.data.name;
+ var value = args.data.value;
+ var details = args.context.templates[0].details;
+ var detailsFormat = '';
+ for (key in details) {
+ detailsFormat += "details[0]." + key + "=" + details[key] + "&";
+ }
+ // Add new detail to the existing ones
+ detailsFormat += "details[0]." + name + "=" + value;
+ $.ajax({
+ url: createURL('updateTemplate&id=' + args.context.templates[0].id + "&" + detailsFormat),
+ async: false,
+ success: function(json) {
+ var template = json.updatetemplateresponse.template;
+ args.context.templates[0].details = template.details;
+ args.response.success({
+ data: template.details
+ });
+ }
+ });
+ }
+ }
+ })
+ }
+ }
}
}
},
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e8049af1/ui/scripts/ui-custom/granularSettings.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui-custom/granularSettings.js b/ui/scripts/ui-custom/granularSettings.js
index 5ab60b7..5312394 100644
--- a/ui/scripts/ui-custom/granularSettings.js
+++ b/ui/scripts/ui-custom/granularSettings.js
@@ -54,4 +54,88 @@
return $listView;
}
};
-}(jQuery, cloudStack));
+ cloudStack.uiCustom.granularDetails = function(args) {
+ var dataProvider = args.dataProvider;
+ var actions = args.actions;
+
+ return function(args) {
+ var context = args.context;
+
+ var listView = {
+ id: 'details',
+ fields: {
+ name: {
+ label: 'label.name'
+ },
+ value: {
+ label: 'label.value',
+ editable: true
+ }
+ },
+ actions: {
+ edit: {
+ label: 'label.change.value',
+ action: actions.edit
+ },
+ remove: {
+ label: 'Remove Setting',
+ messages: {
+ confirm: function(args) {
+ return 'Delete Setting';
+ },
+ notification: function(args) {
+ return 'Setting deleted';
+ }
+ },
+ action: actions.remove,
+ notification: {
+ poll: function(args) {
+ args.complete();
+ }
+ }
+ },
+ add : {
+ label: 'Add Setting',
+ messages: {
+ confirm: function(args) {
+ return 'Add Setting';
+ },
+ notification: function(args) {
+ return 'Setting added';
+ }
+ },
+ preFilter: function(args) {
+ return true;
+ },
+ createForm: {
+ title: 'Add New Setting',
+ fields: {
+ name: {
+ label: 'label.name',
+ validation: {
+ required: true
+ }
+ },
+ value: {
+ label: 'label.value',
+ validation: {
+ required: true
+ }
+ }
+ }
+ },
+ action: actions.add
+ }
+ },
+ dataProvider: dataProvider
+ };
+
+ var $listView = $('<div>').listView({
+ context: context,
+ listView: listView
+ });
+
+ return $listView;
+ }
+ };
+}(jQuery, cloudStack));
\ No newline at end of file
[2/2] git commit: updated refs/heads/master to 202b92f
Posted by ra...@apache.org.
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 <ra...@accelerite.com>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/202b92f2
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/202b92f2
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/202b92f2
Branch: refs/heads/master
Commit: 202b92f2437ea0ebd575998bf7adc7d54aeb762e
Parents: 30aef28 e8049af
Author: Rajani Karuturi <ra...@accelerite.com>
Authored: Wed Feb 8 12:12:36 2017 +0530
Committer: Rajani Karuturi <ra...@accelerite.com>
Committed: Wed Feb 8 12:12:37 2017 +0530
----------------------------------------------------------------------
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
.../api/BaseUpdateTemplateOrIsoCmd.java | 12 +-
.../api/command/user/vm/UpdateVMCmd.java | 9 +
.../com/cloud/storage/VMTemplateDetailVO.java | 16 ++
.../schema/src/com/cloud/vm/UserVmDetailVO.java | 7 +
.../cloud/api/query/dao/UserVmJoinDaoImpl.java | 11 +-
.../com/cloud/template/TemplateManagerImpl.java | 13 +-
server/src/com/cloud/vm/UserVmManagerImpl.java | 14 +-
.../cloud/template/TemplateManagerImplTest.java | 9 +
ui/scripts/instances.js | 167 ++++++++++++++++++-
ui/scripts/templates.js | 121 +++++++++++++-
ui/scripts/ui-custom/granularSettings.js | 86 +++++++++-
12 files changed, 445 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/202b92f2/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/202b92f2/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/202b92f2/ui/scripts/instances.js
----------------------------------------------------------------------