enhancement: add instance info as Libvirt metadata (#11061)

This commit is contained in:
Phsm Qwerty 2025-11-07 14:31:34 +01:00 committed by GitHub
parent a50de029bf
commit 8c86f24261
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 547 additions and 39 deletions

View File

@ -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; }
}

View File

@ -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);

View File

@ -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.
*/

View File

@ -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());
}

View File

@ -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
);
}
}

View File

@ -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;
}