Skip to content

Commit cf8f2fc

Browse files
committed
PR10341: fetch VM IP by checking mac address
1 parent a056021 commit cf8f2fc

File tree

5 files changed

+56
-20
lines changed

5 files changed

+56
-20
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: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +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

7374
init();
7475

75-
ip = ipFromDomIf(sanitizedVmName, networkCidr);
76+
ip = ipFromDomIf(sanitizedVmName, networkCidr, macAddress);
7677

77-
if (ip == null) {
78+
if (ip == null && networkCidr != null) {
7879
if(!command.isWindows()) {
7980
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
8081
} else {
@@ -92,32 +93,56 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
9293
return new Answer(command, result, ip);
9394
}
9495

95-
private String ipFromDomIf(String sanitizedVmName, String networkCidr) {
96+
private String ipFromDomIf(String sanitizedVmName, String networkCidr, String macAddress) {
9697
String ip = null;
9798
List<String[]> commands = new ArrayList<>();
9899
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
99100
Pair<Integer,String> response = executePipedCommands(commands, 0);
100101
if (response != null) {
101102
String output = response.second();
102-
String[] lines = output.split("\n");
103-
for (String line : lines) {
104-
if (line.contains("ipv4")) {
105-
String[] parts = line.split(" ");
106-
String[] ipParts = parts[parts.length-1].split("/");
107-
if (ipParts.length > 1) {
108-
if (NetUtils.isIpWithInCidrRange(ipParts[0], networkCidr)) {
109-
ip = ipParts[0];
110-
break;
111-
}
112-
}
113-
}
103+
Pair<String, String> ipAddresses = getIpAddresses(output, macAddress);
104+
String ipv4 = ipAddresses.first();
105+
if (networkCidr == null || NetUtils.isIpWithInCidrRange(ipv4, networkCidr)) {
106+
ip = ipv4;
114107
}
115108
} else {
116109
s_logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
117110
}
118111
return ip;
119112
}
120113

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+
121146
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
122147
String ip = null;
123148
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: 5 additions & 3 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 {
@@ -2643,7 +2645,7 @@ protected void runInContext() {
26432645
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
26442646

26452647
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
2646-
isWindows, vm.getHostId(), network.getCidr()));
2648+
isWindows, vm.getHostId(), network.getCidr(), nicVo.getMacAddress()));
26472649

26482650
}
26492651
} catch (Exception e) {

0 commit comments

Comments
 (0)