2929import com .cloud .hypervisor .kvm .resource .LibvirtComputingResource ;
3030import com .cloud .resource .CommandWrapper ;
3131import com .cloud .resource .ResourceWrapper ;
32+ import com .cloud .utils .Pair ;
3233import com .cloud .utils .net .NetUtils ;
3334import com .cloud .utils .script .Script ;
3435
@@ -37,6 +38,26 @@ public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<Ge
3738
3839 private static final Logger s_logger = Logger .getLogger (LibvirtGetVmIpAddressCommandWrapper .class );
3940
41+ static String virsh_path = null ;
42+ static String virt_win_reg_path = null ;
43+ static String grep_path = null ;
44+ static String awk_path = null ;
45+ static String sed_path = null ;
46+ static String virt_ls_path = null ;
47+ static String virt_cat_path = null ;
48+ static String tail_path = null ;
49+
50+ static void init () {
51+ virt_ls_path = Script .getExecutableAbsolutePath ("virt-ls" );
52+ virt_cat_path = Script .getExecutableAbsolutePath ("virt-cat" );
53+ virt_win_reg_path = Script .getExecutableAbsolutePath ("virt-win-reg" );
54+ tail_path = Script .getExecutableAbsolutePath ("tail" );
55+ grep_path = Script .getExecutableAbsolutePath ("grep" );
56+ awk_path = Script .getExecutableAbsolutePath ("awk" );
57+ sed_path = Script .getExecutableAbsolutePath ("sed" );
58+ virsh_path = Script .getExecutableAbsolutePath ("virsh" );
59+ }
60+
4061 @ Override
4162 public Answer execute (final GetVmIpAddressCommand command , final LibvirtComputingResource libvirtComputingResource ) {
4263 String ip = null ;
@@ -45,65 +66,113 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin
4566 if (!NetUtils .verifyDomainNameLabel (vmName , true )) {
4667 return new Answer (command , result , ip );
4768 }
69+
4870 String sanitizedVmName = sanitizeBashCommandArgument (vmName );
4971 String networkCidr = command .getVmNetworkCidr ();
72+
73+ ip = ipFromDomIf (sanitizedVmName , networkCidr );
74+
75+ if (ip == null ) {
76+ if (!command .isWindows ()) {
77+ ip = ipFromDhcpLeaseFile (sanitizedVmName , networkCidr );
78+ } else {
79+ ip = ipFromWindowsRegistry (sanitizedVmName , networkCidr );
80+ }
81+ }
82+
83+ if (ip != null ){
84+ result = true ;
85+ s_logger .debug ("GetVmIp: " + vmName + " Found Ip: " +ip );
86+ } else {
87+ s_logger .warn ("GetVmIp: " + vmName + " IP not found." );
88+ }
89+
90+ return new Answer (command , result , ip );
91+ }
92+
93+ private String ipFromDomIf (String sanitizedVmName , String networkCidr ) {
94+ String ip = null ;
5095 List <String []> commands = new ArrayList <>();
51- final String virt_ls_path = Script .getExecutableAbsolutePath ("virt-ls" );
52- final String virt_cat_path = Script .getExecutableAbsolutePath ("virt-cat" );
53- final String virt_win_reg_path = Script .getExecutableAbsolutePath ("virt-win-reg" );
54- final String tail_path = Script .getExecutableAbsolutePath ("tail" );
55- final String grep_path = Script .getExecutableAbsolutePath ("grep" );
56- final String awk_path = Script .getExecutableAbsolutePath ("awk" );
57- final String sed_path = Script .getExecutableAbsolutePath ("sed" );
58- if (!command .isWindows ()) {
59- //List all dhcp lease files inside guestVm
60- commands .add (new String []{virt_ls_path , sanitizedVmName , "/var/lib/dhclient/" });
61- commands .add (new String []{grep_path , ".*\\ *.leases" });
62- String leasesList = Script .executePipedCommands (commands , 0 ).second ();
63- if (leasesList != null ) {
64- String [] leasesFiles = leasesList .split ("\n " );
65- for (String leaseFile : leasesFiles ){
66- //Read from each dhclient lease file inside guest Vm using virt-cat libguestfs utility
67- commands = new ArrayList <>();
68- commands .add (new String []{virt_cat_path , sanitizedVmName , "/var/lib/dhclient/" + leaseFile });
69- commands .add (new String []{tail_path , "-16" });
70- commands .add (new String []{grep_path , "fixed-address" });
71- commands .add (new String []{awk_path , "{print $2}" });
72- commands .add (new String []{sed_path , "-e" , "s/;//" });
73- String ipAddr = Script .executePipedCommands (commands , 0 ).second ();
74- // Check if the IP belongs to the network
75- if ((ipAddr != null ) && NetUtils .isIpWithInCidrRange (ipAddr , networkCidr )) {
76- ip = ipAddr ;
77- break ;
96+ commands .add (new String []{virsh_path , "domifaddr" , sanitizedVmName , "--source" , "agent" });
97+ Pair <Integer ,String > response = executePipedCommands (commands , 0 );
98+ if (response != null ) {
99+ String output = response .second ();
100+ String [] lines = output .split ("\n " );
101+ for (String line : lines ) {
102+ if (line .contains ("ipv4" )) {
103+ String [] parts = line .split (" " );
104+ String [] ipParts = parts [parts .length -1 ].split ("/" );
105+ if (ipParts .length > 1 ) {
106+ if (NetUtils .isIpWithInCidrRange (ipParts [0 ], networkCidr )) {
107+ ip = ipParts [0 ];
108+ break ;
109+ }
78110 }
79- s_logger .debug ("GetVmIp: " + vmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
80111 }
81112 }
82113 } else {
83- // 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
84- commands = new ArrayList <>();
85- commands .add (new String []{virt_win_reg_path , "--unsafe-printable-strings" , sanitizedVmName , "HKEY_LOCAL_MACHINE\\ SYSTEM\\ ControlSet001\\ Services\\ Tcpip\\ Parameters\\ Interfaces" });
86- commands .add (new String []{grep_path , "DhcpIPAddress" });
87- commands .add (new String []{awk_path , "-F" , ":" , "{print $2}" });
88- commands .add (new String []{sed_path , "-e" , "s/^\" //" , "-e" , "s/\" $//" });
89- String ipList = Script .executePipedCommands (commands , 0 ).second ();
90- if (ipList != null ) {
91- s_logger .debug ("GetVmIp: " + vmName + "Ips: " +ipList );
92- String [] ips = ipList .split ("\n " );
93- for (String ipAddr : ips ){
94- // Check if the IP belongs to the network
95- if ((ipAddr != null ) && NetUtils .isIpWithInCidrRange (ipAddr , networkCidr )){
96- ip = ipAddr ;
97- break ;
98- }
99- s_logger .debug ("GetVmIp: " + vmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
114+ s_logger .error ("ipFromDomIf: Command execution failed for VM: " + sanitizedVmName );
115+ }
116+ return ip ;
117+ }
118+
119+ private String ipFromDhcpLeaseFile (String sanitizedVmName , String networkCidr ) {
120+ String ip = null ;
121+ List <String []> commands = new ArrayList <>();
122+ commands .add (new String []{virt_ls_path , sanitizedVmName , "/var/lib/dhclient/" });
123+ commands .add (new String []{grep_path , ".*\\ *.leases" });
124+ Pair <Integer ,String > response = executePipedCommands (commands , 0 );
125+
126+ if (response != null && response .second () != null ) {
127+ String leasesList = response .second ();
128+ String [] leasesFiles = leasesList .split ("\n " );
129+ for (String leaseFile : leasesFiles ){
130+ commands = new ArrayList <>();
131+ commands .add (new String []{virt_cat_path , sanitizedVmName , "/var/lib/dhclient/" + leaseFile });
132+ commands .add (new String []{tail_path , "-16" });
133+ commands .add (new String []{grep_path , "fixed-address" });
134+ commands .add (new String []{awk_path , "{print $2}" });
135+ commands .add (new String []{sed_path , "-e" , "s/;//" });
136+ String ipAddr = executePipedCommands (commands , 0 ).second ();
137+ if ((ipAddr != null ) && NetUtils .isIpWithInCidrRange (ipAddr , networkCidr )) {
138+ ip = ipAddr ;
139+ break ;
100140 }
141+ s_logger .debug ("GetVmIp: " + sanitizedVmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
101142 }
143+ } else {
144+ s_logger .error ("ipFromDhcpLeaseFile: Command execution failed for VM: " + sanitizedVmName );
102145 }
103- if (ip != null ){
104- result = true ;
105- s_logger .debug ("GetVmIp: " + vmName + " Found Ip: " +ip );
146+ return ip ;
147+ }
148+
149+ private String ipFromWindowsRegistry (String sanitizedVmName , String networkCidr ) {
150+ String ip = null ;
151+ List <String []> commands = new ArrayList <>();
152+ commands .add (new String []{virt_win_reg_path , "--unsafe-printable-strings" , sanitizedVmName , "HKEY_LOCAL_MACHINE\\ SYSTEM\\ ControlSet001\\ Services\\ Tcpip\\ Parameters\\ Interfaces" });
153+ commands .add (new String []{grep_path , "DhcpIPAddress" });
154+ commands .add (new String []{awk_path , "-F" , ":" , "{print $2}" });
155+ commands .add (new String []{sed_path , "-e" , "s/^\" //" , "-e" , "s/\" $//" });
156+ Pair <Integer ,String > pair = executePipedCommands (commands , 0 );
157+ if (pair != null && pair .second () != null ) {
158+ String ipList = pair .second ();
159+ ipList = ipList .replaceAll ("\" " , "" );
160+ s_logger .debug ("GetVmIp: " + sanitizedVmName + "Ips: " +ipList );
161+ String [] ips = ipList .split ("\n " );
162+ for (String ipAddr : ips ){
163+ if ((ipAddr != null ) && NetUtils .isIpWithInCidrRange (ipAddr , networkCidr )){
164+ ip = ipAddr ;
165+ break ;
166+ }
167+ s_logger .debug ("GetVmIp: " + sanitizedVmName + " Ip: " +ipAddr +" does not belong to network " +networkCidr );
168+ }
169+ } else {
170+ s_logger .error ("ipFromWindowsRegistry: Command execution failed for VM: " + sanitizedVmName );
106171 }
107- return new Answer (command , result , ip );
172+ return ip ;
173+ }
174+
175+ static Pair <Integer , String > executePipedCommands (List <String []> commands , long timeout ) {
176+ return Script .executePipedCommands (commands , timeout );
108177 }
109178}
0 commit comments