]> xenbits.xensource.com Git - libvirt.git/commitdiff
* configure.in src/Makefile.am: adding dependency to libxml2
authorDaniel Veillard <veillard@redhat.com>
Thu, 16 Feb 2006 22:50:52 +0000 (22:50 +0000)
committerDaniel Veillard <veillard@redhat.com>
Thu, 16 Feb 2006 22:50:52 +0000 (22:50 +0000)
* include/libvirt.h* src/libvirt.c src/xend_internal.[ch]
  src/xml.[ch]: added XML parsing for Xen domain descriptions
  needed for creates, plugged in a converter to s-exp and
  xend call. Modified the virDomainCreateLinux() to reflect
  that XML based description. Seems to work.
* python/tests/create.py: added a test case which seems to work
  not tested much yet
* docs/*: regenerated
Daniel

20 files changed:
ChangeLog
configure.in
docs/APIchunk0.html
docs/APIchunk1.html
docs/APIchunk2.html
docs/APIfunctions.html
docs/html/libvirt-libvirt.html
docs/libvirt-api.xml
docs/libvirt-refs.xml
include/libvirt.h
include/libvirt.h.in
include/libvirt/libvirt.h
include/libvirt/libvirt.h.in
python/tests/create.py [new file with mode: 0755]
src/Makefile.am
src/libvirt.c
src/xend_internal.c
src/xend_internal.h
src/xml.c
src/xml.h [new file with mode: 0644]

index 5a4c6e035bf157b562d464a907bb9bf6c131bca7..43722f88e132fb0ec51a95b45d459fc014a070fe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Thu Feb 16 17:47:00 EST 2006 Daniel Veillard <veillard@redhat.com>
+
+       * configure.in src/Makefile.am: adding dependency to libxml2
+       * include/libvirt.h* src/libvirt.c src/xend_internal.[ch]
+         src/xml.[ch]: added XML parsing for Xen domain descriptions
+         needed for creates, plugged in a converter to s-exp and
+         xend call. Modified the virDomainCreateLinux() to reflect
+         that XML based description. Seems to work.
+       * python/tests/create.py: added a test case which seems to work
+         not tested much yet
+       * docs/*: regenerated
+
 Wed Feb 15 08:20:23 EST 2006 Daniel Veillard <veillard@redhat.com>
 
        * configure.in libvirt.spec.in include/libvirt.h.in python/Makefile.am
index 38162d26457c439db6dff292c96d68d2965ef0f3..75d62ce280b706345f6159ece5c00bd1188298ac 100644 (file)
@@ -90,6 +90,50 @@ then
 dnl search for the Xen store library
 AC_SEARCH_LIBS(xs_read, [xenstore], [], [AC_MSG_ERROR([Xen store library not found])])
 
+dnl ==========================================================================
+dnl find libxml2 library, borrowed from xmlsec
+dnl ==========================================================================
+LIBXML_MIN_VERSION="2.5.0"
+LIBXML_CONFIG="xml2-config"
+LIBXML_CFLAGS=""
+LIBXML_LIBS=""
+LIBXML_FOUND="no"
+AC_ARG_WITH(libxml, [  --with-libxml=[PFX]       libxml2 location])
+if test "z$with_libxml" = "zno" ; then 
+    AC_MSG_CHECKING(for libxml2 libraries >= $LIBXML_MIN_VERSION) 
+    AC_MSG_ERROR(libxml2 >= $LIBXML_MIN_VERSION is required for $XMLSEC_PACKAGE)
+elif test "z$with_libxml" = "z" -a "z$PKG_CONFIG_ENABLED" = "zyes" ; then
+    PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= $LIBXML_MIN_VERSION,
+       [LIBXML_FOUND=yes],
+       [LIBXML_FOUND=no])
+fi
+AC_MSG_CHECKING(libxml2 $with_libxml  $LIBXML_FOUND  )
+if test "z$LIBXML_FOUND" = "zno" ; then
+    AC_MSG_CHECKING(for libxml2 libraries >= $LIBXML_MIN_VERSION) 
+    if test "z$with_libxml" != "z" ; then 
+       LIBXML_CONFIG=$with_libxml/bin/$LIBXML_CONFIG
+    fi
+    AC_MSG_CHECKING(libxml2 $with_libxml  $LIBXML_CONFIG  )
+    if ! $LIBXML_CONFIG --version > /dev/null 2>&1 ; then
+       AC_MSG_ERROR(Could not find libxml2 anywhere (see config.log for details).)
+    fi
+    vers=`$LIBXML_CONFIG --version | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+    minvers=`echo $LIBXML_MIN_VERSION | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+    if test "$vers" -ge "$minvers" ; then
+        LIBXML_LIBS="`$LIBXML_CONFIG --libs`"
+        LIBXML_CFLAGS="`$LIBXML_CONFIG --cflags`"
+       LIBXML_FOUND="yes"
+        AC_MSG_RESULT(yes ('$LIBXML_VERSION'))
+    else
+        AC_MSG_ERROR(You need at least libxml2 $LIBXML_MIN_VERSION for this version of $XMLSEC_PACKAGE)
+    fi
+fi
+
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+AC_SUBST(LIBXML_CONFIG)
+AC_SUBST(LIBXML_MIN_VERSION)
+
 dnl virsh libraries
 AC_CHECK_LIB(curses, initscr, 
        [VIRSH_LIBS="$VIRSH_LIBS -lcurses"], 
index 0fb26353b9ac25f3f31d1a816bcbb91ea50626e1..eb80b7a6bc375269c18cc7f6253687d09680ddbb 100644 (file)
@@ -74,7 +74,8 @@
 </dd></dl><h2>Letter U:</h2><dl><dt>UTF-8</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
 </dd><dt>Use</dt><dd><a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSuspend">virDomainSuspend</a><br />
-</dd></dl><h2>Letter X:</h2><dl><dt>XML</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
+</dd></dl><h2>Letter X:</h2><dl><dt>XML</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
+<a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
 </dd><dt>Xen</dt><dd><a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </dd></dl><h2>Letter a:</h2><dl><dt>about</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetInfo">virDomainGetInfo</a><br />
 </dd><dt>access</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
 </dd><dt>code</dt><dd><a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </dd><dt>collect</dt><dd><a href="html/libvirt-libvirt.html#virConnectListDomains">virConnectListDomains</a><br />
 </dd><dt>command</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 </dd><dt>compiled</dt><dd><a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </dd><dt>connection</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
 <a href="html/libvirt-libvirt.html#virConnectClose">virConnectClose</a><br />
 <a href="html/libvirt-libvirt.html#virDomainFree">virDomainFree</a><br />
 </dd><dt>deallocated</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetName">virDomainGetName</a><br />
 </dd><dt>defined</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-</dd><dt>description</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
+</dd><dt>description</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
+<a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
 </dd><dt>device</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
 </dd><dt>disk</dt><dd><a href="html/libvirt-libvirt.html#virDomainRestore">virDomainRestore</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 <a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSuspend">virDomainSuspend</a><br />
 <a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
-</dd><dt>file</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-<a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
+</dd><dt>file</dt><dd><a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 </dd><dt>filename</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
 </dd><dt>find</dt><dd><a href="html/libvirt-libvirt.html#virDomainLookupByID">virDomainLookupByID</a><br />
 </dd><dt>first</dt><dd><a href="html/libvirt-libvirt.html#virConnectOpen">virConnectOpen</a><br />
 </dd><dt>flags</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
 </dd><dt>for</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
 <a href="html/libvirt-libvirt.html#virConnectGetVersion">virConnectGetVersion</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetID">virDomainGetID</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetName">virDomainGetName</a><br />
 <a href="html/libvirt-libvirt.html#virDomainLookupByName">virDomainLookupByName</a><br />
index f681f48175af757d4064418b17be1a89e8f03c3d..9e82b7718773aafc8988ea244fa18db89e27252e 100644 (file)
 <a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </dd></dl><h2>Letter i:</h2><dl><dt>ignore</dt><dd><a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
 </dd><dt>image</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 </dd><dt>information</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetInfo">virDomainGetInfo</a><br />
 <a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </dd><dt>informations</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetInfo">virDomainGetInfo</a><br />
 </dd><dt>init</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-</dd><dt>initrd</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 </dd><dt>instance</dt><dd><a href="html/libvirt-libvirt.html#virDomainDestroy">virDomainDestroy</a><br />
 <a href="html/libvirt-libvirt.html#virDomainFree">virDomainFree</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetXMLDesc">virDomainGetXMLDesc</a><br />
@@ -48,9 +46,7 @@
 <a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 </dd></dl><h2>Letter k:</h2><dl><dt>kept</dt><dd><a href="html/libvirt-libvirt.html#virDomainFree">virDomainFree</a><br />
 </dd><dt>kernel</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-</dd><dt>kilobytes</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-<a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
+</dd><dt>kilobytes</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
 </dd><dt>knowing</dt><dd><a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
 </dd></dl><h2>Letter l:</h2><dl><dt>lack</dt><dd><a href="html/libvirt-libvirt.html#virConnectGetVersion">virConnectGetVersion</a><br />
@@ -63,7 +59,6 @@
 </dd><dt>limited</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetInfo">virDomainGetInfo</a><br />
 </dd><dt>line</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 </dd><dt>list</dt><dd><a href="html/libvirt-libvirt.html#virConnectListDomains">virConnectListDomains</a><br />
 </dd><dt>listed</dt><dd><a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 </dd><dt>long</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
@@ -80,7 +75,6 @@
 <a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSuspend">virDomainSuspend</a><br />
 </dd><dt>memory</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
 </dd><dt>output</dt><dd><a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 </dd></dl><h2>Letter p:</h2><dl><dt>padding</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
 </dd><dt>parameters</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 </dd><dt>partial</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetInfo">virDomainGetInfo</a><br />
 </dd><dt>pass</dt><dd><a href="html/libvirt-libvirt.html#virConnectOpen">virConnectOpen</a><br />
 <a href="html/libvirt-libvirt.html#virConnectOpenReadOnly">virConnectOpenReadOnly</a><br />
-</dd><dt>path</dt><dd><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-<a href="html/libvirt-libvirt.html#virDomainRestore">virDomainRestore</a><br />
+</dd><dt>path</dt><dd><a href="html/libvirt-libvirt.html#virDomainRestore">virDomainRestore</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
 </dd><dt>physical</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
index b8f369ec8df76286fe69e12a9741aac59a17c6f9..245035d23611ea77547a119d1b3f851a9b6a2ca9 100644 (file)
@@ -19,7 +19,6 @@
 <a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
 </dd><dt>shutdown</dt><dd><a href="html/libvirt-libvirt.html#virDomainDestroy">virDomainDestroy</a><br />
 </dd><dt>size</dt><dd><a href="html/libvirt-libvirt.html#virConnectListDomains">virConnectListDomains</a><br />
-<a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
 <a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
 <a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
 </dd><dt>software</dt><dd><a href="html/libvirt-libvirt.html#virConnectGetType">virConnectGetType</a><br />
index 57e453b36eca5837b4629563d7df72b3b2469c35..e695f402ef38c74e6c72317a59bd65d1195d2b8a 100644 (file)
@@ -2,8 +2,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /><link rel="stylesheet" type="text/css" href="libvirt.css" /><link rel="SHORTCUT ICON" href="/32favicon.png" /><title>List of function manipulating types in libvirt</title></head><body><div id="container"><div id="intro"><div id="adjustments"></div><div id="pageHeader"></div><div id="content2"><h1 class="style1">List of function manipulating types in libvirt</h1><h2>Type int *:</h2><p><a href="html/libvirt-libvirt.html#virConnectListDomains">virConnectListDomains</a><br />
 </p><h2>Type unsigned int:</h2><p><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-</p><h2>Type unsigned long:</h2><p><a href="html/libvirt-libvirt.html#virDomainCreateLinux">virDomainCreateLinux</a><br />
-<a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
+</p><h2>Type unsigned long:</h2><p><a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
 </p><h2>Type unsigned long *:</h2><p><a href="html/libvirt-libvirt.html#virConnectGetVersion">virConnectGetVersion</a><br />
 <a href="html/libvirt-libvirt.html#virGetVersion">virGetVersion</a><br />
 </p><h2>Type virConnectPtr:</h2><p><a href="html/libvirt-libvirt.html#virConnectClose">virConnectClose</a><br />
index 228112f7270d4d506f9e81dddc3f6b97987c957a..9419c7e9ca16a9f30783d7ad4050c9344d6903cf 100644 (file)
@@ -21,7 +21,7 @@ The content of this structure is not made public by the API.
 <pre class="programlisting">int        <a href="#virConnectNumOfDomains">virConnectNumOfDomains</a>            (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)</pre>
 <pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a>     <a href="#virConnectOpen">virConnectOpen</a>            (const char * name)</pre>
 <pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a>     <a href="#virConnectOpenReadOnly">virConnectOpenReadOnly</a>    (const char * name)</pre>
-<pre class="programlisting"><a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a>       <a href="#virDomainCreateLinux">virDomainCreateLinux</a>        (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br />                                     const char * kernel_path, <br />                                        const char * initrd_path, <br />                                        const char * cmdline, <br />                                    unsigned long memory, <br />                                    unsigned int flags)</pre>
+<pre class="programlisting"><a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a>       <a href="#virDomainCreateLinux">virDomainCreateLinux</a>        (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br />                                     const char * xmlDesc, <br />                                    unsigned int flags)</pre>
 <pre class="programlisting">int        <a href="#virDomainDestroy">virDomainDestroy</a>                (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)</pre>
 <pre class="programlisting">int        <a href="#virDomainFree">virDomainFree</a>                      (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)</pre>
 <pre class="programlisting">unsigned int       <a href="#virDomainGetID">virDomainGetID</a>            (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)</pre>
@@ -102,9 +102,9 @@ The content of this structure is not made public by the API.
 </pre><p>This function should be called first to get a connection to the Hypervisor and xen store</p>
 <div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>optional argument currently unused, pass NULL</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error</td></tr></tbody></table></div><h3><a name="virConnectOpenReadOnly" id="virConnectOpenReadOnly"></a>Function: virConnectOpenReadOnly</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a>   virConnectOpenReadOnly  (const char * name)<br />
 </pre><p>This function should be called first to get a restricted connection to the libbrary functionalities. The set of APIs usable are then restricted on the available methods to control the domains.</p>
-<div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>optional argument currently unused, pass NULL</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error</td></tr></tbody></table></div><h3><a name="virDomainCreateLinux" id="virDomainCreateLinux"></a>Function: virDomainCreateLinux</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a>   virDomainCreateLinux    (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br />                                     const char * kernel_path, <br />                                        const char * initrd_path, <br />                                        const char * cmdline, <br />                                    unsigned long memory, <br />                                    unsigned int flags)<br />
+<div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>optional argument currently unused, pass NULL</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error</td></tr></tbody></table></div><h3><a name="virDomainCreateLinux" id="virDomainCreateLinux"></a>Function: virDomainCreateLinux</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a>   virDomainCreateLinux    (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br />                                     const char * xmlDesc, <br />                                    unsigned int flags)<br />
 </pre><p>Launch a new Linux guest domain, unimplemented yet, API to be defined. This would function requires priviledged access to the hypervisor.</p>
-<div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>kernel_path</tt></i>:</span></td><td>the file path to the kernel image</td></tr><tr><td><span class="term"><i><tt>initrd_path</tt></i>:</span></td><td>an optional file path to an initrd</td></tr><tr><td><span class="term"><i><tt>cmdline</tt></i>:</span></td><td>optional command line parameters for the kernel</td></tr><tr><td><span class="term"><i><tt>memory</tt></i>:</span></td><td>the memory size in kilobytes</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>an optional set of virDomainFlags</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a new domain object or NULL in case of failure</td></tr></tbody></table></div><h3><a name="virDomainDestroy" id="virDomainDestroy"></a>Function: virDomainDestroy</h3><pre class="programlisting">int     virDomainDestroy                (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)<br />
+<div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>xmlDesc</tt></i>:</span></td><td>an XML description of the domain</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>an optional set of virDomainFlags</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a new domain object or NULL in case of failure</td></tr></tbody></table></div><h3><a name="virDomainDestroy" id="virDomainDestroy"></a>Function: virDomainDestroy</h3><pre class="programlisting">int virDomainDestroy                (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)<br />
 </pre><p>Destroy the domain object. The running instance is shutdown if not down already and all resources used by it are given back to the hypervisor. The data structure is freed and should not be used thereafter if the call does not return an error. This function may requires priviledged access</p>
 <div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>domain</tt></i>:</span></td><td>a domain object</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success and -1 in case of failure.</td></tr></tbody></table></div><h3><a name="virDomainFree" id="virDomainFree"></a>Function: virDomainFree</h3><pre class="programlisting">int     virDomainFree                   (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain)<br />
 </pre><p>Free the domain object. The running instance is kept alive. The data structure is freed and should not be used thereafter.</p>
index 450487ac427b00add9cc3cc15da2f95c882f3733..f19b6cada75fdbf4fd7f999c84e3be77b1645a5d 100644 (file)
       <info>Launch a new Linux guest domain, unimplemented yet, API to be defined. This would function requires priviledged access to the hypervisor.</info>
       <return type='virDomainPtr' info='a new domain object or NULL in case of failure'/>
       <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
-      <arg name='kernel_path' type='const char *' info='the file path to the kernel image'/>
-      <arg name='initrd_path' type='const char *' info='an optional file path to an initrd'/>
-      <arg name='cmdline' type='const char *' info='optional command line parameters for the kernel'/>
-      <arg name='memory' type='unsigned long' info='the memory size in kilobytes'/>
+      <arg name='xmlDesc' type='const char *' info='an XML description of the domain'/>
       <arg name='flags' type='unsigned int' info='an optional set of virDomainFlags'/>
     </function>
     <function name='virDomainDestroy' file='libvirt' module='libvirt'>
index af83e808a849a6fa5899d74a7011c03043688cae..ac86df8cbd4962fefa1be0d35340ae7dc4f1dcfe 100644 (file)
       <ref name='virDomainCreateLinux'/>
     </type>
     <type name='unsigned long'>
-      <ref name='virDomainCreateLinux'/>
       <ref name='virDomainSetMaxMemory'/>
     </type>
     <type name='unsigned long *'>
       </letter>
       <letter name='X'>
         <word name='XML'>
+          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetXMLDesc'/>
         </word>
         <word name='Xen'>
         </word>
         <word name='command'>
           <ref name='_virDomainKernel'/>
-          <ref name='virDomainCreateLinux'/>
         </word>
         <word name='compiled'>
           <ref name='virGetVersion'/>
           <ref name='virDomainCreateLinux'/>
         </word>
         <word name='description'>
+          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetXMLDesc'/>
         </word>
         <word name='device'>
           <ref name='virGetVersion'/>
         </word>
         <word name='file'>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainSave'/>
         </word>
         <word name='filename'>
         <word name='for'>
           <ref name='_virDomainInfo'/>
           <ref name='virConnectGetVersion'/>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetID'/>
           <ref name='virDomainGetName'/>
           <ref name='virDomainLookupByName'/>
         </word>
         <word name='image'>
           <ref name='_virDomainKernel'/>
-          <ref name='virDomainCreateLinux'/>
         </word>
         <word name='information'>
           <ref name='virDomainGetInfo'/>
         <word name='init'>
           <ref name='_virDomainKernel'/>
         </word>
-        <word name='initrd'>
-          <ref name='virDomainCreateLinux'/>
-        </word>
         <word name='instance'>
           <ref name='virDomainDestroy'/>
           <ref name='virDomainFree'/>
         </word>
         <word name='kernel'>
           <ref name='_virDomainKernel'/>
-          <ref name='virDomainCreateLinux'/>
         </word>
         <word name='kilobytes'>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetMaxMemory'/>
           <ref name='virDomainSetMaxMemory'/>
         </word>
         </word>
         <word name='line'>
           <ref name='_virDomainKernel'/>
-          <ref name='virDomainCreateLinux'/>
         </word>
         <word name='list'>
           <ref name='virConnectListDomains'/>
         </word>
         <word name='memory'>
           <ref name='_virDomainInfo'/>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetMaxMemory'/>
           <ref name='virDomainSave'/>
           <ref name='virDomainSetMaxMemory'/>
         </word>
         <word name='parameters'>
           <ref name='_virDomainKernel'/>
-          <ref name='virDomainCreateLinux'/>
         </word>
         <word name='partial'>
           <ref name='virDomainGetInfo'/>
           <ref name='virConnectOpenReadOnly'/>
         </word>
         <word name='path'>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainRestore'/>
           <ref name='virDomainSave'/>
         </word>
         </word>
         <word name='size'>
           <ref name='virConnectListDomains'/>
-          <ref name='virDomainCreateLinux'/>
           <ref name='virDomainGetMaxMemory'/>
           <ref name='virDomainSetMaxMemory'/>
         </word>
index 10f271b4f59d2ded06165ee8ae47cf1310648b60..b6951868b654a720bc83fed34be30f1f6ae90675 100644 (file)
@@ -200,10 +200,7 @@ int                        virConnectNumOfDomains  (virConnectPtr conn);
  * Domain creation and destruction
  */
 virDomainPtr           virDomainCreateLinux    (virConnectPtr conn,
-                                                const char *kernel_path,
-                                                const char *initrd_path,
-                                                const char *cmdline,
-                                                unsigned long memory,
+                                                const char *xmlDesc,
                                                 unsigned int flags);
 virDomainPtr           virDomainLookupByName   (virConnectPtr conn,
                                                 const char *name);
