mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-15 18:12:35 +01:00
enhancement: add instance info as Libvirt metadata (#11061)
This commit is contained in:
parent
a50de029bf
commit
8c86f24261
@ -0,0 +1,182 @@
|
||||
// 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 java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class VirtualMachineMetadataTO {
|
||||
// VM details
|
||||
private final String name;
|
||||
private final String internalName;
|
||||
private final String displayName;
|
||||
private final String instanceUuid;
|
||||
private final Integer cpuCores;
|
||||
private final Integer memory;
|
||||
private final Long created;
|
||||
private final Long started;
|
||||
|
||||
// Owner details
|
||||
private final String ownerDomainUuid;
|
||||
private final String ownerDomainName;
|
||||
private final String ownerAccountUuid;
|
||||
private final String ownerAccountName;
|
||||
private final String ownerProjectUuid;
|
||||
private final String ownerProjectName;
|
||||
|
||||
// Host and service offering
|
||||
private final String serviceOfferingName;
|
||||
private final List<String> serviceOfferingHostTags;
|
||||
|
||||
// zone, pod, and cluster details
|
||||
private final String zoneName;
|
||||
private final String zoneUuid;
|
||||
private final String podName;
|
||||
private final String podUuid;
|
||||
private final String clusterName;
|
||||
private final String clusterUuid;
|
||||
|
||||
// resource tags
|
||||
private final Map<String, String> resourceTags;
|
||||
|
||||
public VirtualMachineMetadataTO(
|
||||
String name, String internalName, String displayName, String instanceUuid, Integer cpuCores, Integer memory, Long created, Long started,
|
||||
String ownerDomainUuid, String ownerDomainName, String ownerAccountUuid, String ownerAccountName, String ownerProjectUuid, String ownerProjectName,
|
||||
String serviceOfferingName, List<String> serviceOfferingHostTags,
|
||||
String zoneName, String zoneUuid, String podName, String podUuid, String clusterName, String clusterUuid, Map<String, String> resourceTags) {
|
||||
/*
|
||||
* Something failed in the metadata shall not be a fatal error, the VM can still be started
|
||||
* Thus, the unknown fields just get an explicit "unknown" value so it can be fixed in case
|
||||
* there are bugs on some execution paths.
|
||||
* */
|
||||
|
||||
this.name = (name != null) ? name : "unknown";
|
||||
this.internalName = (internalName != null) ? internalName : "unknown";
|
||||
this.displayName = (displayName != null) ? displayName : "unknown";
|
||||
this.instanceUuid = (instanceUuid != null) ? instanceUuid : "unknown";
|
||||
this.cpuCores = (cpuCores != null) ? cpuCores : -1;
|
||||
this.memory = (memory != null) ? memory : -1;
|
||||
this.created = (created != null) ? created : 0;
|
||||
this.started = (started != null) ? started : 0;
|
||||
this.ownerDomainUuid = (ownerDomainUuid != null) ? ownerDomainUuid : "unknown";
|
||||
this.ownerDomainName = (ownerDomainName != null) ? ownerDomainName : "unknown";
|
||||
this.ownerAccountUuid = (ownerAccountUuid != null) ? ownerAccountUuid : "unknown";
|
||||
this.ownerAccountName = (ownerAccountName != null) ? ownerAccountName : "unknown";
|
||||
this.ownerProjectUuid = (ownerProjectUuid != null) ? ownerProjectUuid : "unknown";
|
||||
this.ownerProjectName = (ownerProjectName != null) ? ownerProjectName : "unknown";
|
||||
this.serviceOfferingName = (serviceOfferingName != null) ? serviceOfferingName : "unknown";
|
||||
this.serviceOfferingHostTags = (serviceOfferingHostTags != null) ? serviceOfferingHostTags : new ArrayList<>();
|
||||
this.zoneName = (zoneName != null) ? zoneName : "unknown";
|
||||
this.zoneUuid = (zoneUuid != null) ? zoneUuid : "unknown";
|
||||
this.podName = (podName != null) ? podName : "unknown";
|
||||
this.podUuid = (podUuid != null) ? podUuid : "unknown";
|
||||
this.clusterName = (clusterName != null) ? clusterName : "unknown";
|
||||
this.clusterUuid = (clusterUuid != null) ? clusterUuid : "unknown";
|
||||
|
||||
this.resourceTags = (resourceTags != null) ? resourceTags : new HashMap<>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getInternalName() {
|
||||
return internalName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getInstanceUuid() {
|
||||
return instanceUuid;
|
||||
}
|
||||
|
||||
public Integer getCpuCores() {
|
||||
return cpuCores;
|
||||
}
|
||||
|
||||
public Integer getMemory() {
|
||||
return memory;
|
||||
}
|
||||
|
||||
public Long getCreated() { return created; }
|
||||
|
||||
public Long getStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public String getOwnerDomainUuid() {
|
||||
return ownerDomainUuid;
|
||||
}
|
||||
|
||||
public String getOwnerDomainName() {
|
||||
return ownerDomainName;
|
||||
}
|
||||
|
||||
public String getOwnerAccountUuid() {
|
||||
return ownerAccountUuid;
|
||||
}
|
||||
|
||||
public String getOwnerAccountName() {
|
||||
return ownerAccountName;
|
||||
}
|
||||
|
||||
public String getOwnerProjectUuid() {
|
||||
return ownerProjectUuid;
|
||||
}
|
||||
|
||||
public String getOwnerProjectName() {
|
||||
return ownerProjectName;
|
||||
}
|
||||
|
||||
public String getserviceOfferingName() {
|
||||
return serviceOfferingName;
|
||||
}
|
||||
|
||||
public List<String> getserviceOfferingHostTags() {
|
||||
return serviceOfferingHostTags;
|
||||
}
|
||||
|
||||
public String getZoneName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public String getZoneUuid() {
|
||||
return zoneUuid;
|
||||
}
|
||||
|
||||
public String getPodName() {
|
||||
return podName;
|
||||
}
|
||||
|
||||
public String getPodUuid() {
|
||||
return podUuid;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public String getClusterUuid() {
|
||||
return clusterUuid;
|
||||
}
|
||||
|
||||
public Map<String, String> getResourceTags() { return resourceTags; }
|
||||
}
|
||||
@ -89,6 +89,7 @@ public class VirtualMachineTO {
|
||||
private DeployAsIsInfoTO deployAsIsInfo;
|
||||
private String metadataManufacturer;
|
||||
private String metadataProductName;
|
||||
private VirtualMachineMetadataTO metadata;
|
||||
|
||||
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
|
||||
String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
|
||||
@ -494,6 +495,14 @@ public class VirtualMachineTO {
|
||||
this.metadataProductName = metadataProductName;
|
||||
}
|
||||
|
||||
public VirtualMachineMetadataTO getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(VirtualMachineMetadataTO metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("VM {id: \"%s\", name: \"%s\", uuid: \"%s\", type: \"%s\"}", id, name, uuid, type);
|
||||
|
||||
@ -69,6 +69,7 @@ import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import com.cloud.agent.api.to.VirtualMachineMetadataTO;
|
||||
import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy;
|
||||
import org.apache.cloudstack.command.CommandInfo;
|
||||
import org.apache.cloudstack.command.ReconcileCommandService;
|
||||
@ -199,6 +200,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.MetadataDef;
|
||||
import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceAgentExecutor;
|
||||
import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceExecutor;
|
||||
import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceServiceExecutor;
|
||||
@ -3011,9 +3013,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
vm.addComp(createClockDef(vmTO));
|
||||
vm.addComp(createDevicesDef(vmTO, guest, vcpus, isUefiEnabled));
|
||||
|
||||
MetadataDef metaDef;
|
||||
if ((metaDef = createMetadataDef(vmTO)) != null) {
|
||||
vm.addComp(metaDef);
|
||||
}
|
||||
|
||||
addExtraConfigsToVM(vmTO, vm, extraConfig);
|
||||
}
|
||||
|
||||
protected MetadataDef createMetadataDef(VirtualMachineTO vmTO) {
|
||||
VirtualMachineMetadataTO metadata = vmTO.getMetadata();
|
||||
return (metadata != null) ? new MetadataDef(metadata) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds extra configuration to User VM Domain XML before starting.
|
||||
*/
|
||||
|
||||
@ -17,6 +17,10 @@
|
||||
package com.cloud.hypervisor.kvm.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -29,9 +33,25 @@ import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import com.cloud.agent.api.to.VirtualMachineMetadataTO;
|
||||
|
||||
|
||||
import com.cloud.agent.properties.AgentProperties;
|
||||
import com.cloud.agent.properties.AgentPropertiesFileHandler;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
|
||||
public class LibvirtVMDef {
|
||||
protected static Logger LOGGER = LogManager.getLogger(LibvirtVMDef.class);
|
||||
@ -46,6 +66,157 @@ public class LibvirtVMDef {
|
||||
private final Map<String, Object> components = new HashMap<String, Object>();
|
||||
private static final int NUMBER_OF_IOTHREADS = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.IOTHREADS);
|
||||
|
||||
public static class MetadataDef {
|
||||
private VirtualMachineMetadataTO metaTO;
|
||||
|
||||
public MetadataDef(VirtualMachineMetadataTO data) {
|
||||
metaTO = data;
|
||||
}
|
||||
|
||||
public VirtualMachineMetadataTO getMetadata() {
|
||||
return metaTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
docFactory.setNamespaceAware(true);
|
||||
Document doc = null;
|
||||
try {
|
||||
doc = docFactory.newDocumentBuilder().newDocument();
|
||||
} catch (ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not create a new DOM XML document. The metadata will not be included in the libvirt domain XML: {}", e.getMessage());
|
||||
return "";
|
||||
}
|
||||
Element metadata = doc.createElement("metadata"); // <metadata>
|
||||
Element instance = doc.createElementNS("http://cloudstack.apache.org/instance", "cloudstack:instance"); // <cloudstack:instance>
|
||||
|
||||
Element zone = doc.createElement("cloudstack:zone");
|
||||
zone.setAttribute("uuid", metaTO.getZoneUuid());
|
||||
zone.setTextContent(metaTO.getZoneName());
|
||||
instance.appendChild(zone);
|
||||
|
||||
Element pod = doc.createElement("cloudstack:pod");
|
||||
pod.setAttribute("uuid", metaTO.getPodUuid());
|
||||
pod.setTextContent(metaTO.getPodName());
|
||||
instance.appendChild(pod);
|
||||
|
||||
Element cluster = doc.createElement("cloudstack:cluster");
|
||||
cluster.setAttribute("uuid", metaTO.getClusterUuid());
|
||||
cluster.setTextContent(metaTO.getClusterName());
|
||||
instance.appendChild(cluster);
|
||||
|
||||
Element instanceName = doc.createElement("cloudstack:name");
|
||||
instanceName.setTextContent(metaTO.getName());
|
||||
instance.appendChild(instanceName);
|
||||
|
||||
Element instanceInternalName = doc.createElement("cloudstack:internal_name");
|
||||
instanceInternalName.setTextContent(metaTO.getInternalName());
|
||||
instance.appendChild(instanceInternalName);
|
||||
|
||||
Element instanceDisplayName = doc.createElement("cloudstack:display_name");
|
||||
instanceDisplayName.setTextContent(metaTO.getDisplayName());
|
||||
instance.appendChild(instanceDisplayName);
|
||||
|
||||
Element instanceUuid = doc.createElement("cloudstack:uuid");
|
||||
instanceUuid.setTextContent(metaTO.getInstanceUuid());
|
||||
instance.appendChild(instanceUuid);
|
||||
|
||||
Element serviceOffering = doc.createElement("cloudstack:service_offering"); // <service_offering>
|
||||
|
||||
Element computeOfferingName = doc.createElement("cloudstack:name");
|
||||
computeOfferingName.setTextContent(metaTO.getserviceOfferingName());
|
||||
serviceOffering.appendChild(computeOfferingName);
|
||||
|
||||
Element cpu = doc.createElement("cloudstack:cpu");
|
||||
cpu.setTextContent(metaTO.getCpuCores().toString());
|
||||
serviceOffering.appendChild(cpu);
|
||||
|
||||
Element memory = doc.createElement("cloudstack:memory");
|
||||
memory.setTextContent(metaTO.getMemory().toString());
|
||||
serviceOffering.appendChild(memory);
|
||||
|
||||
Element hostTags = doc.createElement("cloudstack:host_tags");
|
||||
List<String> tags = metaTO.getserviceOfferingHostTags();
|
||||
if (tags != null) {
|
||||
for (String i : metaTO.getserviceOfferingHostTags()) {
|
||||
Element tag = doc.createElement("cloudstack:tag");
|
||||
tag.setTextContent(i);
|
||||
hostTags.appendChild(tag);
|
||||
}
|
||||
}
|
||||
serviceOffering.appendChild(hostTags);
|
||||
|
||||
instance.appendChild(serviceOffering); // </service_offering>
|
||||
|
||||
Element creationTime = doc.createElement("cloudstack:created_at");
|
||||
creationTime.setTextContent(
|
||||
LocalDateTime.ofInstant(Instant.ofEpochSecond(metaTO.getCreated()), ZoneOffset.UTC).format(ISO_LOCAL_DATE_TIME)
|
||||
);
|
||||
instance.appendChild(creationTime);
|
||||
|
||||
Element startedTime = doc.createElement("cloudstack:started_at");
|
||||
startedTime.setTextContent(
|
||||
LocalDateTime.ofInstant(Instant.ofEpochSecond(metaTO.getStarted()), ZoneOffset.UTC).format(ISO_LOCAL_DATE_TIME)
|
||||
);
|
||||
instance.appendChild(startedTime);
|
||||
|
||||
Element owner = doc.createElement("cloudstack:owner"); // <owner>
|
||||
|
||||
Element domain = doc.createElement("cloudstack:domain");
|
||||
domain.setAttribute("uuid", metaTO.getOwnerDomainUuid());
|
||||
domain.setTextContent(metaTO.getOwnerDomainName());
|
||||
owner.appendChild(domain);
|
||||
|
||||
Element account = doc.createElement("cloudstack:account");
|
||||
account.setAttribute("uuid", metaTO.getOwnerAccountUuid());
|
||||
account.setTextContent(metaTO.getOwnerAccountName());
|
||||
owner.appendChild(account);
|
||||
|
||||
Element project = doc.createElement("cloudstack:project");
|
||||
project.setAttribute("uuid", metaTO.getOwnerProjectUuid());
|
||||
project.setTextContent(metaTO.getOwnerProjectName());
|
||||
owner.appendChild(project);
|
||||
|
||||
instance.appendChild(owner); // </owner>
|
||||
|
||||
Element resourceTags = doc.createElement("cloudstack:resource_tags"); // <resource_tags>
|
||||
for (Map.Entry<String, String> entry : metaTO.getResourceTags().entrySet()) {
|
||||
Element tag = doc.createElement("cloudstack:resource_tag"); // <resource_tag>
|
||||
tag.setAttribute("key", entry.getKey());
|
||||
tag.setTextContent(entry.getValue());
|
||||
resourceTags.appendChild(tag); // </resource_tag>
|
||||
}
|
||||
instance.appendChild(resourceTags); // </resource_tags>
|
||||
|
||||
metadata.appendChild(instance); // </cloudstack:instance>
|
||||
doc.appendChild(metadata); // </metadata>
|
||||
|
||||
Transformer transformer = null;
|
||||
try {
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
} catch (TransformerConfigurationException e) {
|
||||
LOGGER.warn("Could not create an XML transformer. The metadata will not be included in the libvirt domain XML: {}", e.getMessage());
|
||||
return "";
|
||||
}
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
|
||||
DOMSource domSource = new DOMSource(doc);
|
||||
StringWriter writer = new StringWriter();
|
||||
StreamResult result = new StreamResult(writer);
|
||||
try {
|
||||
transformer.transform(domSource, result);
|
||||
} catch (TransformerException e) {
|
||||
LOGGER.warn("Could not generate metadata XML. The metadata will not be included in the libvirt domain XML: {}", e.getMessage());
|
||||
return "";
|
||||
}
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GuestDef {
|
||||
enum GuestType {
|
||||
KVM, XEN, EXE, LXC
|
||||
@ -2163,34 +2334,6 @@ public class LibvirtVMDef {
|
||||
}
|
||||
}
|
||||
|
||||
public class MetadataDef {
|
||||
Map<String, Object> customNodes = new HashMap<>();
|
||||
|
||||
public <T> T getMetadataNode(Class<T> fieldClass) {
|
||||
T field = (T) customNodes.get(fieldClass.getName());
|
||||
if (field == null) {
|
||||
try {
|
||||
field = fieldClass.newInstance();
|
||||
customNodes.put(field.getClass().getName(), field);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
LOGGER.debug("No default constructor available in class " + fieldClass.getName() + ", ignoring exception", e);
|
||||
}
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder fsBuilder = new StringBuilder();
|
||||
fsBuilder.append("<metadata>\n");
|
||||
for (Object field : customNodes.values()) {
|
||||
fsBuilder.append(field.toString());
|
||||
}
|
||||
fsBuilder.append("</metadata>\n");
|
||||
return fsBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RngDef {
|
||||
enum RngModel {
|
||||
VIRTIO("virtio");
|
||||
@ -2493,15 +2636,6 @@ public class LibvirtVMDef {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MetadataDef getMetaData() {
|
||||
MetadataDef o = (MetadataDef) components.get(MetadataDef.class.toString());
|
||||
if (o == null) {
|
||||
o = new MetadataDef();
|
||||
addComp(o);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder vmBuilder = new StringBuilder();
|
||||
@ -2513,6 +2647,7 @@ public class LibvirtVMDef {
|
||||
if (_desc != null) {
|
||||
vmBuilder.append("<description>" + _desc + "</description>\n");
|
||||
}
|
||||
|
||||
for (Object o : components.values()) {
|
||||
vmBuilder.append(o.toString());
|
||||
}
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
// under the License.
|
||||
package com.cloud.hypervisor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -24,18 +27,31 @@ import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.agent.api.to.GPUDeviceTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineMetadataTO;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.gpu.VgpuProfileVO;
|
||||
import com.cloud.gpu.dao.VgpuProfileDao;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
@ -97,7 +113,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
@Inject
|
||||
protected AccountManager accountManager;
|
||||
@Inject
|
||||
private DomainDao domainDao;
|
||||
protected DomainDao domainDao;
|
||||
@Inject
|
||||
private DataCenterDao dcDao;
|
||||
@Inject
|
||||
@ -125,7 +141,19 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
@Inject
|
||||
private UserVmManager userVmManager;
|
||||
@Inject
|
||||
protected UserVmDao userVmDao;
|
||||
@Inject
|
||||
protected ProjectDao projectDao;
|
||||
@Inject
|
||||
protected ClusterDao clusterDao;
|
||||
@Inject
|
||||
protected DataCenterDao dataCenterDao;
|
||||
@Inject
|
||||
protected HostPodDao hostPodDao;
|
||||
@Inject
|
||||
private ConfigurationManager configurationManager;
|
||||
@Inject
|
||||
ResourceTagDao tagsDao;
|
||||
|
||||
public static ConfigKey<Boolean> VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.min.memory.equals.memory.divided.by.mem.overprovisioning.factor", "true",
|
||||
"If we set this to 'true', a minimum memory (memory/ mem.overprovisioning.factor) will be set to the VM, independent of using a scalable service offering or not.", true, ConfigKey.Scope.Cluster);
|
||||
@ -470,4 +498,144 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
logger.error("Unsupported operation: cannot remove template file");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates VirtualMachineMetadataTO object from VirtualMachineProfile
|
||||
* It is a helper function to be used in the inherited classes to avoid repetition
|
||||
* while generating metadata for multiple Guru implementations
|
||||
*
|
||||
* @param vmProfile virtual machine profile object
|
||||
* @return A VirtualMachineMetadataTO ready to be appended to VirtualMachineTO object
|
||||
* @see KVMGuru
|
||||
*/
|
||||
protected VirtualMachineMetadataTO makeVirtualMachineMetadata(VirtualMachineProfile vmProfile) {
|
||||
String vmName = "unknown",
|
||||
instanceName = "unknown",
|
||||
displayName = "unknown",
|
||||
instanceUuid = "unknown",
|
||||
clusterName = "unknown",
|
||||
clusterUuid = "unknown",
|
||||
zoneUuid = "unknown",
|
||||
zoneName = "unknown",
|
||||
podUuid = "unknown",
|
||||
podName = "unknown",
|
||||
domainUuid = "unknown",
|
||||
domainName = "unknown",
|
||||
accountUuid = "unknown",
|
||||
accountName = "unknown",
|
||||
projectName = "", // the project can be empty
|
||||
projectUuid = "", // the project can be empty
|
||||
serviceOfferingName = "unknown";
|
||||
long created = 0L;
|
||||
Integer cpuCores = -1, memory = -1;
|
||||
List<String> serviceOfferingTags = new ArrayList<>();
|
||||
HashMap<String, String> resourceTags = new HashMap<>();
|
||||
|
||||
UserVmVO vmVO = userVmDao.findById(vmProfile.getVirtualMachine().getId());
|
||||
if (vmVO != null) {
|
||||
instanceUuid = vmVO.getUuid();
|
||||
vmName = vmVO.getHostName(); // this returns the VM name field
|
||||
instanceName = vmVO.getInstanceName();
|
||||
displayName = vmVO.getDisplayName();
|
||||
created = vmVO.getCreated().getTime() / 1000L;
|
||||
|
||||
HostVO host = hostDao.findById(vmVO.getHostId());
|
||||
if (host != null) {
|
||||
// Find zone and cluster
|
||||
Long clusterId = host.getClusterId();
|
||||
ClusterVO cluster = clusterDao.findById(clusterId);
|
||||
|
||||
if (cluster != null) {
|
||||
clusterName = cluster.getName();
|
||||
clusterUuid = cluster.getUuid();
|
||||
|
||||
DataCenterVO zone = dataCenterDao.findById(cluster.getDataCenterId());
|
||||
if (zone != null) {
|
||||
zoneUuid = zone.getUuid();
|
||||
zoneName = zone.getName();
|
||||
}
|
||||
|
||||
HostPodVO pod = hostPodDao.findById(cluster.getPodId());
|
||||
if (pod != null) {
|
||||
podUuid = pod.getUuid();
|
||||
podName = pod.getName();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("Could not find the Host object for the virtual machine (null value returned). Libvirt metadata for cluster, pod, zone will not be populated.");
|
||||
}
|
||||
|
||||
DomainVO domain = domainDao.findById(vmVO.getDomainId());
|
||||
if (domain != null) {
|
||||
domainUuid = domain.getUuid();
|
||||
domainName = domain.getName();
|
||||
} else {
|
||||
logger.warn("Could not find the Domain object for the virtual machine (null value returned). Libvirt metadata for domain will not be populated.");
|
||||
}
|
||||
|
||||
Account account = accountManager.getAccount(vmVO.getAccountId());
|
||||
if (account != null) {
|
||||
accountUuid = account.getUuid();
|
||||
accountName = account.getName();
|
||||
|
||||
ProjectVO project = projectDao.findByProjectAccountId(account.getId());
|
||||
if (project != null) {
|
||||
projectName = project.getName();
|
||||
projectUuid = project.getUuid();
|
||||
}
|
||||
} else {
|
||||
logger.warn("Could not find the Account object for the virtual machine (null value returned). Libvirt metadata for account and project will not be populated.");
|
||||
}
|
||||
|
||||
List<? extends ResourceTag> resourceTagsList = tagsDao.listBy(vmVO.getId(), ResourceTag.ResourceObjectType.UserVm);
|
||||
if (resourceTagsList != null) {
|
||||
for (ResourceTag tag : resourceTagsList) {
|
||||
resourceTags.put(tag.getKey(), tag.getValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("Could not find the VirtualMachine object by its profile (null value returned). Libvirt metadata will not be populated.");
|
||||
}
|
||||
|
||||
ServiceOffering serviceOffering = vmProfile.getServiceOffering();
|
||||
if (serviceOffering != null) {
|
||||
serviceOfferingName = serviceOffering.getName();
|
||||
cpuCores = serviceOffering.getCpu();
|
||||
memory = serviceOffering.getRamSize();
|
||||
|
||||
String hostTagsCommaSeparated = serviceOffering.getHostTag();
|
||||
if (hostTagsCommaSeparated != null) { // when service offering has no host tags, this value is null
|
||||
serviceOfferingTags = Arrays.asList(hostTagsCommaSeparated.split(","));
|
||||
}
|
||||
} else {
|
||||
logger.warn("Could not find the ServiceOffering object by its profile (null value returned). Libvirt metadata for service offering will not be populated.");
|
||||
}
|
||||
|
||||
|
||||
return new VirtualMachineMetadataTO(
|
||||
vmName, // name
|
||||
instanceName, // internalName
|
||||
displayName, // displayName
|
||||
instanceUuid , // instanceUUID
|
||||
cpuCores, // cpuCores
|
||||
memory, // memory
|
||||
created, // created, unix epoch in seconds
|
||||
System.currentTimeMillis() / 1000L, // started, unix epoch in seconds
|
||||
domainUuid, // ownerDomainUUID
|
||||
domainName, // ownerDomainName
|
||||
accountUuid, // ownerAccountUUID
|
||||
accountName, // ownerAccountName
|
||||
projectUuid,
|
||||
projectName,
|
||||
serviceOfferingName,
|
||||
serviceOfferingTags, // serviceOfferingTags
|
||||
zoneName,
|
||||
zoneUuid,
|
||||
podName,
|
||||
podUuid,
|
||||
clusterName,
|
||||
clusterUuid,
|
||||
resourceTags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +155,6 @@ public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public VirtualMachineTO implement(VirtualMachineProfile vm) {
|
||||
VirtualMachineTO to = toVirtualMachineTO(vm);
|
||||
setVmQuotaPercentage(to, vm);
|
||||
@ -170,6 +169,9 @@ public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||
configureVmOsDescription(virtualMachine, to, host);
|
||||
|
||||
configureVmMemoryAndCpuCores(to, host, virtualMachine, vm);
|
||||
|
||||
to.setMetadata(makeVirtualMachineMetadata(vm));
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user