Skip to content

Commit ae5cbe1

Browse files
weizhouapachedhslove
authored andcommitted
server: fetch IP of VMs on L2 networks (apache#10431)
1 parent 4f45e35 commit ae5cbe1

File tree

5 files changed

+65
-25
lines changed

5 files changed

+65
-25
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
@@ -66,10 +66,13 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
6666

6767
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
6868
String networkCidr = command.getVmNetworkCidr();
69+
String macAddress = command.getMacAddress();
6970

70-
ip = ipFromDomIf(sanitizedVmName, networkCidr);
71+
init();
7172

72-
if (ip == null) {
73+
ip = ipFromDomIf(sanitizedVmName, networkCidr, macAddress);
74+
75+
if (ip == null && networkCidr != null) {
7376
if(!command.isWindows()) {
7477
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
7578
} else {
@@ -87,32 +90,56 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
8790
return new Answer(command, result, ip);
8891
}
8992

90-
private String ipFromDomIf(String sanitizedVmName, String networkCidr) {
93+
private String ipFromDomIf(String sanitizedVmName, String networkCidr, String macAddress) {
9194
String ip = null;
9295
List<String[]> commands = new ArrayList<>();
9396
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
9497
Pair<Integer,String> response = executePipedCommands(commands, 0);
9598
if (response != null) {
9699
String output = response.second();
97-
String[] lines = output.split("\n");
98-
for (String line : lines) {
99-
if (line.contains("ipv4")) {
100-
String[] parts = line.split(" ");
101-
String[] ipParts = parts[parts.length-1].split("/");
102-
if (ipParts.length > 1) {
103-
if (NetUtils.isIpWithInCidrRange(ipParts[0], networkCidr)) {
104-
ip = ipParts[0];
105-
break;
106-
}
107-
}
108-
}
100+
Pair<String, String> ipAddresses = getIpAddresses(output, macAddress);
101+
String ipv4 = ipAddresses.first();
102+
if (networkCidr == null || NetUtils.isIpWithInCidrRange(ipv4, networkCidr)) {
103+
ip = ipv4;
109104
}
110105
} else {
111106
logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
112107
}
113108
return ip;
114109
}
115110

111+
private Pair<String, String> getIpAddresses(String output, String macAddress) {
112+
String ipv4 = null;
113+
String ipv6 = null;
114+
boolean found = false;
115+
String[] lines = output.split("\n");
116+
for (String line : lines) {
117+
String[] parts = line.replaceAll(" +", " ").trim().split(" ");
118+
if (parts.length < 4) {
119+
continue;
120+
}
121+
String device = parts[0];
122+
String mac = parts[1];
123+
if (found) {
124+
if (!device.equals("-") || !mac.equals("-")) {
125+
break;
126+
}
127+
} else if (!mac.equals(macAddress)) {
128+
continue;
129+
}
130+
found = true;
131+
String ipFamily = parts[2];
132+
String ipPart = parts[3].split("/")[0];
133+
if (ipFamily.equals("ipv4")) {
134+
ipv4 = ipPart;
135+
} else if (ipFamily.equals("ipv6")) {
136+
ipv6 = ipPart;
137+
}
138+
}
139+
s_logger.debug(String.format("Found ipv4: %s and ipv6: %s with mac address %s", ipv4, ipv6, macAddress));
140+
return new Pair<>(ipv4, ipv6);
141+
}
142+
116143
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
117144
String ip = null;
118145
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: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -798,20 +798,22 @@ private class VmIpAddrFetchThread extends ManagedContextRunnable {
798798
boolean isWindows;
799799
Long hostId;
800800
String networkCidr;
801+
String macAddress;
801802

802-
public VmIpAddrFetchThread(long vmId, String vmUuid, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
803+
public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr, String macAddress) {
803804
this.vmId = vmId;
804805
this.vmUuid = vmUuid;
805806
this.nicId = nicId;
806807
this.vmName = instanceName;
807808
this.isWindows = windows;
808809
this.hostId = hostId;
809810
this.networkCidr = networkCidr;
811+
this.macAddress = macAddress;
810812
}
811813

812814
@Override
813815
protected void runInContext() {
814-
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
816+
GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows, macAddress);
815817
boolean decrementCount = true;
816818

817819
NicVO nic = _nicDao.findById(nicId);
@@ -2491,9 +2493,10 @@ public boolean start() {
24912493
private void loadVmDetailsInMapForExternalDhcpIp() {
24922494

24932495
List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
2496+
networks.addAll(_networkDao.listByGuestType(Network.GuestType.L2));
24942497

24952498
for (NetworkVO network: networks) {
2496-
if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
2499+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
24972500
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
24982501

24992502
for (NicVO nic : nics) {
@@ -2743,8 +2746,8 @@ protected void runInContext() {
27432746
VirtualMachine vm = vmProfile.getVirtualMachine();
27442747
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
27452748

2746-
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, vmInstance.getUuid(), nicId, vmInstance.getInstanceName(),
2747-
isWindows, vm.getHostId(), network.getCidr()));
2749+
_vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
2750+
isWindows, vm.getHostId(), network.getCidr(), nicVo.getMacAddress()));
27482751

27492752
}
27502753
} catch (Exception e) {
@@ -3457,8 +3460,9 @@ public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityE
34573460
final List<NicVO> nics = _nicDao.listByVmId(vmId);
34583461
for (NicVO nic : nics) {
34593462
Network network = _networkModel.getNetwork(nic.getNetworkId());
3460-
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
3461-
logger.debug("Adding vm {} nic {} into vmIdCountMap as part of vm reboot for vm ip fetch ", userVm, nic);
3463+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
3464+
logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
3465+
"reboot for vm ip fetch ");
34623466
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
34633467
}
34643468
}
@@ -5517,7 +5521,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
55175521
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
55185522
for (NicVO nic : nics) {
55195523
Network network = _networkModel.getNetwork(nic.getNetworkId());
5520-
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
5524+
if (GuestType.L2.equals(network.getGuestType()) || _networkModel.isSharedNetworkWithoutServices(network.getId())) {
55215525
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
55225526
}
55235527
}

0 commit comments

Comments
 (0)