index aa7e0221e230a9c171f52789fc884ba04161f916..6655c388e5566b3ae16163bb99d07b981bcb8119 100644 (file)
@@ -200,10 +200,7 @@ int                        virConnectNumOfDomains  (virConnectPtr conn);
  * Domain creation and destruction
  */
 virDomainPtr           virDomainCreateLinux    (virConnectPtr conn,
-                                                const char *kernel_path,
-                                                const char *initrd_path,
-                                                const char *cmdline,
-                                                unsigned long memory,
+                                                const char *xmlDesc,
                                                 unsigned int flags);
 virDomainPtr           virDomainLookupByName   (virConnectPtr conn,
                                                 const char *name);
index 10f271b4f59d2ded06165ee8ae47cf1310648b60..b6951868b654a720bc83fed34be30f1f6ae90675 100644 (file)
@@ -200,10 +200,7 @@ int                        virConnectNumOfDomains  (virConnectPtr conn);
  * Domain creation and destruction
  */
 virDomainPtr           virDomainCreateLinux    (virConnectPtr conn,
-                                                const char *kernel_path,
-                                                const char *initrd_path,
-                                                const char *cmdline,
-                                                unsigned long memory,
+                                                const char *xmlDesc,
                                                 unsigned int flags);
 virDomainPtr           virDomainLookupByName   (virConnectPtr conn,
                                                 const char *name);
