def start(host, port): assert host assert process.portFree(host, port) host.execute("vtund -s -f %s" % _configPath(port)) util.waitFor(lambda :fileutil.existsFile(host, "/var/run/vtund.server.pid"), 5.0) assert fileutil.existsFile(host, "/var/run/vtund.server.pid") fileutil.copy(host, "/var/run/vtund.server.pid", _pidFile(port))
def useImage(host, vmid, image, move=False): assert fileutil.existsFile(host, image), "Image file does not exist" assert getState(host, vmid) == generic.State.PREPARED, "VM must be stopped to change image" _qm(host, vmid, "set", "--ide0 undef") imagePath = _imagePath(vmid) fileutil.mkdir(host, _imagePathDir(vmid)) if move: fileutil.move(host, image, imagePath) else: fileutil.copy(host, image, imagePath) fileutil.chown(host, imagePath, "root:root") _qm(host, vmid, "set", "--ide0=local:%s/disk.qcow2" % vmid) assert fileutil.existsFile(host, imagePath)
def downloadCaptureUri(host, name, onlyLatest=False): filename = "%s.pcap" % name path = host.getHostServer().randomFilename() if onlyLatest: print path latest = util.lines(host.execute("ls -t1 %s | head -n1" % _remoteDir(name)))[0] if latest: fileutil.copy(host, "%s/%s" % (_remoteDir(name), latest), path) else: host.execute("tcpslice -w %s %s/*" % (path, _remoteDir(name))) if not fileutil.existsFile(host, path) or not fileutil.fileSize(host, path): raise fault.new("No packages captured yet") return host.getHostServer().downloadGrant(path, filename=filename)
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 useImage(host, vmid, image): #FIXME check script sanity assert getState(host, vmid) == generic.State.PREPARED, "VM not prepared" assert fileutil.existsFile(host, image), "Image does not exist" fileutil.copy(host, image, _imagePath(vmid))
def create(host, vmid, template): assert getState(host, vmid) == generic.State.CREATED, "VM already exists" fileutil.mkdir(host, "%s/repy" % config.REMOTE_DIR) fileutil.copy(host, _templatePath(template), _imagePath(vmid)) assert getState(host, vmid) == generic.State.PREPARED, "Failed to create VM"
def copyImage(host, vmid, file): assert getState(host, vmid) != generic.State.CREATED, "VM must be prepared" fileutil.copy(host, _imagePath(vmid), file) assert fileutil.existsFile(host, file)
def useImage(host, vmid, image, move=False): assert fileutil.existsFile(host, image), "Image file does not exist" try: host.execute("qemu-img check -f qcow2 %s; echo $?" % util.escape(image)) except exceptions.CommandError, exc: #Error 1: Leaked clusters, "This means waste of disk space, but no harm to data." if not exc.errorCode in [1]: raise assert getState(host, vmid) == generic.State.PREPARED, "VM must be stopped to change image" _qm(host, vmid, "set", ["--ide0", "undef"]) imagePath = _imagePath(vmid) fileutil.mkdir(host, _imagePathDir(vmid)) if move: fileutil.move(host, image, imagePath) else: fileutil.copy(host, image, imagePath) fileutil.chown(host, imagePath, "root:root") _qm(host, vmid, "set", ["--ide0", "local:%d/disk.qcow2" % vmid]) assert fileutil.existsFile(host, imagePath) def _vncPidfile(vmid): return "%s/vnc-%d.pid" % (config.REMOTE_DIR, vmid) def vncRunning(host, vmid, port): return process.processRunning(host, _vncPidfile(vmid), "tcpserver") def startVnc(host, vmid, port, password): assert getState(host, vmid) == generic.State.STARTED, "VM must be running to start vnc" assert process.portFree(host, port) host.execute("tcpserver -qHRl 0 0 %d qm vncproxy %d %s & echo $! > %s" % ( port, vmid, util.escape(password), _vncPidfile(vmid) )) assert not process.portFree(host, port)