[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