index aa7e0221e230a9c171f52789fc884ba04161f916..6655c388e5566b3ae16163bb99d07b981bcb8119 100644 (file)
@@ -200,10 +200,7 @@ int                        virConnectNumOfDomains  (virConnectPtr conn);
  * Domain creation and destruction
  */
 virDomainPtr           virDomainCreateLinux    (virConnectPtr conn,
-                                                const char *kernel_path,
-                                                const char *initrd_path,
-                                                const char *cmdline,
-                                                unsigned long memory,
+                                                const char *xmlDesc,
                                                 unsigned int flags);
 virDomainPtr           virDomainLookupByName   (virConnectPtr conn,
                                                 const char *name);
diff --git a/python/tests/create.py b/python/tests/create.py
new file mode 100755 (executable)
index 0000000..c31eaa4
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/python -u
+import libvirt
+import sys
+
+conn = libvirt.openReadOnly(None)
+if conn == None:
+    print 'Failed to open connection to the hypervisor'
+    sys.exit(1)
+
+xmldesc="""<domain type='xen'>
+  <name>test</name>
+  <os>
+    <type>linux</type>
+    <kernel>/boot/vmlinuz-2.6.15-1.43_FC5guest</kernel>
+    <initrd>/boot/initrd-2.6.15-1.43_FC5guest.img</initrd>
+    <cmdline> root=/dev/sda1 ro selinux=0 3</cmdline>
+  </os>
+  <memory>131072</memory>
+  <vcpu>1</vcpu>
+  <devices>
+    <disk type='file'>
+      <source file='/u/fc4.img'/>
+      <target dev='sda1'/>
+    </disk>
+    <interface type='bridge'>
+      <source bridge='xenbr0'/>
+      <mac address='aa:00:00:00:00:12'/>
+      <script path='/etc/xen/scripts/vif-bridge'/>
+    </interface>
+  </devices>
+</domain>
+"""
+dom = conn.createLinux(xmldesc, 0)
+if dom == None:
+    print 'Failed to create a domain'
+    sys.exit(1)
+
+# print dom0
+
+print "Domain: id %d running %s" % (dom.ID(), dom.OSType())
+print dom.info()
+del dom
+del conn
+print "OK"
+
+sys.exit(0)
index 7caad2da20e6d6067560ed3a367ef3a4820f0527..c6c78c0cc501b8c1ed1e9a1711d5bea8dba63a58 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-INCLUDES = -I$(top_builddir)/include -I@srcdir@/include
+INCLUDES = -I$(top_builddir)/include -I@srcdir@/include @LIBXML_CFLAGS@
 DEPS = libvirt.la
 LDADDS = @STATIC_BINARIES@ libvirt.la
 VIRSH_LIBS = @VIRSH_LIBS@
