server: fetch IP of VMs on L2 networks (#10431)

This commit is contained in:
Wei Zhou 2025-05-09 10:19:30 +02:00 committed by GitHub
parent 751a0ad559
commit ea32a1a71a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 23 deletions

View File

@ -24,11 +24,13 @@ public class GetVmIpAddressCommand extends Command {
String vmName;
String vmNetworkCidr;
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.windows = windows;
this.vmNetworkCidr = vmNetworkCidr;
this.macAddress = macAddress;
}
@Override
@ -47,4 +49,8 @@ public class GetVmIpAddressCommand extends Command {
public String getVmNetworkCidr() {
return vmNetworkCidr;
}
public String getMacAddress() {
return macAddress;
}
}

View File

@ -69,10 +69,13 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
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()) {
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
} else {
@ -90,25 +93,17 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
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;
List<String[]> commands = new ArrayList<>();
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
Pair<Integer,String> response = executePipedCommands(commands, 0);
if (response != null) {
String output = response.second();
String[] lines = output.split("\n");
for (String line : lines) {
if (line.contains("ipv4")) {
String[] parts = line.split(" ");
String[] ipParts = parts[parts.length-1].split("/");
if (ipParts.length > 1) {
if (NetUtils.isIpWithInCidrRange(ipParts[0], networkCidr)) {
ip = ipParts[0];
break;
}
}
}
Pair<String, String> ipAddresses = getIpAddresses(output, macAddress);
String ipv4 = ipAddresses.first();
if (networkCidr == null || NetUtils.isIpWithInCidrRange(ipv4, networkCidr)) {
ip = ipv4;
}
} else {
s_logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
@ -116,6 +111,38 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
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) {
String ip = null;
List<String[]> commands = new ArrayList<>();

View File

@ -66,6 +66,7 @@ public class LibvirtGetVmIpAddressCommandWrapperTest {
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
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(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.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
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.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
when(getVmIpAddressCommand.isWindows()).thenReturn(true);
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, "192.168.0.10"));

View File

@ -1934,7 +1934,7 @@ public class CitrixRequestWrapperTest {
vmIpsMap.put("Test", "127.0.0.1");
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();
assertNotNull(wrapper);

View File

@ -757,19 +757,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
boolean isWindows;
Long hostId;
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.nicId = nicId;
this.vmName = instanceName;
this.isWindows = windows;
this.hostId = hostId;
this.networkCidr = networkCidr;
this.macAddress = macAddress;
}
@Override
protected void runInContext() {
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows, macAddress);
boolean decrementCount = true;
try {
@ -2397,9 +2399,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private void loadVmDetailsInMapForExternalDhcpIp() {
List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
networks.addAll(_networkDao.listByGuestType(Network.GuestType.L2));
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());
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");
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
isWindows, vm.getHostId(), network.getCidr()));
isWindows, vm.getHostId(), network.getCidr(), nicVo.getMacAddress()));
}
} catch (Exception e) {
@ -3279,7 +3282,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
final List<NicVO> nics = _nicDao.listByVmId(vmId);
for (NicVO nic : nics) {
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 " +
"reboot for vm ip fetch ");
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());
for (NicVO nic : nics) {
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()));
}
}