mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
server: fetch IP of VMs on L2 networks (#10431)
This commit is contained in:
parent
751a0ad559
commit
ea32a1a71a
@ -24,11 +24,13 @@ public class GetVmIpAddressCommand extends Command {
|
|||||||
String vmName;
|
String vmName;
|
||||||
String vmNetworkCidr;
|
String vmNetworkCidr;
|
||||||
boolean windows = false;
|
boolean windows = false;
|
||||||
|
String macAddress;
|
||||||
|
|
||||||
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows) {
|
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows, String macAddress) {
|
||||||
this.vmName = vmName;
|
this.vmName = vmName;
|
||||||
this.windows = windows;
|
this.windows = windows;
|
||||||
this.vmNetworkCidr = vmNetworkCidr;
|
this.vmNetworkCidr = vmNetworkCidr;
|
||||||
|
this.macAddress = macAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,4 +49,8 @@ public class GetVmIpAddressCommand extends Command {
|
|||||||
public String getVmNetworkCidr() {
|
public String getVmNetworkCidr() {
|
||||||
return vmNetworkCidr;
|
return vmNetworkCidr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMacAddress() {
|
||||||
|
return macAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,10 +69,13 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
|
|||||||
|
|
||||||
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
|
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
|
||||||
String networkCidr = command.getVmNetworkCidr();
|
String networkCidr = command.getVmNetworkCidr();
|
||||||
|
String macAddress = command.getMacAddress();
|
||||||
|
|
||||||
ip = ipFromDomIf(sanitizedVmName, networkCidr);
|
init();
|
||||||
|
|
||||||
if (ip == null) {
|
ip = ipFromDomIf(sanitizedVmName, networkCidr, macAddress);
|
||||||
|
|
||||||
|
if (ip == null && networkCidr != null) {
|
||||||
if(!command.isWindows()) {
|
if(!command.isWindows()) {
|
||||||
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
|
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
|
||||||
} else {
|
} else {
|
||||||
@ -90,25 +93,17 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
|
|||||||
return new Answer(command, result, ip);
|
return new Answer(command, result, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String ipFromDomIf(String sanitizedVmName, String networkCidr) {
|
private String ipFromDomIf(String sanitizedVmName, String networkCidr, String macAddress) {
|
||||||
String ip = null;
|
String ip = null;
|
||||||
List<String[]> commands = new ArrayList<>();
|
List<String[]> commands = new ArrayList<>();
|
||||||
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
|
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
|
||||||
Pair<Integer,String> response = executePipedCommands(commands, 0);
|
Pair<Integer,String> response = executePipedCommands(commands, 0);
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
String output = response.second();
|
String output = response.second();
|
||||||
String[] lines = output.split("\n");
|
Pair<String, String> ipAddresses = getIpAddresses(output, macAddress);
|
||||||
for (String line : lines) {
|
String ipv4 = ipAddresses.first();
|
||||||
if (line.contains("ipv4")) {
|
if (networkCidr == null || NetUtils.isIpWithInCidrRange(ipv4, networkCidr)) {
|
||||||
String[] parts = line.split(" ");
|
ip = ipv4;
|
||||||
String[] ipParts = parts[parts.length-1].split("/");
|
|
||||||
if (ipParts.length > 1) {
|
|
||||||
if (NetUtils.isIpWithInCidrRange(ipParts[0], networkCidr)) {
|
|
||||||
ip = ipParts[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s_logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
|
s_logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
|
||||||
@ -116,6 +111,38 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
|
|||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Pair<String, String> getIpAddresses(String output, String macAddress) {
|
||||||
|
String ipv4 = null;
|
||||||
|
String ipv6 = null;
|
||||||
|
boolean found = false;
|
||||||
|
String[] lines = output.split("\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
String[] parts = line.replaceAll(" +", " ").trim().split(" ");
|
||||||
|
if (parts.length < 4) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String device = parts[0];
|
||||||
|
String mac = parts[1];
|
||||||
|
if (found) {
|
||||||
|
if (!device.equals("-") || !mac.equals("-")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!mac.equals(macAddress)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
String ipFamily = parts[2];
|
||||||
|
String ipPart = parts[3].split("/")[0];
|
||||||
|
if (ipFamily.equals("ipv4")) {
|
||||||
|
ipv4 = ipPart;
|
||||||
|
} else if (ipFamily.equals("ipv6")) {
|
||||||
|
ipv6 = ipPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_logger.debug(String.format("Found ipv4: %s and ipv6: %s with mac address %s", ipv4, ipv6, macAddress));
|
||||||
|
return new Pair<>(ipv4, ipv6);
|
||||||
|
}
|
||||||
|
|
||||||
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
|
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
|
||||||
String ip = null;
|
String ip = null;
|
||||||
List<String[]> commands = new ArrayList<>();
|
List<String[]> commands = new ArrayList<>();
|
||||||
|
|||||||
@ -66,6 +66,7 @@ public class LibvirtGetVmIpAddressCommandWrapperTest {
|
|||||||
|
|
||||||
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
|
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
|
||||||
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
||||||
|
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
|
||||||
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
|
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
|
||||||
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
|
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
|
||||||
|
|
||||||
@ -88,6 +89,7 @@ public class LibvirtGetVmIpAddressCommandWrapperTest {
|
|||||||
|
|
||||||
when(getVmIpAddressCommand.getVmName()).thenReturn("invalidVmName!");
|
when(getVmIpAddressCommand.getVmName()).thenReturn("invalidVmName!");
|
||||||
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
||||||
|
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
|
||||||
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
|
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
|
||||||
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
|
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
|
||||||
|
|
||||||
@ -114,6 +116,7 @@ public class LibvirtGetVmIpAddressCommandWrapperTest {
|
|||||||
|
|
||||||
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
|
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
|
||||||
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
|
||||||
|
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
|
||||||
when(getVmIpAddressCommand.isWindows()).thenReturn(true);
|
when(getVmIpAddressCommand.isWindows()).thenReturn(true);
|
||||||
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, "192.168.0.10"));
|
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, "192.168.0.10"));
|
||||||
|
|
||||||
|
|||||||
@ -1934,7 +1934,7 @@ public class CitrixRequestWrapperTest {
|
|||||||
vmIpsMap.put("Test", "127.0.0.1");
|
vmIpsMap.put("Test", "127.0.0.1");
|
||||||
rec.networks = vmIpsMap;
|
rec.networks = vmIpsMap;
|
||||||
|
|
||||||
final GetVmIpAddressCommand getVmIpAddrCmd = new GetVmIpAddressCommand("Test", "127.0.0.1/24", false);
|
final GetVmIpAddressCommand getVmIpAddrCmd = new GetVmIpAddressCommand("Test", "127.0.0.1/24", false, null);
|
||||||
|
|
||||||
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
|
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
|
||||||
assertNotNull(wrapper);
|
assertNotNull(wrapper);
|
||||||
|
|||||||
@ -757,19 +757,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
boolean isWindows;
|
boolean isWindows;
|
||||||
Long hostId;
|
Long hostId;
|
||||||
String networkCidr;
|
String networkCidr;
|
||||||
|
String macAddress;
|
||||||
|
|
||||||
public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
|
public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr, String macAddress) {
|
||||||
this.vmId = vmId;
|
this.vmId = vmId;
|
||||||
this.nicId = nicId;
|
this.nicId = nicId;
|
||||||
this.vmName = instanceName;
|
this.vmName = instanceName;
|
||||||
this.isWindows = windows;
|
this.isWindows = windows;
|
||||||
this.hostId = hostId;
|
this.hostId = hostId;
|
||||||
this.networkCidr = networkCidr;
|
this.networkCidr = networkCidr;
|
||||||
|
this.macAddress = macAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void runInContext() {
|
protected void runInContext() {
|
||||||
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
|
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows, macAddress);
|
||||||
boolean decrementCount = true;
|
boolean decrementCount = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -2397,9 +2399,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
private void loadVmDetailsInMapForExternalDhcpIp() {
|
private void loadVmDetailsInMapForExternalDhcpIp() {
|
||||||
|
|
||||||
List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
|
List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
|
||||||
|
networks.addAll(_networkDao.listByGuestType(Network.GuestType.L2));
|
||||||
|
|
||||||
for (NetworkVO network: networks) {
|
for (NetworkVO network: networks) {
|
||||||
if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||||
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
|
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
|
||||||
|
|
||||||
for (NicVO nic : nics) {
|
for (NicVO nic : nics) {
|
||||||
@ -2642,7 +2645,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
||||||
|
|
||||||
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
|
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
|
||||||
isWindows, vm.getHostId(), network.getCidr()));
|
isWindows, vm.getHostId(), network.getCidr(), nicVo.getMacAddress()));
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -3279,7 +3282,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
final List<NicVO> nics = _nicDao.listByVmId(vmId);
|
final List<NicVO> nics = _nicDao.listByVmId(vmId);
|
||||||
for (NicVO nic : nics) {
|
for (NicVO nic : nics) {
|
||||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||||
s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
|
s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
|
||||||
"reboot for vm ip fetch ");
|
"reboot for vm ip fetch ");
|
||||||
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
||||||
@ -5202,7 +5205,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
|
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
|
||||||
for (NicVO nic : nics) {
|
for (NicVO nic : nics) {
|
||||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||||
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user