@@ -8,7 +8,7 @@ VIRSH_LIBS = @VIRSH_LIBS@
 EXTRA_DIST = libvirt_sym.version
 
 lib_LTLIBRARIES = libvirt.la
-libvirt_la_LIBADD = 
+libvirt_la_LIBADD = @LIBXML_LIBS@
 libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
                     -version-info @LIBVIRT_VERSION_INFO@
 libvirt_la_SOURCES =                                           \
index 00b5f820aab3e30916cc469845789fd3973e5e2c..51f233e16cd33f38417615e2cabed4c2bbd393ea 100644 (file)
@@ -22,6 +22,7 @@
 #include "xen_internal.h"
 #include "xend_internal.h"
 #include "hash.h"
+#include "xml.h"
 
 
 /*
@@ -395,29 +396,67 @@ virConnectNumOfDomains(virConnectPtr conn) {
 /**
  * virDomainCreateLinux:
  * @conn: pointer to the hypervisor connection
- * @kernel_path: the file path to the kernel image
- * @initrd_path: an optional file path to an initrd
- * @cmdline: optional command line parameters for the kernel
- * @memory: the memory size in kilobytes
+ * @xmlDesc: an XML description of the domain
  * @flags: an optional set of virDomainFlags
  *
  * Launch a new Linux guest domain, unimplemented yet, API to be defined.
- * This would function requires priviledged access to the hypervisor.
+ * This function requires priviledged access to the hypervisor.
  * 
  * Returns a new domain object or NULL in case of failure
  */
 virDomainPtr
