def migrate(src_host, src_vmid, dst_host, dst_vmid, ifaces): assert getState(dst_host, dst_vmid) == generic.State.CREATED, "Destination VM already exists" state = getState(src_host, src_vmid) if state == generic.State.CREATED: #nothing to do return #create a tmp directory on both hosts src_tmp = "/tmp/%s" % uuid.uuid1() dst_tmp = "/tmp/%s" % uuid.uuid1() fileutil.mkdir(src_host, src_tmp) fileutil.mkdir(dst_host, dst_tmp) #create destination vm create(dst_host, dst_vmid) #transfer vm disk image fileutil.copy(src_host, _imagePath(src_vmid), "%s/disk.qcow2" % src_tmp) fileutil.fileTransfer(src_host, "%s/disk.qcow2" % src_tmp, dst_host, "%s/disk.qcow2" % dst_tmp, direct=True) if state == generic.State.STARTED: #prepare rdiff before snapshot to save time src_host.execute("rdiff signature %(tmp)s/disk.qcow2 %(tmp)s/rdiff.sigs" % {"tmp": src_tmp}) #create a memory snapshot on old host _monitor(src_host, src_vmid, "stop") _monitor(src_host, src_vmid, "savevm migrate", timeout=900) #stop vm stop(src_host, src_vmid) #create and transfer a disk image rdiff src_host.execute("rdiff -- delta %(tmp)s/rdiff.sigs %(disk)s - | gzip > %(tmp)s/disk.rdiff.gz" % {"tmp": src_tmp, "disk": _imagePath(src_vmid)}) fileutil.fileTransfer(src_host, "%s/disk.rdiff.gz" % src_tmp, dst_host, "%s/disk.rdiff.gz" % dst_tmp) #patch disk image with the rdiff dst_host.execute("gunzip < %(tmp)s/disk.rdiff.gz | rdiff -- patch %(tmp)s/disk.qcow2 - %(tmp)s/disk-patched.qcow2" % {"tmp": dst_tmp}) fileutil.move(dst_host,"%s/disk-patched.qcow2" % dst_tmp, "%s/disk.qcow2" % dst_tmp) #use disk image on new host useImage(dst_host, dst_vmid, "%s/disk.qcow2" % dst_tmp) for iface in ifaces: addInterface(dst_host, dst_vmid, iface) if state == generic.State.STARTED: start(dst_host, dst_vmid) #restore snapshot _monitor(dst_host, dst_vmid, "stop") _monitor(dst_host, dst_vmid, "loadvm migrate", timeout=900) _monitor(dst_host, dst_vmid, "cont") _monitor(dst_host, dst_vmid, "delvm migrate", timeout=900) #destroy vm on old host destroy(src_host, src_vmid) #remove tmp directories fileutil.delete(src_host, src_tmp, recursive=True) fileutil.delete(dst_host, dst_tmp, recursive=True)
def migrate(src_host, src_vmid, dst_host, dst_vmid, template, ifaces): assert getState(dst_host, dst_vmid) == generic.State.CREATED, "Destination VM already exists" state = getState(src_host, src_vmid) if state == generic.State.CREATED: #nothing to do return #create a tmp directory on both hosts src_tmp = "/tmp/%s" % uuid.uuid1() dst_tmp = "/tmp/%s" % uuid.uuid1() fileutil.mkdir(src_host, src_tmp) fileutil.mkdir(dst_host, dst_tmp) #create destination vm create(dst_host, dst_vmid, template) try: #transfer vm disk image copyImage(src_host, src_vmid, "%s/disk.tar" % src_tmp) fileutil.fileTransfer(src_host, "%s/disk.tar" % src_tmp, dst_host, "%s/disk.tar" % dst_tmp, compressed=True) if state == generic.State.STARTED: #prepare rdiff before snapshot to save time src_host.execute("rdiff signature %(tmp)s/disk.tar %(tmp)s/rdiff.sigs" % {"tmp": src_tmp}) #create a memory snapshot on old host res = _vzctl(src_host, src_vmid, "chkpnt", ["--dumpfile", "%s/openvz.dump" % src_tmp]) assert fileutil.existsFile(src_host, "%s/openvz.dump" % src_tmp), "Failed to create snapshot: %s" % res try: fileutil.fileTransfer(src_host, "%s/openvz.dump" % src_tmp, dst_host, "%s/openvz.dump" % dst_tmp, compressed=True) #create and transfer a disk image rdiff copyImage(src_host, src_vmid, "%s/disk2.tar" % src_tmp) src_host.execute("rdiff -- delta %(tmp)s/rdiff.sigs %(disk)s - | gzip > %(tmp)s/disk.rdiff.gz" % {"tmp": src_tmp, "disk": "%s/disk2.tar" % src_tmp}) fileutil.fileTransfer(src_host, "%s/disk.rdiff.gz" % src_tmp, dst_host, "%s/disk.rdiff.gz" % dst_tmp, direct=True) #patch disk image with the rdiff dst_host.execute("gunzip < %(tmp)s/disk.rdiff.gz | rdiff -- patch %(tmp)s/disk.tar - %(tmp)s/disk-patched.tar" % {"tmp": dst_tmp}) fileutil.move(dst_host,"%s/disk-patched.tar" % dst_tmp, "%s/disk.tar" % dst_tmp) except: _vzctl(src_host, src_vmid, "restore", ["--dumpfile", "%s/openvz.dump" % src_tmp]) raise #use disk image on new host useImage(dst_host, dst_vmid, "%s/disk.tar" % dst_tmp) for iface in ifaces: addInterface(dst_host, dst_vmid, iface) if state == generic.State.STARTED: try: #restore snapshot _vzctl(dst_host, dst_vmid, "restore", ["--dumpfile", "%s/openvz.dump" % dst_tmp]) assert getState(dst_host, dst_vmid) == generic.State.STARTED except: _vzctl(src_host, src_vmid, "restore", ["--dumpfile", "%s/openvz.dump" % src_tmp]) raise except: destroy(dst_host, dst_vmid) fileutil.delete(src_host, src_tmp, recursive=True) fileutil.delete(dst_host, dst_tmp, recursive=True) raise #destroy vm on old host destroy(src_host, src_vmid) #remove tmp directories fileutil.delete(src_host, src_tmp, recursive=True) fileutil.delete(dst_host, dst_tmp, recursive=True)