-
-
Save tensorfields/4447791 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# Returns the IP address of a running KVM guest VM | |
# Assumes a working KVM/libvirt environment | |
# | |
# Install: | |
# Add this bash function to your ~/.bashrc and `source ~/.bashrc`. | |
# Usage: | |
# $ virt-addr vm-name | |
# 192.0.2.16 | |
# | |
virt-addr() { | |
VM="$1" | |
arp -an | grep "`virsh dumpxml $VM | grep "mac address" | sed "s/.*'\(.*\)'.*/\1/g"`" | awk '{ gsub(/[\(\)]/,"",$2); print $2 }' | |
} |
Here's an updated, 'extended mix' which parses out a whole lot more information. It is a bit slow, however, so I'll look at doing some caching of the XML to speed it all up...
virt-uuid() {
VM="$1"
uuid=$(virsh dumpxml $VM | grep "<uuid" | sed "s/.*<uuid>\(.*\)<\/uuid>.*/\1/g" );
echo $uuid
}
virt-mem() {
VM="$1"
mem=$(virsh dumpxml $VM | grep "<memory" | sed "s/.*<memory unit='KiB'>\(.*\)<\/memory>.*/\1/g" );
echo $( expr $mem / 1024 )
}
virt-currmem() {
VM="$1"
mem=$(virsh dumpxml $VM | grep "<currentMemory" | sed "s/.*<currentMemory unit='KiB'>\(.*\)<\/currentMemory>.*/\1/g" );
echo $( expr $mem / 1024 )
}
virt-vcpu() {
VM="$1"
vcpu=$(virsh dumpxml $VM | grep "<vcpu" | sed "s/.*<vcpu[^>]*>\(.*\)<\/vcpu>.*/\1/g" );
echo $vcpu
}
virt-store() {
VM="$1"
# Oops! Not implemented yet, but basically this will retrieve the path to the VM file. Might not be true in all cases, however.
}
virt-info() {
echo "------------------------------------------------------------------------------------------------------------------------";
printf "%-30s%-17s%-12s%-12s%-8s%-40s\n" "VM Name" "IP Address" "Memory" "Current" "VCPUs" "UUID";
virsh -c qemu:///system list --all | grep -o '[0-9]* [a-z]*.*running' | while read -r line;
do
line_cropped=$(echo "$line" | sed 's/[0-9][ ]*\([-._0-9a-zA-Z]*\)[ ]*running/\1/' );
printf "%-30s%-17s%-12s%-12s%-8s%-40s\n" "$line_cropped" $( virt-addr "$line_cropped" ) $( virt-mem $line ) $( virt-currmem $line ) $( virt-vcpu $line ) $( virt-uuid $line );
done;
echo "------------------------------------------------------------------------------------------------------------------------";
}
I've forked it here: https://gist.github.com/kevteljeur/ad73ca9ca0cfe8f14458 - with some performance improvements to my listing code (it really is slow when re-reading the same file over and over) and it now also displays info for VMs that aren't running. Hope it helps someone, and if you're reading this and have a faster way to do anything, please share!
if the VMs network is bridge network. the script doesn't work with it. because ' arp -an' cann't find those VMs IP and MAC , could anybody help on this. thanks!!
I found a way to solve my problem. but need do something on virt-manager or virsh edit domain
1:using virt-manager , need add new hardware with channel. channel device need named of org.qemu.guest_agent.0. make sure the guest VM already installed the qemu-guest-agent package. enable and start this service of qemu-ga.service . if you have done those two process . that you can use the script to show the VMs IP.
2: using virsh command , just same with virt-manager. only edit the domain XML file. you can use virsh edit your-VM-domain.add the below hardware info:
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/**your-domain-name**.org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
after that: you can follow the method of using virt-manager. make sure installed qemu-guest-agent, and enable service of qemu-ga.service
Note there is now a command which returns IPs:
virsh domifaddr <domain> [interface] [–full] [–source lease|agent]
Example:
# virsh domifaddr fedora_vm --full
Name MAC address Protocol Address
-------------------------------------------------------------------------------
vnet0 52:54:00:2e:45:ce ipv6 2001:db8:0:f101::2/64
vnet1 52:54:00:b1:70:19 ipv4 192.168.105.201/16
vnet1 52:54:00:b1:70:19 ipv6 2001:db8:ca2:2:1::bd/128
vnet3 52:54:00:20:70:3d ipv4 192.168.105.240/16
And for DHCP leases:
# virsh net-dhcp-leases --network default
Expiry Time MAC address Protocol IP address Hostname Client ID or DUID
-------------------------------------------------------------------------------------------------------------------
2014-06-16 03:40:14 52:54:00:85:90:e2 ipv4 192.168.150.231/24 fedora20-test 01:52:54:00:85:90:e2
2014-06-16 03:40:17 52:54:00:85:90:e2 ipv6 2001:db8:ca2:2:1::c0/64 fedora20-test 00:04:b1:d8:86:42:e1:6a:aa:cf:d5:86:94:23:6f:94:04:cd
2014-06-16 03:34:42 52:54:00:e8:73:eb ipv4 192.168.150.181/24 ubuntu14-vm -
2014-06-16 03:34:46 52:54:00:e8:73:eb ipv6 2001:db8:ca2:2:1::5b/64 - 00:01:00:01:1b:30:c6:aa:52:54:00:e8:73:eb
VM=fedora25;
sudo virsh domifaddr $VM|tail -2 | awk '{print $4}'| cut -d/ -f1
i am sure a bash expert can make that line even better but it works for me and "if its not broken don't fix it" is a good rule for me
@marafa and rest here is an awk only script:
virsh domifaddr $VM | awk -F'[ /]+' '{if (NR>2) print $5}'
virt-info() {
echo "------------------------------------------------------------------------------------------------------------------------";
printf "%-30s%-17s%-12s%-12s%-8s%-40s\n" "VM Name" "IP Address" "Memory" "Current" "VCPUs" "UUID";
virsh -c qemu:///system list --all | grep -o '[0-9]* [a-z]*.*running' | while read -r line;
do
line_cropped=$(echo "$line" | sed 's/[0-9][ ]*\([-._0-9a-zA-Z]*\)[ ]*running/\1/' );
printf "%-30s%-17s%-12s%-12s%-8s%-40s\n" "$line_cropped" $( virt-addr "$line_cropped" ) $( virt-mem $line ) $( virt-currmem $line ) $( virt-vcpu $line ) $( virt-uuid $line );
done;
echo "------------------------------------------------------------------------------------------------------------------------";
}
This breaks if the ID is higher than 9
Change this line
line_cropped=$(echo "$line" | sed 's/[0-9][ ]*\([-._0-9a-zA-Z]*\)[ ]*running/\1/' );
To
line_cropped=$(echo "$line" | sed 's/[0-9]*[ ]*\([-._0-9a-zA-Z]*\)[ ]*running/\1/' );
@mistofvongola and the others.
If you have qmeu-agent installed on the guest machine you can user virsh to fetch the details directly from the VM using virsh.
Example commad: virsh domifaddr Squid-4.1-CentOS-Testing --source agent --full
(the --source agent
flag is important)
[root@kvm4 ~]# virsh list
Id Name State
----------------------------------------------------
1 KVM4-MANAGER running
2 Fast-Windows-10 running
3 CHR-LAB-CLIENT1 running
4 CHR-LAB-PX3 running
5 CHR-LAB-SERVER1 running
6 CHR-R1 running
7 Squid-4.1-CentOS-Testing running
[root@kvm4 ~]# virsh domifaddr Squid-4.1-CentOS-Testing --source agent --full
Name MAC address Protocol Address
-------------------------------------------------------------------------------
lo 00:00:00:00:00:00 ipv4 127.0.0.1/8
lo 00:00:00:00:00:00 ipv6 ::1/128
eth0 52:54:00:7e:7f:29 ipv4 192.168.89.59/24
eth0 52:54:00:7e:7f:29 ipv6 fe80::125d:b868:7bf7:11f0/64
eth1 52:54:00:18:05:6b N/A N/A
eth2 52:54:00:fd:79:85 N/A N/A
eth3 52:54:00:cc:ac:c8 N/A N/A
I know that this an old script, but still works well. I'm guessing others come here looking for it for the same reason as me. This was very useful for me. However, I found that more often, I wanted to see the list of all the addresses for all the running VMs, without having to do the list and then query separately. Here is my solution to that, using your code:
It could be better but I'm not a shell wizard, and I didn't need more at the time of writing. It probably could display more for each VM using the same technique (such as Mac address and some basic stats, RAM & drive limits, etc).