27
27
import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
28
28
import com .cloud .resource .CommandWrapper ;
29
29
import com .cloud .resource .ResourceWrapper ;
30
+ import com .cloud .utils .Pair ;
30
31
import com .cloud .utils .net .NetUtils ;
31
32
import com .cloud .utils .script .Script ;
32
33
33
34
@ ResourceWrapper (handles = GetVmIpAddressCommand .class )
34
35
public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper <GetVmIpAddressCommand , Answer , LibvirtComputingResource > {
35
36
36
37
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
+
37
58
@ Override
38
59
public Answer execute (final GetVmIpAddressCommand command , final LibvirtComputingResource libvirtComputingResource ) {
39
60
String ip = null ;
@@ -42,65 +63,113 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
42
63
if (!NetUtils .verifyDomainNameLabel (vmName , true )) {
43
64
return new Answer (command , result , ip );
44
65
}
66
+
45
67
String sanitizedVmName = sanitizeBashCommandArgument (vmName );
46
68
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 ;
47
92
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
+ }
75
107
}
76
- logger .debug ("GetVmIp: " + vmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
77
108
}
78
109
}
79
110
} 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 ;
97
137
}
138
+ logger .debug ("GetVmIp: " + sanitizedVmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
98
139
}
140
+ } else {
141
+ logger .error ("ipFromDhcpLeaseFile: Command execution failed for VM: " + sanitizedVmName );
99
142
}
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 );
103
168
}
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 );
105
174
}
106
175
}
0 commit comments