-virDomainCreateLinux(virConnectPtr conn, const char *kernel_path,
-                    const char *initrd_path ATTRIBUTE_UNUSED,
-                    const char *cmdline ATTRIBUTE_UNUSED,
-                    unsigned long memory,
+virDomainCreateLinux(virConnectPtr conn, 
+                     const char *xmlDesc,
                     unsigned int flags ATTRIBUTE_UNUSED) {
+    int ret;
+    char *sexpr;
+    char *name = NULL;
+    virDomainPtr dom;
 
     if (!VIR_IS_CONNECT(conn))
        return(NULL);
-    if ((kernel_path == NULL) || (memory < 4096))
+    if (xmlDesc == NULL)
         return(NULL);
-    TODO
+    sexpr = virDomainParseXMLDesc(xmlDesc, &name);
+    if ((sexpr == NULL) || (name == NULL)) {
+        if (sexpr != NULL)
+           free(sexpr);
+        if (name != NULL)
+           free(name);
+
+        return(NULL);
+    }
+
+    printf("%s\n", sexpr);
+
+    ret = xend_create_sexpr(conn, sexpr);
+    free(sexpr);
+    if (ret != 0) {
+        fprintf(stderr, "Failed to create domain %s\n", name);
+       goto error;
+    }
+
+    ret = xend_wait_for_devices(conn, name);
+    if (ret != 0) {
+        fprintf(stderr, "Failed to get devices for domain %s\n", name);
+       xend_destroy(conn, name);
+       goto error;
+    }
+
+    ret = xend_unpause(conn, name);
+    if (ret != 0) {
+        fprintf(stderr, "Failed to resume new domain %s\n", name);
+       xend_destroy(conn, name);
+       goto error;
+    }
+
+    dom = virDomainLookupByName(conn, name);
+    free(name);
+
+    return(dom);
+error:
+    if (name != NULL)
+        free(name);
     return(NULL);
 }
 
index 287f57f569ce0477487a69802e7d4e28a38b85fc..e113338f691458c942e95e3e2b8783f2c387c63f 100644 (file)
@@ -1398,6 +1398,37 @@ xend_create(virConnectPtr xend, const struct xend_domain *dom)
     return ret;
 }
 
