mirror of https://github.com/apache/cloudstack.git
Handle guest OS read from deploy-as-is OVF descriptor
This commit is contained in:
parent
89aa25d023
commit
41354227e2
|
|
@ -46,6 +46,7 @@ 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.Pair;
|
||||
import com.cloud.utils.compression.CompressionUtil;
|
||||
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
|
@ -217,6 +218,12 @@ public class OVFHelper {
|
|||
return getConfigurableOVFPropertiesFromDocument(doc);
|
||||
}
|
||||
|
||||
protected Pair<String, String> getOperatingSystemInfoFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
|
||||
InputSource is = new InputSource(new StringReader(ovfString));
|
||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
|
||||
return getOperatingSystemInfoFromDocument(doc);
|
||||
}
|
||||
|
||||
protected List<OVFConfigurationTO> getOVFDeploymentOptionsFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
|
||||
InputSource is = new InputSource(new StringReader(ovfString));
|
||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
|
||||
|
|
@ -229,6 +236,12 @@ public class OVFHelper {
|
|||
return getVirtualHardwareItemsFromDocumentTree(doc);
|
||||
}
|
||||
|
||||
protected OVFVirtualHardwareSectionTO getVirtualHardwareSectionFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
|
||||
InputSource is = new InputSource(new StringReader(ovfString));
|
||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
|
||||
return getVirtualHardwareSectionFromDocument(doc);
|
||||
}
|
||||
|
||||
protected List<OVFEulaSectionTO> getOVFEulaSectionFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
|
||||
InputSource is = new InputSource(new StringReader(ovfString));
|
||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
|
||||
|
|
@ -726,7 +739,26 @@ public class OVFHelper {
|
|||
if (CollectionUtils.isNotEmpty(items)) {
|
||||
commonItems = items.stream().filter(x -> StringUtils.isBlank(x.getConfigurationIds())).collect(Collectors.toList());
|
||||
}
|
||||
return new OVFVirtualHardwareSectionTO(configurations, commonItems);
|
||||
String minimumHardwareVersion = getMinimumHardwareVersionFromDocumentTree(doc);
|
||||
return new OVFVirtualHardwareSectionTO(configurations, commonItems, minimumHardwareVersion);
|
||||
}
|
||||
|
||||
private String getMinimumHardwareVersionFromDocumentTree(Document doc) {
|
||||
String version = null;
|
||||
if (doc != null) {
|
||||
NodeList systemNodeList = doc.getElementsByTagName("System");
|
||||
if (systemNodeList.getLength() != 0) {
|
||||
Node systemItem = systemNodeList.item(0);
|
||||
String hardwareVersions = getChildNodeValue(systemItem, "VirtualSystemType");
|
||||
if (StringUtils.isNotBlank(hardwareVersions)) {
|
||||
String[] versions = hardwareVersions.split(",");
|
||||
// Order the hardware versions and retrieve the minimum version
|
||||
List<String> versionsList = Arrays.stream(versions).sorted().collect(Collectors.toList());
|
||||
version = versionsList.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private List<OVFConfigurationTO> getDeploymentOptionsFromDocumentTree(Document doc) {
|
||||
|
|
@ -869,6 +901,21 @@ public class OVFHelper {
|
|||
return eulas;
|
||||
}
|
||||
|
||||
public Pair<String, String> getOperatingSystemInfoFromDocument(Document doc) {
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
NodeList guesOsList = doc.getElementsByTagName("OperatingSystemSection");
|
||||
if (guesOsList.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
Node guestOsNode = guesOsList.item(0);
|
||||
Element guestOsElement = (Element) guestOsNode;
|
||||
String osType = getNodeAttribute(guestOsElement, "vmw", "osType");
|
||||
String description = getChildNodeValue(guestOsNode, "Description");
|
||||
return new Pair<>(osType, description);
|
||||
}
|
||||
|
||||
class OVFFile {
|
||||
// <File ovf:href="i-2-8-VM-disk2.vmdk" ovf:id="file1" ovf:size="69120" />
|
||||
public String _href;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// 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;
|
||||
|
||||
import com.cloud.agent.api.LogLevel;
|
||||
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OVFInformationTO {
|
||||
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFPropertyTO> properties;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFNetworkTO> networks;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<DatadiskTO> disks;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private OVFVirtualHardwareSectionTO hardwareSection;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFEulaSectionTO> eulaSections;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private Pair<String, String> guestOsInfo;
|
||||
|
||||
public OVFInformationTO() {
|
||||
}
|
||||
|
||||
public List<OVFPropertyTO> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<OVFPropertyTO> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public List<OVFNetworkTO> getNetworks() {
|
||||
return networks;
|
||||
}
|
||||
|
||||
public void setNetworks(List<OVFNetworkTO> networks) {
|
||||
this.networks = networks;
|
||||
}
|
||||
|
||||
public List<DatadiskTO> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
public void setDisks(List<DatadiskTO> disks) {
|
||||
this.disks = disks;
|
||||
}
|
||||
|
||||
public OVFVirtualHardwareSectionTO getHardwareSection() {
|
||||
return hardwareSection;
|
||||
}
|
||||
|
||||
public void setHardwareSection(OVFVirtualHardwareSectionTO hardwareSection) {
|
||||
this.hardwareSection = hardwareSection;
|
||||
}
|
||||
|
||||
public List<OVFEulaSectionTO> getEulaSections() {
|
||||
return eulaSections;
|
||||
}
|
||||
|
||||
public void setEulaSections(List<OVFEulaSectionTO> eulaSections) {
|
||||
this.eulaSections = eulaSections;
|
||||
}
|
||||
|
||||
public Pair<String, String> getGuestOsInfo() {
|
||||
return guestOsInfo;
|
||||
}
|
||||
|
||||
public void setGuestOsInfo(Pair<String, String> guestOsInfo) {
|
||||
this.guestOsInfo = guestOsInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,12 +25,15 @@ public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformatio
|
|||
public OVFVirtualHardwareSectionTO() {
|
||||
}
|
||||
|
||||
private String minimiumHardwareVersion;
|
||||
private List<OVFConfigurationTO> configurations;
|
||||
private List<OVFVirtualHardwareItemTO> commonHardwareItems;
|
||||
|
||||
public OVFVirtualHardwareSectionTO(List<OVFConfigurationTO> configurations, List<OVFVirtualHardwareItemTO> commonHardwareItems) {
|
||||
public OVFVirtualHardwareSectionTO(List<OVFConfigurationTO> configurations, List<OVFVirtualHardwareItemTO> commonHardwareItems,
|
||||
String minimumHardwareVersion) {
|
||||
this.configurations = configurations;
|
||||
this.commonHardwareItems = commonHardwareItems;
|
||||
this.minimiumHardwareVersion = minimumHardwareVersion;
|
||||
}
|
||||
|
||||
public List<OVFConfigurationTO> getConfigurations() {
|
||||
|
|
@ -40,4 +43,8 @@ public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformatio
|
|||
public List<OVFVirtualHardwareItemTO> getCommonHardwareItems() {
|
||||
return commonHardwareItems;
|
||||
}
|
||||
|
||||
public String getMinimiumHardwareVersion() {
|
||||
return minimiumHardwareVersion;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,4 +24,5 @@ public interface DeployAsIsConstants {
|
|||
String HARDWARE_ITEM_PREFIX = "hardware-item-";
|
||||
String EULA_PREFIX = "eula-";
|
||||
|
||||
String DEFAULT_GUEST_OS_DEPLOY_AS_IS = "OVF Configured OS";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,5 +347,9 @@ public class RegisterTemplateCmd extends BaseCmd implements UserCmd {
|
|||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
|
||||
"Parameter directdownload is only allowed for KVM templates");
|
||||
}
|
||||
|
||||
if (isDeployAsIs() && !getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.VMware.toString())) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameter deployasis is only allowed for VMware templates");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ 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.utils.Pair;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
|
@ -62,204 +64,210 @@ public class OVFHelperTest {
|
|||
" </DeploymentOptionSection>";
|
||||
|
||||
private String ovfFileVirtualHardwareSection =
|
||||
"<VirtualSystem>\n" +
|
||||
"<OperatingSystemSection ovf:id=\"100\" vmw:osType=\"other26xLinux64Guest\">\n" +
|
||||
" <Info>The kind of installed guest operating system</Info>\n" +
|
||||
" <Description>Other 2.6x Linux (64-bit)</Description>\n" +
|
||||
"</OperatingSystemSection>\n" +
|
||||
"<VirtualHardwareSection ovf:transport=\"iso\">\n" +
|
||||
" <Info>Virtual hardware requirements</Info>\n" +
|
||||
" <System>\n" +
|
||||
" <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>\n" +
|
||||
" <vssd:InstanceID>0</vssd:InstanceID>\n" +
|
||||
" <vssd:VirtualSystemIdentifier>ASAv</vssd:VirtualSystemIdentifier>\n" +
|
||||
" <vssd:VirtualSystemType>vmx-08,vmx-09</vssd:VirtualSystemType>\n" +
|
||||
" </System>\n" +
|
||||
" <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
|
||||
" <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
|
||||
" <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>1</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>5000</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>1000</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>3</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv30\">\n" +
|
||||
" <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
|
||||
" <rasd:ElementName>4 virtual CPU(s)</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>1</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>20000</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>1000</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>3</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>4</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
|
||||
" <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Memory Size</rasd:Description>\n" +
|
||||
" <rasd:ElementName>2048MB of memory</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>2</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>2048</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>2048</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>4</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>2048</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv30\">\n" +
|
||||
" <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Memory Size</rasd:Description>\n" +
|
||||
" <rasd:ElementName>8192MB of memory</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>2</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>8192</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>8192</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>4</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>8192</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:Address>0</rasd:Address>\n" +
|
||||
" <rasd:Description>SCSI Controller</rasd:Description>\n" +
|
||||
" <rasd:ElementName>SCSI controller 0</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>3</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>6</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:Address>0</rasd:Address>\n" +
|
||||
" <rasd:Description>IDE Controller</rasd:Description>\n" +
|
||||
" <rasd:ElementName>IDE 0</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>4</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceType>5</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:required=\"false\">\n" +
|
||||
" <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>5</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>4</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>15</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:required=\"false\">\n" +
|
||||
" <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/file/file3</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>18</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>4</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>15</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>7</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>Management0-0</rasd:Connection>\n" +
|
||||
" <rasd:Description>E1000 Ethernet adapter on \"Management Network\"</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 1</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>6</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
|
||||
" <rasd:ElementName>Hard disk 1</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>7</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>3</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>17</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
|
||||
" <rasd:ElementName>Hard disk 2</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/disk/vmdisk2</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>8</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>3</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>17</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>8</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-0</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 2</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>9</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>9</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-1</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 3</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>10</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>10</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-2</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 4</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>11</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>11</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-3</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 5</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>12</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>12</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-4</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 6</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>13</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>13</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-5</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 7</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>14</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>14</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-6</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 8</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>15</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>15</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-7</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 9</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>16</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>16</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-8</rasd:Connection>\n" +
|
||||
" <rasd:Description>Default HA failover E1000 Ethernet adapter, or additional standalone general purpose adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 10</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>17</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <vmw:ExtraConfig vmw:key=\"monitor_control.pseudo_perfctr\" vmw:value=\"TRUE\"></vmw:ExtraConfig>\n" +
|
||||
" </VirtualHardwareSection>";
|
||||
" <Info>Virtual hardware requirements</Info>\n" +
|
||||
" <System>\n" +
|
||||
" <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>\n" +
|
||||
" <vssd:InstanceID>0</vssd:InstanceID>\n" +
|
||||
" <vssd:VirtualSystemIdentifier>ASAv</vssd:VirtualSystemIdentifier>\n" +
|
||||
" <vssd:VirtualSystemType>vmx-08,vmx-09</vssd:VirtualSystemType>\n" +
|
||||
" </System>\n" +
|
||||
" <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
|
||||
" <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
|
||||
" <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>1</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>5000</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>1000</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>3</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv30\">\n" +
|
||||
" <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
|
||||
" <rasd:ElementName>4 virtual CPU(s)</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>1</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>20000</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>1000</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>3</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>4</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
|
||||
" <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Memory Size</rasd:Description>\n" +
|
||||
" <rasd:ElementName>2048MB of memory</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>2</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>2048</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>2048</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>4</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>2048</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:configuration=\"ASAv30\">\n" +
|
||||
" <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
|
||||
" <rasd:Description>Memory Size</rasd:Description>\n" +
|
||||
" <rasd:ElementName>8192MB of memory</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>2</rasd:InstanceID>\n" +
|
||||
" <rasd:Limit>8192</rasd:Limit>\n" +
|
||||
" <rasd:Reservation>8192</rasd:Reservation>\n" +
|
||||
" <rasd:ResourceType>4</rasd:ResourceType>\n" +
|
||||
" <rasd:VirtualQuantity>8192</rasd:VirtualQuantity>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:Address>0</rasd:Address>\n" +
|
||||
" <rasd:Description>SCSI Controller</rasd:Description>\n" +
|
||||
" <rasd:ElementName>SCSI controller 0</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>3</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>6</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:Address>0</rasd:Address>\n" +
|
||||
" <rasd:Description>IDE Controller</rasd:Description>\n" +
|
||||
" <rasd:ElementName>IDE 0</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>4</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceType>5</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:required=\"false\">\n" +
|
||||
" <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>5</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>4</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>15</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item ovf:required=\"false\">\n" +
|
||||
" <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/file/file3</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>18</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>4</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>15</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>7</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>Management0-0</rasd:Connection>\n" +
|
||||
" <rasd:Description>E1000 Ethernet adapter on \"Management Network\"</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 1</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>6</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
|
||||
" <rasd:ElementName>Hard disk 1</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>7</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>3</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>17</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
|
||||
" <rasd:ElementName>Hard disk 2</rasd:ElementName>\n" +
|
||||
" <rasd:HostResource>ovf:/disk/vmdisk2</rasd:HostResource>\n" +
|
||||
" <rasd:InstanceID>8</rasd:InstanceID>\n" +
|
||||
" <rasd:Parent>3</rasd:Parent>\n" +
|
||||
" <rasd:ResourceType>17</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>8</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-0</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 2</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>9</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>9</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-1</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 3</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>10</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>10</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-2</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 4</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>11</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>11</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-3</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 5</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>12</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>12</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-4</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 6</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>13</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>13</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-5</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 7</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>14</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>14</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-6</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 8</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>15</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>15</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-7</rasd:Connection>\n" +
|
||||
" <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 9</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>16</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <Item>\n" +
|
||||
" <rasd:AddressOnParent>16</rasd:AddressOnParent>\n" +
|
||||
" <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
|
||||
" <rasd:Connection>GigabitEthernet0-8</rasd:Connection>\n" +
|
||||
" <rasd:Description>Default HA failover E1000 Ethernet adapter, or additional standalone general purpose adapter</rasd:Description>\n" +
|
||||
" <rasd:ElementName>Network adapter 10</rasd:ElementName>\n" +
|
||||
" <rasd:InstanceID>17</rasd:InstanceID>\n" +
|
||||
" <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
|
||||
" <rasd:ResourceType>10</rasd:ResourceType>\n" +
|
||||
" </Item>\n" +
|
||||
" <vmw:ExtraConfig vmw:key=\"monitor_control.pseudo_perfctr\" vmw:value=\"TRUE\"></vmw:ExtraConfig>\n" +
|
||||
" </VirtualHardwareSection>\n" +
|
||||
"</VirtualSystem>";
|
||||
|
||||
private String eulaSections =
|
||||
"<VirtualSystem>\n" +
|
||||
|
|
@ -729,4 +737,17 @@ public class OVFHelperTest {
|
|||
List<OVFPropertyTO> props = ovfHelper.getOVFPropertiesFromXmlString(productSectionWithCategories);
|
||||
Assert.assertEquals(18, props.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOperatingSystemInfo() throws IOException, SAXException, ParserConfigurationException {
|
||||
Pair<String, String> guestOsPair = ovfHelper.getOperatingSystemInfoFromXmlString(ovfFileVirtualHardwareSection);
|
||||
Assert.assertEquals("other26xLinux64Guest", guestOsPair.first());
|
||||
Assert.assertEquals("Other 2.6x Linux (64-bit)", guestOsPair.second());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMinimumHardwareVersion() throws IOException, SAXException, ParserConfigurationException {
|
||||
OVFVirtualHardwareSectionTO hardwareSection = ovfHelper.getVirtualHardwareSectionFromXmlString(ovfFileVirtualHardwareSection);
|
||||
Assert.assertEquals("vmx-08", hardwareSection.getMinimiumHardwareVersion());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,18 +20,13 @@
|
|||
package com.cloud.agent.api.storage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
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.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
|
||||
|
||||
public class DownloadAnswer extends Answer {
|
||||
private String jobId;
|
||||
|
|
@ -45,15 +40,7 @@ public class DownloadAnswer extends Answer {
|
|||
private String checkSum;
|
||||
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFPropertyTO> ovfProperties;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFNetworkTO> networkRequirements;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<DatadiskTO> disks;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private OVFVirtualHardwareSectionTO ovfHardwareSection;
|
||||
@LogLevel(LogLevel.Log4jLevel.Off)
|
||||
private List<OVFEulaSectionTO> eulaSections;
|
||||
private OVFInformationTO ovfInformationTO;
|
||||
|
||||
public String getCheckSum() {
|
||||
return checkSum;
|
||||
|
|
@ -164,43 +151,11 @@ public class DownloadAnswer extends Answer {
|
|||
return templatePhySicalSize;
|
||||
}
|
||||
|
||||
public List<OVFPropertyTO> getOvfProperties() {
|
||||
return ovfProperties;
|
||||
public OVFInformationTO getOvfInformationTO() {
|
||||
return ovfInformationTO;
|
||||
}
|
||||
|
||||
public void setOvfProperties(List<OVFPropertyTO> ovfProperties) {
|
||||
this.ovfProperties = ovfProperties;
|
||||
}
|
||||
|
||||
public List<OVFNetworkTO> getNetworkRequirements() {
|
||||
return networkRequirements;
|
||||
}
|
||||
|
||||
public void setNetworkRequirements(List<OVFNetworkTO> networkRequirements) {
|
||||
this.networkRequirements = networkRequirements;
|
||||
}
|
||||
|
||||
public List<DatadiskTO> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
public void setDisks(List<DatadiskTO> disks) {
|
||||
this.disks = disks;
|
||||
}
|
||||
|
||||
public OVFVirtualHardwareSectionTO getOvfHardwareSection() {
|
||||
return ovfHardwareSection;
|
||||
}
|
||||
|
||||
public void setOvfHardwareSection(OVFVirtualHardwareSectionTO ovfHardwareSection) {
|
||||
this.ovfHardwareSection = ovfHardwareSection;
|
||||
}
|
||||
|
||||
public List<OVFEulaSectionTO> getEulaSections() {
|
||||
return eulaSections;
|
||||
}
|
||||
|
||||
public void setEulaSections(List<OVFEulaSectionTO> eulaSections) {
|
||||
this.eulaSections = eulaSections;
|
||||
public void setOvfInformationTO(OVFInformationTO ovfInformationTO) {
|
||||
this.ovfInformationTO = ovfInformationTO;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import javax.naming.ConfigurationException;
|
|||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import com.cloud.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
|
||||
|
|
@ -35,6 +36,7 @@ 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.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
|
@ -107,30 +109,34 @@ public class OVAProcessor extends AdapterBase implements Processor {
|
|||
OVFHelper ovfHelper = new OVFHelper();
|
||||
Document doc = ovfHelper.getDocumentFromFile(ovfFilePath);
|
||||
|
||||
List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfoFromFile(ovfFilePath, doc, null);
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(String.format("Found %d disks in template %s", CollectionUtils.isNotEmpty(disks) ? disks.size() : 0, ovfFilePath));
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(disks)) {
|
||||
info.disks = disks;
|
||||
}
|
||||
OVFInformationTO ovfInformationTO = createOvfInformationTO(ovfHelper, doc, ovfFilePath);
|
||||
info.ovfInformationTO = ovfInformationTO;
|
||||
}
|
||||
|
||||
private OVFInformationTO createOvfInformationTO(OVFHelper ovfHelper, Document doc, String ovfFilePath) throws InternalErrorException {
|
||||
OVFInformationTO ovfInformationTO = new OVFInformationTO();
|
||||
|
||||
List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfoFromFile(ovfFilePath, doc, null);
|
||||
if (CollectionUtils.isNotEmpty(disks)) {
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(String.format("Found %d disks in template %s", disks.size(), ovfFilePath));
|
||||
}
|
||||
ovfInformationTO.setDisks(disks);
|
||||
}
|
||||
List<OVFNetworkTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc);
|
||||
if (CollectionUtils.isNotEmpty(nets)) {
|
||||
LOGGER.info("Found " + nets.size() + " prerequisite networks");
|
||||
info.networks = nets;
|
||||
ovfInformationTO.setNetworks(nets);
|
||||
} else if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(String.format("no net prerequisites found in template %s", ovfFilePath));
|
||||
}
|
||||
|
||||
List<OVFPropertyTO> ovfProperties = ovfHelper.getConfigurableOVFPropertiesFromDocument(doc);
|
||||
if (CollectionUtils.isNotEmpty(ovfProperties)) {
|
||||
LOGGER.info("Found " + ovfProperties.size() + " configurable OVF properties");
|
||||
info.ovfProperties = ovfProperties;
|
||||
ovfInformationTO.setProperties(ovfProperties);
|
||||
} else if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(String.format("no ovf properties found in template %s", ovfFilePath));
|
||||
}
|
||||
|
||||
OVFVirtualHardwareSectionTO hardwareSection = ovfHelper.getVirtualHardwareSectionFromDocument(doc);
|
||||
List<OVFConfigurationTO> configurations = hardwareSection.getConfigurations();
|
||||
if (CollectionUtils.isNotEmpty(configurations)) {
|
||||
|
|
@ -140,12 +146,21 @@ public class OVAProcessor extends AdapterBase implements Processor {
|
|||
if (CollectionUtils.isNotEmpty(hardwareItems)) {
|
||||
LOGGER.info("Found " + hardwareItems.size() + " virtual hardware items");
|
||||
}
|
||||
info.hardwareSection = hardwareSection;
|
||||
if (StringUtils.isNotBlank(hardwareSection.getMinimiumHardwareVersion())) {
|
||||
LOGGER.info("Found minimum hardware version " + hardwareSection.getMinimiumHardwareVersion());
|
||||
}
|
||||
ovfInformationTO.setHardwareSection(hardwareSection);
|
||||
List<OVFEulaSectionTO> eulaSections = ovfHelper.getEulaSectionsFromDocument(doc);
|
||||
if (CollectionUtils.isNotEmpty(eulaSections)) {
|
||||
LOGGER.info("Found " + eulaSections.size() + " license agreements");
|
||||
info.eulaSections = eulaSections;
|
||||
ovfInformationTO.setEulaSections(eulaSections);
|
||||
}
|
||||
Pair<String, String> guestOsPair = ovfHelper.getOperatingSystemInfoFromDocument(doc);
|
||||
if (guestOsPair != null) {
|
||||
LOGGER.info("Found guest OS information: " + guestOsPair.first() + " - " + guestOsPair.second());
|
||||
ovfInformationTO.setGuestOsInfo(guestOsPair);
|
||||
}
|
||||
return ovfInformationTO;
|
||||
}
|
||||
|
||||
private void setFileSystemAccessRights(String templatePath) {
|
||||
|
|
|
|||
|
|
@ -21,16 +21,11 @@ package com.cloud.storage.template;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
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.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.exception.InternalErrorException;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
|
||||
|
||||
/**
|
||||
* Generic interface to process different types of image formats
|
||||
|
|
@ -58,11 +53,7 @@ public interface Processor extends Adapter {
|
|||
public long virtualSize;
|
||||
public String filename;
|
||||
public boolean isCorrupted;
|
||||
public List<OVFPropertyTO> ovfProperties;
|
||||
public List<OVFNetworkTO> networks;
|
||||
public List<DatadiskTO> disks;
|
||||
public OVFVirtualHardwareSectionTO hardwareSection;
|
||||
public List<OVFEulaSectionTO> eulaSections;
|
||||
public OVFInformationTO ovfInformationTO;
|
||||
}
|
||||
|
||||
long getVirtualSize(File file) throws IOException;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
|
|
@ -49,8 +50,10 @@ public class DownloadAnswerTest {
|
|||
List<OVFNetworkTO> networks = new ArrayList<>();
|
||||
networks.add(new OVFNetworkTO());
|
||||
|
||||
answer.setOvfProperties(properties);
|
||||
answer.setNetworkRequirements(networks);
|
||||
OVFInformationTO informationTO = new OVFInformationTO();
|
||||
informationTO.setProperties(properties);
|
||||
informationTO.setNetworks(networks);
|
||||
answer.setOvfInformationTO(informationTO);
|
||||
|
||||
String json = gson.toJson(answer);
|
||||
Answer received = gson.fromJson(json, Answer.class);
|
||||
|
|
|
|||
|
|
@ -21,4 +21,5 @@ import com.cloud.utils.db.GenericDao;
|
|||
|
||||
public interface GuestOSCategoryDao extends GenericDao<GuestOSCategoryVO, Long> {
|
||||
|
||||
GuestOSCategoryVO findByCategoryName(String categoryName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.storage.GuestOSCategoryVO;
|
||||
|
|
@ -29,4 +30,10 @@ public class GuestOSCategoryDaoImpl extends GenericDaoBase<GuestOSCategoryVO, Lo
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuestOSCategoryVO findByCategoryName(String categoryName) {
|
||||
final QueryBuilder<GuestOSCategoryVO> sc = QueryBuilder.create(GuestOSCategoryVO.class);
|
||||
sc.and(sc.entity().getName(), SearchCriteria.Op.EQ, categoryName);
|
||||
return sc.find();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
|||
import com.cloud.storage.GuestOSHypervisorVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Long> {
|
||||
|
||||
HypervisorType findHypervisorTypeByGuestOsId(long guestOsId);
|
||||
|
|
@ -31,4 +33,9 @@ public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Lo
|
|||
GuestOSHypervisorVO findByOsIdAndHypervisorAndUserDefined(long guestOsId, String hypervisorType, String hypervisorVersion, boolean isUserDefined);
|
||||
|
||||
GuestOSHypervisorVO findByOsNameAndHypervisor(String guestOsName, String hypervisorType, String hypervisorVersion);
|
||||
|
||||
List<GuestOSHypervisorVO> listByOsNameAndHypervisorMinimumVersion(String guestOsName, String hypervisorType,
|
||||
String minHypervisorVersion);
|
||||
|
||||
List<String> listHypervisorSupportedVersionsFromMinimumVersion(String hypervisorType, String hypervisorVersion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@
|
|||
// under the License.
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
|
|||
protected final SearchBuilder<GuestOSHypervisorVO> mappingSearch;
|
||||
protected final SearchBuilder<GuestOSHypervisorVO> userDefinedMappingSearch;
|
||||
protected final SearchBuilder<GuestOSHypervisorVO> guestOsNameSearch;
|
||||
protected final SearchBuilder<GuestOSHypervisorVO> availableHypervisorVersionSearch;
|
||||
|
||||
protected GuestOSHypervisorDaoImpl() {
|
||||
guestOsSearch = createSearchBuilder();
|
||||
|
|
@ -60,6 +63,15 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
|
|||
guestOsNameSearch.and("hypervisor_type", guestOsNameSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
guestOsNameSearch.and("hypervisor_version", guestOsNameSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
|
||||
guestOsNameSearch.done();
|
||||
|
||||
availableHypervisorVersionSearch = createSearchBuilder();
|
||||
availableHypervisorVersionSearch.and("hypervisor_type",
|
||||
availableHypervisorVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
availableHypervisorVersionSearch.and("hypervisor_version",
|
||||
availableHypervisorVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ);
|
||||
availableHypervisorVersionSearch.select(null, SearchCriteria.Func.DISTINCT,
|
||||
availableHypervisorVersionSearch.entity().getHypervisorVersion());
|
||||
availableHypervisorVersionSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -121,4 +133,29 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
|
|||
return CollectionUtils.isNotEmpty(results) ? results.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GuestOSHypervisorVO> listByOsNameAndHypervisorMinimumVersion(String guestOsName, String hypervisorType,
|
||||
String minHypervisorVersion) {
|
||||
final QueryBuilder<GuestOSHypervisorVO> sc = QueryBuilder.create(GuestOSHypervisorVO.class);
|
||||
sc.and(sc.entity().getGuestOsName(), SearchCriteria.Op.EQ, guestOsName);
|
||||
sc.and(sc.entity().getHypervisorType(), SearchCriteria.Op.EQ, hypervisorType);
|
||||
sc.and(sc.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ, minHypervisorVersion);
|
||||
sc.and(sc.entity().getHypervisorVersion(), SearchCriteria.Op.NEQ, "default");
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listHypervisorSupportedVersionsFromMinimumVersion(String hypervisorType, String hypervisorVersion) {
|
||||
List<String> versions = new ArrayList<>();
|
||||
SearchCriteria<GuestOSHypervisorVO> sc = availableHypervisorVersionSearch.create();
|
||||
sc.setParameters("hypervisor_type", hypervisorType);
|
||||
sc.setParameters("hypervisor_version", hypervisorVersion);
|
||||
Filter filter = new Filter(GuestOSHypervisorVO.class, "hypervisorVersion", true, null, null);
|
||||
List<GuestOSHypervisorVO> mappings = listBy(sc, filter);
|
||||
for (GuestOSHypervisorVO mapping : mappings) {
|
||||
versions.add(mapping.getHypervisorVersion());
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,4 +515,7 @@ ALTER VIEW `cloud`.`image_store_view` AS
|
|||
left join
|
||||
`cloud`.`data_center` ON image_store.data_center_id = data_center.id
|
||||
left join
|
||||
`cloud`.`image_store_details` ON image_store_details.store_id = image_store.id;
|
||||
`cloud`.`image_store_details` ON image_store_details.store_id = image_store.id;
|
||||
|
||||
-- OVF configured OS while registering deploy-as-is templates
|
||||
INSERT IGNORE INTO `cloud`.`guest_os` (uuid, category_id, display_name, created) VALUES (UUID(), 11, 'OVF Configured OS', now());
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ 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.NicTO;
|
||||
import com.cloud.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
|
||||
import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
|
||||
|
|
@ -34,11 +35,24 @@ 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.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.GuestOSCategoryVO;
|
||||
import com.cloud.storage.GuestOSHypervisorVO;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.GuestOSHypervisorDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.compression.CompressionUtil;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
|
@ -47,14 +61,18 @@ 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.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class DeployAsIsHelperImpl implements DeployAsIsHelper {
|
||||
|
|
@ -70,6 +88,14 @@ public class DeployAsIsHelperImpl implements DeployAsIsHelper {
|
|||
private PrimaryDataStoreDao storagePoolDao;
|
||||
@Inject
|
||||
private VMTemplatePoolDao templateStoragePoolDao;
|
||||
@Inject
|
||||
private VMTemplateDao templateDao;
|
||||
@Inject
|
||||
private GuestOSDao guestOSDao;
|
||||
@Inject
|
||||
private GuestOSHypervisorDao guestOSHypervisorDao;
|
||||
@Inject
|
||||
private GuestOSCategoryDao guestOSCategoryDao;
|
||||
|
||||
static {
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
|
|
@ -78,30 +104,180 @@ public class DeployAsIsHelperImpl implements DeployAsIsHelper {
|
|||
}
|
||||
|
||||
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();
|
||||
OVFInformationTO ovfInformationTO = answer.getOvfInformationTO();
|
||||
if (ovfInformationTO != null) {
|
||||
List<OVFPropertyTO> ovfProperties = ovfInformationTO.getProperties();
|
||||
List<OVFNetworkTO> networkRequirements = ovfInformationTO.getNetworks();
|
||||
OVFVirtualHardwareSectionTO ovfHardwareSection = ovfInformationTO.getHardwareSection();
|
||||
List<OVFEulaSectionTO> eulaSections = ovfInformationTO.getEulaSections();
|
||||
Pair<String, String> guestOsInfo = ovfInformationTO.getGuestOsInfo();
|
||||
|
||||
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(ovfProperties)) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, ovfProperties);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getCommonHardwareItems());
|
||||
if (CollectionUtils.isNotEmpty(networkRequirements)) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, networkRequirements);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(eulaSections)) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, eulaSections);
|
||||
}
|
||||
String minimumHardwareVersion = null;
|
||||
if (ovfHardwareSection != null) {
|
||||
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getConfigurations());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) {
|
||||
persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getCommonHardwareItems());
|
||||
}
|
||||
minimumHardwareVersion = ovfHardwareSection.getMinimiumHardwareVersion();
|
||||
}
|
||||
if (guestOsInfo != null) {
|
||||
String osType = guestOsInfo.first();
|
||||
String osDescription = guestOsInfo.second();
|
||||
LOGGER.info("Guest OS information retrieved from the template: " + osType + " - " + osDescription);
|
||||
try {
|
||||
handleGuestOsFromOVFDescriptor(templateId, osType, osDescription, minimumHardwareVersion);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error handling the guest OS read from the OVF " + osType, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the guest OS read from the OVF and try to match it to an existing guest OS in DB.
|
||||
* If the guest OS cannot be mapped to an existing guest OS in DB, then create it and create support for hypervisor versions.
|
||||
* Roll back actions in case of unexpected erros
|
||||
*/
|
||||
private void handleGuestOsFromOVFDescriptor(long templateId, String guestOsType, String guestOsDescription,
|
||||
String minimumHardwareVersion) {
|
||||
VMTemplateVO template = templateDao.findById(templateId);
|
||||
Hypervisor.HypervisorType hypervisor = template.getHypervisorType();
|
||||
if (hypervisor != Hypervisor.HypervisorType.VMware) {
|
||||
return;
|
||||
}
|
||||
String minimumHypervisorVersion = getMinimumSupportedHypervisorVersionForHardwareVersion(minimumHardwareVersion);
|
||||
LOGGER.info("Minimum hardware version " + minimumHardwareVersion + " matched to hypervisor version " + minimumHypervisorVersion + ". " +
|
||||
"Checking guest OS supporting this version");
|
||||
|
||||
List<GuestOSHypervisorVO> guestOsMappings = guestOSHypervisorDao.listByOsNameAndHypervisorMinimumVersion(guestOsType,
|
||||
hypervisor.toString(), minimumHypervisorVersion);
|
||||
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
if (CollectionUtils.isNotEmpty(guestOsMappings)) {
|
||||
Pair<Boolean, Set<String>> result = updateDeployAsIsTemplateToExistingGuestOs(template, guestOsMappings, guestOsDescription);
|
||||
if (!result.first()) {
|
||||
// If couldnt find a guest OS matching the display name, create a new guest OS
|
||||
updateDeployAsIsTemplateToNewGuestOs(template, guestOsType, guestOsDescription, hypervisor, result.second());
|
||||
}
|
||||
} else {
|
||||
// The guest OS is not present in DB, create a new guest OS entry and mappings for supported versions
|
||||
List<String> hypervisorVersions = guestOSHypervisorDao.listHypervisorSupportedVersionsFromMinimumVersion(
|
||||
hypervisor.toString(), minimumHypervisorVersion);
|
||||
updateDeployAsIsTemplateToNewGuestOs(template, guestOsType, guestOsDescription, hypervisor, hypervisorVersions);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the template guest OS can be updated to an existing guest OS matching the display name to
|
||||
* the guest OS description from the OVF. (the second element of the returned pair is not used)
|
||||
* If the guest OS does not exist, return false and the hypervisor versions that the guest OS must support
|
||||
*/
|
||||
private Pair<Boolean, Set<String>> updateDeployAsIsTemplateToExistingGuestOs(VMTemplateVO template,
|
||||
List<GuestOSHypervisorVO> guestOsMappings,
|
||||
String guestOsDescription) {
|
||||
Set<String> versionsToSupport = new HashSet<>();
|
||||
for (GuestOSHypervisorVO mapping : guestOsMappings) {
|
||||
long guestOsId = mapping.getGuestOsId();
|
||||
GuestOSVO guestOs = guestOSDao.findById(guestOsId);
|
||||
versionsToSupport.add(mapping.getHypervisorVersion());
|
||||
if (guestOs.getDisplayName().equalsIgnoreCase(guestOsDescription)) {
|
||||
LOGGER.info("Found guest OS mapping for OVF read guest OS " + guestOsDescription +
|
||||
" to hypervisor version " + mapping.getHypervisorVersion());
|
||||
LOGGER.info("Updating deploy-as-is template guest OS to " + guestOs.getDisplayName());
|
||||
updateTemplateGuestOsId(template, guestOsId);
|
||||
return new Pair<>(true, versionsToSupport);
|
||||
}
|
||||
}
|
||||
LOGGER.info("Could not map the OVF read guest OS " + guestOsDescription + " to an existing guest OS");
|
||||
return new Pair<>(false, versionsToSupport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the deploy-as-is template guest OS doing:
|
||||
* - Create a new guest OS with the guest OS description parsed from the OVF
|
||||
* - Create mappings for the new guest OS and supported hypervisor versions
|
||||
* - Update the template guest OS ID to the new guest OS ID
|
||||
*/
|
||||
private void updateDeployAsIsTemplateToNewGuestOs(VMTemplateVO template, String guestOsType, String guestOsDescription,
|
||||
Hypervisor.HypervisorType hypervisor, Collection<String> hypervisorVersions) {
|
||||
GuestOSVO newGuestOs = createGuestOsEntry(guestOsDescription);
|
||||
for (String hypervisorVersion : hypervisorVersions) {
|
||||
LOGGER.info(String.format("Adding a new guest OS mapping for hypervisor: %s version: %s and " +
|
||||
"guest OS: %s", hypervisor.toString(), hypervisorVersion, guestOsType));
|
||||
createGuestOsHypervisorMapping(newGuestOs.getId(), guestOsType, hypervisor.toString(), hypervisorVersion);
|
||||
}
|
||||
updateTemplateGuestOsId(template, newGuestOs.getId());
|
||||
}
|
||||
|
||||
private void updateTemplateGuestOsId(VMTemplateVO template, long guestOsId) {
|
||||
template.setGuestOSId(guestOsId);
|
||||
templateDao.update(template.getId(), template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new entry on guest_os_hypervisor
|
||||
*/
|
||||
private void createGuestOsHypervisorMapping(long guestOsId, String guestOsType, String hypervisorType, String hypervisorVersion) {
|
||||
GuestOSHypervisorVO mappingVO = new GuestOSHypervisorVO();
|
||||
mappingVO.setGuestOsId(guestOsId);
|
||||
mappingVO.setHypervisorType(hypervisorType);
|
||||
mappingVO.setHypervisorVersion(hypervisorVersion);
|
||||
mappingVO.setGuestOsName(guestOsType);
|
||||
guestOSHypervisorDao.persist(mappingVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new guest OS entry with category 'Other'
|
||||
*/
|
||||
private GuestOSVO createGuestOsEntry(String guestOsDescription) {
|
||||
GuestOSCategoryVO categoryVO = guestOSCategoryDao.findByCategoryName("Other");
|
||||
long categoryId = categoryVO != null ? categoryVO.getId() : 7L;
|
||||
GuestOSVO guestOSVO = new GuestOSVO();
|
||||
guestOSVO.setDisplayName(guestOsDescription);
|
||||
guestOSVO.setCategoryId(categoryId);
|
||||
return guestOSDao.persist(guestOSVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum VMware hosts supported version is 6.0
|
||||
*/
|
||||
protected String getMinimumSupportedHypervisorVersionForHardwareVersion(String hardwareVersion) {
|
||||
// From https://kb.vmware.com/s/article/1003746 and https://kb.vmware.com/s/article/2007240
|
||||
String hypervisorVersion = "default";
|
||||
if (StringUtils.isBlank(hardwareVersion)) {
|
||||
return hypervisorVersion;
|
||||
}
|
||||
String hwVersion = hardwareVersion.replace("vmx-", "");
|
||||
try {
|
||||
int hwVersionNumber = Integer.parseInt(hwVersion);
|
||||
if (hwVersionNumber <= 11) {
|
||||
hypervisorVersion = "6.0";
|
||||
} else if (hwVersionNumber == 13) {
|
||||
hypervisorVersion = "6.5";
|
||||
} else if (hwVersionNumber >= 14) {
|
||||
hypervisorVersion = "6.7";
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
LOGGER.error("Cannot parse hardware version " + hwVersion + " to integer. Using default hypervisor version", e);
|
||||
}
|
||||
return hypervisorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vm) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.deployasis.DeployAsIsConstants;
|
||||
import com.cloud.storage.upload.params.IsoUploadParams;
|
||||
import com.cloud.storage.upload.params.TemplateUploadParams;
|
||||
import com.cloud.storage.upload.params.UploadParams;
|
||||
|
|
@ -167,6 +168,13 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
if (requiresHVM == null) {
|
||||
requiresHVM = true;
|
||||
}
|
||||
if (deployAsIs) {
|
||||
GuestOS deployAsIsGuestOs = ApiDBUtils.findGuestOSByDisplayName(DeployAsIsConstants.DEFAULT_GUEST_OS_DEPLOY_AS_IS);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Setting default guest OS for deploy-as-is template while the template registration is not completed");
|
||||
}
|
||||
guestOSId = deployAsIsGuestOs.getId();
|
||||
}
|
||||
}
|
||||
|
||||
if (isExtractable == null) {
|
||||
|
|
|
|||
|
|
@ -37,10 +37,7 @@ import java.util.concurrent.Executors;
|
|||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
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.to.deployasis.OVFPropertyTO;
|
||||
import com.cloud.agent.api.to.OVFInformationTO;
|
||||
import com.cloud.storage.template.Processor;
|
||||
import com.cloud.storage.template.S3TemplateDownloader;
|
||||
import com.cloud.storage.template.TemplateDownloader;
|
||||
|
|
@ -58,7 +55,6 @@ 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 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;
|
||||
|
|
@ -66,7 +62,6 @@ import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType
|
|||
import org.apache.cloudstack.storage.NfsMountManagerImpl.PathParser;
|
||||
import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
|
||||
import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.storage.DownloadAnswer;
|
||||
|
|
@ -131,11 +126,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
|||
private long templatePhysicalSize;
|
||||
private final long id;
|
||||
private final ResourceType resourceType;
|
||||
private List<OVFPropertyTO> ovfProperties;
|
||||
private List<OVFNetworkTO> networks;
|
||||
private List<DatadiskTO> disks;
|
||||
private OVFVirtualHardwareSectionTO hardwareSection;
|
||||
private List<OVFEulaSectionTO> eulaSections;
|
||||
private OVFInformationTO ovfInformationTO;
|
||||
|
||||
public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
|
||||
String installPathPrefix, ResourceType resourceType) {
|
||||
|
|
@ -231,44 +222,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
|||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
public List<OVFPropertyTO> getOvfProperties() {
|
||||
return ovfProperties;
|
||||
public OVFInformationTO getOvfInformationTO() {
|
||||
return ovfInformationTO;
|
||||
}
|
||||
|
||||
public void setOvfProperties(List<OVFPropertyTO> ovfProperties) {
|
||||
this.ovfProperties = ovfProperties;
|
||||
}
|
||||
|
||||
public List<OVFNetworkTO> getNetworks() {
|
||||
return networks;
|
||||
}
|
||||
|
||||
public void setNetworks(List<OVFNetworkTO> networks) {
|
||||
this.networks = networks;
|
||||
}
|
||||
|
||||
public List<DatadiskTO> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
public void setDisks(List<DatadiskTO> disks) {
|
||||
this.disks = disks;
|
||||
}
|
||||
|
||||
public void setVirtualHardwareSection(OVFVirtualHardwareSectionTO section) {
|
||||
this.hardwareSection = section;
|
||||
}
|
||||
|
||||
public OVFVirtualHardwareSectionTO getVirtualHardwareSection() {
|
||||
return this.hardwareSection;
|
||||
}
|
||||
|
||||
public List<OVFEulaSectionTO> getEulaSections() {
|
||||
return eulaSections;
|
||||
}
|
||||
|
||||
public void setEulaSections(List<OVFEulaSectionTO> eulaSections) {
|
||||
this.eulaSections = eulaSections;
|
||||
public void setOvfInformationTO(OVFInformationTO ovfInformationTO) {
|
||||
this.ovfInformationTO = ovfInformationTO;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -563,18 +522,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
|||
}
|
||||
dnld.setTemplatesize(info.virtualSize);
|
||||
dnld.setTemplatePhysicalSize(info.size);
|
||||
if (CollectionUtils.isNotEmpty(info.ovfProperties)) {
|
||||
dnld.setOvfProperties(info.ovfProperties);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(info.networks)) {
|
||||
dnld.setNetworks(info.networks);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(info.disks)) {
|
||||
dnld.setDisks(info.disks);
|
||||
}
|
||||
dnld.setVirtualHardwareSection(info.hardwareSection);
|
||||
if (CollectionUtils.isNotEmpty(info.eulaSections)) {
|
||||
dnld.setEulaSections(info.eulaSections);
|
||||
if (info.ovfInformationTO != null) {
|
||||
dnld.setOvfInformationTO(info.ovfInformationTO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -876,18 +825,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
|
|||
answer =
|
||||
new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
|
||||
getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
|
||||
if (CollectionUtils.isNotEmpty(dj.getOvfProperties())) {
|
||||
answer.setOvfProperties(dj.getOvfProperties());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(dj.getNetworks())) {
|
||||
answer.setNetworkRequirements(dj.getNetworks());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(dj.getDisks())) {
|
||||
answer.setDisks(dj.getDisks());
|
||||
}
|
||||
answer.setOvfHardwareSection(dj.getVirtualHardwareSection());
|
||||
if (CollectionUtils.isNotEmpty(dj.getEulaSections())) {
|
||||
answer.setEulaSections(dj.getEulaSections());
|
||||
if (dj.getOvfInformationTO() != null) {
|
||||
answer.setOvfInformationTO(dj.getOvfInformationTO());
|
||||
}
|
||||
jobs.remove(jobId);
|
||||
return answer;
|
||||
|
|
|
|||
Loading…
Reference in New Issue