Skip to content

Commit 48ed5e2

Browse files
committed
Merge branch '4.19' into 4.20
2 parents 3aabedd + b41acf2 commit 48ed5e2

File tree

10 files changed

+941
-170
lines changed

10 files changed

+941
-170
lines changed

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

Lines changed: 118 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,34 @@
2727
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
2828
import com.cloud.resource.CommandWrapper;
2929
import com.cloud.resource.ResourceWrapper;
30+
import com.cloud.utils.Pair;
3031
import com.cloud.utils.net.NetUtils;
3132
import com.cloud.utils.script.Script;
3233

3334
@ResourceWrapper(handles = GetVmIpAddressCommand.class)
3435
public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<GetVmIpAddressCommand, Answer, LibvirtComputingResource> {
3536

3637

38+
static String virsh_path = null;
39+
static String virt_win_reg_path = null;
40+
static String grep_path = null;
41+
static String awk_path = null;
42+
static String sed_path = null;
43+
static String virt_ls_path = null;
44+
static String virt_cat_path = null;
45+
static String tail_path = null;
46+
47+
static void init() {
48+
virt_ls_path = Script.getExecutableAbsolutePath("virt-ls");
49+
virt_cat_path = Script.getExecutableAbsolutePath("virt-cat");
50+
virt_win_reg_path = Script.getExecutableAbsolutePath("virt-win-reg");
51+
tail_path = Script.getExecutableAbsolutePath("tail");
52+
grep_path = Script.getExecutableAbsolutePath("grep");
53+
awk_path = Script.getExecutableAbsolutePath("awk");
54+
sed_path = Script.getExecutableAbsolutePath("sed");
55+
virsh_path = Script.getExecutableAbsolutePath("virsh");
56+
}
57+
3758
@Override
3859
public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputingResource libvirtComputingResource) {
3960
String ip = null;
@@ -42,65 +63,113 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
4263
if (!NetUtils.verifyDomainNameLabel(vmName, true)) {
4364
return new Answer(command, result, ip);
4465
}
66+
4567
String sanitizedVmName = sanitizeBashCommandArgument(vmName);
4668
String networkCidr = command.getVmNetworkCidr();
69+
70+
ip = ipFromDomIf(sanitizedVmName, networkCidr);
71+
72+
if (ip == null) {
73+
if(!command.isWindows()) {
74+
ip = ipFromDhcpLeaseFile(sanitizedVmName, networkCidr);
75+
} else {
76+
ip = ipFromWindowsRegistry(sanitizedVmName, networkCidr);
77+
}
78+
}
79+
80+
if(ip != null){
81+
result = true;
82+
logger.debug("GetVmIp: "+ vmName + " Found Ip: "+ip);
83+
} else {
84+
logger.warn("GetVmIp: "+ vmName + " IP not found.");
85+
}
86+
87+
return new Answer(command, result, ip);
88+
}
89+
90+
private String ipFromDomIf(String sanitizedVmName, String networkCidr) {
91+
String ip = null;
4792
List<String[]> commands = new ArrayList<>();
48-
final String virt_ls_path = Script.getExecutableAbsolutePath("virt-ls");
49-
final String virt_cat_path = Script.getExecutableAbsolutePath("virt-cat");
50-
final String virt_win_reg_path = Script.getExecutableAbsolutePath("virt-win-reg");
51-
final String tail_path = Script.getExecutableAbsolutePath("tail");
52-
final String grep_path = Script.getExecutableAbsolutePath("grep");
53-
final String awk_path = Script.getExecutableAbsolutePath("awk");
54-
final String sed_path = Script.getExecutableAbsolutePath("sed");
55-
if(!command.isWindows()) {
56-
//List all dhcp lease files inside guestVm
57-
commands.add(new String[]{virt_ls_path, sanitizedVmName, "/var/lib/dhclient/"});
58-
commands.add(new String[]{grep_path, ".*\\*.leases"});
59-
String leasesList = Script.executePipedCommands(commands, 0).second();
60-
if(leasesList != null) {
61-
String[] leasesFiles = leasesList.split("\n");
62-
for(String leaseFile : leasesFiles){
63-
//Read from each dhclient lease file inside guest Vm using virt-cat libguestfs utility
64-
commands = new ArrayList<>();
65-
commands.add(new String[]{virt_cat_path, sanitizedVmName, "/var/lib/dhclient/" + leaseFile});
66-
commands.add(new String[]{tail_path, "-16"});
67-
commands.add(new String[]{grep_path, "fixed-address"});
68-
commands.add(new String[]{awk_path, "{print $2}"});
69-
commands.add(new String[]{sed_path, "-e", "s/;//"});
70-
String ipAddr = Script.executePipedCommands(commands, 0).second();
71-
// Check if the IP belongs to the network
72-
if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)) {
73-
ip = ipAddr;
74-
break;
93+
commands.add(new String[]{virsh_path, "domifaddr", sanitizedVmName, "--source", "agent"});
94+
Pair<Integer,String> response = executePipedCommands(commands, 0);
95+
if (response != null) {
96+
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+
}
75107
}
76-
logger.debug("GetVmIp: "+ vmName + " Ip: "+ipAddr+" does not belong to network "+networkCidr);
77108
}
78109
}
79110
} else {
80-
// For windows, read from guest Vm registry using virt-win-reg libguestfs ulitiy. Registry Path: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\<service>\DhcpIPAddress
81-
commands = new ArrayList<>();
82-
commands.add(new String[]{virt_win_reg_path, "--unsafe-printable-strings", sanitizedVmName, "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces"});
83-
commands.add(new String[]{grep_path, "DhcpIPAddress"});
84-
commands.add(new String[]{awk_path, "-F", ":", "{print $2}"});
85-
commands.add(new String[]{sed_path, "-e", "s/^\"//", "-e", "s/\"$//"});
86-
String ipList = Script.executePipedCommands(commands, 0).second();
87-
if(ipList != null) {
88-
logger.debug("GetVmIp: "+ vmName + "Ips: "+ipList);
89-
String[] ips = ipList.split("\n");
90-
for (String ipAddr : ips){
91-
// Check if the IP belongs to the network
92-
if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)){
93-
ip = ipAddr;
94-
break;
95-
}
96-
logger.debug("GetVmIp: "+ vmName + " Ip: "+ipAddr+" does not belong to network "+networkCidr);
111+
logger.error("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName);
112+
}
113+
return ip;
114+
}
115+
116+
private String ipFromDhcpLeaseFile(String sanitizedVmName, String networkCidr) {
117+
String ip = null;
118+
List<String[]> commands = new ArrayList<>();
119+
commands.add(new String[]{virt_ls_path, sanitizedVmName, "/var/lib/dhclient/"});
120+
commands.add(new String[]{grep_path, ".*\\*.leases"});
121+
Pair<Integer,String> response = executePipedCommands(commands, 0);
122+
123+
if(response != null && response.second() != null) {
124+
String leasesList = response.second();
125+
String[] leasesFiles = leasesList.split("\n");
126+
for(String leaseFile : leasesFiles){
127+
commands = new ArrayList<>();
128+
commands.add(new String[]{virt_cat_path, sanitizedVmName, "/var/lib/dhclient/" + leaseFile});
129+
commands.add(new String[]{tail_path, "-16"});
130+
commands.add(new String[]{grep_path, "fixed-address"});
131+
commands.add(new String[]{awk_path, "{print $2}"});
132+
commands.add(new String[]{sed_path, "-e", "s/;//"});
133+
String ipAddr = executePipedCommands(commands, 0).second();
134+
if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)) {
135+
ip = ipAddr;
136+
break;
97137
}
138+
logger.debug("GetVmIp: "+ sanitizedVmName + " Ip: "+ipAddr+" does not belong to network "+networkCidr);
98139
}
140+
} else {
141+
logger.error("ipFromDhcpLeaseFile: Command execution failed for VM: " + sanitizedVmName);
99142
}
100-
if(ip != null){
101-
result = true;
102-
logger.debug("GetVmIp: "+ vmName + " Found Ip: "+ip);
143+
return ip;
144+
}
145+
146+
private String ipFromWindowsRegistry(String sanitizedVmName, String networkCidr) {
147+
String ip = null;
148+
List<String[]> commands = new ArrayList<>();
149+
commands.add(new String[]{virt_win_reg_path, "--unsafe-printable-strings", sanitizedVmName, "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces"});
150+
commands.add(new String[]{grep_path, "DhcpIPAddress"});
151+
commands.add(new String[]{awk_path, "-F", ":", "{print $2}"});
152+
commands.add(new String[]{sed_path, "-e", "s/^\"//", "-e", "s/\"$//"});
153+
Pair<Integer,String> pair = executePipedCommands(commands, 0);
154+
if(pair != null && pair.second() != null) {
155+
String ipList = pair.second();
156+
ipList = ipList.replaceAll("\"", "");
157+
logger.debug("GetVmIp: "+ sanitizedVmName + "Ips: "+ipList);
158+
String[] ips = ipList.split("\n");
159+
for (String ipAddr : ips){
160+
if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)){
161+
ip = ipAddr;
162+
break;
163+
}
164+
logger.debug("GetVmIp: "+ sanitizedVmName + " Ip: "+ipAddr+" does not belong to network "+networkCidr);
165+
}
166+
} else {
167+
logger.error("ipFromWindowsRegistry: Command execution failed for VM: " + sanitizedVmName);
103168
}
104-
return new Answer(command, result, ip);
169+
return ip;
170+
}
171+
172+
static Pair<Integer, String> executePipedCommands(List<String[]> commands, long timeout) {
173+
return Script.executePipedCommands(commands, timeout);
105174
}
106175
}

0 commit comments

Comments
 (0)