[libvirt] serial console/events example script
Dave Allan
dallan at redhat.com
Thu Mar 29 20:55:39 UTC 2012
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()
More information about the libvir-list
mailing list