XenServer. Backup виртуальных машин.

При наличии XenServer появляется задача бэкапа виртуальных машин, я решил ее скриптом на Python. За основу была взята идея с этого сайта http://jansipke.nl/creating-backups-of-running-vms-in-xenserver/.

Дополнение от 03.02.2016. Скрипт переписан на bash: Linux. Backup виртуальных машин XenServer скриптом на bash.

# -*- coding: utf-8 -*-
"""
Бэкап всех виртуальных машин с XenServer на сетевое хранилище
 
Написан по мотивам http://jansipke.nl/creating-backups-of-running-vms-in-xenserver/
 
Принцип работы:
        В список result добавляются кортеж (uuid,имя машины), для всех виртуальных машин функцией get_backup_vms.
        Ко всем кортежам применяется функция backup_vm, которая создает снапшот целевой VM, восстанавливает его
                в новую VM экспортирует его на хранилище, потом удаляет новую VM.
 
"""
 
#импорт необходимых библиотек
 
import commands,os,time,subprocess
from glob import glob
 
#Объявление глобальных переменных
cifs="//10.10.10.10/backup"     #шара с бэкапами
mnt="/mnt/backup"               #папка куда монтируется шара
user_cifs="back"              	#пользователь для подключения к шаре
passwd_cifs="back"         	#пароль пользователя
mnt_xen="/mnt/xenserver" 	#папка, куда складываются бэкапы на примонтированной шаре
max_day_live = 14               #время жизни бэкапов в днях
 
def get_backup_vms():
   """
   функция составляющая список имеющихся виртуальных машин, список  состоит из кортежей вида (uuid, name)
   """
   result = []
 
   cmd = "xe vm-list is-control-domain=false is-a-snapshot=false"
   output = commands.getoutput(cmd)
 
   for vm in output.split("\n\n\n"):
      lines = vm.splitlines()
      uuid = lines[0].split(":")[1][1:]
      name = lines[1].split(":")[1][1:]
      result += [(uuid, name)]
 
   return result
 
def backup_vm(uuid, filename, timestamp):
   """
   делает дамп VM с предложенным uuid, восстанавливает дамп в новую VM,
   делает её бэкап на примонтированные хранилище и удаляет её.
   """
   cmd = "xe vm-snapshot uuid=" + uuid + " new-name-label=" + timestamp
   snapshot_uuid = commands.getoutput(cmd)
   cmd = "xe template-param-set is-a-template=false ha-always-run=false uuid=" + snapshot_uuid
   commands.getoutput(cmd)
   cmd = "xe vm-export vm=" + snapshot_uuid + " filename=" + filename
   commands.getoutput(cmd)
   cmd = "xe vm-uninstall uuid=" + snapshot_uuid + " force=true"
   commands.getoutput(cmd)
 
def rm_old_back(dir_pwd):
    """
    удаляет папки и файлы старше max_day_live дней.
    """
    day_today = time.gmtime()
    for i in glob (dir_pwd + "/*"):
        file_metadata = os.stat("%s" %i)
        file_day = time.localtime(file_metadata.st_mtime)
        if (int(day_today.tm_year) - int(file_day.tm_year)) == 0:
            if (int(day_today.tm_yday) - int(file_day.tm_yday)) > max_day_live:
                try:
                    os.rmdir("%s" %i)
                except:
                    os.remove("%s" %i)
        elif (int(day_today.tm_year) - int(file_day.tm_year)) <> 0:
            if (int(day_today.tm_yday)+365*(int(day_today.tm_year) - int(file_day.tm_year)) - int(file_day.tm_yday)) > max_day_live:
                try:
                    os.rmdir("%s" %i)
                except:
                    os.remove("%s" %i)
 
 
def main():
 
    subprocess.call("mount -t cifs %s %s -o username=%s,password=%s" % (cifs,mnt,user_cifs,passwd_cifs), shell=True)
    dirname=time.strftime("%m_%d_%y", time.gmtime())
    os.mkdir("%s/%s" % (mnt_xen,dirname))
    for (uuid, name) in get_backup_vms():
       print uuid, name
       timestamp = time.strftime("%Y%m%d-%H%M", time.gmtime())
       filename = "\"" + mnt_xen + "/" +dirname + "/" + timestamp + " " + name + ".xva\""
       backup_vm(uuid, filename, timestamp)
    rm_old_back(mnt_xen)
    subprocess.call("umount %s" % mnt, shell=True)
 
main()

Для восстановления виртуальных машин из бэкапа нужно воспользоваться командой:

xe vm-import filename=/путь до созданного бэкапа/необходимый бэкап

Все протестировано и работает в боевых условиях.