On Wed, Feb 15, 2012 at 09:11:32PM -0500, Dave Allan wrote:
Hi all,
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. Is it worth adding to the examples? It
might need some work, as I am not terribly strong with Python.
Dave
I was just going through some old mail and realized that I don't think
this ever got a response. Anybody have any thoughts on it?
Dave
#!/usr/bin/python -u
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()