mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Add new template and vm deploy as is details table and refactor
This commit is contained in:
parent
fab6b41c90
commit
bb4ce2118d
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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 {
|
||||
@ -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() {
|
||||
}
|
||||
@ -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 {
|
||||
}
|
||||
@ -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-";
|
||||
|
||||
}
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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> {
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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")
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -72,4 +72,6 @@
|
||||
|
||||
<bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" />
|
||||
|
||||
<bean id="deployAsIsImageStoreHelper" class="org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelperImpl" />
|
||||
|
||||
</beans>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user