Backup Kvm Vms With Python Libvirt
we changed the vm platform from esxi to kvm a few months ago,so we need to writ
e some scripts to backup vms automatically.
we only have a few vms,so we just need a simple script that can do the following operation:
- shutdown vm
- backup configure xml and images
- start vm
- send email when backup completely
so we write the following script to do that:
#!/usr/bin/env python3
import sys
import os
import time
import shutil
import libvirt
from xml.dom import minidom
import logging
logging.basicConfig(
level=logging.INFO,
encoding='utf-8',
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler("~/backup_vm.log"),
logging.StreamHandler(sys.stdout)
]
)
root_backup_dir='~/mnt'
backup_list = ['vm_1','vm_2','vm_3']
max_retry_count=20
def backup_vm(dom,domName):
logging.info("backup vm:{0} start".format(domName))
back_path = os.path.join(root_backup_dir,domName+time.strftime("_%Y%m%d", time.localtime()))
if not os.path.exists(back_path):
os.mkdir(back_path)
#backup xml
raw_xml = dom.XMLDesc(0)
with open(os.path.join(back_path,domName+'.xml'),'w+') as fp:
fp.write(raw_xml)
# backup vm disk
xml = minidom.parseString(raw_xml)
diskTypes = xml.getElementsByTagName('disk')
for diskType in diskTypes:
if diskType.getAttribute('device') != 'disk':
continue
sourceNode = diskType.getElementsByTagName('source')[0]
src=sourceNode.getAttribute('file')
shutil.copyfile(src,os.path.join(back_path,os.path.basename(src)))
logging.info("backup vm:{0} end".format(domName))
def main():
conn = libvirt.open("qemu:///system")
for domName in backup_list:
dom = conn.lookupByName(domName)
if dom.isActive():
dom.shutdown()
time.sleep(60)
retry_count=0
while len(backup_list) != 0:
for domName in backup_list:
dom = conn.lookupByName(domName)
if dom.isActive():
dom.shutdown()
time.sleep(5)
if retry_count > max_retry_count:
backup_list.remove(domName)
logging.error('重试次数超过最大值。虚拟机:{0}备份失败'.format(domName))
break
retry_count = retry_count +1
continue
backup_vm(dom,domName)
dom.create()
backup_list.remove(domName)
retry_count=0
break
conn.close()
if __name__ == '__main__':
try:
main()
from youjian import SendEmail
send = SendEmail()
user_list = ['[email protected]']
sub = u"备份虚拟机成功"
content = u"备份虚拟机成功"
send.send_mail(user_list,sub,content)
except Exception as e:
logging.error(e)
raise e