CLOUDSTACK-9095 : Hypervisor changes to support UserData for Nuage VSP

This commit is contained in:
Nick Livens 2015-12-07 10:26:47 +01:00
parent f30fbe9a5c
commit 0957268e92
3 changed files with 103 additions and 11 deletions

View File

@ -2201,6 +2201,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
private void createVif(final LibvirtVMDef vm, final NicTO nic, final String nicAdapter) throws InternalErrorException, LibvirtException {
if (nic.getType().equals(TrafficType.Guest) && nic.getBroadcastType().equals(BroadcastDomainType.Vsp)) {
String vrIp = nic.getBroadcastUri().getPath().substring(1);
vm.getMetaData().getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension(nic.getMac(), vrIp);
if (s_logger.isDebugEnabled()) {
s_logger.debug("NIC with MAC " + nic.getMac() + " and BroadcastDomainType " + nic.getBroadcastType() + " in network(" + nic.getGateway() + "/" + nic.getNetmask()
+ ") is " + nic.getType() + " traffic type. So, vsp-vr-ip " + vrIp + " is set in the metadata");
}
}
vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getPlatformEmulator().toString(), nicAdapter).toString());
}

View File

@ -16,7 +16,9 @@
// under the License.
package com.cloud.hypervisor.kvm.resource;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.HashMap;
@ -24,6 +26,8 @@ import java.util.List;
import java.util.Map;
public class LibvirtVMDef {
private static final Logger s_logger = Logger.getLogger(LibvirtVMDef.class);
private String _hvsType;
private static long s_libvirtVersion;
private static long s_qemuVersion;
@ -1311,6 +1315,57 @@ public class LibvirtVMDef {
}
}
public static 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) {
s_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 NuageExtensionDef {
private Map<String, String> addresses = Maps.newHashMap();
public void addNuageExtension(String macAddress, String vrIp) {
addresses.put(macAddress, vrIp);
}
@Override
public String toString() {
StringBuilder fsBuilder = new StringBuilder();
for (Map.Entry<String, String> address : addresses.entrySet()) {
fsBuilder.append("<nuage-extension>\n")
.append(" <interface mac='")
.append(address.getKey())
.append("' vsp-vr-ip='")
.append(address.getValue())
.append("'></interface>\n")
.append("</nuage-extension>\n");
}
return fsBuilder.toString();
}
}
public void setHvsType(String hvs) {
_hvsType = hvs;
}
@ -1371,6 +1426,15 @@ 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();

View File

@ -937,8 +937,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
NicTO nicTo = cmd.getNic();
VirtualDevice nic;
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
String dvSwitchUuid = null;
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
String dvSwitchUuid;
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
@ -961,7 +961,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo);
setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
if (!vmMo.configureVm(vmConfigSpec)) {
throw new Exception("Failed to configure devices when running PlugNicCommand");
}
@ -1681,6 +1681,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
NiciraNvpApiVersion.logNiciraApiVersion();
Map<String, String> nicUuidToDvSwitchUuid = new HashMap<String, String>();
for (NicTO nicTo : sortNicsByDeviceId(nics)) {
s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
@ -1699,6 +1700,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
nic =
VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), nicUnitNumber++,
i + 1, true, true);
if (nicTo.getUuid() != null) {
nicUuidToDvSwitchUuid.put(nicTo.getUuid(), dvSwitchUuid);
}
} else {
s_logger.info("Preparing NIC device on network " + networkInfo.second());
nic =
@ -1735,7 +1739,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// pass boot arguments through machine.id & perform customized options to VMX
ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
configBasicExtraOption(extraOptions, vmSpec);
configNvpExtraOption(extraOptions, vmSpec);
configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
configCustomExtraOption(extraOptions, vmSpec);
// config VNC
@ -1945,7 +1949,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
extraOptions.add(newVal);
}
private static void configNvpExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
private static void configNvpExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec, Map<String, String> nicUuidToDvSwitchUuid) {
/**
* Extra Config : nvp.vm-uuid = uuid
* - Required for Nicira NVP integration
@ -1966,20 +1970,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
newVal.setKey("nvp.iface-id." + nicNum);
newVal.setValue(nicTo.getUuid());
extraOptions.add(newVal);
setNuageVspVrIpInExtraConfig(extraOptions, nicTo);
setNuageVspVrIpInExtraConfig(extraOptions, nicTo, nicUuidToDvSwitchUuid.get(nicTo.getUuid()));
}
nicNum++;
}
}
private static void setNuageVspVrIpInExtraConfig(List<OptionValue> extraOptions, NicTO nicTo) {
URI broadcastUri = nicTo.getBroadcastUri();
if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) {
String path = broadcastUri.getPath();
OptionValue newVal = new OptionValue();
private static void setNuageVspVrIpInExtraConfig(List<OptionValue> extraOptions, NicTO nicTo, String dvSwitchUuid) {
if (nicTo.getBroadcastType() != BroadcastDomainType.Vsp) {
return;
}
OptionValue newVal;
if (nicTo.getType().equals(TrafficType.Guest) && dvSwitchUuid != null && nicTo.getGateway() != null && nicTo.getNetmask() != null) {
String vrIp = nicTo.getBroadcastUri().getPath().substring(1);
newVal = new OptionValue();
newVal.setKey("vsp.vr-ip." + nicTo.getMac());
newVal.setValue(path.substring(1));
newVal.setValue(vrIp);
extraOptions.add(newVal);
newVal = new OptionValue();
newVal.setKey("vsp.dvswitch." + nicTo.getMac());
newVal.setValue(dvSwitchUuid);
extraOptions.add(newVal);
if (s_logger.isDebugEnabled()) {
s_logger.debug("NIC with MAC " + nicTo.getMac() + " and BroadcastDomainType " + nicTo.getBroadcastType() + " in network(" + nicTo.getGateway() + "/"
+ nicTo.getNetmask() + ") is " + nicTo.getType() + " traffic type. So, vsp-vr-ip is set in the extraconfig");
}
}
}