python2.7管理kvm虚拟主机
说明:
- 脚本是基于
python 2.7.5
版本调试- 脚本使用到
libvirt
库,请安装好相应的库
依赖库
检查 libvirt
库
[root@localhost ~]# python
Python 2.7.5 (default, Oct 30 2018, 23:45:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import libvirt
>>>
由与上述不一样,请安装好下面两个包即可
[root@localhost ~]# rpm -qa epel-release libvirt-python
epel-release-7-14.noarch
libvirt-python-4.5.0-1.el7.x86_64
python代码
#!/usr/bin/python
# coding=utf-8
import time
import libvirt
import getopt
import os
import sys
# 克隆主机的模板
## 通常启动所有主机时, 是不启动模板机的.
Template_name="CentOS7"
# 脚本使用参数指南
def help():
print('''
Usage:
python test.py [-o operate] [-n vmnames] [-c cloneName] [-l list]
-o operate: Operation of kvm virtual host, such as start, stop, restart, delete, clone..
-n vmnames: The kvm virtual host being operated, Separate multiple hosts with commas
-c cloneName: The parameters of the clone host must be used with the -o clone option and the -n parameter can only specify one host
-l list: View the running status of all kvm virtual machines on the machine
--ip: View all started kvm virtual host IP addresses
Example:
# Start multiple kvm virtual hosts
kvmmanage -o start -n test01,test02
# Shut down all kvm virtual hosts
kvmmanage -o stop -n all
# Quickly create kvm virtual host
kvmmanage -o clone -n CentOS7 -c test01
# delete kvm virtual host
kvmmanage -o delete -n test01
# View all started kvm virtual host IP addresses
kvmmanage --ip
''')
sys.exit()
# python脚本参数
def option(argv):
operate = cloneName = ''
vmnames = []
try:
opts, args = getopt.getopt(argv, "ho:n:c:l", ["help", "operate=", "vmnames=", "cloneName=", "list", "ip"])
except getopt.GetoptError:
help()
for opt, arg in opts:
if opt in ('-h', '--help'):
help()
elif opt in ("-o", "--operate"):
operate = arg
elif opt in ("-n", "--vmnames"):
vmnames = arg.split(",")
elif opt in ("-c", "--cloneName"):
cloneName = arg
elif opt in ("-l", "--list"):
conn = createConnection()
down_vm_list_name, up_vm_list_name = getStatusDomainName(conn)
print("未启动虚拟主机: %s" % down_vm_list_name)
print("已启动虚拟主机: %s" % up_vm_list_name)
closeConnection(conn)
elif opt == '--ip':
conn = createConnection()
down_vm_list_name, up_vm_list_name = getStatusDomainName(conn)
if len(up_vm_list_name) != 0:
vmnames_obj = getDomInfoByName(conn, up_vm_list_name)
vmnames_ip = getDomainIP(conn, vmnames_obj)
star = "*"
print("%skvm虚拟主机对应的IP地址%s" % (star * 8, star * 8))
for hostname, ip in dict(zip(up_vm_list_name, vmnames_ip)).items():
print("%15s: %s" % (hostname, ip))
print(star * 39)
else:
print("All kvm virtual hosts are not started")
closeConnection(conn)
check_option(operate, vmnames, cloneName, args)
return operate, vmnames, cloneName
# 检查命令参数
def check_option(operate, vmnames, cloneName, args):
if args != []:
help()
elif operate == "" or vmnames == []:
print("\033[1;31m[ERROR]\033[0m Except the parameters are list, help, the operation and vmnames parameters cannot be missing in other cases.\n")
sys.exit()
elif operate == "delete":
warn = raw_input("[Dangerous operation] Are you sure you want to delete the kvm virtual machine? [y/n]: ").strip()
if warn in ["y", "Y"]:
pass
elif operate == 'clone':
if cloneName == "" or len(vmnames) != 1:
print("\033[1;31m[ERROR]\033[0m When the -o clone parameter is used, the name of the new clone kvm virtual host must be specified with -c and the -n parameter can only specify one kvm virtual host name")
sys.exit()
elif "all" in vmnames:
if operate not in ["restart", "stop", "start"]:
print("\033[1;31m[ERROR]\033[0m When -n is specified as all, -o can only specify the operations of start, stop, restart\n")
sys.exit()
elif len(vmnames) != 1:
print("\033[1;31m[ERROR]\033[0m When -n contains all, then -n cannot have other kvm virtual hosts\n")
sys.exit()
# 创建 kvm 连接
def createConnection():
try:
conn = libvirt.open(None)
print("---Successfully opened connection to hypervisor---")
except Exception as e:
print(e)
else:
return conn
# 关闭 kvm 连接
def closeConnection(conn):
try:
conn.close()
print("---Successfully closed the hypervisor connection---")
except Exception as e:
print(e)
print("\n本次操作耗时 %.3f 秒" % (time.time() - t1))
sys.exit()
# 查看本机所有 kvm 虚拟主机运行情况
def getStatusDomainName(conn):
up_vm_list_id = conn.listDomainsID()
up_vm_list_name = []
for st_vm in up_vm_list_id:
up_vm_list_name.append(conn.lookupByID(st_vm).name())
down_vm_list_id = conn.listDefinedDomains()
down_vm_list_name = []
for sd_vm in down_vm_list_id:
down_vm_list_name.append(conn.lookupByName(sd_vm).name())
return down_vm_list_name, up_vm_list_name
# 操作 kvm 虚拟主机的对象
def getDomInfoByName(conn, vmnames, operate=None):
domain = ''
domains = []
if vmnames[0] == "all" and len(vmnames) == 1:
down_vm_list_name, up_vm_list_name = getStatusDomainName(conn)
if operate in ["stop", "restart"]:
vmnames = up_vm_list_name
elif operate == "start":
down_vm_list_name.remove(Template_name)
vmnames = down_vm_list_name
for vmname in vmnames:
try:
domain = conn.lookupByName(vmname)
domains.append(domain)
except Exception as e:
print(e)
closeConnection(conn)
return domains
# 获取kvm虚拟主机IP地址
def getDomainIP(conn, vmnames_obj):
vmnames_ip = []
for vmname_obj in vmnames_obj:
try:
ifaces = vmname_obj.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, 0)
except Exception as e:
print(e)
print("\033[1;31m[ERROR]\033[0m Failed to connect to the kvm virtual host, it may not be fully booted.")
closeConnection(conn)
for key, value in ifaces.items():
if key == "lo":
continue
else:
try:
for ip in value["addrs"]:
if ip["prefix"] == 24:
if ip["addr"] == '':
vmnames_ip.append(ip["None"])
else:
vmnames_ip.append(ip["addr"])
except Exception as e:
print(e)
print("\033[1;31m[ERROR]\033[0m Failed to obtain the IP network card information of the kvm virtual host, it may be that the network is not started normally. Please try again later...")
closeConnection(conn)
return vmnames_ip
# 操作kvm虚拟主机的方法
def manageVM(vms, operate, *args):
for vm in vms:
try:
if operate == "start":
vm.create()
elif operate == "stop":
vm.destroy()
elif operate == "restart":
vm.reboot()
elif operate == "clone" and args != "":
cvms = args[0].split(",")
for cvm in cvms:
clone_cmd = "virt-clone -o %s -n %s -f /var/lib/libvirt/images/%s.qcow2" % (vm.name(), cvm, cvm)
if os.system(clone_cmd) != 0:
closeConnection(conn)
elif operate == "delete":
delete_cmd = '''virsh undefine %s && rm -rf /var/lib/libvirt/images/%s.qcow2''' % (vm.name(), vm.name())
print("[CMD] %s" % delete_cmd)
if os.system(delete_cmd) != 0:
closeConnection(conn)
else:
print("[ERROR] %s 操作类型不正确" % operate)
closeConnection(conn)
except Exception as e:
print(e)
closeConnection(conn)
if __name__ == '__main__':
t1 = time.time()
if len(sys.argv) == 1:
help()
operate, vmnames, cloneName = option(sys.argv[1:])
conn = createConnection()
domains_obj = getDomInfoByName(conn, vmnames, operate)
manageVM(domains_obj, operate, cloneName)
if operate == "clone":
print("%s 克隆完成, 新的 kvm 虚拟机主机为 %s." % (vmnames[0], cloneName.split(",")))
elif vmnames[0] == "all":
print("所有kvm虚拟主机操作完成~~")
else:
print("%s kvm 虚拟主机 %s 操作完成~~~" % (vmnames, operate))
closeConnection(conn)