Centos7环境下全自动创建kvm虚拟机

作者: ropon 分类: Kvm 发布时间: 2017-04-13 23:25

主要功能

  • 自动配置外网、内网ip
  • 自动设置主机名
  • 自动扩容数据盘
  • 可预设定vnc、root密码

具体代码

#!/bin/bash
#centos6,7 模板数据盘都是10G

export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"

dateTime=$(date +%Y%m%d%H%M%S)
tmpDiskFile6_os="/vmdata/template/centos64_os"
tmpDiskFile6_data="/vmdata/template/centos64_data"
tmpDiskFile7_os="/vmdata/template/template_os.qcow2"
tmpDiskFile7_data="/vmdata/template/template_data.qcow2"
vmDir="/vmdata"
test -d $vmDir || mkdir -p $vmDir
vncpasswd="ropon.top"
newpasswd="ropon.top"

help() {
    cat >> /dev/stdout <<EOF
Usage: $(basename $0) vmname vcpu memory ip [TempleteDiskFile] | -h
Example: ./$(basename $0) vmname=ebs-11 vcpu=1 memory=1024M datasize=20 ip=192.168.7.221 ostype=centos7
Example: ./$(basename $0) vmname=ebs-2 vcpu=1 memory=1024M datasize=20 ip=192.168.123.12 ostype=centos6
Example: ./$(basename $0) -h     //print help infomations
EOF
}

error() {
    echo -e "input parameter error: $1 \n please try again!"
}

if [[ "$#" -eq 0 || "$1" == "-h" ]]; then
    help
    exit 0
fi

for line in $@
    do
    case $line in
    vmname*)
        vmName=$(echo $line | awk -F "=" '{print $2}')
        ;;
    vcpu*)
        vCpu=$(echo $line | awk -F "=" '{print $2}')
        if ! echo $vCpu | grep '^[0-9]$' > /dev/null; then
            error $line
            help
            exit 1
        fi
        ;;
    memory*)
        memTmp=$(echo $line | awk -F "=" '{print $2}')
        memNum=$(echo ${memTmp:0:${#memTmp}-1})
        memUnit=$(echo ${memTmp:0-1} | tr '[a-z]' '[A-Z]')
        if ! echo $memNum | grep '[0-9]' > /dev/null; then
            error $line
            help
            exit 1
        fi
        if [[ "$memUnit" != "G" && "$memUnit" != "M" && "$memUnit" != "K" ]]; then
            error $line
            help
            exit 1
        fi
        ;;
    datasize*)
        datasize=$(echo $line | awk -F "=" '{print $2}')
        if ! echo $datasize | grep '^[0-9]' > /dev/null; then
            error $line
            help
            exit 1
        fi
        ;;
    ip*)
        vmIp=$(echo $line | awk -F "=" '{print $2}')
        if ! echo $vmIp | grep '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' > /dev/null; then
            error $line
            help
            exit 1
        fi
        ;;
    ostype*)
        ostype=$(echo $line | awk -F "=" '{print $2}')
        [ $ostype == "centos6" ] && echo "you chose centos6" && diskFile=$tmpDiskFile6_os && diskFile1=$tmpDiskFile6_data
        [ $ostype == "centos7" ] && echo "you chose centos7" && diskFile=$tmpDiskFile7_os && diskFile1=$tmpDiskFile7_data
        if [ ! -f "$diskFile" ] || [ ! -f "$diskFile1" ] ; then
            error $line
            help
            exit 1
        fi
        ;;
    *)
        error $line
        help
        exit 1
        ;;
    esac
done

if [ -z "$vmName" ] || [ -z "$vCpu" ] || [ -z "$memNum" ] || [ -z "$vmIp" ];
    then
    echo -e "input parameter incomplete: $@"
    help
    exit 1
fi

#read -p "please input vnc passwd:" vncpasswd
if [ -z $vncpasswd ] ;then
    vncpasswd=`echo $RANDOM|md5sum|cut -c 1-6`
fi
create_config() {
memUnit="$memUnit"iB
cat > $vmDir/$vmName/$vmName.xml <<EOF
<domain type='kvm'>
  <name>$vmName</name>
  <uuid>$vmUuid</uuid>
  <memory unit='$memUnit'>$memNum</memory>
  <currentMemory unit='$memUnit'>$memNum</currentMemory>
  <vcpu placement='static'>$vCpu</vcpu>
  <cpu mode='host-passthrough'/>
  <os>
    <type arch='x86_64' machine='pc'>hvm</type>
    <boot dev='cdrom'/>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='$vmDir/$vmName/$vmNameos'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='$vmDir/$vmName/$vmNamedata'/>
      <target dev='vdb' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x16' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </controller>
    <interface type='bridge'>
      <mac address='$vmMac'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <interface type='bridge'>
      <mac address='$vmMac1'/>
      <source bridge='br1'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x13' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' passwd='$vncpasswd'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <video>
      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </memballoon>
  </devices>
</domain>
EOF
}

create_mac() {
test -f /tmp/mac.py && rm -f /tmp/mac.py
cat > /tmp/mac.py <<EOF
#!/usr/bin/python
# macgen.py script to generate a MAC address for Red Hat Virtualization guests
#
import random
#
def randomMAC():
        mac = [ 0x54, 0x52, 0x00,
                random.randint(0x00, 0x7f),
                random.randint(0x00, 0xff),
                random.randint(0x00, 0xff) ]
        return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()
EOF
vmMac=$(python /tmp/mac.py)
vmMac1=$(python /tmp/mac.py)
}

create_uuid() {
vmUuid=$(uuidgen)
}

dots() {
sec=$1
while true
    do
    echo -e ".\c"
    sleep $sec
done
}

