Dear Chris,

It is not true, you can snapshot a machine, then clone the snapshot and
export it for backup purposes after that you can remove the snapshot, all
on the live VM.
However, you need newer versions of libvirt to do that, right now we are
using CentOS 7.1 and the libvirt that comes with it is capable of doing
live merge which is necessary to achieve this.

But i have to warn you, we are experiencing a problem when removing the
snapshots (the part is commented in the attached script) it sometimes
kills virtual machines in a way that makes it necessary to put the
hypervisor to maintenance and then restart vdsmd and libvirtd before you
can start that VM again.

There is a bug filed already and it is in progress

https://bugzilla.redhat.com/show_bug.cgi?id=1231754

I also have to add that i newer version of libvirt (on Fedora 20 with the
libvirt preview repo) did not have that problem, so i am confident that
this will be solved soon.

Last but not least there is a plan to be able to export snapshots right
away for backup without having to clone them first, this is a huge step
forward for the backup procedure in terms of time that is needed and the
load on the storage and hypervisor systems.

I would really appreciate if you would help improving that script (we are
not python developers), i will see that i make this a github project or
something like that

Cheers
Soeren





On 08/07/15 17:13, "users-boun...@ovirt.org on behalf of Chris Jones -
BookIt.com Systems Administrator" <users-boun...@ovirt.org on behalf of
chris.jo...@bookit.com> wrote:

> From what I can tell, you can only backup a VM to an export domain if
>the VM is shut down. Is a live VM backup not possible through oVirt? If
>not, why not? Most other virtualization tools can handle this.
>
>If it is possible, how do I do it through the backup API?
>api.vms.myvm.export requires it to be shutdown so what would the
>alternative be?
>
>Thanks.
>
>-- 
>This email was Virus checked by UTM 9. For issues please contact the
>Windows Systems Admin.
>_______________________________________________
>Users mailing list
>Users@ovirt.org
>http://lists.ovirt.org/mailman/listinfo/users

#!/usr/bin/python

import Queue
import threading
import time
from ovirtsdk.api import API
from ovirtsdk.xml import params
import sys
import datetime
import smtplib
from email.mime.text import MIMEText


global SNAPSHOT_NAME

VERSION             = params.Version(major='3', minor='0')
ENGINE_SERVER       = ''
ENGINE_USER         = ''
ENGINE_PASSWORD     = ''
ENGINE_CERT         = ''
NOW                 = datetime.datetime.now()
SNAPSHOT_NAME       = 'BACKUP_' + NOW.strftime("%Y-%m-%d-%H%M")
DAY_OF_WEEK         = NOW.strftime("%w")
BACKUP              = "FULL"

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
        self.api = api
        global message
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data.name)
            vm = api.vms.get(name=data.name)
            vmname = data.name +"_"
            newvmname = vmname + SNAPSHOT_NAME
            cluster = api.clusters.get(id=vm.cluster.id)
            dc = api.datacenters.get(id=cluster.data_center.id)
            export = None
            for sd in dc.storagedomains.list():
                if sd.type_ == "export":
                    export = sd
            if not export:
                print("Export domain required, and none found, exitting...\n")
                sys.exit(1)
            if (data.name != 'HostedEngine' and cluster.name == 'CC-01'):
                vm.snapshots.add(params.Snapshot(description=SNAPSHOT_NAME, vm=vm ))
                snap = vm.snapshots.list(description=SNAPSHOT_NAME)[0]
                while vm.snapshots.get(id=snap.id).snapshot_status == "locked":
                    print("%s Waiting for snapshot of %s to finish") % (threadName, vm.name)
                    time.sleep(60)
                print("%s Snapshotting %s is done") % (threadName,vm.name)
                try:
                    snapshots = params.Snapshots(snapshot=[params.Snapshot(id=snap.id)])
                    api.vms.add(params.VM(name=newvmname, snapshots=snapshots, cluster=cluster, template=api.templates.get(name="Blank")))
                    while api.vms.get(name=newvmname).status.state == "image_locked":
                        print("%s Waiting for clone of %s to finish") % (threadName, vm.name)
                        time.sleep(300)
                    print("%s Cloning of %s  done") % (threadName, vm.name)
                    api.vms.get(name=newvmname).export(params.Action(storage_domain=export))
                    while api.vms.get(name=newvmname).status.state == "image_locked":
                        print("%s Waiting for export of %s finish") % (threadName, vm.name)
                        time.sleep(300)
                    print("%s Exporting %s done") % (threadName, vm.name)
                    api.vms.get(name=newvmname).delete()
                except Exception as e:
                    print ("Something went wrong with the cloning or exporting\n%s") % str(e)
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Backup-Thread-1", "Backup-Thread-2", "Backup-Thread-3", "Backup-Thread-4"]

def Connect():
    global api
    api = API(url=ENGINE_SERVER, username=ENGINE_USER, password=ENGINE_PASSWORD, ca_file=ENGINE_CERT)

def Disconnect(exitcode):
    api.disconnect()
    sys.exit(exitcode)

try:
    Connect()
    vms = api.vms.list()

except Exception as e:
    print 'Failed:\n%s' % str(e)

nameList = vms 
queueLock = threading.Lock()
workQueue = Queue.Queue(0)
threads = []
threadID = 1

# Create new threads for backup
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# Fill the queue
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Wait for queue to empty
while not workQueue.empty():
    pass

# Notify threads it's time to exit
exitFlag = 1

# Wait for all threads to complete
for t in threads:
    t.join()
print "Cloning and Exporting done"
api.disconnect()
#print "Snapshot deletion"
#try:
#    time.sleep(300)
#    Connect()
#    vms = api.vms.list()
#    for vm in vms:
#        snapshotlist = vm.snapshots.list()
#        for snapshot in snapshotlist:
#            if snapshot.description != "Active VM":
#                snapshot.delete()
#                time.sleep(60)
#                try:
#                    while api.vms.get(name=vm.name).snapshots.get(id=snapshot.id).snapshot_status == "locked":
#                        print("Waiting for snapshot %s on %s deletion to finish") % (snapshot.description, vm.name)
#                        time.sleep(300)
#                except Exception as e:
#                    print ("Snapshot %s does not exist anymore") % snapshot.description
#        print ("Snapshot deletion for %s done") % vm.name
#    print ("Deletion of snapshots done") 
#    api.disconnect()
#except Exception as e:
#    print ("Something went wrong when deleting the snapshots\n%s") % str(e)

_______________________________________________
Users mailing list
Users@ovirt.org
http://lists.ovirt.org/mailman/listinfo/users

Reply via email to