From 5afff61e6fdfca17d3c1ca5c2a09cf6c72862152 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 20 Dec 2019 14:05:09 +0100 Subject: [PATCH 1/6] create template from snapshot regression (partly reverted) (#3767) --- ui/scripts/sharedFunctions.js | 102 ++++++++++++++++++++++++++++++++++ ui/scripts/storage.js | 2 +- 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 2180f058767..d3e6fe870be 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -2841,6 +2841,7 @@ cloudStack.createTemplateMethod = function (isSnapshot){ isChecked: false } } + }, action: function(args) { var data = { @@ -2898,6 +2899,107 @@ cloudStack.createTemplateMethod = function (isSnapshot){ } }; }; +cloudStack.createTemplateFromSnapshotMethod = function (){ + return { + label: 'label.create.template', + messages: { + confirm: function(args) { + return 'message.create.template'; + }, + notification: function(args) { + return 'label.create.template'; + } + }, + createForm: { + title: 'label.create.template', + desc: '', + + + fields: { + name: { + label: 'label.name', + validation: { + required: true + } + }, + displayText: { + label: 'label.description', + validation: { + required: true + } + }, + osTypeId: { + label: 'label.os.type', + select: function(args) { + $.ajax({ + url: createURL("listOsTypes"), + dataType: "json", + async: true, + success: function(json) { + var ostypes = json.listostypesresponse.ostype; + var items = []; + $(ostypes).each(function() { + items.push({ + id: this.id, + description: this.description + }); + }); + args.response.success({ + data: items + }); + } + }); + } + }, + isPublic: { + label: 'label.public', + isBoolean: true + }, + isPasswordEnabled: { + label: 'label.password.enabled', + isBoolean: true + }, + isdynamicallyscalable: { + label: 'label.dynamically.scalable', + isBoolean: true + } + } + }, + action: function(args) { + var data = { + snapshotid: args.context.snapshots[0].id, + name: args.data.name, + displayText: args.data.displayText, + osTypeId: args.data.osTypeId, + isPublic: (args.data.isPublic == "on"), + passwordEnabled: (args.data.isPasswordEnabled == "on"), + isdynamicallyscalable: (args.data.isdynamicallyscalable == "on") + }; + + $.ajax({ + url: createURL('createTemplate'), + data: data, + success: function(json) { + var jid = json.createtemplateresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return {}; //nothing in this snapshot needs to be updated + }, + getActionFilter: function() { + return snapshotActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }; +}; cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty = function(array, parameterName, value){ if (value != null && value.length > 0) { diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index a51e8f33492..ab9747990eb 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -1960,7 +1960,7 @@ detailView: { name: 'Snapshot detail', actions: { - createTemplate: cloudStack.createTemplateMethod(true), + createTemplate: cloudStack.createTemplateFromSnapshotMethod(), createVolume: { label: 'label.action.create.volume', From 0b34971b6df5ff52954cd4df4ca341255943d3b5 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 20 Dec 2019 14:10:02 +0100 Subject: [PATCH 2/6] Once again allow a VM to be on multiple networks from VPCs (#3754) to once again allow a VM to be on multiple networks from VPCs --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index bb4246eb7df..da38205037a 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3613,7 +3613,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir short defaultNetworkNumber = 0; boolean securityGroupEnabled = false; - boolean vpcNetwork = false; for (NetworkVO network : networkList) { if ((network.getDataCenterId() != zone.getId())) { if (!network.isStrechedL2Network()) { @@ -3684,14 +3683,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir securityGroupEnabled = true; } - // vm can't be a part of more than 1 VPC network - if (network.getVpcId() != null) { - if (vpcNetwork) { - throw new InvalidParameterValueException("Vm can't be a part of more than 1 VPC network"); - } - vpcNetwork = true; - } - networkNicMap.put(network.getUuid(), profile); } From 90ce1d8c39d8bf316341aa7aa00c5c422b935d48 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 20 Dec 2019 14:11:36 +0100 Subject: [PATCH 3/6] convert protocal names to be found as labels (#3747) * convert protocal names to be found as labels * format --- ui/scripts/network.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 7e5f554d08a..aa6af96afd4 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -6843,7 +6843,8 @@ return []; } - var protocols = protocolCapabilities.value.split(','); + // make sure protocols are found in a script compatible way: i.e. "tcp,udp,tcp.proxy" , no minus sign or spaces + var protocols = protocolCapabilities.value.replace(/\s/g,'').replace('-','.').split(','); if (!protocols) { return []; From 3ac03c8858890461fbe34bbe18f6505bbd99b611 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 20 Dec 2019 14:12:10 +0100 Subject: [PATCH 4/6] filter hosts to query on zone wide storage (#3733) --- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index da38205037a..3e6022cf6ef 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -40,6 +40,7 @@ import java.util.stream.Stream; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.storage.ScopeType; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -1942,14 +1943,23 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocators, int timeout) { List neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up); - StoragePool storagePool = _storagePoolDao.findPoolByUUID(poolUuid); + StoragePoolVO storagePool = _storagePoolDao.findPoolByUUID(poolUuid); for (HostVO neighbor : neighbors) { - if (storagePool.isManaged()) { + // apply filters: + // - managed storage + // - local storage + if (storagePool.isManaged() || storagePool.isLocal()) { volumeLocators = getVolumesByHost(neighbor, storagePool); } + // - zone wide storage for specific hypervisortypes + if (ScopeType.ZONE.equals(storagePool.getScope()) && storagePool.getHypervisor() != neighbor.getHypervisorType()) { + // skip this neighbour if their hypervisor type is not the same as that of the store + continue; + } + GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocators); if (timeout > 0) { From 2712decf50340c500ed8bf853e3263a5f0cd945a Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 20 Dec 2019 15:17:22 +0100 Subject: [PATCH 5/6] config: add isdynamic flag in configuration response (#3729) --- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../api/response/ConfigurationResponse.java | 13 +++++++++++++ .../main/java/com/cloud/api/ApiResponseHelper.java | 1 + ui/scripts/globalSettings.js | 4 ++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index fb44a8a11f4..e8595e67745 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -187,6 +187,7 @@ public class ApiConstants { public static final String IP_LIMIT = "iplimit"; public static final String IP_TOTAL = "iptotal"; public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired"; + public static final String IS_DYNAMIC = "isdynamic"; public static final String IS_EXTRACTABLE = "isextractable"; public static final String IS_FEATURED = "isfeatured"; public static final String IS_PORTABLE = "isportable"; diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java index 2d815deb286..c42307c265a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java @@ -48,6 +48,10 @@ public class ConfigurationResponse extends BaseResponse { @Param(description = "the description of the configuration") private String description; + @SerializedName(ApiConstants.IS_DYNAMIC) + @Param(description = "true if the configuration is dynamic") + private boolean isDynamic; + public String getCategory() { return category; } @@ -87,4 +91,13 @@ public class ConfigurationResponse extends BaseResponse { public void setScope(String scope) { this.scope = scope; } + + public boolean isDynamic() { + return isDynamic; + } + + public void setIsDynamic(boolean isDynamic) { + this.isDynamic = isDynamic; + } + } diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 8e6731dd20d..b8e60325ea2 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -491,6 +491,7 @@ public class ApiResponseHelper implements ResponseGenerator { } else { cfgResponse.setValue(cfg.getValue()); } + cfgResponse.setIsDynamic(cfg.isDynamic()); cfgResponse.setObjectName("configuration"); return cfgResponse; diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js index 3e926ea678f..5d34982de29 100644 --- a/ui/scripts/globalSettings.js +++ b/ui/scripts/globalSettings.js @@ -41,11 +41,11 @@ data: data, success: function(json) { var item = json.updateconfigurationresponse.configuration; - if (item.category == "Usage") + if (item.category == "Usage" && item.isdynamic == false) cloudStack.dialog.notice({ message: _l('message.restart.mgmt.usage.server') }); - else + else if (item.isdynamic == false) cloudStack.dialog.notice({ message: _l('message.restart.mgmt.server') }); From 100308536ce3cdbd81e09b498122a2e1e501659d Mon Sep 17 00:00:00 2001 From: Spaceman1984 <49917670+Spaceman1984@users.noreply.github.com> Date: Mon, 23 Dec 2019 17:48:51 +0200 Subject: [PATCH 6/6] Added zone check for attach iso (#3755) --- .../main/java/com/cloud/template/TemplateManagerImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index b81faeb0bd2..646d2c3cd55 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1187,6 +1187,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId); } + long dcId = vm.getDataCenterId(); + VMTemplateZoneVO exists = _tmpltZoneDao.findByZoneTemplate(dcId, isoId); + if (null == exists) { + throw new InvalidParameterValueException("ISO is not available in the zone the VM is in."); + } + // check permissions // check if caller has access to VM and ISO // and also check if the VM's owner has access to the ISO.