Add new template and vm deploy as is details table and refactor

This commit is contained in:
nvazquez 2020-09-14 10:34:01 -03:00 committed by Harikrishna Patnala
parent fab6b41c90
commit bb4ce2118d
45 changed files with 1190 additions and 630 deletions

View File

@ -39,10 +39,15 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.exception.InternalErrorException;
import com.cloud.utils.compression.CompressionUtil;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
@ -573,7 +578,7 @@ public class OVFHelper {
return null;
}
public List<NetworkPrerequisiteTO> getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException {
public List<OVFNetworkTO> getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException {
if (doc == null) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("no document to parse; returning no prerequiste networks");
@ -581,7 +586,7 @@ public class OVFHelper {
return Collections.emptyList();
}
Map<String, NetworkPrerequisiteTO> nets = getNetworksFromDocumentTree(doc);
Map<String, OVFNetworkTO> nets = getNetworksFromDocumentTree(doc);
checkForOnlyOneSystemNode(doc);
@ -590,7 +595,7 @@ public class OVFHelper {
return new ArrayList<>(nets.values());
}
private void matchNicsToNets(Map<String, NetworkPrerequisiteTO> nets, Node systemElement) {
private void matchNicsToNets(Map<String, OVFNetworkTO> nets, Node systemElement) {
final DocumentTraversal traversal = (DocumentTraversal) systemElement;
final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true);
if (s_logger.isTraceEnabled()) {
@ -606,9 +611,9 @@ public class OVFHelper {
if(s_logger.isInfoEnabled()) {
s_logger.info(String.format("found a nic definition without a network definition byname %s, adding it to the list.", name));
}
nets.put(name, new NetworkPrerequisiteTO());
nets.put(name, new OVFNetworkTO());
}
NetworkPrerequisiteTO thisNet = nets.get(name);
OVFNetworkTO thisNet = nets.get(name);
if (e.getParentNode() != null) {
fillNicPrerequisites(thisNet,e.getParentNode());
}
@ -625,7 +630,7 @@ public class OVFHelper {
* @param nic the object to carry through the system
* @param parentNode the xml container node for nic data
*/
private void fillNicPrerequisites(NetworkPrerequisiteTO nic, Node parentNode) {
private void fillNicPrerequisites(OVFNetworkTO nic, Node parentNode) {
String addressOnParentStr = getChildNodeValue(parentNode, "AddressOnParent");
String automaticAllocationStr = getChildNodeValue(parentNode, "AutomaticAllocation");
String description = getChildNodeValue(parentNode, "Description");
@ -667,9 +672,9 @@ public class OVFHelper {
}
}
private Map<String, NetworkPrerequisiteTO> getNetworksFromDocumentTree(Document doc) {
private Map<String, OVFNetworkTO> getNetworksFromDocumentTree(Document doc) {
NodeList networkElements = doc.getElementsByTagName("Network");
Map<String, NetworkPrerequisiteTO> nets = new HashMap<>();
Map<String, OVFNetworkTO> nets = new HashMap<>();
for (int i = 0; i < networkElements.getLength(); i++) {
Element networkElement = (Element)networkElements.item(i);
@ -677,7 +682,7 @@ public class OVFHelper {
String description = getChildNodeValue(networkElement, "Description");
NetworkPrerequisiteTO network = new NetworkPrerequisiteTO();
OVFNetworkTO network = new OVFNetworkTO();
network.setName(networkName);
network.setNetworkDescription(description);

View File

@ -16,36 +16,37 @@
// under the License.
package com.cloud.agent.api.to;
import com.cloud.agent.api.LogLevel;
import java.util.HashMap;
import java.util.Map;
public class DeployAsIsInfoTO {
private boolean deployAsIs;
private String templatePath;
private String deploymentConfiguration;
private String destStoragePool;
@LogLevel(LogLevel.Log4jLevel.Off)
private Map<String, String> properties = new HashMap<>();
public DeployAsIsInfoTO() {
}
public boolean isDeployAsIs() {
return deployAsIs;
}
public void setDeployAsIs(boolean deployAsIs) {
this.deployAsIs = deployAsIs;
public DeployAsIsInfoTO(String templatePath, String destStoragePool, Map<String, String> properties) {
this.templatePath = templatePath;
this.destStoragePool = destStoragePool;
this.properties = properties;
}
public String getTemplatePath() {
return templatePath;
}
public void setTemplatePath(String templateInSecondaryPath) {
this.templatePath = templateInSecondaryPath;
public Map<String, String> getProperties() {
return properties;
}
public String getDeploymentConfiguration() {
return deploymentConfiguration;
public String getDestStoragePool() {
return destStoragePool;
}
public void setDeploymentConfiguration(String deploymentConfiguration) {
this.deploymentConfiguration = deploymentConfiguration;
}
}

View File

@ -20,8 +20,6 @@ import java.util.List;
import java.util.Map;
import java.util.HashMap;
import com.cloud.agent.api.LogLevel;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
@ -80,8 +78,6 @@ public class VirtualMachineTO {
Map<String, String> guestOsDetails = new HashMap<String, String>();
Map<String, String> extraConfig = new HashMap<>();
@LogLevel(LogLevel.Log4jLevel.Off)
List<OVFPropertyTO> ovfProperties;
DeployAsIsInfoTO deployAsIsInfo;
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
@ -376,13 +372,6 @@ public class VirtualMachineTO {
return extraConfig;
}
public List<OVFPropertyTO> getOvfProperties() {
return ovfProperties;
}
public void setOvfProperties(List<OVFPropertyTO> ovfProperties) {
this.ovfProperties = ovfProperties;
}
public String getBootType() {
return bootType;
}

View File

@ -16,11 +16,11 @@
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.storage;
package com.cloud.agent.api.to.deployasis;
import java.util.List;
public class OVFConfigurationTO {
public class OVFConfigurationTO implements TemplateDeployAsIsInformationTO {
private final String id;
private final String label;

View File

@ -16,16 +16,14 @@
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.storage;
package com.cloud.agent.api.to.deployasis;
import com.cloud.agent.api.LogLevel;
import java.io.Serializable;
/**
* End-user licence agreement
*/
public class OVFEulaSectionTO implements Serializable {
public class OVFEulaSectionTO implements TemplateDeployAsIsInformationTO {
private String info;
@LogLevel(LogLevel.Log4jLevel.Off)
private byte[] compressedLicense;

View File

@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.net;
package com.cloud.agent.api.to.deployasis;
/**
* container for the network prerequisites as found in the appliance template
@ -38,7 +38,7 @@ package org.apache.cloudstack.api.net;
* </Item>
* {code}
*/
public class NetworkPrerequisiteTO {
public class OVFNetworkTO implements TemplateDeployAsIsInformationTO {
String name;
String networkDescription;

View File

@ -17,7 +17,7 @@
// under the License.
//
package com.cloud.agent.api.storage;
package com.cloud.agent.api.to.deployasis;
import com.cloud.agent.api.LogLevel;
@ -30,7 +30,7 @@ import com.cloud.agent.api.LogLevel;
* Choose "Remote HTTP and SSH Client Routes" to route only traffic destined for the management client(s), when they are on remote networks.</Description>
* </Property>
*/
public class OVFPropertyTO {
public class OVFPropertyTO implements TemplateDeployAsIsInformationTO {
private String key;
private String type;

View File

@ -14,10 +14,10 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.agent.api.storage;
package com.cloud.agent.api.to.deployasis;
// From: https://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData.xsd
public class OVFVirtualHardwareItemTO {
public class OVFVirtualHardwareItemTO implements TemplateDeployAsIsInformationTO{
//From: https://schemas.dmtf.org/wbem/cim-html/2/CIM_ResourceAllocationSettingData.html
public enum HardwareResourceType {

View File

@ -16,11 +16,11 @@
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.storage;
package com.cloud.agent.api.to.deployasis;
import java.util.List;
public class OVFVirtualHardwareSectionTO {
public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformationTO {
public OVFVirtualHardwareSectionTO() {
}

View File

@ -0,0 +1,24 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.to.deployasis;
import java.io.Serializable;
public interface TemplateDeployAsIsInformationTO extends Serializable {
}

View File

@ -0,0 +1,27 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis;
public interface DeployAsIsConstants {
String ACS_PROPERTY_PREFIX = "ACS-property-";
String REQUIRED_NETWORK_PREFIX = "ACS-network-";
String OVF_HARDWARE_CONFIGURATION_PREFIX = "ACS-configuration-";
String OVF_HARDWARE_ITEM_PREFIX = "ACS-hardware-item-";
String OVF_EULA_SECTION_PREFIX = "ACS-eula-";
}

View File

@ -21,13 +21,6 @@ import org.apache.cloudstack.api.InternalIdentity;
public interface ImageStore extends Identity, InternalIdentity {
String ACS_PROPERTY_PREFIX = "ACS-property-";
String REQUIRED_NETWORK_PREFIX = "ACS-network-";
String DISK_DEFINITION_PREFIX = "ACS-disk-";
String OVF_HARDWARE_CONFIGURATION_PREFIX = "ACS-configuration-";
String OVF_HARDWARE_ITEM_PREFIX = "ACS-hardware-item-";
String OVF_EULA_SECTION_PREFIX = "ACS-eula-";
/**
* @return name of the object store.
*/

View File

@ -826,6 +826,7 @@ public class ApiConstants {
public static final String BOOT_MODE = "bootmode";
public static final String BOOT_INTO_SETUP = "bootintosetup";
public static final String DEPLOY_AS_IS = "deployasis";
public static final String DEPLOY_AS_IS_DETAILS = "deployasisdetails";
public static final String CROSS_ZONES = "crossZones";
public static final String TEMPLATETYPE = "templatetype";
public static final String SOURCETEMPLATEID = "sourcetemplateid";

View File

@ -199,6 +199,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
@Param(description = "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.")
private Boolean deployAsIs;
@SerializedName(ApiConstants.DEPLOY_AS_IS_DETAILS)
@Param(description = "VMware only: additional key/value details tied with deploy-as-is template")
private Map<String, String> deployAsIsDetails;
@SerializedName("parenttemplateid")
@Param(description = "if Datadisk template, then id of the root disk template this template belongs to")
@Deprecated(since = "4.15")
@ -429,4 +433,19 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
public void setRequiresHvm(Boolean requiresHvm) {
this.requiresHvm = requiresHvm;
}
public Map<String, String> getDeployAsIsDetails() {
return this.deployAsIsDetails;
}
public void setDeployAsIsDetails(Map<String, String> details) {
this.deployAsIsDetails = details;
}
public void addDeployAsIsDetail(String key, String value) {
if (this.deployAsIsDetails == null) {
setDeployAsIsDetails(new HashMap<>());
}
this.deployAsIsDetails.put(key,value);
}
}

View File

@ -16,6 +16,10 @@
// under the License.
package com.cloud.agent.api.storage;
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.SAXException;

View File

@ -26,9 +26,12 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.LogLevel;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
public class DownloadAnswer extends Answer {
private String jobId;
@ -44,7 +47,7 @@ public class DownloadAnswer extends Answer {
@LogLevel(LogLevel.Log4jLevel.Off)
private List<OVFPropertyTO> ovfProperties;
@LogLevel(LogLevel.Log4jLevel.Off)
private List<NetworkPrerequisiteTO> networkRequirements;
private List<OVFNetworkTO> networkRequirements;
@LogLevel(LogLevel.Log4jLevel.Off)
private List<DatadiskTO> disks;
@LogLevel(LogLevel.Log4jLevel.Off)
@ -169,11 +172,11 @@ public class DownloadAnswer extends Answer {
this.ovfProperties = ovfProperties;
}
public List<NetworkPrerequisiteTO> getNetworkRequirements() {
public List<OVFNetworkTO> getNetworkRequirements() {
return networkRequirements;
}
public void setNetworkRequirements(List<NetworkPrerequisiteTO> networkRequirements) {
public void setNetworkRequirements(List<OVFNetworkTO> networkRequirements) {
this.networkRequirements = networkRequirements;
}

View File

@ -28,12 +28,12 @@ import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import com.cloud.agent.api.storage.OVFConfigurationTO;
import com.cloud.agent.api.storage.OVFEulaSectionTO;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareItemTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
@ -115,7 +115,7 @@ public class OVAProcessor extends AdapterBase implements Processor {
info.disks = disks;
}
List<NetworkPrerequisiteTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc);
List<OVFNetworkTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc);
if (CollectionUtils.isNotEmpty(nets)) {
LOGGER.info("Found " + nets.size() + " prerequisite networks");
info.networks = nets;

View File

@ -23,14 +23,14 @@ import java.io.File;
import java.io.IOException;
import java.util.List;
import com.cloud.agent.api.storage.OVFEulaSectionTO;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.utils.component.Adapter;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
/**
* Generic interface to process different types of image formats
@ -59,7 +59,7 @@ public interface Processor extends Adapter {
public String filename;
public boolean isCorrupted;
public List<OVFPropertyTO> ovfProperties;
public List<NetworkPrerequisiteTO> networks;
public List<OVFNetworkTO> networks;
public List<DatadiskTO> disks;
public OVFVirtualHardwareSectionTO hardwareSection;
public List<OVFEulaSectionTO> eulaSections;

View File

@ -17,10 +17,11 @@
package com.cloud.agent.api.storage;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.serializer.GsonHelper;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.google.gson.Gson;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.junit.Assert;
import org.junit.Test;
@ -45,8 +46,8 @@ public class DownloadAnswerTest {
{
List<OVFPropertyTO> properties = new ArrayList<>();
properties.add(new OVFPropertyTO());
List<NetworkPrerequisiteTO> networks = new ArrayList<>();
networks.add(new NetworkPrerequisiteTO());
List<OVFNetworkTO> networks = new ArrayList<>();
networks.add(new OVFNetworkTO());
answer.setOvfProperties(properties);
answer.setNetworkRequirements(networks);

View File

@ -1472,8 +1472,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (disk.getType() != Volume.Type.ISO) {
final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
final VolumeVO volume = _volsDao.findById(vol.getId());
if (vmSpec.getDeployAsIsInfo() != null && vmSpec.getDeployAsIsInfo().isDeployAsIs()
&& StringUtils.isNotBlank(vol.getPath())) {
if (vmSpec.getDeployAsIsInfo() != null && StringUtils.isNotBlank(vol.getPath())) {
volume.setPath(vol.getPath());
_volsDao.update(volume.getId(), volume);
}

View File

@ -40,9 +40,10 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
@ -181,7 +182,6 @@ import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.user.Account;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
@ -304,7 +304,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Inject
UserVmManager _userVmMgr;
@Inject
VMTemplateDetailsDao templateDetailsDao;
TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
List<NetworkGuru> networkGurus;
@ -884,7 +884,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
List<NetworkPrerequisiteTO> netprereqs = templateDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
if (size < netprereqs.size()) {
size = netprereqs.size();
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "template_deploy_as_is_details")
public class TemplateDeployAsIsDetailVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "template_id")
private long templateId;
@Column(name = "name")
private String name;
@Lob
@Column(name = "value", length = 65535)
private String value;
public TemplateDeployAsIsDetailVO() {
}
public TemplateDeployAsIsDetailVO(long templateId, String name, String value) {
this.templateId = templateId;
this.name = name;
this.value = value;
}
@Override
public long getId() {
return id;
}
public long getResourceId() {
return templateId;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public boolean isDisplay() {
return true;
}
public void setId(long id) {
this.id = id;
}
public void setTemplateId(long resourceId) {
this.templateId = resourceId;
}
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "template_deploy_as_is_details")
public class TemplateDeployAsIsDetailVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "template_id")
private long resourceId;
@Column(name = "name")
private String name;
@Lob
@Column(name = "value", length = 65535)
private String value;
public TemplateDeployAsIsDetailVO() {
}
public TemplateDeployAsIsDetailVO(long templateId, String name, String value) {
this.resourceId = templateId;
this.name = name;
this.value = value;
}
@Override
public long getId() {
return id;
}
public long getResourceId() {
return resourceId;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public boolean isDisplay() {
return true;
}
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;
}
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "user_vm_deploy_as_is_details")
public class UserVmDeployAsIsDetailVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "vm_id")
private long vmId;
@Column(name = "name")
private String name;
@Lob
@Column(name = "value", length = 65535)
private String value;
public UserVmDeployAsIsDetailVO() {
}
public UserVmDeployAsIsDetailVO(long vmId, String name, String value) {
this.vmId = vmId;
this.name = name;
this.value = value;
}
@Override
public long getId() {
return id;
}
public long getResourceId() {
return vmId;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public boolean isDisplay() {
return true;
}
public void setId(long id) {
this.id = id;
}
public void setVmId(long resourceId) {
this.vmId = resourceId;
}
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "user_vm_deploy_as_is_details")
public class UserVmDeployAsIsDetailVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "vm_id")
private long resourceId;
@Column(name = "name")
private String name;
@Lob
@Column(name = "value", length = 65535)
private String value;
public UserVmDeployAsIsDetailVO() {
}
public UserVmDeployAsIsDetailVO(long vmId, String name, String value) {
this.resourceId = vmId;
this.name = name;
this.value = value;
}
@Override
public long getId() {
return id;
}
public long getResourceId() {
return resourceId;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
@Override
public boolean isDisplay() {
return true;
}
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;
}
}

View File

@ -0,0 +1,32 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis.dao;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
import java.util.List;
public interface TemplateDeployAsIsDetailsDao extends GenericDao<TemplateDeployAsIsDetailVO, Long>, ResourceDetailsDao<TemplateDeployAsIsDetailVO> {
OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key);
List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix);
List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId);
}

View File

@ -0,0 +1,83 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis.dao;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.deployasis.DeployAsIsConstants;
import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
import com.cloud.utils.db.SearchCriteria;
import com.google.gson.Gson;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Component
public class TemplateDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase<TemplateDeployAsIsDetailVO> implements TemplateDeployAsIsDetailsDao {
private Gson gson = new Gson();
public TemplateDeployAsIsDetailsDaoImpl() {
}
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new TemplateDeployAsIsDetailVO(resourceId, key, value));
}
@Override
public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) {
SearchCriteria<TemplateDeployAsIsDetailVO> sc = createSearchCriteria();
sc.addAnd("templateId", SearchCriteria.Op.EQ, templateId);
sc.addAnd("name", SearchCriteria.Op.EQ, key.startsWith(DeployAsIsConstants.ACS_PROPERTY_PREFIX) ? key : DeployAsIsConstants.ACS_PROPERTY_PREFIX + key);
OVFPropertyTO property = null;
TemplateDeployAsIsDetailVO detail = findOneBy(sc);
if (detail != null) {
property = gson.fromJson(detail.getValue(), OVFPropertyTO.class);
}
return property;
}
@Override
public List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) {
SearchCriteria<TemplateDeployAsIsDetailVO> ssc = createSearchCriteria();
ssc.addAnd("templateId", SearchCriteria.Op.EQ, templateId);
ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%");
return search(ssc, null);
}
@Override
public List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId) {
List<TemplateDeployAsIsDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX);
List<OVFNetworkTO> networkPrereqs = new ArrayList<>();
for (TemplateDeployAsIsDetailVO property : networkDetails) {
OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class);
networkPrereqs.add(ovfPropertyTO);
}
networkPrereqs.sort(new Comparator<OVFNetworkTO>() {
@Override
public int compare(OVFNetworkTO o1, OVFNetworkTO o2) {
return o1.getInstanceID() - o2.getInstanceID();
}
});
return networkPrereqs;
}
}

View File

@ -0,0 +1,83 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis.dao;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.deployasis.DeployAsIsConstants;
import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
import com.cloud.utils.db.SearchCriteria;
import com.google.gson.Gson;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Component
public class TemplateDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase<TemplateDeployAsIsDetailVO> implements TemplateDeployAsIsDetailsDao {
private Gson gson = new Gson();
public TemplateDeployAsIsDetailsDaoImpl() {
}
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new TemplateDeployAsIsDetailVO(resourceId, key, value));
}
@Override
public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) {
SearchCriteria<TemplateDeployAsIsDetailVO> sc = createSearchCriteria();
sc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId);
sc.addAnd("name", SearchCriteria.Op.EQ, key.startsWith(DeployAsIsConstants.ACS_PROPERTY_PREFIX) ? key : DeployAsIsConstants.ACS_PROPERTY_PREFIX + key);
OVFPropertyTO property = null;
TemplateDeployAsIsDetailVO detail = findOneBy(sc);
if (detail != null) {
property = gson.fromJson(detail.getValue(), OVFPropertyTO.class);
}
return property;
}
@Override
public List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) {
SearchCriteria<TemplateDeployAsIsDetailVO> ssc = createSearchCriteria();
ssc.addAnd("resouceId", SearchCriteria.Op.EQ, templateId);
ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%");
return search(ssc, null);
}
@Override
public List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId) {
List<TemplateDeployAsIsDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX);
List<OVFNetworkTO> networkPrereqs = new ArrayList<>();
for (TemplateDeployAsIsDetailVO property : networkDetails) {
OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class);
networkPrereqs.add(ovfPropertyTO);
}
networkPrereqs.sort(new Comparator<OVFNetworkTO>() {
@Override
public int compare(OVFNetworkTO o1, OVFNetworkTO o2) {
return o1.getInstanceID() - o2.getInstanceID();
}
});
return networkPrereqs;
}
}

View File

@ -0,0 +1,24 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis.dao;
import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
public interface UserVmDeployAsIsDetailsDao extends GenericDao<UserVmDeployAsIsDetailVO, Long>, ResourceDetailsDao<UserVmDeployAsIsDetailVO> {
}

View File

@ -0,0 +1,30 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.deployasis.dao;
import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.springframework.stereotype.Component;
@Component
public class UserVmDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase<UserVmDeployAsIsDetailVO> implements UserVmDeployAsIsDetailsDao {
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new UserVmDeployAsIsDetailVO(resourceId, key, value));
}
}

View File

@ -21,7 +21,6 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.cloudstack.api.ResourceDetail;
@ -40,8 +39,7 @@ public class VMTemplateDetailVO implements ResourceDetail {
@Column(name = "name")
private String name;
@Lob
@Column(name = "value", length = 65535)
@Column(name = "value", length = 1024)
private String value;
@Column(name = "display")

View File

@ -16,25 +16,11 @@
// under the License.
package com.cloud.storage.dao;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.DatadiskTO;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
import com.cloud.storage.VMTemplateDetailVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface VMTemplateDetailsDao extends GenericDao<VMTemplateDetailVO, Long>, ResourceDetailsDao<VMTemplateDetailVO> {
boolean existsOption(long templateId, String key);
OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key);
void saveOptions(List<OVFPropertyTO> opts);
List<OVFPropertyTO> listPropertiesByTemplateId(long templateId);
List<NetworkPrerequisiteTO> listNetworkRequirementsByTemplateId(long templateId);
List<DatadiskTO> listDisksByTemplateId(long templateId);
List<VMTemplateDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix);
String getTemplateEulaSectionsUrl(long templateId);
}

View File

@ -17,137 +17,17 @@
package com.cloud.storage.dao;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.storage.ImageStore;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import com.cloud.storage.VMTemplateDetailVO;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.TransactionLegacy;
import com.google.gson.Gson;
@Component
public class VMTemplateDetailsDaoImpl extends ResourceDetailsDaoBase<VMTemplateDetailVO> implements VMTemplateDetailsDao {
private final static Logger LOGGER = Logger.getLogger(VMTemplateDetailsDaoImpl.class);
Gson gson = new Gson();
SearchBuilder<VMTemplateDetailVO> OptionsSearchBuilder;
public VMTemplateDetailsDaoImpl() {
super();
OptionsSearchBuilder = createSearchBuilder();
OptionsSearchBuilder.and("resourceId", OptionsSearchBuilder.entity().getResourceId(), SearchCriteria.Op.EQ);
OptionsSearchBuilder.and("name", OptionsSearchBuilder.entity().getName(), SearchCriteria.Op.EQ);
OptionsSearchBuilder.done();
}
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new VMTemplateDetailVO(resourceId, key, value, display));
}
@Override
public boolean existsOption(long templateId, String key) {
return findPropertyByTemplateAndKey(templateId, key) != null;
}
@Override
public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) {
SearchCriteria<VMTemplateDetailVO> sc = OptionsSearchBuilder.create();
sc.setParameters("resourceId", templateId);
sc.setParameters("name", key.startsWith(ImageStore.ACS_PROPERTY_PREFIX) ? key : ImageStore.ACS_PROPERTY_PREFIX + key);
OVFPropertyTO property = null;
VMTemplateDetailVO detail = findOneBy(sc);
if (detail != null) {
property = gson.fromJson(detail.getValue(), OVFPropertyTO.class);
}
return property;
}
@Override
public void saveOptions(List<OVFPropertyTO> opts) {
if (CollectionUtils.isEmpty(opts)) {
return;
}
TransactionLegacy txn = TransactionLegacy.currentTxn();
txn.start();
for (OVFPropertyTO opt : opts) {
String json = gson.toJson(opt);
VMTemplateDetailVO templateDetailVO = new VMTemplateDetailVO(opt.getTemplateId(), ImageStore.ACS_PROPERTY_PREFIX + opt.getKey(), json, opt.isUserConfigurable());
persist(templateDetailVO);
}
txn.commit();
}
@Override
public List<OVFPropertyTO> listPropertiesByTemplateId(long templateId) {
List<VMTemplateDetailVO> ovfProperties = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.ACS_PROPERTY_PREFIX);
List<OVFPropertyTO> properties = new ArrayList<>();
for (VMTemplateDetailVO property : ovfProperties) {
OVFPropertyTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFPropertyTO.class);
properties.add(ovfPropertyTO);
}
return properties;
}
@Override
public List<NetworkPrerequisiteTO> listNetworkRequirementsByTemplateId(long templateId) {
List<VMTemplateDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.REQUIRED_NETWORK_PREFIX);
List<NetworkPrerequisiteTO> networkPrereqs = new ArrayList<>();
for (VMTemplateDetailVO property : networkDetails) {
NetworkPrerequisiteTO ovfPropertyTO = gson.fromJson(property.getValue(), NetworkPrerequisiteTO.class);
networkPrereqs.add(ovfPropertyTO);
}
networkPrereqs.sort(new Comparator<NetworkPrerequisiteTO>() {
@Override
public int compare(NetworkPrerequisiteTO o1, NetworkPrerequisiteTO o2) {
return o1.getInstanceID() - o2.getInstanceID();
}
});
return networkPrereqs;
}
@Override
public List<DatadiskTO> listDisksByTemplateId(long templateId) {
List<VMTemplateDetailVO> diskDefinitions = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.DISK_DEFINITION_PREFIX);
List<DatadiskTO> disks = new ArrayList<>();
for (VMTemplateDetailVO detail : diskDefinitions) {
DatadiskTO datadiskTO = gson.fromJson(detail.getValue(), DatadiskTO.class);
disks.add(datadiskTO);
}
return disks;
}
@Override
public List<VMTemplateDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) {
SearchCriteria<VMTemplateDetailVO> ssc = createSearchCriteria();
ssc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId);
ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%");
return search(ssc, null);
}
@Override
public String getTemplateEulaSectionsUrl(long templateId) {
List<VMTemplateDetailVO> details = findDetails(templateId, ImageStore.OVF_EULA_SECTION_PREFIX);
if (CollectionUtils.isEmpty(details)) {
return null;
}
if (details.size() > 1) {
LOGGER.error("Multiple details for EULA sections for template " + templateId + " returning one");
}
return details.get(0).getValue();
}
}

View File

@ -30,7 +30,6 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.storage.ImageStore;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
@ -383,25 +382,13 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>();
for (Map.Entry<String, String> entry : detailsStr.entrySet()) {
boolean display = visibilityMap.getOrDefault(entry.getKey(), true) && displayOVFDetails(entry.getKey());
boolean display = visibilityMap.getOrDefault(entry.getKey(), true);
details.add(new UserVmDetailVO(vm.getId(), entry.getKey(), entry.getValue(), display));
}
_detailsDao.saveDetails(details);
}
/*
Do not display VM properties parsed from OVF, handled internally
*/
private boolean displayOVFDetails(String key) {
if (key.startsWith(ImageStore.ACS_PROPERTY_PREFIX) || key.startsWith(ImageStore.OVF_HARDWARE_ITEM_PREFIX) ||
key.startsWith(ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX) || key.startsWith(ImageStore.DISK_DEFINITION_PREFIX) ||
key.startsWith(ImageStore.REQUIRED_NETWORK_PREFIX) || key.startsWith(ImageStore.OVF_EULA_SECTION_PREFIX)) {
return false;
}
return true;
}
@Override
public List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId) {
TransactionLegacy txn = TransactionLegacy.currentTxn();

View File

@ -295,4 +295,6 @@
<bean id="directDownloadCertificateHostMapDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMapDaoImpl" />
<bean id="routerHealthCheckResultsDaoImpl" class="com.cloud.network.dao.RouterHealthCheckResultDaoImpl" />
<bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" />
<bean id="TemplateDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDaoImpl" />
<bean id="UserVmDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDaoImpl" />
</beans>

View File

@ -473,6 +473,92 @@ ADD CONSTRAINT `fk_template_spool_ref__template_id`
ON DELETE NO ACTION
ON UPDATE NO ACTION;
CREATE TABLE IF NOT EXISTS `cloud`.`vsphere_storage_policy` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(255) UNIQUE,
`zone_id` bigint(20) unsigned NOT NULL COMMENT 'id of the zone',
`policy_id` varchar(255) NOT NULL COMMENT 'the identifier of the Storage Policy in vSphere DataCenter',
`name` varchar(255) NOT NULL COMMENT 'name of the storage policy',
`description` text COMMENT 'description of the storage policy',
`update_time` datetime COMMENT 'last updated when policy imported',
`removed` datetime COMMENT 'date removed',
PRIMARY KEY (`id`),
KEY `fk_vsphere_storage_policy__zone_id` (`zone_id`),
UNIQUE KEY (`zone_id`, `policy_id`),
CONSTRAINT `fk_vsphere_storage_policy__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`storage_pool` ADD COLUMN `parent` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'ID of the Datastore cluster (storage pool) if this is a child in that Datastore cluster';
-- Added parent column to support datastore clusters in vmware vsphere
DROP VIEW IF EXISTS `cloud`.`storage_pool_view`;
CREATE VIEW `cloud`.`storage_pool_view` AS
SELECT
`storage_pool`.`id` AS `id`,
`storage_pool`.`uuid` AS `uuid`,
`storage_pool`.`name` AS `name`,
`storage_pool`.`status` AS `status`,
`storage_pool`.`path` AS `path`,
`storage_pool`.`pool_type` AS `pool_type`,
`storage_pool`.`host_address` AS `host_address`,
`storage_pool`.`created` AS `created`,
`storage_pool`.`removed` AS `removed`,
`storage_pool`.`capacity_bytes` AS `capacity_bytes`,
`storage_pool`.`capacity_iops` AS `capacity_iops`,
`storage_pool`.`scope` AS `scope`,
`storage_pool`.`hypervisor` AS `hypervisor`,
`storage_pool`.`storage_provider_name` AS `storage_provider_name`,
`storage_pool`.`parent` AS `parent`,
`cluster`.`id` AS `cluster_id`,
`cluster`.`uuid` AS `cluster_uuid`,
`cluster`.`name` AS `cluster_name`,
`cluster`.`cluster_type` AS `cluster_type`,
`data_center`.`id` AS `data_center_id`,
`data_center`.`uuid` AS `data_center_uuid`,
`data_center`.`name` AS `data_center_name`,
`data_center`.`networktype` AS `data_center_type`,
`host_pod_ref`.`id` AS `pod_id`,
`host_pod_ref`.`uuid` AS `pod_uuid`,
`host_pod_ref`.`name` AS `pod_name`,
`storage_pool_tags`.`tag` AS `tag`,
`op_host_capacity`.`used_capacity` AS `disk_used_capacity`,
`op_host_capacity`.`reserved_capacity` AS `disk_reserved_capacity`,
`async_job`.`id` AS `job_id`,
`async_job`.`uuid` AS `job_uuid`,
`async_job`.`job_status` AS `job_status`,
`async_job`.`account_id` AS `job_account_id`
FROM
((((((`storage_pool`
LEFT JOIN `cluster` ON ((`storage_pool`.`cluster_id` = `cluster`.`id`)))
LEFT JOIN `data_center` ON ((`storage_pool`.`data_center_id` = `data_center`.`id`)))
LEFT JOIN `host_pod_ref` ON ((`storage_pool`.`pod_id` = `host_pod_ref`.`id`)))
LEFT JOIN `storage_pool_tags` ON (((`storage_pool_tags`.`pool_id` = `storage_pool`.`id`))))
LEFT JOIN `op_host_capacity` ON (((`storage_pool`.`id` = `op_host_capacity`.`host_id`)
AND (`op_host_capacity`.`capacity_type` IN (3 , 9)))))
LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `storage_pool`.`id`)
AND (`async_job`.`instance_type` = 'StoragePool')
AND (`async_job`.`job_status` = 0))));
CREATE TABLE `cloud`.`template_deploy_as_is_details` (
`id` bigint unsigned NOT NULL auto_increment,
`template_id` bigint unsigned NOT NULL COMMENT 'template id',
`name` varchar(255) NOT NULL,
`value` TEXT,
PRIMARY KEY (`id`),
CONSTRAINT `fk_template_deploy_as_is_details__template_id` FOREIGN KEY `fk_template_deploy_as_is_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`user_vm_deploy_as_is_details` (
`id` bigint unsigned NOT NULL auto_increment,
`vm_id` bigint unsigned NOT NULL COMMENT 'virtual machine id',
`name` varchar(255) NOT NULL,
`value` TEXT,
PRIMARY KEY (`id`),
CONSTRAINT `fk_user_vm_deploy_as_is_details__vm_id` FOREIGN KEY `fk_user_vm_deploy_as_is_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`image_store` ADD COLUMN `readonly` boolean DEFAULT false COMMENT 'defines status of image store';
ALTER VIEW `cloud`.`image_store_view` AS

View File

@ -18,7 +18,6 @@
*/
package org.apache.cloudstack.storage.image;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.PreparedStatement;
@ -33,19 +32,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import com.cloud.agent.api.storage.OVFConfigurationTO;
import com.cloud.agent.api.storage.OVFEulaSectionTO;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareItemTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO;
import com.cloud.storage.ImageStore;
import com.cloud.storage.Upload;
import com.cloud.storage.VMTemplateDetailVO;
import com.cloud.utils.compression.CompressionUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper;
import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@ -89,7 +77,6 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
@ -123,14 +110,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
@Inject
AlertManager _alertMgr;
@Inject
VMTemplateDetailsDao templateDetailsDao;
@Inject
DefaultEndPointSelector _defaultEpSelector;
@Inject
AccountDao _accountDao;
@Inject
ResourceLimitService _resourceLimitMgr;
@Inject
DeployAsIsHelper deployAsIsHelper;
@Inject
HostDao hostDao;
@Inject
CommandExecLogDao _cmdExecLogDao;
@ -143,14 +130,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
protected String _proxy = null;
private static Gson gson;
static {
GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
gson = builder.create();
}
protected Proxy getHttpProxy() {
if (_proxy == null) {
return null;
@ -211,91 +190,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
}
}
/**
* Persist OVF properties as template details for template with id = templateId
*/
private void persistOVFProperties(List<OVFPropertyTO> ovfProperties, long templateId) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving properties for template %d as details", templateId));
}
for (OVFPropertyTO property : ovfProperties) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving property %s for template %d as detail", property.getKey(), templateId));
}
persistOvfPropertyAsSetOfTemplateDetails(templateId, property);
}
}
private void persistOvfPropertyAsSetOfTemplateDetails(long templateId, OVFPropertyTO property) {
String key = property.getKey();
String propKey = ImageStore.ACS_PROPERTY_PREFIX + key;
try {
String propValue = gson.toJson(property);
savePropertyAttribute(templateId, propKey, propValue);
} catch (RuntimeException re) {
LOGGER.error("gson marshalling of property object fails: " + propKey,re);
}
}
private void persistNetworkRequirements(List<NetworkPrerequisiteTO> networkRequirements, long templateId) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving network requirements for template %d as details", templateId));
}
for (NetworkPrerequisiteTO network : networkRequirements) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving property %s for template %d as detail", network.getName(), templateId));
}
persistRequiredNetworkAsASingleTemplateDetail(templateId, network);
}
}
private void persistDiskDefinitions(List<DatadiskTO> disks, long templateId) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving disk definitionsn for template %d as details", templateId));
}
for (DatadiskTO disk : disks) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving property %s for template %d as detail", disk.getDiskId(), templateId));
}
persistDiskDefinitionAsASingleTemplateDetail(templateId, disk);
}
}
private void persistRequiredNetworkAsASingleTemplateDetail(long templateId, NetworkPrerequisiteTO network) {
String key = network.getName();
String propKey = ImageStore.REQUIRED_NETWORK_PREFIX + key;
try {
String propValue = gson.toJson(network);
savePropertyAttribute(templateId, propKey, propValue);
} catch (RuntimeException re) {
LOGGER.warn("gson marshalling of network object fails: " + propKey,re);
}
}
private void persistDiskDefinitionAsASingleTemplateDetail(long templateId, DatadiskTO disk) {
String key = disk.getDiskId();
String propKey = ImageStore.DISK_DEFINITION_PREFIX + key;
try {
String propValue = gson.toJson(disk);
savePropertyAttribute(templateId, propKey, propValue);
} catch (RuntimeException re) {
LOGGER.warn("gson marshalling of disk definition object fails: " + propKey,re);
}
}
private void savePropertyAttribute(long templateId, String key, String value) {
if ( templateDetailsDao.findDetail(templateId,key) != null) {
LOGGER.debug(String.format("detail '%s' existed for template %d, deleting.", key, templateId));
templateDetailsDao.removeDetail(templateId,key);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("template detail for template %d to save is '%s': '%s'", templateId, key, value));
}
VMTemplateDetailVO detailVO = new VMTemplateDetailVO(templateId, key, value, false);
LOGGER.debug("Persisting template details " + detailVO.getName() + " from OVF properties for template " + templateId);
templateDetailsDao.persist(detailVO);
}
protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback,
CreateContext<CreateCmdResult> context) {
if (LOGGER.isDebugEnabled()) {
@ -304,17 +198,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
DownloadAnswer answer = callback.getResult();
DataObject obj = context.data;
DataStore store = obj.getDataStore();
List<OVFPropertyTO> ovfProperties = answer.getOvfProperties();
List<NetworkPrerequisiteTO> networkRequirements = answer.getNetworkRequirements();
List<DatadiskTO> disks = answer.getDisks();
OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection();
List<OVFEulaSectionTO> eulaSections = answer.getEulaSections();
VMTemplateVO template = _templateDao.findById(obj.getId());
TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
if (tmpltStoreVO != null) {
if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
persistExtraDetails(obj, ovfProperties, networkRequirements, disks, ovfHardwareSection, eulaSections);
if (template.isDeployAsIs()) {
deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
}
@ -354,7 +245,9 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
templateDaoBuilder.setChecksum(answer.getCheckSum());
_templateDao.update(obj.getId(), templateDaoBuilder);
}
persistExtraDetails(obj, ovfProperties, networkRequirements, disks, ovfHardwareSection, eulaSections);
if (template.isDeployAsIs()) {
deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer);
}
CreateCmdResult result = new CreateCmdResult(null, null);
caller.complete(result);
@ -362,76 +255,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
return null;
}
private void persistExtraDetails(DataObject obj, List<OVFPropertyTO> ovfProperties, List<NetworkPrerequisiteTO> networkRequirements, List<DatadiskTO> disks, OVFVirtualHardwareSectionTO ovfHardwareSection, List<OVFEulaSectionTO> eulaSections) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving %d ovf properties for template '%s' as details", ovfProperties != null ? ovfProperties.size() : 0, obj.getUuid()));
}
if (CollectionUtils.isNotEmpty(ovfProperties)) {
persistOVFProperties(ovfProperties, obj.getId());
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving %d required network requirements for template '%s' as details", networkRequirements != null ? networkRequirements.size() : 0, obj.getUuid()));
}
if (CollectionUtils.isNotEmpty(networkRequirements)) {
persistNetworkRequirements(networkRequirements, obj.getId());
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("saving %d disks definitions for template '%s' as details", disks != null ? disks.size() : 0, obj.getUuid()));
}
if (CollectionUtils.isNotEmpty(disks)) {
persistDiskDefinitions(disks, obj.getId());
}
if (CollectionUtils.isNotEmpty(eulaSections)) {
persistEulaSectionsAsTemplateDetails(eulaSections, obj.getId());
}
persistOVFHardwareSectionAsTemplateDetails(ovfHardwareSection, obj.getId());
}
private void persistEulaSectionsAsTemplateDetails(List<OVFEulaSectionTO> eulaSections, long templateId) {
CompressionUtil compressionUtil = new CompressionUtil();
for (OVFEulaSectionTO eulaSectionTO : eulaSections) {
String key = ImageStore.OVF_EULA_SECTION_PREFIX + eulaSectionTO.getIndex() + "-" + eulaSectionTO.getInfo();
byte[] compressedLicense = eulaSectionTO.getCompressedLicense();
try {
String detailValue = compressionUtil.decompressByteArary(compressedLicense);
savePropertyAttribute(templateId, key, detailValue);
} catch (IOException e) {
LOGGER.error("Could not decompress the license for template " + templateId, e);
}
}
}
/**
* Persist template details for template with ID=templateId, with name=key and value=json(object)
*/
private void persistTemplateDetailGsonEncoded(long templateId, String key, Object object) {
try {
String propValue = gson.toJson(object);
savePropertyAttribute(templateId, key, propValue);
} catch (RuntimeException re) {
LOGGER.error("gson marshalling of property object fails: " + key, re);
}
}
private void persistOVFHardwareSectionAsTemplateDetails(OVFVirtualHardwareSectionTO ovfHardwareSection, long templateId) {
if (ovfHardwareSection != null) {
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) {
for (OVFConfigurationTO configuration : ovfHardwareSection.getConfigurations()) {
String key = configuration.getId();
String propKey = ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX + configuration.getIndex() + "-" + key;
persistTemplateDetailGsonEncoded(templateId, propKey, configuration);
}
}
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) {
for (OVFVirtualHardwareItemTO item : ovfHardwareSection.getCommonHardwareItems()) {
String key = item.getResourceType().getName().trim().replaceAll("\\s","") + "-" + item.getInstanceId();
String propKey = ImageStore.OVF_HARDWARE_ITEM_PREFIX + key;
persistTemplateDetailGsonEncoded(templateId, propKey, item);
}
}
}
}
protected Void
createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) {
DownloadAnswer answer = callback.getResult();

View File

@ -0,0 +1,15 @@
package org.apache.cloudstack.storage.image.deployasis;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.vm.VirtualMachineProfile;
import java.util.Map;
public interface DeployAsIsHelper {
void persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer);
Map<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vmId);
String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool);
String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm);
}

View File

@ -0,0 +1,212 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.image.deployasis;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.deployasis.TemplateDeployAsIsInformationTO;
import com.cloud.deployasis.DeployAsIsConstants;
import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.Volume;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.utils.compression.CompressionUtil;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.vm.VirtualMachineProfile;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class DeployAsIsHelperImpl implements DeployAsIsHelper {
private static final Logger LOGGER = Logger.getLogger(DeployAsIsHelperImpl.class);
private static Gson gson;
@Inject
private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
@Inject
private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
@Inject
private PrimaryDataStoreDao storagePoolDao;
@Inject
private VMTemplatePoolDao templateStoragePoolDao;
static {
GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
gson = builder.create();
}
public void persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer) {
List<OVFPropertyTO> ovfProperties = answer.getOvfProperties();
List<OVFNetworkTO> networkRequirements = answer.getNetworkRequirements();
OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection();
List<OVFEulaSectionTO> eulaSections = answer.getEulaSections();
if (CollectionUtils.isNotEmpty(ovfProperties)) {
persistTemplateDeployAsIsInformationTOList(templateId, ovfProperties);
}
if (CollectionUtils.isNotEmpty(networkRequirements)) {
persistTemplateDeployAsIsInformationTOList(templateId, networkRequirements);
}
if (CollectionUtils.isNotEmpty(eulaSections)) {
persistTemplateDeployAsIsInformationTOList(templateId, eulaSections);
}
if (ovfHardwareSection != null) {
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) {
persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getConfigurations());
}
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) {
persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getCommonHardwareItems());
}
}
}
@Override
public Map<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vm) {
Map<String, String> map = new HashMap<>();
List<UserVmDeployAsIsDetailVO> details = userVmDeployAsIsDetailsDao.listDetails(vm.getId());
if (CollectionUtils.isNotEmpty(details)) {
for (UserVmDeployAsIsDetailVO detail : details) {
OVFPropertyTO property = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), detail.getName());
String value = property.isPassword() ? DBEncryptionUtil.decrypt(detail.getValue()) : detail.getValue();
map.put(detail.getName(), value);
}
}
return map;
}
@Override
public String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool) {
StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(destStoragePool);
VMTemplateStoragePoolVO tmplRef = templateStoragePoolDao.findByPoolTemplate(storagePoolVO.getId(),
vm.getTemplate().getId(), configuration);
if (tmplRef != null) {
return tmplRef.getInstallPath();
}
return null;
}
@Override
public String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm) {
if (vm != null) {
if (CollectionUtils.isNotEmpty(vm.getDisks())) {
for (DiskTO disk : vm.getDisks()) {
if (disk.getType() == Volume.Type.ISO) {
continue;
}
DataTO data = disk.getData();
if (data != null) {
DataStoreTO dataStore = data.getDataStore();
if (dataStore != null) {
return dataStore.getUuid();
}
}
}
}
}
return null;
}
private void persistTemplateDeployAsIsInformationTOList(long templateId,
List<? extends TemplateDeployAsIsInformationTO> informationTOList) {
for (TemplateDeployAsIsInformationTO informationTO : informationTOList) {
String propKey = getKeyFromInformationTO(informationTO);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("Saving property %s for template %d as detail", propKey, templateId));
}
String propValue = null;
try {
propValue = getValueFromInformationTO(informationTO);
} catch (RuntimeException re) {
LOGGER.error("gson marshalling of property object fails: " + propKey,re);
} catch (IOException e) {
LOGGER.error("Could not decompress the license for template " + templateId, e);
}
saveTemplateDeployAsIsPropertyAttribute(templateId, propKey, propValue);
}
}
private String getValueFromInformationTO(TemplateDeployAsIsInformationTO informationTO) throws IOException {
if (informationTO instanceof OVFEulaSectionTO) {
CompressionUtil compressionUtil = new CompressionUtil();
byte[] compressedLicense = ((OVFEulaSectionTO) informationTO).getCompressedLicense();
return compressionUtil.decompressByteArary(compressedLicense);
}
return gson.toJson(informationTO);
}
private String getKeyFromInformationTO(TemplateDeployAsIsInformationTO informationTO) {
if (informationTO instanceof OVFPropertyTO) {
return DeployAsIsConstants.ACS_PROPERTY_PREFIX + ((OVFPropertyTO) informationTO).getKey();
} else if (informationTO instanceof OVFNetworkTO) {
return DeployAsIsConstants.REQUIRED_NETWORK_PREFIX + ((OVFNetworkTO) informationTO).getName();
} else if (informationTO instanceof OVFConfigurationTO) {
return DeployAsIsConstants.OVF_HARDWARE_CONFIGURATION_PREFIX +
((OVFConfigurationTO) informationTO).getIndex() + "-" + ((OVFConfigurationTO) informationTO).getId();
} else if (informationTO instanceof OVFVirtualHardwareItemTO) {
String key = ((OVFVirtualHardwareItemTO) informationTO).getResourceType().getName().trim().replaceAll("\\s","")
+ "-" + ((OVFVirtualHardwareItemTO) informationTO).getInstanceId();
return DeployAsIsConstants.OVF_HARDWARE_ITEM_PREFIX + key;
} else if (informationTO instanceof OVFEulaSectionTO) {
return DeployAsIsConstants.OVF_EULA_SECTION_PREFIX + ((OVFEulaSectionTO) informationTO).getIndex() +
"-" + ((OVFEulaSectionTO) informationTO).getInfo();
}
return null;
}
private void saveTemplateDeployAsIsPropertyAttribute(long templateId, String key, String value) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("Saving property %s for template %d as detail", key, templateId));
}
if (templateDeployAsIsDetailsDao.findDetail(templateId,key) != null) {
LOGGER.debug(String.format("Detail '%s' existed for template %d, deleting.", key, templateId));
templateDeployAsIsDetailsDao.removeDetail(templateId,key);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("Template detail for template %d to save is '%s': '%s'", templateId, key, value));
}
TemplateDeployAsIsDetailVO detailVO = new TemplateDeployAsIsDetailVO(templateId, key, value);
LOGGER.debug("Persisting template details " + detailVO.getName() + " from OVF properties for template " + templateId);
templateDeployAsIsDetailsDao.persist(detailVO);
}
}

View File

@ -72,4 +72,6 @@
<bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" />
<bean id="deployAsIsImageStoreHelper" class="org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelperImpl" />
</beans>

View File

@ -16,9 +16,7 @@
// under the License.
package com.cloud.hypervisor.guru;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.DeployAsIsInfoTO;
import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.exception.InsufficientAddressCapacityException;
@ -35,12 +33,8 @@ import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.ImageStore;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.Volume;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.GuestOSHypervisorDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.exception.CloudRuntimeException;
@ -51,10 +45,8 @@ import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper;
import org.apache.commons.lang.BooleanUtils;
import org.apache.log4j.Logger;
@ -65,7 +57,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class VmwareVmImplementer {
private static final Logger LOGGER = Logger.getLogger(VmwareVmImplementer.class);
@ -89,9 +80,9 @@ class VmwareVmImplementer {
@Inject
VMTemplatePoolDao templateStoragePoolDao;
@Inject
VMTemplateDetailsDao templateDetailsDao;
@Inject
VmwareManager vmwareMgr;
@Inject
DeployAsIsHelper deployAsIsHelper;
private Boolean globalNestedVirtualisationEnabled;
private Boolean globalNestedVPerVMEnabled;
@ -183,9 +174,7 @@ class VmwareVmImplementer {
}
if (deployAsIs) {
List<OVFPropertyTO> ovfProperties = getOvfPropertyList(vm, details);
handleOvfProperties(vm, to, details, ovfProperties);
setDeployAsIsParams(vm, to, details);
setDeployAsIsInfoTO(vm, to, details);
}
setDetails(to, details);
@ -193,44 +182,25 @@ class VmwareVmImplementer {
return to;
}
private void setDeployAsIsParams(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) {
DeployAsIsInfoTO info = new DeployAsIsInfoTO();
String configuration = null;
if (details.containsKey(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION)) {
configuration = details.get(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION);
info.setDeploymentConfiguration(configuration);
}
// Deploy as-is disks are all allocated to the same storage pool
String deployAsIsStoreUuid = vm.getDisks().get(0).getData().getDataStore().getUuid();
StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(deployAsIsStoreUuid);
VMTemplateStoragePoolVO tmplRef = templateStoragePoolDao.findByPoolTemplate(storagePoolVO.getId(), vm.getTemplate().getId(), configuration);
if (tmplRef != null) {
info.setTemplatePath(tmplRef.getInstallPath());
}
info.setDeployAsIs(true);
/**
* Set the information relevant for deploy-as-is VMs on the VM TO
*/
private void setDeployAsIsInfoTO(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) {
String configuration = details.getOrDefault(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION, null);
Map<String, String> properties = deployAsIsHelper.getVirtualMachineDeployAsIsProperties(vm);
String destStoragePool = deployAsIsHelper.getAllocatedVirtualMachineDestinationStoragePool(vm);
String templatePath = deployAsIsHelper.getAllocatedVirtualMachineTemplatePath(vm, configuration, destStoragePool);
DeployAsIsInfoTO info = new DeployAsIsInfoTO(templatePath, destStoragePool, properties);
to.setDeployAsIsInfo(info);
}
private void setDetails(VirtualMachineTO to, Map<String, String> details) {
Map<String, String> detailsToSend = new HashMap<>();
for (String key: details.keySet()) {
if (key.startsWith(ImageStore.OVF_EULA_SECTION_PREFIX) ||
key.startsWith(ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX) ||
key.startsWith(ImageStore.OVF_HARDWARE_ITEM_PREFIX)) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(String.format("Discarding detail for VM %s: %s => %s", to.getName(), key, details.get(key)));
}
continue;
}
if (LOGGER.isTraceEnabled()) {
if (LOGGER.isTraceEnabled()) {
for (String key : details.keySet()) {
LOGGER.trace(String.format("Detail for VM %s: %s => %s", to.getName(), key, details.get(key)));
}
detailsToSend.put(key, details.get(key));
}
to.setDetails(detailsToSend);
to.setDetails(details);
}
private void configureDomainRouterNicsAndDetails(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<NicProfile> nicProfiles) {
@ -318,49 +288,6 @@ class VmwareVmImplementer {
}
}
private void handleOvfProperties(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<OVFPropertyTO> ovfProperties) {
if (CollectionUtils.isNotEmpty(ovfProperties)) {
removeOvfPropertiesFromDetails(ovfProperties, details);
to.setOvfProperties(ovfProperties);
}
}
private DiskTO getRootDiskTOFromVM(VirtualMachineProfile vm) {
DiskTO rootDiskTO;
List<DiskTO> rootDiskList;
rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == Volume.Type.ROOT).collect(Collectors.toList());
if (rootDiskList.size() != 1) {
if (vm.getTemplate().isDeployAsIs()) {
rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == null).collect(Collectors.toList());
if (rootDiskList.size() < 1) {
throw new CloudRuntimeException("Did not find a template to serve as root disk for VM " + vm.getHostName());
}
} else {
throw new CloudRuntimeException("Did not find only one root disk for VM " + vm.getHostName());
}
}
rootDiskTO = rootDiskList.get(0);
return rootDiskTO;
}
private List<OVFPropertyTO> getOvfPropertyList(VirtualMachineProfile vm, Map<String, String> details) {
List<OVFPropertyTO> ovfProperties = new ArrayList<OVFPropertyTO>();
for (String detailKey : details.keySet()) {
if (detailKey.startsWith(ImageStore.ACS_PROPERTY_PREFIX)) {
OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), detailKey);
String vmPropertyKey = detailKey.replace(ImageStore.ACS_PROPERTY_PREFIX, "");
if (propertyTO == null) {
LOGGER.warn(String.format("OVF property %s not found on template, discarding", vmPropertyKey));
continue;
}
propertyTO.setKey(vmPropertyKey);
propertyTO.setValue(details.get(detailKey));
ovfProperties.add(propertyTO);
}
}
return ovfProperties;
}
private void addReservationDetails(long clusterId, Map<String, String> details) {
details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString());
details.put(VMwareGuru.VmwareReserveMemory.key(), VMwareGuru.VmwareReserveMemory.valueIn(clusterId).toString());
@ -408,16 +335,6 @@ class VmwareVmImplementer {
// details.put(VmDetailConstants.BOOT_TYPE, to.getBootType());
}
/*
Remove OVF properties from details to be sent to hypervisor (avoid duplicate data)
*/
private void removeOvfPropertiesFromDetails(List<OVFPropertyTO> ovfProperties, Map<String, String> details) {
for (OVFPropertyTO propertyTO : ovfProperties) {
String key = propertyTO.getKey();
details.remove(ApiConstants.PROPERTIES + "-" + key);
}
}
/**
* Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
* @param details vm details should not be null

View File

@ -47,7 +47,6 @@ import javax.xml.datatype.XMLGregorianCalendar;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.DeployAsIsInfoTO;
import com.cloud.storage.ImageStore;
import com.cloud.agent.api.ValidateVcenterDetailsCommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.storage.configdrive.ConfigDrive;
@ -56,7 +55,6 @@ import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
@ -180,7 +178,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.MigrateVolumeAnswer;
import com.cloud.agent.api.storage.MigrateVolumeCommand;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
@ -253,7 +251,6 @@ import com.cloud.utils.ExecutionResult;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionUtil;
@ -1842,14 +1839,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
DiskTO[] specDisks = vmSpec.getDisks();
DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo();
boolean installAsIs = deployAsIsInfo != null && deployAsIsInfo.isDeployAsIs();
boolean installAsIs = deployAsIsInfo != null;
if (installAsIs && dcMo.findVm(vmInternalCSName) == null) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Deploying OVA from as is");
}
String deployAsIsTemplate = deployAsIsInfo.getTemplatePath();
String destDatastore = getDatastoreFromSpecDisks(specDisks);
String deploymentConfiguration = deployAsIsInfo.getDeploymentConfiguration();
String destDatastore = deployAsIsInfo.getDestStoragePool();
vmInVcenter = _storageProcessor.cloneVMFromTemplate(deployAsIsTemplate, vmInternalCSName, destDatastore);
mapSpecDisksToClonedDisks(vmInVcenter, vmInternalCSName, specDisks);
}
@ -1996,7 +1992,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("current count(s) desired: %d/ found:%d. now adding device to device count for vApp config ISO", totalChangeDevices, hackDeviceCount));
}
if (vmSpec.getOvfProperties() != null) {
if (deployAsIsInfo != null && deployAsIsInfo.getProperties() != null) {
totalChangeDevices++;
}
@ -2381,18 +2377,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// config video card
configureVideoCard(vmMo, vmSpec, vmConfigSpec);
// Set OVF properties (if available)
List<OVFPropertyTO> ovfProperties = vmSpec.getOvfProperties();
VmConfigInfo templateVappConfig;
if (ovfProperties != null) {
VirtualMachineMO templateVMmo = dcMo.findVm(deployAsIsInfo.getTemplatePath());
templateVappConfig = templateVMmo.getConfigInfo().getVAppConfig();
// Set OVF properties (if available)
if (CollectionUtils.isNotEmpty(ovfProperties)) {
s_logger.info("Copying OVF properties from template and setting them to the values the user provided");
copyVAppConfigsFromTemplate(templateVappConfig, ovfProperties, vmConfigSpec);
}
}
setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec);
setBootOptions(vmSpec, bootMode, vmConfigSpec);
@ -2483,26 +2468,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
private String getDatastoreFromSpecDisks(DiskTO[] specDisks) {
if (specDisks.length == 0) {
return null;
/**
* Set OVF properties (if available)
*/
private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo,
VirtualMachineConfigSpec vmConfigSpec) throws Exception {
if (deployAsIsInfo != null) {
Map<String, String> properties = deployAsIsInfo.getProperties();
VmConfigInfo vAppConfig = vmMo.getConfigInfo().getVAppConfig();
s_logger.info("Copying OVF properties to the values the user provided");
setVAppPropertiesToConfigSpec(vAppConfig, properties, vmConfigSpec);
}
Map<String, List<DiskTO>> psDisksMap = Arrays.asList(specDisks).stream()
.filter(x -> x.getType() != Volume.Type.ISO && x.getData() != null && x.getData().getDataStore() != null)
.collect(Collectors.groupingBy(x -> x.getData().getDataStore().getUuid()));
String dataStore;
if (MapUtils.isEmpty(psDisksMap)) {
s_logger.error("Could not find a destination datastore for VM volumes");
return null;
} else {
dataStore = psDisksMap.keySet().iterator().next();
if (psDisksMap.keySet().size() > 1) {
s_logger.info("Found multiple destination datastores for VM volumes, selecting " + dataStore);
}
}
return dataStore;
}
/**
@ -2624,17 +2600,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
/**
* Set the properties section from existing vApp configuration and values set on ovfProperties
*/
protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, List<OVFPropertyTO> ovfProperties) {
protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map<String, String> ovfProperties) {
List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty();
List<VAppPropertySpec> specs = new ArrayList<>();
Map<String, Pair<String, Boolean>> ovfMap = getOVFMap(ovfProperties);
for (VAppPropertyInfo info : productFromOvf) {
VAppPropertySpec spec = new VAppPropertySpec();
if (ovfMap.containsKey(info.getId())) {
Pair<String, Boolean> pair = ovfMap.get(info.getId());
String value = pair.first();
boolean isPassword = pair.second();
info.setValue(isPassword ? DBEncryptionUtil.decrypt(value) : value);
if (ovfProperties.containsKey(info.getId())) {
String value = ovfProperties.get(info.getId());
info.setValue(value);
}
spec.setInfo(info);
spec.setOperation(ArrayUpdateOperation.ADD);
@ -2662,9 +2635,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
* Set the vApp configuration to vmConfig spec, copying existing configuration from vAppConfig
* and seting properties values from ovfProperties
*/
protected void copyVAppConfigsFromTemplate(VmConfigInfo vAppConfig,
List<OVFPropertyTO> ovfProperties,
VirtualMachineConfigSpec vmConfig) throws Exception {
protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig,
Map<String, String> ovfProperties,
VirtualMachineConfigSpec vmConfig) throws Exception {
VmConfigSpec vmConfigSpec = new VmConfigSpec();
vmConfigSpec.getEula().addAll(vAppConfig.getEula());
vmConfigSpec.setInstallBootStopDelay(vAppConfig.getInstallBootStopDelay());
@ -3009,10 +2982,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
private static void configCustomExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
// we no longer to validation anymore
for (Map.Entry<String, String> entry : vmSpec.getDetails().entrySet()) {
if (entry.getKey().equalsIgnoreCase(VmDetailConstants.BOOT_MODE) ||
entry.getKey().startsWith(ImageStore.REQUIRED_NETWORK_PREFIX) ||
entry.getKey().startsWith(ImageStore.ACS_PROPERTY_PREFIX) ||
entry.getKey().startsWith(ImageStore.DISK_DEFINITION_PREFIX)) {
if (entry.getKey().equalsIgnoreCase(VmDetailConstants.BOOT_MODE)) {
continue;
}
OptionValue newVal = new OptionValue();

View File

@ -26,6 +26,9 @@ import java.util.Set;
import javax.inject.Inject;
import com.cloud.deployasis.DeployAsIsConstants;
import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.utils.security.DigestHelper;
import org.apache.log4j.Logger;
@ -83,6 +86,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
private ImageStoreDao dataStoreDao;
@Inject
private VMTemplateDetailsDao _templateDetailsDao;
@Inject
private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
@ -240,6 +245,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
if (detailsView.contains(ApiConstants.DomainDetails.all)) {
Map<String, String> details = _templateDetailsDao.listDetailsKeyPairs(template.getId());
templateResponse.setDetails(details);
setDeployAsIsDetails(template, templateResponse);
}
// update tag information
@ -272,6 +279,19 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
return templateResponse;
}
private void setDeployAsIsDetails(TemplateJoinVO template, TemplateResponse templateResponse) {
if (template.isDeployAsIs()) {
List<TemplateDeployAsIsDetailVO> deployAsIsDetails = templateDeployAsIsDetailsDao.listDetails(template.getId());
for (TemplateDeployAsIsDetailVO deployAsIsDetailVO : deployAsIsDetails) {
if (deployAsIsDetailVO.getName().startsWith(DeployAsIsConstants.OVF_HARDWARE_ITEM_PREFIX)) {
//Do not list hardware items
continue;
}
templateResponse.addDeployAsIsDetail(deployAsIsDetailVO.getName(), deployAsIsDetailVO.getValue());
}
}
}
//TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse
// compared to listTemplates and listIsos.
@Override

View File

@ -47,12 +47,12 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.ImageStore;
import com.cloud.storage.VMTemplateDetailVO;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.affinity.AffinityGroupService;
@ -83,7 +83,7 @@ import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
@ -507,7 +507,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject
private ResourceTagDao resourceTagDao;
@Inject
private VMTemplateDetailsDao templateDetailsDao;
private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
@Inject
private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
private ScheduledExecutorService _executor = null;
private ScheduledExecutorService _vmIpFetchExecutor = null;
@ -2503,17 +2505,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
}
}
for (String detailName : details.keySet()) {
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("looking for vm detail '%s'", detailName));
}
if (detailName.startsWith(ImageStore.ACS_PROPERTY_PREFIX)) {
OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vmInstance.getTemplateId(),detailName);
if (propertyTO != null && propertyTO.isPassword()) {
details.put(detailName, DBEncryptionUtil.encrypt(details.get(detailName)));
}
}
}
vmInstance.setDetails(details);
_vmDao.saveDetails(vmInstance);
}
@ -4007,11 +3998,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
vm.setDetail(VmDetailConstants.DEPLOY_VM, "true");
copyDiskDetailsToVm(vm, template);
setPropertiesOnVM(vm, userVmOVFPropertiesMap);
copyNetworkRequirementsToVm(vm, template);
persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap);
_vmDao.saveDetails(vm);
if (!isImport) {
@ -4056,33 +4043,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
});
}
private void copyNetworkRequirementsToVm(UserVmVO vm, VirtualMachineTemplate template) {
if (template.isDeployAsIs()) {
List<VMTemplateDetailVO> details = templateDetailsDao.listDetailsByTemplateIdMatchingPrefix(template.getId(), ImageStore.REQUIRED_NETWORK_PREFIX);
for (VMTemplateDetailVO detail : details) {
vm.setDetail(detail.getName(), detail.getValue());
}
}
}
private void copyDiskDetailsToVm(UserVmVO vm, VirtualMachineTemplate template) {
if (template.isDeployAsIs()) {
List<VMTemplateDetailVO> details = templateDetailsDao.listDetailsByTemplateIdMatchingPrefix(template.getId(), ImageStore.DISK_DEFINITION_PREFIX);
for (VMTemplateDetailVO detail : details) {
vm.setDetail(detail.getName(), detail.getValue());
}
}
}
/**
* take the properties and set them on the vm.
* consider should we be complete, and make sure all default values are copied as well if known?
* I.E. iterate over the template details as well to copy any that are not defined yet.
*/
private void setPropertiesOnVM(UserVmVO vm, Map<String, String> userVmOVFPropertiesMap) {
private void persistVMDeployAsIsProperties(UserVmVO vm, Map<String, String> userVmOVFPropertiesMap) {
if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) {
for (String key : userVmOVFPropertiesMap.keySet()) {
String detailKey = ImageStore.ACS_PROPERTY_PREFIX + key;
String detailKey = key;
String value = userVmOVFPropertiesMap.get(key);
// Sanitize boolean values to expected format and encrypt passwords
@ -4092,7 +4061,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
} else if (value.equalsIgnoreCase("False")) {
value = "False";
} else {
OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key);
OVFPropertyTO propertyTO = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key);
if (propertyTO != null && propertyTO.isPassword()) {
value = DBEncryptionUtil.encrypt(value);
}
@ -4101,7 +4070,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("setting property '%s' as '%s' with value '%s'", key, detailKey, value));
}
vm.setDetail(detailKey, value);
UserVmDeployAsIsDetailVO detail = new UserVmDeployAsIsDetailVO(vm.getId(), detailKey, value);
userVmDeployAsIsDetailsDao.persist(detail);
}
}
}
@ -7378,19 +7348,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private LinkedHashMap<Integer, Long> getVmOvfNetworkMapping(DataCenter zone, Account owner, VirtualMachineTemplate template, Map<Integer, Long> vmNetworkMapping) throws InsufficientCapacityException, ResourceAllocationException {
LinkedHashMap<Integer, Long> mapping = new LinkedHashMap<>();
if (ImageFormat.OVA.equals(template.getFormat())) {
List<NetworkPrerequisiteTO> networkPrerequisiteTOList =
templateDetailsDao.listNetworkRequirementsByTemplateId(template.getId());
if (CollectionUtils.isNotEmpty(networkPrerequisiteTOList)) {
List<OVFNetworkTO> OVFNetworkTOList =
templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(template.getId());
if (CollectionUtils.isNotEmpty(OVFNetworkTOList)) {
Network lastMappedNetwork = null;
for (NetworkPrerequisiteTO networkPrerequisiteTO : networkPrerequisiteTOList) {
Long networkId = vmNetworkMapping.get(networkPrerequisiteTO.getInstanceID());
for (OVFNetworkTO OVFNetworkTO : OVFNetworkTOList) {
Long networkId = vmNetworkMapping.get(OVFNetworkTO.getInstanceID());
if (networkId == null && lastMappedNetwork == null) {
lastMappedNetwork = getNetworkForOvfNetworkMapping(zone, owner);
}
if (networkId == null) {
networkId = lastMappedNetwork.getId();
}
mapping.put(networkPrerequisiteTO.getInstanceID(), networkId);
mapping.put(OVFNetworkTO.getInstanceID(), networkId);
}
}
}

View File

@ -37,10 +37,10 @@ import java.util.concurrent.Executors;
import javax.naming.ConfigurationException;
import com.cloud.agent.api.storage.OVFEulaSectionTO;
import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.storage.OVFPropertyTO;
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.storage.template.Processor;
import com.cloud.storage.template.S3TemplateDownloader;
import com.cloud.storage.template.TemplateDownloader;
@ -58,7 +58,7 @@ import com.cloud.storage.template.RawImageProcessor;
import com.cloud.storage.template.TARProcessor;
import com.cloud.storage.template.VhdProcessor;
import com.cloud.storage.template.TemplateConstants;
import org.apache.cloudstack.api.net.NetworkPrerequisiteTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
@ -132,7 +132,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
private final long id;
private final ResourceType resourceType;
private List<OVFPropertyTO> ovfProperties;
private List<NetworkPrerequisiteTO> networks;
private List<OVFNetworkTO> networks;
private List<DatadiskTO> disks;
private OVFVirtualHardwareSectionTO hardwareSection;
private List<OVFEulaSectionTO> eulaSections;
@ -239,11 +239,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
this.ovfProperties = ovfProperties;
}
public List<NetworkPrerequisiteTO> getNetworks() {
public List<OVFNetworkTO> getNetworks() {
return networks;
}
public void setNetworks(List<NetworkPrerequisiteTO> networks) {
public void setNetworks(List<OVFNetworkTO> networks) {
this.networks = networks;
}