Skip to content

Commit ea32a1a

Browse files
server: fetch IP of VMs on L2 networks (#10431)
1 parent 751a0ad commit ea32a1a

File tree

5 files changed

+62
-23
lines changed

5 files changed

+62
-23
lines changed

core/src/main/java/com/cloud/agent/api/GetVmIpAddressCommand.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ public class GetVmIpAddressCommand extends Command {
2424
String vmName;
2525
String vmNetworkCidr;
2626
boolean windows = false;
27+
String macAddress;
2728

28-
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows) {
29+
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows, String macAddress) {
2930
this.vmName = vmName;
3031
this.windows = windows;
3132
this.vmNetworkCidr = vmNetworkCidr;
33+
this.macAddress = macAddress;
3234
}
3335

3436
@Override
@@ -47,4 +49,8 @@ public boolean isWindows(){
4749
public String getVmNetworkCidr() {
4850
return vmNetworkCidr;
4951
}
52+
53+
public String getMacAddress() {
54+
return macAddress;
55+
}
5056
}

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
6969

7070
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
7171
String networkCidr = command.getVmNetworkCidr();
72+
String macAddress = command.getMacAddress();
7273

73-
ip = ipFromDomIf(sanitizedVmName, networkCidr);
74+
init();
7475

75-
if (ip == null) {
76+
ip = ipFromDomIf(sanitizedVmName, networkCidr, macAddress);
77+
78+
if (ip == null && networkCidr != null) {
7679
if(!command.isWindows()) {
7780
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
7881
} else {
@@ -90,32 +93,56 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
9093
return new Answer(command, result, ip);
9194
}
9295

93-
private String ipFromDomIf(String sanitizedVmName, String networkCidr) {
96+
private String ipFromDomIf(String sanitizedVmName, String networkCidr, String macAddress) {
9497
String ip = null;
9598
List<String[]> commands = new ArrayList<>();
9699
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
97100
Pair<Integer,String> response = executePipedCommands(commands, 0);
98101
if (response != null) {
99102
String output = response.second();
100-
String[] lines = output.split("\n");
101-
for (String line : lines) {
102-
if (line.contains("ipv4")) {
103-
String[] parts = line.split(" ");
104-
String[] ipParts = parts[parts.length-1].split("/");
105-
if (ipParts.length > 1) {
106-
if (NetUtils.isIpWithInCidrRange(ipParts[0], networkCidr)) {
107-
ip = ipParts[0];
108-
break;
109-
}
110-
}
111-
}
103+
Pair<String, String> ipAddresses = getIpAddresses(output, macAddress);
104+
String ipv4 = ipAddresses.first();
105+
if (networkCidr == null || NetUtils.isIpWithInCidrRange(ipv4, networkCidr)) {
106+
ip = ipv4;
112107
}
113108
} else {
114109
s_logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
115110
}
116111
return ip;
117112
}
118113

114+
private Pair<String, String> getIpAddresses(String output, String macAddress) {
115+
String ipv4 = null;
116+
String ipv6 = null;
117+
boolean found = false;
118+
String[] lines = output.split("\n");
119+
for (String line : lines) {
120+
String[] parts = line.replaceAll(" +", " ").trim().split(" ");
121+
if (parts.length < 4) {
122+
continue;
123+
}
124+
String device = parts[0];
125+
String mac = parts[1];
126+
if (found) {
127+
if (!device.equals("-") || !mac.equals("-")) {
128+
break;
129+
}
130+
} else if (!mac.equals(macAddress)) {
131+
continue;
132+
}
133+
found = true;
134+
String ipFamily = parts[2];
135+
String ipPart = parts[3].split("/")[0];
136+
if (ipFamily.equals("ipv4")) {
137+
ipv4 = ipPart;
138+
} else if (ipFamily.equals("ipv6")) {
139+
ipv6 = ipPart;
140+
}
141+
}
142+
s_logger.debug(String.format("Found ipv4: %s and ipv6: %s with mac address %s", ipv4, ipv6, macAddress));
143+
return new Pair<>(ipv4, ipv6);
144+
}
145+
119146
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
120147
String ip = null;
121148
List<String[]> commands = new ArrayList<>();

plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapperTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public void testExecuteWithValidVmName() {
6666

6767
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
6868
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
69+
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
6970
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
7071
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
7172

@@ -88,6 +89,7 @@ public void testExecuteWithInvalidVmName() {
8889

8990
when(getVmIpAddressCommand.getVmName()).thenReturn("invalidVmName!");
9091
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
92+
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
9193
when(getVmIpAddressCommand.isWindows()).thenReturn(false);
9294
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, VIRSH_DOMIF_OUTPUT));
9395

@@ -114,6 +116,7 @@ public void testExecuteWithWindowsVm() {
114116

115117
when(getVmIpAddressCommand.getVmName()).thenReturn("validVmName");
116118
when(getVmIpAddressCommand.getVmNetworkCidr()).thenReturn("192.168.0.0/24");
119+
when(getVmIpAddressCommand.getMacAddress()).thenReturn("02:0c:02:f9:00:80");
117120
when(getVmIpAddressCommand.isWindows()).thenReturn(true);
118121
when(Script.executePipedCommands(anyList(), anyLong())).thenReturn(new Pair<>(0, "192.168.0.10"));
119122

plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapperTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,7 @@ public void testGetVmIpAddressCommand() throws XenAPIException, XmlRpcException
19341934
vmIpsMap.put("Test", "127.0.0.1");
19351935
rec.networks = vmIpsMap;
19361936

1937-
final GetVmIpAddressCommand getVmIpAddrCmd = new GetVmIpAddressCommand("Test", "127.0.0.1/24", false);
1937+
final GetVmIpAddressCommand getVmIpAddrCmd = new GetVmIpAddressCommand("Test", "127.0.0.1/24", false, null);
19381938

19391939
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
19401940
assertNotNull(wrapper);

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -757,19 +757,21 @@ private class VmIpAddrFetchThread extends ManagedContextRunnable {
757757
boolean isWindows;
758758
Long hostId;
759759
String networkCidr;
760+
String macAddress;
760761

761-
public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
762+
public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr, String macAddress) {
762763
this.vmId = vmId;
763764
this.nicId = nicId;
764765
this.vmName = instanceName;
765766
this.isWindows = windows;
766767
this.hostId = hostId;
767768
this.networkCidr = networkCidr;
769+
this.macAddress = macAddress;
768770
}
769771

770772
@Override
771773
protected void runInContext() {
772-
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
774+
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows, macAddress);
773775
boolean decrementCount = true;
774776

775777
try {
@@ -2397,9 +2399,10 @@ public boolean start() {
23972399
private void loadVmDetailsInMapForExternalDhcpIp() {
23982400

23992401
List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
2402+
networks.addAll(_networkDao.listByGuestType(Network.GuestType.L2));
24002403

24012404
for (NetworkVO network: networks) {
2402-
if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
2405+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
24032406
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
24042407

24052408
for (NicVO nic : nics) {
@@ -2642,7 +2645,7 @@ protected void runInContext() {
26422645
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
26432646

26442647
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
2645-
isWindows, vm.getHostId(), network.getCidr()));
2648+
isWindows, vm.getHostId(), network.getCidr(), nicVo.getMacAddress()));
26462649

26472650
}
26482651
} catch (Exception e) {
@@ -3279,7 +3282,7 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE
32793282
final List<NicVO> nics = _nicDao.listByVmId(vmId);
32803283
for (NicVO nic : nics) {
32813284
Network network = _networkModel.getNetwork(nic.getNetworkId());
3282-
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
3285+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
32833286
s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
32843287
"reboot for vm ip fetch ");
32853288
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
@@ -5202,7 +5205,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
52025205
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
52035206
for (NicVO nic : nics) {
52045207
Network network = _networkModel.getNetwork(nic.getNetworkId());
5205-
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
5208+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
52065209
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
52075210
}
52085211
}

0 commit comments

Comments
 (0)