2727import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
2828import com .cloud .resource .CommandWrapper ;
2929import com .cloud .resource .ResourceWrapper ;
30+ import com .cloud .utils .Pair ;
3031import com .cloud .utils .net .NetUtils ;
3132import com .cloud .utils .script .Script ;
3233
3334@ ResourceWrapper (handles = GetVmIpAddressCommand .class )
3435public 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