]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
examples: add consolecallback example python script
authorDave Allan <dallan@redhat.com>
Tue, 29 May 2012 22:49:13 +0000 (16:49 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 29 May 2012 22:54:12 +0000 (16:54 -0600)
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.

examples/python/Makefile.am
examples/python/consolecallback.py [new file with mode: 0644]

index d782a28bfd7a560506ba5a6ffe44b22dc3bd8240..b04d1261c5794adbf62740a6f2261668e7fb0b8e 100644 (file)
@@ -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
 
 EXTRA_DIST=                                            \
        README                                          \
+       consolecallback.py                              \
        dominfo.py domrestore.py domsave.py domstart.py esxlist.py
diff --git a/examples/python/consolecallback.py b/examples/python/consolecallback.py
new file mode 100644 (file)
index 0000000..23316ce
--- /dev/null
@@ -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("\1d"):
+        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()