define_kvm() {

virsh define $vmDir/$vmName/$vmName.xml
if [ $? -ne 0 ]; then
    echo -e "virsh define $vmName.xml error!"
    exit 1
fi
virsh start $vmName
if [ $? -ne 0 ]; then
    echo -e "virsh start $vmName error!"
    exit 1
fi
virsh list
vncPort=$(virsh vncdisplay $vmName)
vncIp=`ifconfig br0|grep -w inet|awk '{print $2}'`
echo -e "VNC IP and Port is: $vncIp$vncPort"
echo -e "$vmName vnc passwd:$vncpasswd \n"
}

modify_disk() {
    #vmHostName=$(echo $vmIp | awk -F "." '{print "YN-" $3 "-" $4}')
    vmIpPri=172.16.$(echo $vmIp | awk -F "." '{print $3 "." $4}')
    #vmGy=${vmIp%.*}.1
    vmGy=192.168.0.1
    vmNm=255.255.248.0
    vmNm1=255.255.255.0
    mnttemp=/tmp/$vmName
    [ ! -d $mnttemp ] && mkdir -p $mnttemp
    guestmount -a $vmDir/$vmName/$vmNameos  -m /dev/sda2  --rw $mnttemp
    if [ $? -ne 0 ]; then
        echo -e "mount $vmDir/$vmName/$vmNameos failed! "
        exit 1
    fi
    tmpGy="$mnttemp/etc/sysconfig/network"
    tmpIp1="$mnttemp/etc/sysconfig/network-scripts/ifcfg-eth0"
    tmpIp2="$mnttemp/etc/sysconfig/network-scripts/ifcfg-eth1"
    sed -i "/^127.0/a\127.0.0.1   $vmName"  $mnttemp/etc/hosts
    sed -i "s/GATEWAY=/GATEWAY=$vmGy/g" $tmpGy
    sed -i "s/IPADDR=/IPADDR=$vmIp/g" $tmpIp1
    sed -i "s/NETMASK=/NETMASK=$vmNm/g" $tmpIp1
    sed -i "s/IPADDR=/IPADDR=$vmIpPri/g" $tmpIp2
    sed -i "s/NETMASK=/NETMASK=$vmNm1/g" $tmpIp2
    #read -p "please input root passwd:" newpasswd
    if [ -z $newpasswd ] ;then
        newpasswd=`echo $RANDOM|md5sum|cut -c 7-12`
    fi
    sed -i "s/passwdtemp/$newpasswd/g" $mnttemp/root/set.sh
    sed -i "s/vmnametemp/$vmName/g" $mnttemp/root/set.sh
    sed -i "s/tempdisksize/$tempdisksize/g" $mnttemp/root/set.sh
    sed -i "/^touch/a\/root/set.sh"  $mnttemp/etc/rc.d/rc.local
    sleep 1
    umount $mnttemp
    sleep 1
    rm -rf $mnttemp
}

main() {
    vmNameos="$vmName"_os.qcow2
    vmNamedata="$vmName"_data.qcow2
    test -d $vmDir/$vmName || mkdir -p $vmDir/$vmName
    if [ -f "$vmDir/$vmName/$vmName.xml" ]; then
        mv $vmDir/$vmName/$vmName.xml $vmDir/$vmName/$vmName.xml.$dateTime
        echo -e "$vmDir/$vmName/$vmName.xml exist, rename $vmDir/$vmName/$vmName.xml.$dateTime "
    fi
    echo -e "create virtual machine config file:"
    [ -f "/etc/libvirt/qemu/$vmName.xml" ] && echo -e "$vmName is exist, Please check!" && exit 1
    create_mac
    create_uuid
    create_config
    echo -e "create config file($vmDir/$vmName/$vmName.xml) success"
    if [ ! -f "$diskFile" ]; then
        echo -e "$diskFile not found, Please try again!"
        exit 1
    fi
    if [ ! -f "$diskFile1" ]; then
        echo -e "$diskFile1 not found, Please try again!"
        exit 1
    fi
    if [ -f "$vmDir/$vmName/$vmNameos" ]; then
        mv $vmDir/$vmName/$vmNameos $vmDir/$vmName/$vmNameos.$dateTime
        echo -e "$vmDir/$vmName/$vmName exist, rename $vmDir/$vmName/$vmName.$dateTime "
    fi
    echo -e "cow 写时复制新技术生成: $vmDir/$vmName/$vmNameos"
    qemu-img create -f qcow2 -b $diskFile $vmDir/$vmName/$vmNameos
    echo -e "cow 写时复制新技术生成: $vmDir/$vmName/$vmNamedata"
    qemu-img create -f qcow2 -b $diskFile1 $vmDir/$vmName/$vmNamedata
    [ $ostype == "centos7" ] && tempdisksize=$[datasize -10]
    [ $ostype == "centos6" ] && tempdisksize=$[datasize -10]
    if [ $tempdisksize -gt 0 ];then
        echo -e "modify data_os size ..."
        qemu-img resize $vmDir/$vmName/$vmNamedata +${tempdisksize}G
    fi
}

startTime=`date +%s`
main
echo
echo -e "modify virtual machine IP and Hostname..."
modify_disk
echo -e "define virtual machine ..."
define_kvm
echo -e "$vmName ip: $vmIp\n"
echo -e "$vmName gy: $vmGy\n"
echo -e "$vmName nip: $vmIpPri\n"
echo -e "$vmName root passwd:$newpasswd \n"
echo -e "create KVM virtual machine:$vmName finish! \n"
endTime=`date +%s`
installTime=$[$endTime-$startTime]
echo "create kvm time: $installTime second"

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注