/*
* This file is part of LCMC written by Rasto Levrinc.
*
* Copyright (C) 2015, Rastislav Levrinc.
*
* The LCMC is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The LCMC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LCMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package lcmc.vm.domain;
import com.google.common.collect.Maps;
import lcmc.common.domain.StringValue;
import lcmc.common.domain.Value;
import lcmc.common.domain.XMLTools;
import lcmc.common.domain.util.Tools;
import lcmc.host.domain.Host;
import lcmc.logger.Logger;
import lcmc.logger.LoggerFactory;
import lcmc.vm.domain.data.DiskData;
import lcmc.vm.domain.data.DomainData;
import lcmc.vm.domain.data.FilesystemData;
import lcmc.vm.domain.data.GraphicsData;
import lcmc.vm.domain.data.InputDevData;
import lcmc.vm.domain.data.InterfaceData;
import lcmc.vm.domain.data.ParallelData;
import lcmc.vm.domain.data.SerialData;
import lcmc.vm.domain.data.SoundData;
import lcmc.vm.domain.data.VideoData;
import lombok.val;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Optional;
@Named
public class VMParser {
private static final Logger LOG = LoggerFactory.getLogger(VMParser.class);
private static final Pattern DISPLAY_PATTERN = Pattern.compile(".*:(\\d+)$");
private final Map<String, DomainData> domainDataMap = Maps.newHashMap();
private final Collection<String> domainNames = new ArrayList<String>();
private final Map<Value, String> configsToNames = new HashMap<Value, String>();
private final Collection<String> usedMacAddresses = new HashSet<String>();
private final Collection<String> sourceFileDirs = new TreeSet<String>();
private DomainData getDomainData(final String domainName) {
DomainData domainData = domainDataMap.get(domainName);
if (domainData == null) {
domainData = new DomainData(domainName);
domainDataMap.put(domainName, domainData);
}
return domainData;
}
public void parseVM(final Node vmNode, final Host definedOnHost, final Map<String, String> namesToConfigs) {
/* one vm */
if (vmNode == null) {
return;
}
final Node infoNode = XMLTools.getChildNode(vmNode, "info");
final String domainName = XMLTools.getAttribute(vmNode, VMParams.VM_PARAM_NAME);
final String autostart = XMLTools.getAttribute(vmNode, VMParams.VM_PARAM_AUTOSTART);
final String virshOptions = XMLTools.getAttribute(vmNode, VMParams.VM_PARAM_VIRSH_OPTIONS);
val domainData = getDomainData(domainName);
if (virshOptions != null) {
domainData.setParameter(VMParams.VM_PARAM_VIRSH_OPTIONS, virshOptions);
}
if (autostart != null && "True".equals(autostart)) {
domainData.setParameter(VMParams.VM_PARAM_AUTOSTART, definedOnHost.getName());
} else {
domainData.removeParameter(VMParams.VM_PARAM_AUTOSTART);
}
if (infoNode != null) {
parseInfo(domainName, XMLTools.getText(infoNode));
}
final Node vncdisplayNode = XMLTools.getChildNode(vmNode, "vncdisplay");
domainData.setRemotePort(-1);
if (vncdisplayNode != null) {
final String vncdisplay = XMLTools.getText(vncdisplayNode).trim();
final Matcher m = DISPLAY_PATTERN.matcher(vncdisplay);
if (m.matches()) {
domainData.setRemotePort(Integer.parseInt(m.group(1)) + 5900);
}
}
final Node configNode = XMLTools.getChildNode(vmNode, "config");
final String type = parseConfig(configNode, domainName);
final String configName = VmsXml.getConfigName(type, domainName);
configsToNames.put(new StringValue(configName), domainName);
namesToConfigs.put(domainName, configName);
}
public String getValue(final String name, final String param) {
return getDomainData(name).getValue(param);
}
public Map<String, DiskData> getDisks(final String name) {
return getDomainData(name).getDisksMap();
}
public Map<String, FilesystemData> getFilesystems(final String name) {
return getDomainData(name).getFilesystemsMap();
}
public Map<String, InterfaceData> getInterfaces(final String name) {
return getDomainData(name).getInterfacesMap();
}
public Map<String, InputDevData> getInputDevs(final String name) {
return getDomainData(name).getInputDevsMap();
}
public Map<String, GraphicsData> getGraphicDisplays(final String name) {
return getDomainData(name).getGraphicsDevsMap();
}
public Map<String, SoundData> getSounds(final String name) {
return getDomainData(name).getSoundsMap();
}
public Map<String, SerialData> getSerials(final String name) {
return getDomainData(name).getSerialsMap();
}
public Map<String, ParallelData> getParallels(final String name) {
return getDomainData(name).getParallelsMap();
}
public Map<String, VideoData> getVideos(final String name) {
return getDomainData(name).getVideosMap();
}
public Collection<String> getDomainNames() {
return domainNames;
}
public int getRemotePort(final String domainName) {
final Integer port = getDomainData(domainName).getRemotePort();
if (port == null) {
return -1;
} else {
return port;
}
}
public Collection<Value> getConfigs() {
return configsToNames.keySet();
}
public String getNameFromConfig(final String config) {
return configsToNames.get(new StringValue(config));
}
public boolean isRunning(final String domainName) {
final Boolean running = getDomainData(domainName).isRunning();
if (running != null) {
return running;
}
return false;
}
public boolean isSuspended(final String domainName) {
final Boolean suspended = getDomainData(domainName).isSuspended();
if (suspended != null) {
return suspended;
}
return false;
}
/** Return set of mac addresses. */
public Collection<String> getUsedMacAddresses() {
return usedMacAddresses;
}
public Iterable<String> getSourceFileDirs() {
return sourceFileDirs;
}
/** Updates all data for this domain. */
private void parseInfo(final String domainName, final String info) {
if (info != null) {
boolean running = false;
boolean suspended = false;
for (final String line : info.split("\n")) {
final String[] optionValue = line.split(":");
if (optionValue.length == 2) {
final String option = optionValue[0].trim();
final String value = optionValue[1].trim();
if ("State".equals(option)) {
if ("running".equals(value) || "idle".equals(value)) {
running = true;
suspended = false;
} else if ("paused".equals(value)) {
running = true;
suspended = true;
}
}
}
}
val domainData = getDomainData(domainName);
domainData.setRunning(running);
domainData.setSuspended(suspended);
}
}
/** Parses the libvirt config file. */
private String parseConfig(final Node configNode, final String nameInFilename) {
if (configNode == null) {
return null;
}
final Node domainNode = XMLTools.getChildNode(configNode, "domain");
if (domainNode == null) {
return null;
}
final String domainType = XMLTools.getAttribute(domainNode, "type");
final NodeList options = domainNode.getChildNodes();
boolean tabletOk = false;
Optional<DomainData> domainData = Optional.absent();
for (int i = 0; i < options.getLength(); i++) {
final Node option = options.item(i);
if (VMParams.VM_PARAM_NAME.equals(option.getNodeName())) {
final String domainName = XMLTools.getText(option);
domainData = Optional.of(getDomainData(domainName));
if (!domainNames.contains(domainName)) {
domainNames.add(domainName);
}
domainData.get().setParameter(VMParams.VM_PARAM_NAME, domainName);
domainData.get().setParameter(VMParams.VM_PARAM_DOMAIN_TYPE, domainType);
if (!domainName.equals(nameInFilename)) {
LOG.appWarning("parseConfig: unexpected name: " + domainName + " != " + nameInFilename);
return domainType;
}
} else if (VMParams.VM_PARAM_UUID.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_UUID, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_VCPU.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_VCPU, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_BOOTLOADER.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_BOOTLOADER, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_CURRENTMEMORY.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_CURRENTMEMORY, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_MEMORY.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_MEMORY, XMLTools.getText(option));
} else if ("os".equals(option.getNodeName())) {
final NodeList osOptions = option.getChildNodes();
int bootOption = 0;
for (int j = 0; j < osOptions.getLength(); j++) {
final Node osOption = osOptions.item(j);
if (VMParams.OS_BOOT_NODE.equals(osOption.getNodeName())) {
if (bootOption == 0) {
domainData.get().setParameter(VMParams.VM_PARAM_BOOT, XMLTools.getAttribute(osOption, VMParams.OS_BOOT_NODE_DEV));
} else {
domainData.get().setParameter(VMParams.VM_PARAM_BOOT_2, XMLTools.getAttribute(osOption, VMParams.OS_BOOT_NODE_DEV));
}
bootOption++;
} else if (VMParams.VM_PARAM_LOADER.equals(osOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_LOADER, XMLTools.getText(osOption));
} else if (VMParams.VM_PARAM_TYPE.equals(osOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_TYPE, XMLTools.getText(osOption));
domainData.get().setParameter(VMParams.VM_PARAM_TYPE_ARCH, XMLTools.getAttribute(osOption, "arch"));
domainData.get().setParameter(VMParams.VM_PARAM_TYPE_MACHINE, XMLTools.getAttribute(osOption, "machine"));
} else if (VMParams.VM_PARAM_INIT.equals(osOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_INIT, XMLTools.getText(osOption));
} else {
domainData.get().setParameter(osOption.getNodeName(), XMLTools.getText(osOption));
}
}
} else if ("features".equals(option.getNodeName())) {
final NodeList ftrOptions = option.getChildNodes();
for (int j = 0; j < ftrOptions.getLength(); j++) {
final Node ftrOption = ftrOptions.item(j);
if (VMParams.VM_PARAM_ACPI.equals(ftrOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_ACPI, "True");
} else if (VMParams.VM_PARAM_APIC.equals(ftrOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_APIC, "True");
} else if (VMParams.VM_PARAM_PAE.equals(ftrOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_PAE, "True");
} else if (VMParams.VM_PARAM_HAP.equals(ftrOption.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_HAP, "True");
}
}
} else if ("clock".equals(option.getNodeName())) {
final String offset = XMLTools.getAttribute(option, "offset");
domainData.get().setParameter(VMParams.VM_PARAM_CLOCK_OFFSET, offset);
} else if ("cpu".equals(option.getNodeName())) {
final String match = XMLTools.getAttribute(option, "match");
if (!"".equals(match)) {
domainData.get().setParameter(VMParams.VM_PARAM_CPU_MATCH, match);
final NodeList cpuMatchOptions = option.getChildNodes();
String policy = "";
final Collection<String> features = new ArrayList<String>();
for (int j = 0; j < cpuMatchOptions.getLength(); j++) {
final Node cpuMatchOption = cpuMatchOptions.item(j);
final String op = cpuMatchOption.getNodeName();
if ("topology".equals(op)) {
domainData.get().setParameter(
VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_SOCKETS,
XMLTools.getAttribute(cpuMatchOption, VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_SOCKETS));
domainData.get().setParameter(
VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_CORES,
XMLTools.getAttribute(cpuMatchOption, VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_CORES));
domainData.get().setParameter(
VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_THREADS,
XMLTools.getAttribute(cpuMatchOption, VMParams.VM_PARAM_CPUMATCH_TOPOLOGY_THREADS));
} else if ("feature".equals(op)) {
/* asuming the same policy for all */
policy = XMLTools.getAttribute(cpuMatchOption, VMParams.VM_PARAM_CPUMATCH_FEATURE_POLICY);
features.add(XMLTools.getAttribute(cpuMatchOption, "name"));
} else {
domainData.get().setParameter(op, XMLTools.getText(cpuMatchOption));
}
}
if (!"".equals(policy) && !features.isEmpty()) {
domainData.get().setParameter(VMParams.VM_PARAM_CPUMATCH_FEATURE_POLICY, policy);
domainData.get().setParameter(VMParams.VM_PARAM_CPUMATCH_FEATURES, Tools.join(" ", features));
}
}
} else if (VMParams.VM_PARAM_ON_POWEROFF.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_ON_POWEROFF, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_ON_REBOOT.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_ON_REBOOT, XMLTools.getText(option));
} else if (VMParams.VM_PARAM_ON_CRASH.equals(option.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_ON_CRASH, XMLTools.getText(option));
} else if ("devices".equals(option.getNodeName())) {
final Map<String, DiskData> devMap = new LinkedHashMap<String, DiskData>();
final Map<String, FilesystemData> fsMap = new LinkedHashMap<String, FilesystemData>();
final Map<String, InterfaceData> macMap = new LinkedHashMap<String, InterfaceData>();
final Map<String, InputDevData> inputMap = new LinkedHashMap<String, InputDevData>();
final Map<String, GraphicsData> graphicsMap = new LinkedHashMap<String, GraphicsData>();
final Map<String, SoundData> soundMap = new LinkedHashMap<String, SoundData>();
final Map<String, SerialData> serialMap = new LinkedHashMap<String, SerialData>();
final Map<String, ParallelData> parallelMap = new LinkedHashMap<String, ParallelData>();
final Map<String, VideoData> videoMap = new LinkedHashMap<String, VideoData>();
final NodeList devices = option.getChildNodes();
for (int j = 0; j < devices.getLength(); j++) {
final Node deviceNode = devices.item(j);
if ("emulator".equals(deviceNode.getNodeName())) {
domainData.get().setParameter(VMParams.VM_PARAM_EMULATOR, XMLTools.getText(deviceNode));
} else if ("input".equals(deviceNode.getNodeName())) {
final String type = XMLTools.getAttribute(deviceNode, "type");
final String bus = XMLTools.getAttribute(deviceNode, "bus");
if ("tablet".equals(type)) {
tabletOk = true;
}
final InputDevData inputDevData = new InputDevData(type, bus);
inputMap.put(type + " : " + bus, inputDevData);
} else if ("graphics".equals(deviceNode.getNodeName())) {
/** remotePort will be overwritten with virsh output */
final String type = XMLTools.getAttribute(deviceNode, "type");
final String port = XMLTools.getAttribute(deviceNode, "port");
final String autoport = XMLTools.getAttribute(deviceNode, "autoport");
final String listen = XMLTools.getAttribute(deviceNode, "listen");
final String passwd = XMLTools.getAttribute(deviceNode, "passwd");
final String keymap = XMLTools.getAttribute(deviceNode, "keymap");
final String display = XMLTools.getAttribute(deviceNode, "display");
final String xauth = XMLTools.getAttribute(deviceNode, "xauth");
LOG.debug2("parseConfig: type: " + type);
LOG.debug2("parseConfig: port: " + port);
LOG.debug2("parseConfig: autoport: " + autoport);
if ("vnc".equals(type)) {
if (port != null && Tools.isNumber(port)) {
domainData.get().setRemotePort(Integer.parseInt(port));
}
if ("yes".equals(autoport)) {
domainData.get().setAutoport(true);
} else {
domainData.get().setAutoport(false);
}
}
final GraphicsData graphicsData =
new GraphicsData(type, port, listen, passwd, keymap, display, xauth);
graphicsMap.put(VmsXml.graphicsDisplayName(type, port, display), graphicsData);
} else if ("disk".equals(deviceNode.getNodeName())) {
parseDiskNode(deviceNode, devMap);
} else if ("filesystem".equals(deviceNode.getNodeName())) {
final String type = XMLTools.getAttribute(deviceNode, "type");
final NodeList opts = deviceNode.getChildNodes();
String sourceDir = null;
String sourceName = null;
String targetDir = null;
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("source".equals(nodeName)) {
sourceDir = XMLTools.getAttribute(optionNode, "dir");
sourceName = XMLTools.getAttribute(optionNode, "name");
} else if ("target".equals(nodeName)) {
targetDir = XMLTools.getAttribute(optionNode, "dir");
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown fs option: " + nodeName);
}
}
if (targetDir != null) {
final FilesystemData filesystemData =
new FilesystemData(type, sourceDir, sourceName, targetDir);
fsMap.put(targetDir, filesystemData);
}
} else if ("interface".equals(deviceNode.getNodeName())) {
final String type = XMLTools.getAttribute(deviceNode, "type");
String macAddress = null;
String sourceNetwork = null;
String sourceBridge = null;
String targetDev = null;
String modelType = null;
String scriptPath = null;
final NodeList opts = deviceNode.getChildNodes();
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("source".equals(nodeName)) {
sourceBridge = XMLTools.getAttribute(optionNode, "bridge");
sourceNetwork = XMLTools.getAttribute(optionNode, "network");
} else if ("target".equals(nodeName)) {
targetDev = XMLTools.getAttribute(optionNode, "dev");
} else if ("mac".equals(nodeName)) {
macAddress = XMLTools.getAttribute(optionNode, "address");
} else if ("model".equals(nodeName)) {
modelType = XMLTools.getAttribute(optionNode, "type");
} else if ("script".equals(nodeName)) {
scriptPath = XMLTools.getAttribute(optionNode, "path");
} else if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown interface option: " + nodeName);
}
}
if (macAddress != null) {
final InterfaceData interfaceData = new InterfaceData(type,
macAddress,
sourceNetwork,
sourceBridge,
targetDev,
modelType,
scriptPath);
macMap.put(macAddress, interfaceData);
usedMacAddresses.add(macAddress);
}
} else if ("sound".equals(deviceNode.getNodeName())) {
final String model = XMLTools.getAttribute(deviceNode, "model");
final NodeList opts = deviceNode.getChildNodes();
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown sound option: " + nodeName);
}
}
if (model != null) {
final SoundData soundData = new SoundData(model);
soundMap.put(model, soundData);
}
} else if ("serial".equals(deviceNode.getNodeName())) {
final String type = XMLTools.getAttribute(deviceNode, "type");
final NodeList opts = deviceNode.getChildNodes();
String sourcePath = null;
String bindSourceMode = null;
String bindSourceHost = null;
String bindSourceService = null;
String connectSourceMode = null;
String connectSourceHost = null;
String connectSourceService = null;
String protocolType = null;
String targetPort = null;
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("source".equals(nodeName)) {
sourcePath = XMLTools.getAttribute(optionNode, "path");
final String sourceMode = XMLTools.getAttribute(optionNode, "mode");
if ("bind".equals(sourceMode)) {
bindSourceMode = sourceMode;
bindSourceHost = XMLTools.getAttribute(optionNode, "host");
bindSourceService = XMLTools.getAttribute(optionNode, "service");
} else if ("connect".equals(sourceMode)) {
connectSourceMode = sourceMode;
connectSourceHost = XMLTools.getAttribute(optionNode, "host");
connectSourceService = XMLTools.getAttribute(optionNode, "service");
} else {
LOG.appWarning("parseConfig: uknown source mode: " + sourceMode);
}
} else if ("protocol".equals(nodeName)) {
protocolType = XMLTools.getAttribute(optionNode, "type");
} else if ("target".equals(nodeName)) {
targetPort = XMLTools.getAttribute(optionNode, "port");
} else if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown serial option: " + nodeName);
}
}
if (type != null) {
final SerialData serialData = new SerialData(type,
sourcePath,
bindSourceMode,
bindSourceHost,
bindSourceService,
connectSourceMode,
connectSourceHost,
connectSourceService,
protocolType,
targetPort);
serialMap.put("serial " + targetPort + " / " + type, serialData);
}
} else if ("parallel".equals(deviceNode.getNodeName())) {
final String type = XMLTools.getAttribute(deviceNode, "type");
final NodeList opts = deviceNode.getChildNodes();
String sourcePath = null;
String bindSourceMode = null;
String bindSourceHost = null;
String bindSourceService = null;
String connectSourceMode = null;
String connectSourceHost = null;
String connectSourceService = null;
String protocolType = null;
String targetPort = null;
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("source".equals(nodeName)) {
sourcePath = XMLTools.getAttribute(optionNode, "path");
final String sourceMode = XMLTools.getAttribute(optionNode, "mode");
if ("bind".equals(sourceMode)) {
bindSourceMode = sourceMode;
bindSourceHost = XMLTools.getAttribute(optionNode, "host");
bindSourceService = XMLTools.getAttribute(optionNode, "service");
} else if ("connect".equals(sourceMode)) {
connectSourceMode = sourceMode;
connectSourceHost = XMLTools.getAttribute(optionNode, "host");
connectSourceService = XMLTools.getAttribute(optionNode, "service");
} else {
LOG.appWarning("parseConfig: unknown source mode: " + sourceMode);
}
} else if ("protocol".equals(nodeName)) {
protocolType = XMLTools.getAttribute(optionNode, "type");
} else if ("target".equals(nodeName)) {
targetPort = XMLTools.getAttribute(optionNode, "port");
} else if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown parallel option: " + nodeName);
}
}
if (type != null) {
final ParallelData parallelData = new ParallelData(type,
sourcePath,
bindSourceMode,
bindSourceHost,
bindSourceService,
connectSourceMode,
connectSourceHost,
connectSourceService,
protocolType,
targetPort);
parallelMap.put("parallel " + targetPort + " / " + type, parallelData);
}
} else if ("video".equals(deviceNode.getNodeName())) {
final NodeList opts = deviceNode.getChildNodes();
String modelType = null;
String modelVRAM = null;
String modelHeads = null;
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("model".equals(nodeName)) {
modelType = XMLTools.getAttribute(optionNode, "type");
modelVRAM = XMLTools.getAttribute(optionNode, "vram");
modelHeads = XMLTools.getAttribute(optionNode, "heads");
} else if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseConfig: unknown video option: " + nodeName);
}
}
if (modelType != null) {
final VideoData videoData = new VideoData(modelType, modelVRAM, modelHeads);
videoMap.put(modelType, videoData);
}
} else if ("controller".equals(deviceNode.getNodeName())) {
/* it's generated, ignore */
} else if ("memballoon".equals(deviceNode.getNodeName())) {
/* it's generated, ignore */
} else if (!"#text".equals(deviceNode.getNodeName())) {
LOG.appWarning("parseConfig: unknown device: " + deviceNode.getNodeName());
}
}
domainData.get().setDisksMap(devMap);
domainData.get().setFilesystemsMap(fsMap);
domainData.get().setInterfacesMap(macMap);
domainData.get().setInputDevsMap(inputMap);
domainData.get().setGraphicsDevsMap(graphicsMap);
domainData.get().setSoundsMap(soundMap);
domainData.get().setSerialsMap(serialMap);
domainData.get().setParallelsMap(parallelMap);
domainData.get().setVideosMap(videoMap);
}
}
if (!tabletOk) {
LOG.appWarning("parseConfig: you should enable input type tablet for " + domainData.get().getDomainName());
}
return domainType;
}
/** Parse disk xml and populate the devMap. */
private void parseDiskNode(final Node diskNode, final Map<String, DiskData> devMap) {
final String type = XMLTools.getAttribute(diskNode, "type");
final String device = XMLTools.getAttribute(diskNode, "device");
final NodeList opts = diskNode.getChildNodes();
String sourceFile = null;
String sourceDev = null;
String sourceProtocol = null;
String sourceName = null;
final Collection<String> sourceHostNames = new ArrayList<String>();
final Collection<String> sourceHostPorts = new ArrayList<String>();
String authUsername = null;
String authSecretType = null;
String authSecretUuid = null;
String targetDev = null;
String targetBus = null;
String driverName = null;
String driverType = null;
String driverCache = null;
boolean readonly = false;
boolean shareable = false;
for (int k = 0; k < opts.getLength(); k++) {
final Node optionNode = opts.item(k);
final String nodeName = optionNode.getNodeName();
if ("source".equals(nodeName)) {
sourceFile = XMLTools.getAttribute(optionNode, "file");
final String dir = Tools.getDirectoryPart(sourceFile);
if (dir != null) {
sourceFileDirs.add(dir);
}
sourceDev = XMLTools.getAttribute(optionNode, "dev");
sourceProtocol = XMLTools.getAttribute(optionNode, "protocol");
sourceName = XMLTools.getAttribute(optionNode, "name");
getHostNodes(optionNode, sourceHostNames, sourceHostPorts);
} else if ("auth".equals(nodeName)) {
authUsername = XMLTools.getAttribute(optionNode, "username");
final Node secretN = XMLTools.getChildNode(optionNode, "secret");
if (secretN != null) {
authSecretType = XMLTools.getAttribute(secretN, "type");
authSecretUuid = XMLTools.getAttribute(secretN, "uuid");
}
} else if ("target".equals(nodeName)) {
targetDev = XMLTools.getAttribute(optionNode, "dev");
targetBus = XMLTools.getAttribute(optionNode, "bus");
} else if ("driver".equals(nodeName)) {
driverName = XMLTools.getAttribute(optionNode, "name");
driverType = XMLTools.getAttribute(optionNode, "type");
driverCache = XMLTools.getAttribute(optionNode, "cache");
} else if ("readonly".equals(nodeName)) {
readonly = true;
} else if ("shareable".equals(nodeName)) {
shareable = true;
} else if (VMParams.HW_ADDRESS.equals(nodeName)) {
/* it's generated, ignoring. */
} else if (!"#text".equals(nodeName)) {
LOG.appWarning("parseDiskNode: unknown disk option: " + nodeName);
}
}
if (targetDev != null) {
final DiskData diskData = new DiskData(type,
targetDev,
sourceFile,
sourceDev,
sourceProtocol,
sourceName,
Tools.join(", ", sourceHostNames),
Tools.join(", ", sourceHostPorts),
authUsername,
authSecretType,
authSecretUuid,
targetBus + '/' + device,
driverName,
driverType,
driverCache,
readonly,
shareable);
devMap.put(targetDev, diskData);
}
}
/**
* Zero, one or more host nodes.
*/
private void getHostNodes(final Node n, final Collection<String> names, final Collection<String> ports) {
final NodeList nodes = n.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
final Node hostN = nodes.item(i);
if ("host".equals(hostN.getNodeName())) {
names.add(XMLTools.getAttribute(hostN, "name"));
ports.add(XMLTools.getAttribute(hostN, "port"));
}
}
}
}