+/**
+ * xend_create_sexpr:
+ * @xend: A xend instance
+ * @sexpr: An S-Expr description of the domain.
+ *
+ * This method will create a domain based the passed in description.  The
+ * domain will be paused after creation and must be unpaused with
+ * xend_unpause() to begin execution.
+ * This method may be deprecated once switching to XML-RPC based communcations
+ * with xend.
+ *
+ * Returns 0 for success, -1 (with errno) on error
+ */
+
+int
+xend_create_sexpr(virConnectPtr xend, const char *sexpr)
+{
+    int ret, serrno;
+    char *ptr;
+
+    ptr = urlencode(sexpr);
+
+    ret = xend_op(xend, "", "op", "create", "config", ptr, NULL);
+
+    serrno = errno;
+    free(ptr);
+    errno = serrno;
+
+    return ret;
+}
+
 /**
  * xend_set_max_memory:
  * @xend: A xend instance
index 7ac55ae92bb5bdf6bed561bcc613f119d995109a..5f7266a62fb82b045907bdf2f9067cd9e3d65b6d 100644 (file)
@@ -636,6 +636,18 @@ char **xend_get_domains(virConnectPtr xend);
  */
 int xend_create(virConnectPtr xend, const struct xend_domain *info);
 
+/**
+ * \brief Create a new domain
+ * \param xend A xend instance
+ * \param sexpr An S-Expr defining the domain
+ * \return 0 for success; -1 (with errno) on error
+ *
+ * This method will create a domain based the passed in description.  The
+ * domain will be paused after creation and must be unpaused with
+ * xend_unpause() to begin execution.
+ */
+int xend_create_sexpr(virConnectPtr xend, const char *sexpr);
+
 /**
  * \brief Set the maximum memory for a domain
  * \param xend A xend instance
index 68c85669924ca6d2398bcb3ce73045d508304b55..fe4836c234cc172226ece150e894b29d4a6a04b8 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
 #include <string.h>
 #include <stdarg.h>
 #include <xs.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
 #include "internal.h"
 #include "hash.h"
+#include "xml.h"
 
 /**
  * virBuffer:
@@ -459,3 +463,420 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags) {
     buf.content[buf.use] = 0;
     return(ret);
 }
+
+/**
+ * virDomainParseXMLOSDesc:
+ * @xmldesc: string with the XML description
+ * @buf: a buffer for the result S-Expr
+ *
+ * Parse the OS part of the XML description and add it to the S-Expr in buf
+ * This is a temporary interface as the S-Expr interface
+ * will be replaced by XML-RPC in the future. However the XML format should
+ * stay valid over time.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+static int
+virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf) {
+    xmlNodePtr cur, txt;
+    const xmlChar *type = NULL;
+    const xmlChar *root = NULL;
+    const xmlChar *kernel = NULL;
+    const xmlChar *initrd = NULL;
+    const xmlChar *cmdline = NULL;
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+           if ((type == NULL) && (xmlStrEqual(cur->name, BAD_CAST "type"))) {
+               txt = cur->children;
+               if ((txt->type == XML_TEXT_NODE) && (txt->next == NULL))
+                   type = txt->content;
+           } else if ((kernel == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "kernel"))) {
+               txt = cur->children;
+               if ((txt->type == XML_TEXT_NODE) && (txt->next == NULL))
+                   kernel = txt->content;
+           } else if ((root == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "root"))) {
+               txt = cur->children;
+               if ((txt->type == XML_TEXT_NODE) && (txt->next == NULL))
+                   root = txt->content;
+           } else if ((initrd == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "initrd"))) {
+               txt = cur->children;
+               if ((txt->type == XML_TEXT_NODE) && (txt->next == NULL))
+                   initrd = txt->content;
+           } else if ((cmdline == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "cmdline"))) {
+               txt = cur->children;
+               if ((txt->type == XML_TEXT_NODE) && (txt->next == NULL))
+                   cmdline = txt->content;
+           }
+       }
+        cur = cur->next;
+    }
+    if ((type != NULL) && (!xmlStrEqual(type, BAD_CAST "linux"))) {
+        /* VIR_ERR_OS_TYPE */
+       return(-1);
+    }
+    virBufferAdd(buf, "(linux ", 7);
+    if (kernel == NULL) {
+        /* VIR_ERR_NO_KERNEL */
+       return(-1);
+    }
+    virBufferVSprintf(buf, "(kernel '%s')", (const char *) kernel);
+    if (initrd != NULL)
+       virBufferVSprintf(buf, "(ramdisk '%s')", (const char *) initrd);
+    if (root == NULL) {
+       const xmlChar *base, *tmp;
+        /* need to extract root info from command line */
+       if (cmdline == NULL) {
+           /* VIR_ERR_NO_ROOT */
+           return(-1);
+       }
+       base = cmdline;
+       while (*base != 0) {
+           if ((base[0] == 'r') && (base[1] == 'o') && (base[2] == 'o') &&
+               (base[3] == 't')) {
+               base += 4;
+               break;
+           }
+           base++;
+       }
+       while ((*base == ' ') || (*base == '\t')) base++;
+       if (*base == '=') {
+           base++;
+           while ((*base == ' ') || (*base == '\t')) base++;
+       }
+       tmp = base;
+       while ((*tmp != 0) && (*tmp != ' ') && (*tmp != '\t')) tmp++;
+       if (tmp == base) {
+           /* VIR_ERR_NO_ROOT */
+           return(-1);
+       }
+       root = xmlStrndup(base, tmp - base);
+        virBufferVSprintf(buf, "(root '%s')", (const char *) root);
+       xmlFree((xmlChar *) root);
+       virBufferVSprintf(buf, "(args '%s')", (const char *) cmdline);
+    } else {
+        virBufferVSprintf(buf, "(root '%s')", (const char *) root);
+       if (cmdline != NULL)
+           virBufferVSprintf(buf, "(args '%s')", (const char *) cmdline);
+    }
+    virBufferAdd(buf, ")", 1);
+    return(0);
+}
+
+/**
+ * virDomainParseXMLDiskDesc:
+ * @xmldesc: string with the XML description
+ * @buf: a buffer for the result S-Expr
+ *
+ * Parse the one disk in the XML description and add it to the S-Expr in buf
+ * This is a temporary interface as the S-Expr interface
+ * will be replaced by XML-RPC in the future. However the XML format should
+ * stay valid over time.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+static int
+virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf) {
+    xmlNodePtr cur;
+    xmlChar *type = NULL;
+    xmlChar *source = NULL;
+    xmlChar *target = NULL;
+    int ro = 0;
+    int typ = 0;
+
+    type = xmlGetProp(node, BAD_CAST "type");
+    if (type != NULL) {
+        if (xmlStrEqual(type, BAD_CAST "file")) typ = 0;
+       else if (xmlStrEqual(type, BAD_CAST "block")) typ = 1;
+       xmlFree(type);
+    }
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+           if ((source == NULL) &&
+               (xmlStrEqual(cur->name, BAD_CAST "source"))) {
+
+               if (typ == 0)
+                   source = xmlGetProp(cur, BAD_CAST "file");
+               else
+                   source = xmlGetProp(cur, BAD_CAST "dev");
+           } else if ((target == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "target"))) {
+               target = xmlGetProp(cur, BAD_CAST "dev");
+           } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
+               ro = 1;
+           }
+       }
+        cur = cur->next;
+    }
+
+    if (source == NULL) {
+        /* VIR_ERR_NO_SOURCE */
+       if (target != NULL)
+           xmlFree(target);
+       return(-1);
+    }
+    if (target == NULL) {
+        /* VIR_ERR_NO_TARGET */
+       if (source != NULL)
+           xmlFree(source);
+       return(-1);
+    }
+    virBufferAdd(buf, "(vbd ", 5);
+    if (target[0] == '/')
+       virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
+    else
+       virBufferVSprintf(buf, "(dev '/dev/%s')", (const char *) target);
+    if (typ == 0)
+        virBufferVSprintf(buf, "(uname 'file:%s')", source);
+    else if (typ == 1) {
+        if (source[0] == '/')
+           virBufferVSprintf(buf, "(uname 'phys:%s')", source);
+       else
+           virBufferVSprintf(buf, "(uname 'phys:/dev/%s')", source);
+    }
+    if (ro == 0)
+        virBufferVSprintf(buf, "(mode 'w')");
+    else if (ro == 1)
+        virBufferVSprintf(buf, "(mode 'r')");
+
+    virBufferAdd(buf, ")", 1);
+    xmlFree(target);
+    xmlFree(source);
+    return(0);
+}
+
+/**
+ * virDomainParseXMLIfDesc:
+ * @xmldesc: string with the XML description
+ * @buf: a buffer for the result S-Expr
+ *
+ * Parse the one interface the XML description and add it to the S-Expr in buf
+ * This is a temporary interface as the S-Expr interface
+ * will be replaced by XML-RPC in the future. However the XML format should
+ * stay valid over time.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+static int
+virDomainParseXMLIfDesc(xmlNodePtr node, virBufferPtr buf) {
+    xmlNodePtr cur;
+    xmlChar *type = NULL;
+    xmlChar *source = NULL;
+    xmlChar *mac = NULL;
+    xmlChar *script = NULL;
+    int typ = 0;
+
+    type = xmlGetProp(node, BAD_CAST "type");
+    if (type != NULL) {
+        if (xmlStrEqual(type, BAD_CAST "bridge")) typ = 0;
+       else if (xmlStrEqual(type, BAD_CAST "ethernet")) typ = 1;
+       xmlFree(type);
+    }
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+           if ((source == NULL) &&
+               (xmlStrEqual(cur->name, BAD_CAST "source"))) {
+
+               if (typ == 0)
+                   source = xmlGetProp(cur, BAD_CAST "bridge");
+               else
+                   source = xmlGetProp(cur, BAD_CAST "dev");
+           } else if ((mac == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "mac"))) {
+               mac = xmlGetProp(cur, BAD_CAST "address");
+           } else if ((script == NULL) &&
+                      (xmlStrEqual(cur->name, BAD_CAST "script"))) {
+               script = xmlGetProp(cur, BAD_CAST "path");
+           }
+       }
+        cur = cur->next;
+    }
+
+    virBufferAdd(buf, "(vif ", 5);
+    if (mac != NULL)
+       virBufferVSprintf(buf, "(mac '%s')", (const char *) mac);
+    if (source != NULL) {
+       if (typ == 0)
+           virBufferVSprintf(buf, "(bridge '%s')", (const char *) source);
+       else /* TODO does that work like that ? */
+           virBufferVSprintf(buf, "(dev '%s')", (const char *) source);
+    }
+    if (script != NULL)
+        virBufferVSprintf(buf, "(script '%s')", script);
+
+    virBufferAdd(buf, ")", 1);
+    if (mac != NULL)
+       xmlFree(mac);
+    if (source != NULL)
+       xmlFree(source);
+    if (script != NULL)
+       xmlFree(script);
+    return(0);
+}
+
+/**
+ * virDomainParseXMLDesc:
+ * @xmldesc: string with the XML description
+ *
+ * Parse the XML description and turn it into the xend sexp needed to
+ * create the comain. This is a temporary interface as the S-Expr interface
+ * will be replaced by XML-RPC in the future. However the XML format should
+ * stay valid over time.
+ *
+ * Returns the 0 terminatedi S-Expr string or NULL in case of error.
+ *         the caller must free() the returned value.
+ */
+char *
+virDomainParseXMLDesc(const char *xmldesc, char **name) {
+    xmlDocPtr xml = NULL;
+    xmlNodePtr node;
+    char *ret = NULL;
+    virBuffer buf;
+    xmlChar *prop;
+    xmlXPathObjectPtr obj = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    int i, res;
+
+    if (name != NULL)
+       *name = NULL;
+    ret = malloc(1000);
+    if (ret == NULL)
+        return(NULL);
+    buf.content = ret;
+    buf.size = 1000;
+    buf.use = 0;
+
+    xml = xmlReadDoc((const xmlChar *) xmldesc, "domain.xml", NULL,
+                XML_PARSE_NOENT | XML_PARSE_NONET | 
+                XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
+    if (xml == NULL) {
+        goto error;
+    }
+    node = xmlDocGetRootElement(xml);
+    if ((node == NULL) || (!xmlStrEqual(node->name, BAD_CAST "domain")))
+        goto error;
+
+    prop = xmlGetProp(node, BAD_CAST "type");
+    if (prop != NULL) {
+        if (!xmlStrEqual(prop, BAD_CAST "xen")) {
+           xmlFree(prop);
+           goto error;
+       }
+       xmlFree(prop);
+    }
+    virBufferAdd(&buf, "(vm ", 4);
+    ctxt = xmlXPathNewContext(xml);
+    if (ctxt == NULL) {
+        goto error;
+    }
+    /*
+     * extract soem of the basics, name, memory, cpus ...
+     */
+    obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
+    if ((obj == NULL) || (obj->type != XPATH_STRING) || 
+        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
+       /* VIR_ERR_NO_NAME */
+        goto error;
+    }
+    virBufferVSprintf(&buf, "(name '%s')", obj->stringval);
+    if (name != NULL)
+       *name = strdup((const char *) obj->stringval);
+    xmlXPathFreeObject(obj);
+
+    obj = xmlXPathEval(BAD_CAST "number(/domain/memory[1])", ctxt);
+    if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
+        (obj->floatval < 64000)) {
+       virBufferVSprintf(&buf, "(memory 128)(maxmem 128)");
+    } else {
+        unsigned long mem = (obj->floatval / 1024);
+        virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)", mem, mem);
+    }
+    xmlXPathFreeObject(obj);
+
+    obj = xmlXPathEval(BAD_CAST "number(/domain/vcpu[1])", ctxt);
+    if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
+        (obj->floatval <= 0)) {
+       virBufferVSprintf(&buf, "(vcpus 1)");
+    } else {
+        unsigned int cpu = (unsigned int) obj->floatval;
+        virBufferVSprintf(&buf, "(vcpus %u)", cpu);
+    }
+    xmlXPathFreeObject(obj);
+
+    /* analyze of the os description */
+    virBufferAdd(&buf, "(image ", 7);
+    obj = xmlXPathEval(BAD_CAST "/domain/os[1]", ctxt);
+    if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+        (obj->nodesetval == NULL) ||
+       (obj->nodesetval->nodeNr != 1)) {
+       /* VIR_ERR_NO_OS */
+        goto error;
+    }
+    res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf);
+    if (res != 0) {
+        goto error;
+    }
+    xmlXPathFreeObject(obj);
+    virBufferAdd(&buf, ")", 1);
+
+    /* analyze of the devices */
+    virBufferAdd(&buf, "(device ", 8);
+    obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
+    if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+        (obj->nodesetval == NULL) ||
+       (obj->nodesetval->nodeNr < 1)) {
+       /* VIR_ERR_NO_DEVICE */
+        goto error;
+    }
+    for (i = 0;i < obj->nodesetval->nodeNr;i++) {
+       res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf);
+       if (res != 0) {
+           goto error;
+       }
+    }
+    xmlXPathFreeObject(obj);
+    obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt);
+    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
+        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
+       for (i = 0;i < obj->nodesetval->nodeNr;i++) {
+           res = virDomainParseXMLIfDesc(obj->nodesetval->nodeTab[i], &buf);
+           if (res != 0) {
+               goto error;
+           }
+       }
+    }
+    xmlXPathFreeObject(obj);
+    virBufferAdd(&buf, ")", 1);
+
+
+    virBufferAdd(&buf, ")", 1);
+    buf.content[buf.use] = 0;
+
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+    
+    return(ret);
+
+error:
+    if (name != NULL) {
+        if (*name != NULL)
+           free(*name);
+       *name = NULL;
+    }
+    if (obj != NULL)
+        xmlXPathFreeObject(obj);
+    if (ctxt != NULL)
+        xmlXPathFreeContext(ctxt);
+    if (xml != NULL)
+        xmlFreeDoc(xml);
+    if (ret != NULL)
+        free(ret);
+    return(NULL);
+}
diff --git a/src/xml.h b/src/xml.h
new file mode 100644 (file)
index 0000000..1ba6c50
--- /dev/null
+++ b/src/xml.h
@@ -0,0 +1,22 @@
+/*
+ * internal.h: internal definitions just used by code from the library
+ */
+
+#ifndef __VIR_XML_H__
+#define __VIR_XML_H__
+
+#include "libvirt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char * virDomainParseXMLDesc   (const char *xmldesc,
+                                char **name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __VIR_XML_H__ */
+