OK, turning the logging on and off didn't work - timing issues, probably.
The expect script below worked for me when called like this
# ip=$(./virsh-expect nodetwo | tr -d '\r' | grep '^192.168')
# echo $ip
192.168.122.99
The important thing to note here is that carriage returns are stripped from the output with tr
and grepping for the IP here in the shell script. The expect script doesn't even try to "expect" it, it just expects the next root shell prompt and exits.
I have also made the expect script more generic - it just expects "login:" rather than "localhost login:" (which would fail on any VM that actually had a hostname...and most will), and a plain "# " for the root shell prompt.
#!/usr/bin/expect -f
set nodename [lindex $argv 0]
spawn virsh console $nodename
expect "Escape character is"
send "\n\n"
expect "login: " {
send "root\n"
expect "Password: "
send "cloud123\n"
}
expect "# " {
send "ifconfig | awk \'/192\.168/ {print \$2}\'"
send "\n"
expect "# "
send "exit"
}
Another alternative is not to use expect
at all, but use perl's Expect.pm
or python's pexpect
instead. These work in pretty much the same way as expect
but make it easier to extract data from the expect session.
I still think that there are far better ways to get the IP address of a VM than using expect
on virsh console
.
Here's a way of doing it that extracts the MAC Address from virsh dumpxml
and then greps for the matching dnsmasq-dhcp entry in /var/log/daemon.log
using awk
:
# mac=$(virsh dumpxml nodetwo | sed -n -e "/mac address/ s/.*'\([^']*\)'.*/\1/ p" | tail -1)
# ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \$7}" /var/log/daemon.log | tail -1)
# echo $ip
192.168.122.99
On my system, the VM has two network interfaces, and i'm only interested in the last one for this purpose so i'm using tail -1
on the virsh dumpxml
line. The tail -1
on the awk
line is to ensure we only get the latest dhcp allocation for that MAC address.
(actually, the VM I tested with on my system is called 'sid', not 'nodetwo' but I edited the output, as well as the password in the expect script, to suit your question. Also the IP addresses I'm using for my VMs are 192.168.122.x rather than 192.168.1.x - but that's a trivial difference in detail)
Update
I had to use this myself last night to find the IP of a freebsd vm I created. I use ISC dhcpd
rather than dnsmasq
, so the log format is slightly different. This version works for both dnsmasq
and dhcpd
:
$ cat find-vm-ip-by-name.sh
#!/bin/bash
mac=$(virsh dumpxml "$1" | sed -n -e "/mac address/ s/.*'\([^']*\)'.*/\1/ p" | tail -1)
ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \$7} ; /dhcpd.*DHCPACK.*$mac/ {print \$8}" /var/log/daemon.log | tail -1)
echo $ip
ip=$(host nodetwo | awk '/has address/ {print $4}')
ssh nodetwo ifconfig | awk '/192\.168\.1\./ { print $2}'