def useImage(host, vmid, image, forceGzip=False): assert getState(host, vmid) == generic.State.PREPARED, "VM not prepared" assert fileutil.existsFile(host, image), "Image does not exist" dst = _imagePath(vmid) fileutil.delete(host, dst, recursive=True) fileutil.mkdir(host, dst) fileutil.unpackdir(host, image, dst, "-z" if forceGzip else "")
def destroy(host, vmid): assert getState(host, vmid) != generic.State.STARTED, "VM not stopped" fileutil.delete(host, _imagePath(vmid)) fileutil.delete(host, _logFile(vmid)) fileutil.delete(host, _pidFile(vmid)) fileutil.delete(host, _vncPidFile(vmid)) fileutil.delete(host, _profileFile(vmid)) assert getState(host, vmid) == generic.State.CREATED, "Failed to destroy VM"
def startCaptureToFile(host, name, iface, filter=""): assert name, "Name not given" assert ifaceutil.interfaceExists(host, iface), "Interface does not exist" assert _checkSyntax(host, filter=filter), "Syntax error: tcpdump -i %s %s" % (iface, filter) rdir = _remoteDir(name) fileutil.delete(host, rdir, True) fileutil.mkdir(host, rdir) ifaceutil.ifup(host, iface) _tcpdump(host, "-i %(iface)s -n -C 10 -w %(rdir)s/capture -U -W 5 -s0 %(filter)s >/dev/null 2>&1 </dev/null & echo $! > %(rdir)s.file.pid" % {"iface": util.escape(iface), "rdir": rdir, "filter": util.escape(filter) })
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)
def _createHostFile(endpoint): path = _tmpPath(endpoint) fileutil.mkdir(util.localhost, path+"/hosts") util.localhost.execute("openssl genrsa -out %s/rsa_key.priv" % path) hostFd = open("%s/hosts/%s" % (path, _tincName(endpoint)), "w") hostFd.write("Address=%s\n" % endpoint.getHost()) hostFd.write("Port=%s\n" % endpoint.getPort()) hostFd.write("Cipher=none\n") hostFd.write("Digest=none\n") for sn in endpoint.getSubnets(): hostFd.write("Subnet=%s\n" % sn) util.localhost.execute("openssl rsa -pubout -in %s/rsa_key.priv -out %s/hosts/%s.pub" % (path, path, _tincName(endpoint))) hostPubFd = open("%s/hosts/%s.pub" % (path, _tincName(endpoint)), "r") shutil.copyfileobj(hostPubFd, hostFd) hostFd.close() hostPubFd.close() fileutil.delete(util.localhost, "%s/hosts/%s.pub" % (path, _tincName(endpoint)))
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 _qm(host, vmid, cmd, params=[], maxWait=30, unlock=True): waitStep = 1 while True: try: return host.execute("qm %s %d %s" % (util.escape(cmd), vmid, " ".join(map(util.escape, params)))) except exceptions.CommandError, exc: if not (exc.errorCode == 4 and "lock" in exc.errorMessage and "timeout" in exc.errorMessage): raise if maxWait > 0: time.sleep(waitStep) #print "wait %s" % waitStep waitStep *= 2 maxWait -= waitStep else: if not unlock: raise unlock = False #print "unlock" fileutil.delete(host, "/var/lock/qemu-server/lock-%d.conf" % vmid)
def stop(host, vmid): assert getState(host, vmid) != generic.State.CREATED, "VM not running" process.killPidfile(host, _pidFile(vmid)) fileutil.delete(host, _logFile(vmid)) assert getState(host, vmid) == generic.State.PREPARED, "Failed to stop VM"
def removeCapture(host, name): rdir = _remoteDir(name) fileutil.delete(host, rdir, recursive=True) fileutil.delete(host, "%s.*.pid" % rdir)
def _deleteFiles(endpoint): assert getState(endpoint) != generic.State.STARTED fileutil.delete(endpoint.getHost(), _configDir(endpoint), recursive=True)
def _removeTemporaryFiles(endpoint): fileutil.delete(util.localhost, _tmpPath(endpoint), recursive=True)
def _deleteConfig(host, port): assert getState(host, port) != generic.State.STARTED fileutil.delete(host, _configPath(port))
def _removeTemporaryFiles(port): fileutil.delete(util.localhost, _tmpFile(port))
def _deleteFiles(endpoint): if getState(endpoint) == generic.State.STARTED: _stopEndpoint(endpoint) fileutil.delete(endpoint.getHost(), _configDir(endpoint), recursive=True)