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

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

1、自动配置外网、内网ip
2、自动设置主机名
3、自动扩容数据盘
4、可预设定vnc、root密码
5、需要注意的是:模板磁盘格式只能使用raw

#!/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/centos7_os"
tmpDiskFile7_data="/vmdata/template/centos7_data"
vmDir="/vmdata"
test -d $vmDir || mkdir -p $vmDir

help() {
	cat >> /dev/stdout <<EOF
Usage: $(basename $0) vmname vcpu memory ip [TempleteDiskFile] | -h
Example: ./$(basename $0) vmname=ebs-1 vcpu=1 memory=1024M datasize=20 ip=192.168.199.70 ostype=centos6
Example: ./$(basename $0) vmname=ebs-2 vcpu=1 memory=1024M datasize=20 ip=192.168.199.71 ostype=centos7
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>
  <os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>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/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='$vmDir/$vmName/${vmNameos}.qcow2'/>
      <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}.qcow2'/>
      <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}')
vmIpPri=172.16.$(echo $vmIp | awk -F "." '{print $3 "." $4}')
vmGy=${vmIp%.*}.1
vmNm=255.255.255.0
vmNm1=255.255.255.0
sectorSize=$(parted $vmDir/$vmName/$vmNameos unit s print | awk '/Sector size/{print $4}' | awk -F "B" '{print $1}')
[ $ostype == "centos7" ] && sst=$(parted $vmDir/$vmName/$vmNameos unit s print | awk '/ 1  /{print $2}')
[ $ostype == "centos6" ] && sst=$(parted $vmDir/$vmName/$vmNameos unit s print | awk '/ 2  /{print $2}')
startSector=${sst:0:${#sst}-1}
offSet=$(($startSector*$sectorSize))
mnttemp=/tmp/$vmName
mkdir -p $mnttemp
mount -o loop,offset=$offSet $vmDir/$vmName/$vmNameos $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
}

convert_disk() {
	dots 3 &
	bgPid2=$!
	qemu-img convert -f raw -O qcow2 $vmDir/$vmName/$vmNameos $vmDir/$vmName/${vmNameos}.qcow2
	kill $bgPid2 > /dev/null
	sleep 2
	dots 3 &
	bgPid3=$!
	qemu-img convert -f raw -O qcow2 $vmDir/$vmName/$vmNamedata $vmDir/$vmName/${vmNamedata}.qcow2
	kill $bgPid3 > /dev/null
	rm -rf $vmDir/$vmName/$vmNameos $vmDir/$vmName/$vmNamedata
}

main() {
	vmNameos="$vmName"_os
	vmNamedata="$vmName"_data
	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 "create virtual machine disk file: $vmDir/$vmName/$vmNameos"
	dots 3 &
	bgPid=$!
	cp $diskFile $vmDir/$vmName/$vmNameos
	kill $bgPid > /dev/null
	echo -e "\n"
	sleep 2
	echo -e "create virtual machine disk file: $vmDir/$vmName/$vmNamedata"
	dots 3 &
	bgPid1=$!
	cp $diskFile1 $vmDir/$vmName/$vmNamedata
	kill $bgPid1 > /dev/null
	echo -e "\n"
	[ $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
}

main
echo
echo -e "modify virtual machine IP and Hostname..."
modify_disk
echo -e " convert disk "
convert_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"

 

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

发表评论

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