mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-6106 supporting VPC VR on Hyper-V
This commit is contained in:
parent
794b38a789
commit
1b4325d2c8
|
|
@ -21,6 +21,7 @@ public class ModifyVmNicConfigCommand extends Command {
|
|||
String vmName;
|
||||
int vlan;
|
||||
String macAddress;
|
||||
int index;
|
||||
protected ModifyVmNicConfigCommand() {
|
||||
}
|
||||
|
||||
|
|
@ -30,6 +31,12 @@ public class ModifyVmNicConfigCommand extends Command {
|
|||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public ModifyVmNicConfigCommand(String vmName, int vlan, int position) {
|
||||
this.vmName = vmName;
|
||||
this.vlan = vlan;
|
||||
this.index = position;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import com.cloud.storage.dao.GuestOSDao;
|
|||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.hypervisor.hyperv.manager.HypervManager;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
|
|
@ -74,16 +75,20 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
if(vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
|
||||
|
||||
NicProfile publicNicProfile = null;
|
||||
NicProfile controlNicProfile = null;
|
||||
NicProfile profile = null;
|
||||
for(NicProfile nicProfile : nicProfiles) {
|
||||
if(nicProfile.getTrafficType() == TrafficType.Public) {
|
||||
publicNicProfile = nicProfile;
|
||||
break;
|
||||
}
|
||||
else if (nicProfile.getTrafficType() == TrafficType.Control) {
|
||||
controlNicProfile = nicProfile;
|
||||
}
|
||||
}
|
||||
|
||||
if(publicNicProfile != null) {
|
||||
if(publicNicProfile != null || controlNicProfile != null) {
|
||||
NicTO[] nics = to.getNics();
|
||||
|
||||
// reserve extra NICs
|
||||
NicTO[] expandedNics = new NicTO[MaxNicSupported];
|
||||
int i = 0;
|
||||
|
|
@ -95,18 +100,27 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
}
|
||||
deviceId++;
|
||||
|
||||
long networkId = publicNicProfile.getNetworkId();
|
||||
long networkId = 0;
|
||||
if(publicNicProfile != null ) {
|
||||
networkId= publicNicProfile.getNetworkId();
|
||||
profile = publicNicProfile;
|
||||
}
|
||||
else {
|
||||
networkId = controlNicProfile.getNetworkId();
|
||||
profile = controlNicProfile;
|
||||
}
|
||||
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
// for Hyperv Hot Nic plug is not supported and it will support upto 8 nics.
|
||||
// creating the VR with extra nics (actual nics(3) + extra nics) will be 8
|
||||
for(; i < MaxNicSupported; i++) {
|
||||
NicTO nicTo = new NicTO();
|
||||
nicTo.setDeviceId(deviceId++);
|
||||
nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
|
||||
nicTo.setType(publicNicProfile.getTrafficType());
|
||||
nicTo.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
nicTo.setType(TrafficType.Public);
|
||||
nicTo.setIp("0.0.0.0");
|
||||
nicTo.setNetmask("255.255.255.255");
|
||||
nicTo.setName(publicNicProfile.getName());
|
||||
nicTo.setName(profile.getName());
|
||||
|
||||
try {
|
||||
String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
|
||||
|
|
@ -114,16 +128,16 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
} catch (InsufficientAddressCapacityException e) {
|
||||
throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
|
||||
}
|
||||
nicTo.setDns1(publicNicProfile.getDns1());
|
||||
nicTo.setDns2(publicNicProfile.getDns2());
|
||||
if (publicNicProfile.getGateway() != null) {
|
||||
nicTo.setDns1(profile.getDns1());
|
||||
nicTo.setDns2(profile.getDns2());
|
||||
if (publicNicProfile != null && publicNicProfile.getGateway() != null) {
|
||||
nicTo.setGateway(publicNicProfile.getGateway());
|
||||
} else {
|
||||
nicTo.setGateway(network.getGateway());
|
||||
}
|
||||
nicTo.setDefaultNic(false);
|
||||
nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
|
||||
nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
|
||||
nicTo.setBroadcastUri(profile.getBroadCastUri());
|
||||
nicTo.setIsolationuri(profile.getIsolationUri());
|
||||
|
||||
Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
|
||||
nicTo.setNetworkRateMbps(networkRate);
|
||||
|
|
@ -137,9 +151,12 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
|
|||
for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
|
||||
sbMacSequence.append(nicTo.getMac()).append("|");
|
||||
}
|
||||
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
|
||||
String bootArgs = to.getBootArgs();
|
||||
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
|
||||
|
||||
if (!sbMacSequence.toString().isEmpty()) {
|
||||
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
|
||||
String bootArgs = to.getBootArgs();
|
||||
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,10 +83,14 @@ import com.cloud.agent.api.NetworkUsageCommand;
|
|||
import com.cloud.agent.api.PingCommand;
|
||||
import com.cloud.agent.api.PingRoutingCommand;
|
||||
import com.cloud.agent.api.PingTestCommand;
|
||||
import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.SetupGuestNetworkCommand;
|
||||
import com.cloud.agent.api.StartCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.UnPlugNicAnswer;
|
||||
import com.cloud.agent.api.UnPlugNicCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand.VmState;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.UnsupportedAnswer;
|
||||
|
|
@ -172,7 +176,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
protected final int _retry = 24;
|
||||
protected final int _sleep = 10000;
|
||||
protected static final int DEFAULT_DOMR_SSHPORT = 3922;
|
||||
|
||||
private final int maxid = 4094;
|
||||
private String _clusterGuid;
|
||||
|
||||
// Used by initialize to assert object configured before
|
||||
|
|
@ -477,7 +481,12 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
answer = execute((SetStaticRouteCommand) cmd);
|
||||
} else if (clazz == SetMonitorServiceCommand.class) {
|
||||
answer = execute((SetMonitorServiceCommand) cmd);
|
||||
} else {
|
||||
} else if (clazz == PlugNicCommand.class) {
|
||||
answer = execute((PlugNicCommand)cmd);
|
||||
} else if (clazz == UnPlugNicCommand.class) {
|
||||
answer = execute((UnPlugNicCommand)cmd);
|
||||
}
|
||||
else {
|
||||
if (clazz == StartCommand.class) {
|
||||
VirtualMachineTO vmSpec = ((StartCommand)cmd).getVirtualMachine();
|
||||
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
||||
|
|
@ -509,6 +518,59 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
return answer;
|
||||
}
|
||||
|
||||
|
||||
private PlugNicAnswer execute(PlugNicCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource PlugNicCommand " + s_gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
String vmName = cmd.getVmName();
|
||||
NicTO nic = cmd.getNic();
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
|
||||
throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + nic.getBroadcastUri());
|
||||
}
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int publicNicInfo = -1;
|
||||
publicNicInfo = getVmNics(vmName, maxid);
|
||||
if (publicNicInfo > 0) {
|
||||
modifyNicVlan(vmName, vlanId, publicNicInfo);
|
||||
}
|
||||
return new PlugNicAnswer(cmd, true, "success");
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Unexpected exception: ", e);
|
||||
return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource UnPlugNicCommand " + s_gson.toJson(cmd));
|
||||
}
|
||||
|
||||
try {
|
||||
String vmName = cmd.getVmName();
|
||||
NicTO nic = cmd.getNic();
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
|
||||
throw new InternalErrorException("Unable to unassign a public IP to a VIF on network " + nic.getBroadcastUri());
|
||||
}
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int publicNicInfo = -1;
|
||||
publicNicInfo = getVmNics(vmName, vlanId);
|
||||
if (publicNicInfo > 0) {
|
||||
modifyNicVlan(vmName, maxid, publicNicInfo);
|
||||
}
|
||||
return new UnPlugNicAnswer(cmd, true, "success");
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Unexpected exception: ", e);
|
||||
return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionResult executeInVR(String routerIP, String script, String args) {
|
||||
Pair<Boolean, String> result;
|
||||
|
|
@ -621,14 +683,18 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
|
||||
protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
|
||||
NicTO nic = cmd.getNic();
|
||||
String routerIp = getRouterSshControlIp(cmd);
|
||||
String domrName =
|
||||
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
|
||||
try {
|
||||
int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp,
|
||||
nic.getMac());
|
||||
nic.setDeviceId(ethDeviceNum);
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int ethDeviceNum = getVmNics(domrName, vlanId);
|
||||
if (ethDeviceNum > 0) {
|
||||
nic.setDeviceId(ethDeviceNum);
|
||||
} else {
|
||||
return new ExecutionResult(false, "Prepare SetupGuestNetwork failed due to unable to find the nic");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
|
||||
s_logger.warn(msg, e);
|
||||
|
|
@ -640,23 +706,27 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
|
||||
private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
|
||||
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
String routerIp = getRouterSshControlIp(cmd);
|
||||
|
||||
try {
|
||||
IpAddressTO[] ips = cmd.getIpAddresses();
|
||||
for (IpAddressTO ip : ips) {
|
||||
|
||||
int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress());
|
||||
if (ethDeviceNum < 0) {
|
||||
URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
|
||||
if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
|
||||
throw new InternalErrorException("Invalid Broadcast URI " + ip.getBroadcastUri());
|
||||
}
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int publicNicInfo = -1;
|
||||
publicNicInfo = getVmNics(routerName, vlanId);
|
||||
if (publicNicInfo < 0) {
|
||||
if (ip.isAdd()) {
|
||||
throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
|
||||
} else {
|
||||
} else {
|
||||
s_logger.debug("VIF to deassociate IP with does not exist, return success");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ip.setNicDevId(ethDeviceNum);
|
||||
ip.setNicDevId(publicNicInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception: ", e);
|
||||
|
|
@ -668,12 +738,17 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
|
||||
protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
|
||||
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
String routerIp = getRouterSshControlIp(cmd);
|
||||
IpAddressTO pubIp = cmd.getIpAddress();
|
||||
|
||||
try {
|
||||
int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
|
||||
pubIp.setNicDevId(ethDeviceNum);
|
||||
String broadcastUri = pubIp.getBroadcastUri();
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int ethDeviceNum = getVmNics(routerName, vlanId);
|
||||
if (ethDeviceNum > 0) {
|
||||
pubIp.setNicDevId(ethDeviceNum);
|
||||
} else {
|
||||
return new ExecutionResult(false, "Prepare Ip SNAT failed due to unable to find the nic");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Prepare Ip SNAT failure due to " + e.toString();
|
||||
s_logger.error(msg, e);
|
||||
|
|
@ -686,12 +761,16 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
NicTO nic = cmd.getNic();
|
||||
String routerName =
|
||||
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
String routerIp = getRouterSshControlIp(cmd);
|
||||
|
||||
try {
|
||||
int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp,
|
||||
nic.getMac());
|
||||
nic.setDeviceId(ethDeviceNum);
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
|
||||
int ethDeviceNum = getVmNics(routerName, vlanId);
|
||||
if (ethDeviceNum > 0) {
|
||||
nic.setDeviceId(ethDeviceNum);
|
||||
} else {
|
||||
return new ExecutionResult(false, "Prepare SetNetworkACL failed due to unable to find the nic");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Prepare SetNetworkACL failed due to " + e.toString();
|
||||
s_logger.error(msg, e);
|
||||
|
|
@ -1730,6 +1809,27 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
|||
}
|
||||
}
|
||||
|
||||
protected void modifyNicVlan(String vmName, int vlanId, int pos) {
|
||||
ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, pos);
|
||||
URI agentUri = null;
|
||||
try {
|
||||
String cmdName = ModifyVmNicConfigCommand.class.getName();
|
||||
agentUri =
|
||||
new URI("https", null, _agentIp, _port,
|
||||
"/api/HypervResource/" + cmdName, null, null);
|
||||
} catch (URISyntaxException e) {
|
||||
String errMsg = "Could not generate URI for Hyper-V agent";
|
||||
s_logger.error(errMsg, e);
|
||||
}
|
||||
String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
|
||||
Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
|
||||
s_logger.debug("executeRequest received response "
|
||||
+ s_gson.toJson(result));
|
||||
if (result.length > 0) {
|
||||
ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
|
||||
final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
|
||||
|
||||
|
|
|
|||
|
|
@ -2289,6 +2289,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
hTypes.add(HypervisorType.KVM);
|
||||
hTypes.add(HypervisorType.Simulator);
|
||||
hTypes.add(HypervisorType.LXC);
|
||||
hTypes.add(HypervisorType.Hyperv);
|
||||
return hTypes;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue