mirror of https://gitee.com/openkylin/libvirt.git
examples: add consolecallback example python script
A while back I wrote the attached code to demonstrate how to use events and serial console to create a serial console that stays up even when the VM is down. It might need some work, as I am not terribly strong with Python. * examples/python/consolecallback.py: New file. * examples/python/Makefile.am (EXTRA_DIST): Ship it.
This commit is contained in:
parent
620dda6661
commit
ffc9f7ab4f
|
@ -1,6 +1,7 @@
|
||||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
## Copyright (C) 2005-2012 Red Hat, Inc.
|
||||||
## See COPYING.LIB for the License of this software
|
## See COPYING.LIB for the License of this software
|
||||||
|
|
||||||
EXTRA_DIST= \
|
EXTRA_DIST= \
|
||||||
README \
|
README \
|
||||||
|
consolecallback.py \
|
||||||
dominfo.py domrestore.py domsave.py domstart.py esxlist.py
|
dominfo.py domrestore.py domsave.py domstart.py esxlist.py
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# consolecallback - provide a persistent console that survives guest reboots
|
||||||
|
|
||||||
|
import sys, os, logging, libvirt, tty, termios, atexit
|
||||||
|
|
||||||
|
def reset_term():
|
||||||
|
termios.tcsetattr(0, termios.TCSADRAIN, attrs)
|
||||||
|
|
||||||
|
def error_handler(unused, error):
|
||||||
|
# The console stream errors on VM shutdown; we don't care
|
||||||
|
if (error[0] == libvirt.VIR_ERR_RPC and
|
||||||
|
error[1] == libvirt.VIR_FROM_STREAMS):
|
||||||
|
return
|
||||||
|
logging.warn(error)
|
||||||
|
|
||||||
|
class Console(object):
|
||||||
|
def __init__(self, uri, uuid):
|
||||||
|
self.uri = uri
|
||||||
|
self.uuid = uuid
|
||||||
|
self.connection = libvirt.open(uri)
|
||||||
|
self.domain = self.connection.lookupByUUIDString(uuid)
|
||||||
|
self.state = self.domain.state(0)
|
||||||
|
self.connection.domainEventRegister(lifecycle_callback, self)
|
||||||
|
self.stream = None
|
||||||
|
self.run_console = True
|
||||||
|
logging.info("%s initial state %d, reason %d",
|
||||||
|
self.uuid, self.state[0], self.state[1])
|
||||||
|
|
||||||
|
def check_console(console):
|
||||||
|
if (console.state[0] == libvirt.VIR_DOMAIN_RUNNING or
|
||||||
|
console.state[0] == libvirt.VIR_DOMAIN_PAUSED):
|
||||||
|
if console.stream == None:
|
||||||
|
console.stream = console.connection.newStream(libvirt.VIR_STREAM_NONBLOCK)
|
||||||
|
console.domain.openConsole(None, console.stream, 0)
|
||||||
|
console.stream.eventAddCallback(libvirt.VIR_STREAM_EVENT_READABLE, stream_callback, console)
|
||||||
|
else:
|
||||||
|
if console.stream:
|
||||||
|
console.stream.eventRemoveCallback()
|
||||||
|
console.stream = None
|
||||||
|
|
||||||
|
return console.run_console
|
||||||
|
|
||||||
|
def stdin_callback(watch, fd, events, console):
|
||||||
|
readbuf = os.read(fd, 1024)
|
||||||
|
if readbuf.startswith(""):
|
||||||
|
console.run_console = False
|
||||||
|
return
|
||||||
|
if console.stream:
|
||||||
|
console.stream.send(readbuf)
|
||||||
|
|
||||||
|
def stream_callback(stream, events, console):
|
||||||
|
try:
|
||||||
|
received_data = console.stream.recv(1024)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
os.write(0, received_data)
|
||||||
|
|
||||||
|
def lifecycle_callback (connection, domain, event, detail, console):
|
||||||
|
console.state = console.domain.state(0)
|
||||||
|
logging.info("%s transitioned to state %d, reason %d",
|
||||||
|
console.uuid, console.state[0], console.state[1])
|
||||||
|
|
||||||
|
# main
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print "Usage:", sys.argv[0], "URI UUID"
|
||||||
|
print "for example:", sys.argv[0], "'qemu:///system' '32ad945f-7e78-c33a-e96d-39f25e025d81'"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
uri = sys.argv[1]
|
||||||
|
uuid = sys.argv[2]
|
||||||
|
|
||||||
|
print "Escape character is ^]"
|
||||||
|
logging.basicConfig(filename='msg.log', level=logging.DEBUG)
|
||||||
|
logging.info("URI: %s", uri)
|
||||||
|
logging.info("UUID: %s", uuid)
|
||||||
|
|
||||||
|
libvirt.virEventRegisterDefaultImpl()
|
||||||
|
libvirt.registerErrorHandler(error_handler, None)
|
||||||
|
|
||||||
|
atexit.register(reset_term)
|
||||||
|
attrs = termios.tcgetattr(0)
|
||||||
|
tty.setraw(0)
|
||||||
|
|
||||||
|
console = Console(uri, uuid)
|
||||||
|
console.stdin_watch = libvirt.virEventAddHandle(0, libvirt.VIR_EVENT_HANDLE_READABLE, stdin_callback, console)
|
||||||
|
|
||||||
|
while check_console(console):
|
||||||
|
libvirt.virEventRunDefaultImpl()
|
Loading…
Reference in New Issue