[Libguestfs] [PATCH v2 3/3] python: Implement Pointer ("virDomainPtr", _) (RHBZ#1075164).

Richard W.M. Jones rjones at redhat.com
Wed Dec 10 21:15:45 UTC 2014


This allows the Python binding of guestfs_add_libvirt_dom to work.

This requires some insight into the internals of python-libvirt.
There is a regression test to ensure this keeps working.
---
 generator/python.ml            | 27 ++++++++++++++++++++-------
 python/run-python-tests        |  3 +++
 python/t/910-python-libvirt.py | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 7 deletions(-)
 create mode 100644 python/t/910-python-libvirt.py

diff --git a/generator/python.ml b/generator/python.ml
index 82afb2e..f751d65 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -49,6 +49,15 @@ let rec generate_python_c () =
 
 #include \"guestfs-py.h\"
 
+/* Copied from python-libvirt. */
+#define PyvirDomain_Get(v) (((v) == Py_None) ? NULL : \
+        (((PyvirDomain_Object *)(v))->obj))
+
+typedef struct {
+    PyObject_HEAD
+    void * /* really virDomainPtr */ obj;
+} PyvirDomain_Object;
+
 /* This list should be freed (but not the strings) after use. */
 static char **
 get_string_list (PyObject *obj)
@@ -294,7 +303,6 @@ put_table (char * const * const argv)
         | Int n -> pr "  int %s;\n" n
         | Int64 n -> pr "  long long %s;\n" n
         | Pointer (t, n) ->
-            pr "  long long %s_int64;\n" n;
             pr "  void * /* %s */ %s;\n" t n
       ) args;
 
@@ -324,11 +332,12 @@ put_table (char * const * const argv)
         | StringList _ | DeviceList _ -> pr "O"
         | Bool _ -> pr "i" (* XXX Python has booleans? *)
         | Int _ -> pr "i"
-        | Int64 _ | Pointer _ ->
+        | Int64 _ ->
             (* XXX Whoever thought it was a good idea to
              * emulate C's int/long/long long in Python?
              *)
             pr "L"
+        | Pointer _ -> pr "O"
         | BufferIn _ -> pr "s#"
       ) args;
 
@@ -347,7 +356,7 @@ put_table (char * const * const argv)
         | Bool n -> pr ", &%s" n
         | Int n -> pr ", &%s" n
         | Int64 n -> pr ", &%s" n
-        | Pointer (_, n) -> pr ", &%s_int64" n
+        | Pointer (_, n) -> pr ", &%s" n
         | BufferIn n -> pr ", &%s, &%s_size" n n
       ) args;
 
@@ -369,8 +378,9 @@ put_table (char * const * const argv)
         | StringList n | DeviceList n ->
             pr "  %s = get_string_list (py_%s);\n" n n;
             pr "  if (!%s) goto out;\n" n
-        | Pointer (t, n) ->
-            pr "  %s = POINTER_NOT_IMPLEMENTED (\"%s\");\n" n t
+        | Pointer ("virDomainPtr", n) ->
+            pr "  %s = PyvirDomain_Get (%s);\n" n n
+        | Pointer _ -> assert false
       ) args;
 
       pr "\n";
@@ -798,9 +808,12 @@ class GuestFS(object):
         | Pathname _ | Device _ | Mountable _
         | Dev_or_Path _ | Mountable_or_Path _ | String _ | Key _
         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
-        | BufferIn _ | Pointer _ | GUID _ -> ()
+        | BufferIn _ | GUID _ -> ()
         | StringList n | DeviceList n ->
-            pr "        %s = list (%s)\n" n n
+          pr "        %s = list (%s)\n" n n
+        | Pointer ("virDomainPtr", n) ->
+          pr "        %s = %s._o\n" n n
+        | Pointer _ -> assert false
       ) args;
       pr "        self._check_not_closed ()\n";
       pr "        r = libguestfsmod.%s (self._o" f.name;
diff --git a/python/run-python-tests b/python/run-python-tests
index bcc40d8..3a899ec 100755
--- a/python/run-python-tests
+++ b/python/run-python-tests
@@ -18,6 +18,9 @@
 
 set -e
 
+guestsdir="$(cd ../tests/guests && pwd)"
+export guestsdir
+
 for f in $srcdir/t/*.py; do
   $PYTHON $f
 done
diff --git a/python/t/910-python-libvirt.py b/python/t/910-python-libvirt.py
new file mode 100644
index 0000000..4d02cba
--- /dev/null
+++ b/python/t/910-python-libvirt.py
@@ -0,0 +1,40 @@
+# libguestfs Python bindings
+# Copyright (C) 2014 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Ensure that python libvirt API keeps working.
+
+from types import *
+import os
+import guestfs
+
+guestsdir = os.environ['guestsdir']
+
+try:
+    import libvirt
+except:
+    print "could not import python-libvirt"
+    exit (77)
+
+conn = libvirt.open ("test:///%s/guests.xml" % guestsdir)
+dom = conn.lookupByName ("blank-disk")
+
+g = guestfs.GuestFS ()
+
+r = g.add_libvirt_dom (dom, readonly=1)
+
+if r != 1:
+    raise "unexpected return value from add_libvirt_dom (%d)" % r
-- 
2.1.0




More information about the Libguestfs mailing list