KVM 虚拟机信息查看工具

vmm这个工具是在 vminfo 的基础上根据自己的需求进行修改的,vminfo 的原作者在这里 https://github.com/opengers/vminfo

先介绍下 vmm 工具 (Virtual Machine Manager),如图

主要功能: 获取 KVM 宿主机上运行的所有虚拟机信息,包括NameIPCPU, MEM, DISK.

使用方法: 将文件拷贝到 /usr/sbin/vmm,执行 sudo vmm 即可。

vmm 的详细代码在 https://gist.github.com/vcent/d0ccd634629fdcf2b51c

#!/bin/bash

# clone from https://github.com/opengers/vminfo
# edit by wangzezhi


vm_info_file="/tmp/vminfo"

#get vm name
function get_vmnames() {  
    ps aux | grep "qemu-kvm " | grep -v 'grep' | \
    awk '{
        for(i=1;i<=NF;i++) {
            if($i == "-name"){ print $(i+1);break }
        }
    }' > $vm_info_file
}


#get all ip address from host and execute arp broadcast
function get_arptable() {  
        IpLists=`ifconfig | awk '/inet addr/ && !/127.0.0.1/ {print substr($2,6)}' | cut -d. -f 1-3`
        for iip in $IpLists
        do
            for ij in `seq 1 254`;do
                ( ping -W 1 -c 1 ${iip}.${ij} &>/dev/null) &
            done
            wait
        done
}

#get vm cpu,memory
function get_vcpuvmems() {  
    virsh dominfo "$1" | \
    awk '
        /^CPU\(s\)/ {print $2}
        /^Used memory/ {print $3/1024/1024"G"}
    ' | xargs
}

#get vhost block
#awk: change the unit "M" to "G"
function get_vmblk() {  
    blklist=$(virsh domblklist "$1" | awk 'NR>=3{if($2 != "-" && NF>=1) print $1":"$2}' | xargs)
    declare -i num && num=1
    for ii in ${blklist}
    do 
        blkbasename=`basename ${ii}`
        qemu-img info $(echo $ii | awk -F '[:]' '{print $2}') | \
        awk -v a="$ii" -v b="${blkbasename}" -v c="${num}" -v d="f${alter}" '
            /^virtual size:/ {Vsize=$3}
            /^disk size:/ {if($3 ~ /M/ && d == "f-s") Dsize=int(substr($3,1,match($3,/M/)-1)/1024*100)/100"G";else Dsize=$3}
        END{
            if(d == "f-s") print "d:"Dsize":v:"Vsize
            else if(d == "f-d") print a"["Dsize"]""["Vsize"]"
            else if(c >= 2) print "["Dsize"]""["Vsize"]"
            else print a"["Dsize"]""["Vsize"]"
        }'
        num+=1
    done | xargs | sed "s/ /,/g"
}

#get vm ip
function get_vmip() {  
    vm_mac="`virsh domiflist "$1" | awk 'NR>2{if($0 != "") print $5}' | xargs`"
    vm_mac=${vm_mac:-no_mac}
    iplists=`
        for ik in ${vm_mac}
        do
            arp -n | grep -i "${ik}" | awk '{print $1}'
        done | xargs | sed "s/ /,/g" 
    `
    echo ${iplists:-noip}
}

function usage() {  
    echo "option args: [-d | -i | -s ]"
        echo "usage:"
        echo "-i      display the vm ip"
        echo "-s      display the total resources"
        echo "-h      display this help"
}

function format_line() {  
get_vmnames  
get_arptable

for i in `cat $vm_info_file | awk '{print $1}'`;do  
    if [ "${alter}" == "-i" ];then
        vmipinfo="`get_vmip ${i}`"
        sed -i -r "/^${i}/s/.*/& ${vmipinfo}/g" $vm_info_file
    elif [ "${alter}" == "-s" ];then
        vcpumem="`get_vcpuvmems ${i}`"
        blkinfo_temp="`get_vmblk ${i}`"
        blkinfo=$(echo ${blkinfo_temp} | sed -r 's/\//\\\//g')
        sed -i -r "/^${i}/s/.*/& ${vcpumem} ${blkinfo}/g" $vm_info_file
    else
        vmipinfo="`get_vmip ${i}`"
        vcpumem="`get_vcpuvmems ${i}`"
        blkinfo_temp="`get_vmblk ${i}`"
        blkinfo=$(echo ${blkinfo_temp} | sed -r 's/\//\\\//g')
        sed -i -r "/^${i}/s/.*/& ${vmipinfo} ${vcpumem} ${blkinfo}/g" $vm_info_file

    fi
done  
}


function format_printf() {  
format_line

#Get the first output field width according to the size of the domain name
Length_tmp=$(cat $vm_info_file | awk 'BEGIN{A=0} {if(length($1)>=A) A=length($1)} END{print A}')  
Length=$((Length_tmp + 5))

case ${alter} in

-i)
    cat $vm_info_file | \
    awk -v L=${Length} '
    BEGIN{printf "%-*s %-15s\n",L,"Instance Name","IP Address";for(i=1;i<=14;i++)printf "---";print ""}
    {printf "%-*s %-15s\n",L,$1,$2}'
;;

-s)
    cat $vm_info_file | sed "s/G//g" | \
    awk -F'[ :,]' '
        BEGIN{ a=0;b=0 } {
        for(i=1;i<=NF;i++){
            if($i == "d") a+=$(i+1);
            else if($i == "v") b+=$(i+1) 
        };
        c+=$2;
        m+=$3 }
        END { printf "%-20s %-20s %-20s %-20s\n","vCPU","vRAM","DiskUsage","VdiskUsage";for(i=1;i<=34;i++)printf "---";print ""}
        END { printf "%-20s %-20s %-20s %-20s\n",c,m,b"G",a"G" }
    '
;;

-h)
    usage
;;

*)
    cat $vm_info_file | \
    awk -v L=${Length} '
    BEGIN{printf "%-*s %-27s %-6s %-6s %-20s\n",L,"Instance Name","IP Address","vCPU","vRAM","vDisk";for(i=1;i<=46;i++)printf "---";print ""}
    {printf "%-*s %-27s %-6s %-6s %-20s\n",L,$1,$2,$3,$4,$5,$6,$7,$8}'
;;
esac

}

alter=$1  
format_printf