[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xend: Add support for URI ('file:' and 'data:' scheme) for PV/kernel



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1251208614 -3600
# Node ID 4fc6ff1e114126b2c815744bee132c376a20c22f
# Parent  c5125c0ea051be8babe0533c94a5635eaa760272
xend: Add support for URI ('file:' and 'data:' scheme) for PV/kernel
and PV/ramdisk

Add support for 'file:' and 'data:' URI schemes for the parameters
'PV/kernel' and 'PV/ramdisk' in the VM.create() call. The 'data:'
scheme handling enables using a file which is stored inside the
management system (from where the XenAPI call is send) as kernel or
ramdisk.

Notes:
o all included: a detailed description can be found in the xenapi
documentation
o bumped up the version of the API document to 1.0.8 (because of
(minimal) interface extension)
o Future enhancements (like http:, ftp: schemes) fit seamlessly into
the current design / classes
o Unittest cases and xm-test case included

Signed-off-by: Andreas Florath <xen@xxxxxxxxxxxx>
---
 docs/xen-api/bibliography.tex                         |    5 
 docs/xen-api/revision-history.tex                     |   58 +---
 docs/xen-api/xenapi-coversheet.tex                    |    4 
 docs/xen-api/xenapi-datamodel.tex                     |   91 +++++++
 docs/xen-api/xenapi.tex                               |    2 
 tools/python/xen/util/fileuri.py                      |  156 +++++++++++++
 tools/python/xen/xend/XendConfig.py                   |   17 +
 tools/python/xen/xend/XendDomainInfo.py               |    6 
 tools/python/xen/xend/image.py                        |   17 +
 tools/tests/run_tests.sh                              |   61 +++++
 tools/tests/utests/run_all_tests.py                   |   32 ++
 tools/tests/utests/ut_util/ut_fileuri.py              |  209 ++++++++++++++++++
 tools/tests/utests/ut_xend/ut_XendConfig.py           |  117 ++++++++++
 tools/tests/utests/ut_xend/ut_image.py                |  147 ++++++++++++
 tools/xm-test/tests/xapi/04_xapi-data_uri_handling.py |   65 +++++
 tools/xm-test/tests/xapi/Makefile.am                  |    3 
 16 files changed, 935 insertions(+), 55 deletions(-)

diff -r c5125c0ea051 -r 4fc6ff1e1141 docs/xen-api/bibliography.tex
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/xen-api/bibliography.tex     Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,5 @@
+\begin{thebibliography}{9}
+\bibitem[RFC2397]{RFC2397}
+Masinter L., \textbf{The "data" URL scheme}, RFC 2397, August 1998,
+Network Working Group, http://www.ietf.org/rfc/rfc2397.txt
+\end{thebibliography}
diff -r c5125c0ea051 -r 4fc6ff1e1141 docs/xen-api/revision-history.tex
--- a/docs/xen-api/revision-history.tex Mon Aug 24 08:27:30 2009 +0100
+++ b/docs/xen-api/revision-history.tex Tue Aug 25 14:56:54 2009 +0100
@@ -1,69 +1,49 @@
 { \bf Revision History}
 
+% Please do not use minipages in a tabular environment; this results
+% in bad vertical alignment. 
+
+\begin{flushleft}
 \begin{center}
- \begin{tabular}{|l|l|l|l|}
+ \begin{tabular}{|l|l|l|>{\raggedright}p{7cm}|}
   \hline
   1.0.0 & 27th April 07 & Xensource et al. &
-   \begin{minipage}[t][.7cm]{7cm}
-     Initial Revision
-   \end{minipage}\\
+     Initial Revision\tabularnewline
   \hline
   1.0.1 & 10th Dec. 07 & S. Berger &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
      Added XSPolicy.reset\_xspolicy, VTPM.get\_other\_config,
-     VTPM.set\_otherconfig. ACMPolicy.get\_enforced\_binary methods.
-    \end{flushleft}
-   \end{minipage}\\
+     VTPM.set\_otherconfig. ACMPolicy.get\_enforced\_binary 
methods.\tabularnewline
   \hline
   1.0.2 & 25th Jan. 08 & J. Fehlig &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
-     Added Crashed VM power state.
-    \end{flushleft}
-   \end{minipage}\\
+     Added Crashed VM power state.\tabularnewline
   \hline
   1.0.3 & 11th Feb. 08 & S. Berger &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
-     Added table of contents and hyperlink cross reference.
-    \end{flushleft}
-   \end{minipage}\\
+     Added table of contents and hyperlink cross reference.\tabularnewline
   \hline
   1.0.4 & 23rd March 08 & S. Berger &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
-     Added XSPolicy.can\_run
-    \end{flushleft}
-   \end{minipage}\\
+     Added XSPolicy.can\_run\tabularnewline
   \hline
   1.0.5 & 17th Apr. 08 & S. Berger &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
      Added undocumented fields and methods for default\_netmask and
      default\_gateway to the Network class. Removed an unimplemented
      method from the XSPolicy class and removed the 'optional' from
-     'oldlabel' parameters.
-    \end{flushleft}
-   \end{minipage}\\
+     'oldlabel' parameters.\tabularnewline
   \hline
   1.0.6 & 24th Jul. 08 & Y. Iwamatsu &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
      Added definitions of new classes DPCI and PPCI. Updated the table
      and the diagram representing relationships between classes.
-     Added host.PPCIs and VM.DPCIs fields.
-    \end{flushleft}
-   \end{minipage}\\
+     Added host.PPCIs and VM.DPCIs fields.\tabularnewline
   \hline
   1.0.7 & 20th Oct. 08 & M. Kanno &
-   \begin{minipage}[t]{7cm}
-    \begin{flushleft}
      Added definitions of new classes DSCSI and PSCSI. Updated the table
      and the diagram representing relationships between classes.
-     Added host.PSCSIs and VM.DSCSIs fields.
-    \end{flushleft}
-   \end{minipage}\\
+     Added host.PSCSIs and VM.DSCSIs fields.\tabularnewline
+  \hline
+  1.0.8 & 17th Jun. 09 & A. Florath &
+     Updated interactive session example.
+     Added description for \texttt{PV/kernel} and \texttt{PV/ramdisk}
+     parameters using URIs.\tabularnewline
   \hline
  \end{tabular}
 \end{center}
+\end{flushleft}
diff -r c5125c0ea051 -r 4fc6ff1e1141 docs/xen-api/xenapi-coversheet.tex
--- a/docs/xen-api/xenapi-coversheet.tex        Mon Aug 24 08:27:30 2009 +0100
+++ b/docs/xen-api/xenapi-coversheet.tex        Tue Aug 25 14:56:54 2009 +0100
@@ -17,12 +17,12 @@
 \newcommand{\coversheetlogo}{xen.eps}
 
 %% Document date
-\newcommand{\datestring}{20th October 2008}
+\newcommand{\datestring}{17th June 2009}
 
 \newcommand{\releasestatement}{Stable Release}
 
 %% Document revision
-\newcommand{\revstring}{API Revision 1.0.7}
+\newcommand{\revstring}{API Revision 1.0.8}
 
 %% Document authors
 \newcommand{\docauthors}{
diff -r c5125c0ea051 -r 4fc6ff1e1141 docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Mon Aug 24 08:27:30 2009 +0100
+++ b/docs/xen-api/xenapi-datamodel.tex Tue Aug 25 14:56:54 2009 +0100
@@ -1,5 +1,6 @@
 %
 % Copyright (c) 2006-2007 XenSource, Inc.
+% Copyright (c) 2009 flonatel GmbH & Co. KG
 %
 % Permission is granted to copy, distribute and/or modify this document under
 % the terms of the GNU Free Documentation License, Version 1.2 or any later
@@ -9,6 +10,7 @@
 % "GNU Free Documentation License" or the file fdl.tex.
 %
 % Authors: Ewan Mellor, Richard Sharp, Dave Scott, Jon Harrop.
+% Contributor: Andreas Florath
 %
 
 \chapter{API Reference}
@@ -1378,10 +1380,10 @@ the batch of events
 \newpage
 \section{Class: VM}
 \subsection{Fields for class: VM}
-\begin{longtable}{|lllp{0.38\textwidth}|}
+\begin{longtable}{|llp{0.21\textwidth}p{0.33\textwidth}|}
 \hline
 \multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VM} \\
-\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
+\multicolumn{4}{|l|}{\parbox{11cm}{\em Description: A
 virtual machine (or 'guest').}} \\
 \hline
 Quals & Field & Type & Description \\
@@ -1413,8 +1415,8 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt DPCIs} & (DPCI ref) Set & pass-through PCI 
devices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt DSCSIs} & (DSCSI ref) Set & 
half-virtualized SCSI devices \\
 $\mathit{RW}$ &  {\tt PV/bootloader} & string & name of or path to bootloader 
\\
-$\mathit{RW}$ &  {\tt PV/kernel} & string & path to the kernel \\
-$\mathit{RW}$ &  {\tt PV/ramdisk} & string & path to the initrd \\
+$\mathit{RW}$ &  {\tt PV/kernel} & string & URI of kernel \\
+$\mathit{RW}$ &  {\tt PV/ramdisk} & string & URI of initrd \\
 $\mathit{RW}$ &  {\tt PV/args} & string & kernel command-line arguments \\
 $\mathit{RW}$ &  {\tt PV/bootloader\_args} & string & miscellaneous arguments 
for the bootloader \\
 $\mathit{RW}$ &  {\tt HVM/boot\_policy} & string & HVM boot policy \\
@@ -1429,6 +1431,87 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt security/label} & string & the VM's 
security label \\
 \hline
 \end{longtable}
+\subsection{Parameter Details}
+\subsubsection{PV/kernel and PV/ramdisk}
+The \texttt{PV/kernel} and \texttt{PV/ramdisk} parameters should be
+specified as URIs with either a \texttt{file} or \texttt{data} scheme.
+
+The \texttt{file} scheme must be used when a file on the remote dom0
+should be used.  The remote dom0 is the one where the guest system
+should be started on. Only absolute filenames are supported, i.e. the
+string must start with \texttt{file://} appended with the absolute
+path.  This is typically used when the guest system use the same
+operating systems as the dom0 or there is some kind of shared storage
+for the images inside the dom0s.
+
+Note that for compatibility reasons it is possible --- but not
+recommended --- to leave out the scheme specification for
+\texttt{file}, i.e. \texttt{file:///some/path} and \texttt{/some/path}
+is equivalent.
+
+Examples (in python):
+
+Use kernel image which resides in the \texttt{/boot} directory:
+\begin{verbatim}
+xenapi.VM.create({ ...
+   'PV_kernel': 'file:///boot/vmlinuz-2.6.26-2-xen-686',
+   ... })
+\end{verbatim}
+
+Use ramdisk image which resides on a (shared) nfs directory:
+\begin{verbatim}
+xenapi.VM.create({ ...
+   'PV_ramdisk': 'file:///nfs/xen/debian/5.0.1/initrd.img-2.6.26-2-xen-686'
+   ... })
+\end{verbatim}
+
+When an image should be used which resides on the local system,
+i.e. the system where the XenAPI call is send from, it is possible to
+use the \texttt{data} URI scheme as described in \cite{RFC2397}.  The
+media-type must be set to \texttt{application/octet-stream}.
+Currently only base64 encoding is supported.  The URI must therefore
+start with \texttt{data:application/octet-stream;base64,} followed by
+the base64 encoded image.
+
+The \texttt{xen/util/fileuri.py} provides a helper function which
+takes a local filename as parameter and build up the correct URI from
+this.
+
+Examples (in python):
+
+Use kernel image specified inline:
+\begin{verbatim}
+xenapi.VM.create({ ...
+   'PV_kernel': 'data:application/octet-stream;base64,H4Zu....'
+      # most of base64 encoded data is omitted 
+   ... })
+\end{verbatim}
+
+Using the utility function:
+\begin{verbatim}
+from xen.util.fileuri import scheme_data
+xenapi.VM.create({ ...
+   'PV_kernel': scheme_data.create_from_file(
+       "/xen/guests/images/debian/5.0.1/vmlinuz-2.6.26-2-xen-686"),
+   ... })
+\end{verbatim}
+
+Currently when using the \texttt{data} URI scheme, a temporary file is
+created on the remote dom0 in the directory
+\texttt{/var/run/xend/boot} which is then used for booting. When not
+used any longer the file is deleted.  (Therefore reading of the
+\texttt{PV/kernel} or \texttt{PV/ramdisk} parameters when created with
+a \texttt{data} URI scheme returns a filename to a temporary file ---
+which might even not exists when querying.)  This implementation might
+change in the way that the data is directly used --- without the
+indirection using a file.  Therefore do not rely on the data resulting
+from a read of a variables which was set using the \texttt{data}
+scheme.
+
+Note: a mix of different schemes for the parameters is possible; e.g.
+the kernel can be specified with a \texttt{file} and the ramdisk with
+the \texttt{data} URI scheme.
+
 \subsection{RPCs associated with class: VM}
 \subsubsection{RPC name:~clone}
 
diff -r c5125c0ea051 -r 4fc6ff1e1141 docs/xen-api/xenapi.tex
--- a/docs/xen-api/xenapi.tex   Mon Aug 24 08:27:30 2009 +0100
+++ b/docs/xen-api/xenapi.tex   Tue Aug 25 14:56:54 2009 +0100
@@ -18,6 +18,7 @@
 \usepackage{longtable}
 \usepackage{fancyhdr}
 \usepackage{hyperref}
+\usepackage{array}
 
 \setlength\topskip{0cm}
 \setlength\topmargin{0cm}
@@ -54,5 +55,6 @@ Xen-enabled host.
 \include{vm-lifecycle}
 \include{xenapi-datamodel}
 \include{fdl}
+\include{bibliography}
 
 \end{document}
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/python/xen/util/fileuri.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/fileuri.py  Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,156 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+
+import logging
+import os
+import base64
+import tempfile
+import stat
+from xen.xend.XendLogging import log
+from xen.util import mkdir
+
+#
+# This functions and classes can be used where a filename is expected -
+# especially in the xenapi.VM.create() for PV_kernel and PV_ramdisk.
+#
+# The functions have a backward compatibility mode, i.e. when there is
+# no appropriate scheme detected, the data is seens as a path to a
+# (local) file.
+#
+
+class scheme_error(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+# Data scheme (as defined in RFC 2397):
+#  data:application/octet-stream;base64,<base64 encoded data>
+# It looks that there is currently no general purpose implementation
+# available (in python) for this URL scheme - so the very basic is
+# done here.
+#
+# Limitations
+# o Only base64 is currently supported
+class scheme_data:
+
+    def encode(data, mediatype = 'application/octet-stream', 
+               encoding = 'base64'):
+        # XXX Limit this to base64 for current implementation
+        if encoding!='base64':
+            raise scheme_error("invalid encoding")
+        return 'data:' + mediatype + ";" + encoding \
+            + "," + base64.b64encode(data)
+    encode = staticmethod(encode)
+
+    # Private method: parse encoded data
+    def parse(encoded_data):
+        if not isinstance(encoded_data, str):
+            raise scheme_error("encoded data has wrong type")
+        if not encoded_data.startswith('data:'):
+            raise scheme_error("'data:' scheme declaration missing")
+        comma = encoded_data.find(',', 5)
+        if comma == -1:
+            raise scheme_error("data separator (comma) is missing")
+        # Cut off the media type and encoding
+        mtenc = encoded_data[5:comma]
+        if len(mtenc)==0:
+            raise scheme_error("encoding is empty")
+        # XXX Limit to base64 encoding
+        if not mtenc.endswith(';base64'):
+            raise scheme_error("encoding is not base64")
+        mediatype = mtenc[:-7]
+        return (mediatype, 'base64', comma+1)
+    parse = staticmethod(parse)
+
+    # Stores the data in a local file and returns the filename
+    # and a flag if this file in temporary only and must be deleted
+    # after starting the VM.
+    def decode(encoded_data):
+        mkdir.parents("/var/run/xend/boot/", stat.S_IRWXU)
+        mediatype, encoding, data_start = scheme_data.parse(encoded_data)
+        fd, filename = tempfile.mkstemp(
+            prefix="data_uri_file.", dir="/var/run/xend/boot")
+        # Because of python 2.3 support, there is a need to nest these
+        # (see http://www.python.org/doc/2.3/ref/try.html)
+        try:
+            try:
+                os.write(fd, base64.b64decode(encoded_data[data_start:]))
+            except TypeError, se:
+                raise scheme_error("failed to decode as base64")
+        finally:
+            os.close(fd)
+        return filename, True
+    decode = staticmethod(decode)
+
+    # Utility function which reads in the given (local) file and
+    # creates a data scheme from this.
+    def create_from_file(filename):
+        try:
+            f = open(filename, "r")
+            d = f.read()
+            f.close()
+            return scheme_data.encode(d)
+        except IOError:
+            raise scheme_error("file does not exists")
+    create_from_file = staticmethod(create_from_file)
+
+
+# File Scheme
+# This class supports absolut paths only.
+class scheme_file:
+
+    def encode(filename):
+        if len(filename) == 0:
+            raise scheme_error("filename is empty")
+        if filename[0] != '/':
+            raise scheme_error("filename is not absolut")
+        return 'file://' + filename
+    encode = staticmethod(encode)
+
+    def decode(encoded_data):
+        if not encoded_data.startswith("file://"):
+            raise scheme_error("no file:// scheme found")
+        path = encoded_data[7:]
+        if len(path)==0:
+            raise scheme_error("path is empty")
+        if path[0]!='/':
+            raise scheme_error("path is not absolute")
+        return path, False
+    decode = staticmethod(decode)
+
+
+class scheme_set:
+
+    def __init__(self):
+        self.schemes = [scheme_data, scheme_file]
+
+    # log_decode_exception flags whether a specific uri schema
+    # decoding exception should be logged or not (default: False - do
+    # not log).
+    def decode(self, uri, log_decode_exception=False):
+        for scheme in self.schemes:
+            try:
+                # If this passes, it is the correct scheme
+                return scheme.decode(uri)
+            except scheme_error, se:
+                if log_decode_exception:
+                    log.debug("Decode throws an error: '%s'" % se)
+        return uri, False
+
+schemes = scheme_set()
+        
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Mon Aug 24 08:27:30 2009 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Tue Aug 25 14:56:54 2009 +0100
@@ -41,6 +41,7 @@ from xen.xend.XendSXPDev import dev_dict
 from xen.xend.XendSXPDev import dev_dict_to_sxp
 from xen.util import xsconstants
 from xen.util import auxbin
+import xen.util.fileuri
 
 log = logging.getLogger("xend.XendConfig")
 log.setLevel(logging.WARN)
@@ -337,6 +338,8 @@ class XendConfig(dict):
         elif dominfo:
             # output from xc.domain_getinfo
             self._dominfo_to_xapi(dominfo, update_mem = True)
+
+        self.handle_fileuris()
 
         log.debug('XendConfig.init: %s' % scrub_password(self))
 
@@ -1999,10 +2002,14 @@ class XendConfig(dict):
             self['_temp_kernel'] = sxp.child_value(image_sxp, 'kernel','')
             self['_temp_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
             self['_temp_args'] = kernel_args
+            self['use_tmp_kernel'] = True
+            self['use_tmp_ramdisk'] = True
         else:
             self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
             self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
             self['PV_args'] = kernel_args
+            self['use_tmp_kernel'] = False
+            self['use_tmp_ramdisk'] = False
 
         self['superpages'] = sxp.child_value(image_sxp, 'superpages',0)
 
@@ -2072,4 +2079,12 @@ class XendConfig(dict):
                 opts = pci_opts_list_from_sxp(dev)
                 pci.append([domain, bus, slot, func, vdevfn, opts])
         self['platform']['pci'] = pci
-
+ 
+    def handle_fileuris(self):
+        for arg in [('PV_kernel', 'use_tmp_kernel'), 
+                    ('PV_ramdisk', 'use_tmp_ramdisk')]:
+            if arg[0] in self and self[arg[0]]!='':
+                self[arg[0]], self[arg[1]] \
+                    = xen.util.fileuri.schemes.decode(self[arg[0]])
+                log.debug("fileuri '%s' = '%s'" % (arg[0], self[arg[0]][:100]))
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Aug 24 08:27:30 2009 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Aug 25 14:56:54 2009 +0100
@@ -2662,7 +2662,7 @@ class XendDomainInfo:
 
             self._createDevices()
 
-            self.image.cleanupBootloading()
+            self.image.cleanupTmpImages()
 
             self.info['start_time'] = time.time()
 
@@ -2670,12 +2670,12 @@ class XendDomainInfo:
         except VmError, exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
             if self.image:
-                self.image.cleanupBootloading()
+                self.image.cleanupTmpImages()
             raise exn
         except RuntimeError, exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
             if self.image:
-                self.image.cleanupBootloading()
+                self.image.cleanupTmpImages()
             raise VmError(str(exn))
 
 
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Mon Aug 24 08:27:30 2009 +0100
+++ b/tools/python/xen/xend/image.py    Tue Aug 25 14:56:54 2009 +0100
@@ -89,6 +89,8 @@ class ImageHandler:
         self.vm = vm
 
         self.bootloader = False
+        self.use_tmp_kernel = False
+        self.use_tmp_ramdisk = False
         self.kernel = None
         self.ramdisk = None
         self.cmdline = None
@@ -106,6 +108,12 @@ class ImageHandler:
             self.kernel = vmConfig['PV_kernel']
             self.cmdline = vmConfig['PV_args']
             self.ramdisk = vmConfig['PV_ramdisk']
+        # There a code-paths where use_tmp_xxx is not set at all; but if
+        # this is set, the variable itself is a boolean.
+        if 'use_tmp_kernel' in vmConfig and vmConfig['use_tmp_kernel']:
+            self.use_tmp_kernel = True
+        if 'use_tmp_ramdisk' in vmConfig and vmConfig['use_tmp_ramdisk']:
+            self.use_tmp_ramdisk = True
         self.vm.storeVm(("image/ostype", self.ostype),
                         ("image/kernel", self.kernel),
                         ("image/cmdline", self.cmdline),
@@ -135,11 +143,11 @@ class ImageHandler:
         if 'cpuid_check' in vmConfig:
             self.cpuid_check = vmConfig['cpuid_check']
 
-    def cleanupBootloading(self):
-        if self.bootloader:
+    def cleanupTmpImages(self):
+        if self.use_tmp_kernel:
             self.unlink(self.kernel)
+        if self.use_tmp_ramdisk:
             self.unlink(self.ramdisk)
-
 
     def unlink(self, f):
         if not f: return
@@ -659,8 +667,6 @@ class ImageHandler:
                 transformed[sinput] = t
             self.cpuid_check = transformed
 
-
-
 class LinuxImageHandler(ImageHandler):
 
     ostype = "linux"
@@ -1028,3 +1034,4 @@ def findImageHandlerClass(image):
         return _handlers[arch.type][image_type]
     except KeyError:
         raise VmError('unknown image type: ' + image_type)
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/tests/run_tests.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tests/run_tests.sh  Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# This runs the available unit-tests with all different supported
+# python versions.
+# 
+# To run this this must be 'cd'ed to the tests directory.
+#
+
+ENABLE_UNSUPPORTED=0
+
+function usage()
+{
+    printf "Usage: %s: [-u]\n" $0
+    printf "   -u: run test with unsupported python versions also\n"
+}
+
+function run_one_test()
+{
+    PYTHON=$1
+    PYTHON_EXECUTABLE=`echo $PYTHON | tr -d "-"`
+    echo "+++ Running tests with $PYTHON"
+    export LD_LIBRARY_PATH=./regression/installed/$PYTHON/lib
+    ./regression/installed/$PYTHON/bin/$PYTHON_EXECUTABLE \
+       utests/run_all_tests.py
+    echo "--- Finished tests with $PYTHON"
+}
+
+function run_all_tests()
+{
+    for PYTHON in $@;
+    do
+       run_one_test $PYTHON
+    done
+}
+
+while getopts u name
+do
+    case $name in
+       h)  usage; exit 0;;
+       u)  ENABLE_UNSUPPORTED=1;;
+       ?)  usage; exit 2;;
+    esac
+done
+
+# Build the different python versions
+(cd regression && make -j4 runtime-environment)
+
+# Supported: when an unit test fails this should be seen as an error
+PYTHON_SUPPORTED="python-2.4 python-2.5 python-2.6"
+# Unsupported: failure should be seen as a hint
+PYTHON_UNSUPPORTED="python-3.1"
+
+export PYTHONPATH=`echo $PWD/../python/build/lib.*`:$PWD
+
+set -e
+run_all_tests $PYTHON_SUPPORTED
+
+if test $ENABLE_UNSUPPORTED -eq 1
+then
+    run_all_tests $PYTHON_UNSUPPORTED
+fi
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/tests/utests/run_all_tests.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tests/utests/run_all_tests.py       Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,32 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+
+import unittest
+
+import utests.ut_util.ut_fileuri
+import utests.ut_xend.ut_XendConfig
+import utests.ut_xend.ut_image
+
+suite = unittest.TestSuite(
+    [utests.ut_util.ut_fileuri.suite(),
+     utests.ut_xend.ut_XendConfig.suite(),
+     utests.ut_xend.ut_image.suite(),
+     ])
+
+if __name__ == "__main__":
+    testresult = unittest.TextTestRunner(verbosity=3).run(suite)
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/tests/utests/ut_util/ut_fileuri.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tests/utests/ut_util/ut_fileuri.py  Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,209 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+
+import os
+import unittest
+
+from xen.util.fileuri import scheme_error
+from xen.util.fileuri import scheme_data
+from xen.util.fileuri import scheme_file
+from xen.util.fileuri import schemes
+
+class scheme_data_unit_tests(unittest.TestCase):
+
+    def check_basic_encoding(self):
+        "util.fileuri.scheme_data - basic encoding"
+        sd = scheme_data.encode('Hello!')
+        self.assertEqual(sd, 'data:application/octet-stream;base64,SGVsbG8h')
+
+    def check_encoding_with_given_mediatype(self):
+        "util.fileuri.scheme_data - encoding with given media name"
+        sd = scheme_data.encode('Hello!', 'application/x-my-linux-kernel')
+        self.assertEqual(sd,
+              'data:application/x-my-linux-kernel;base64,SGVsbG8h')
+
+    def check_parse_01(self):
+        "util.fileuri.scheme_data - parsing of None"
+        self.assertRaises(scheme_error, scheme_data.parse, None)
+
+    def check_parse_02(self):
+        "util.fileuri.scheme_data - parsing of empty string"
+        self.assertRaises(scheme_error, scheme_data.parse, "")
+
+    def check_parse_03(self):
+        "util.fileuri.scheme_data - parsing of unstructured data"
+        self.assertRaises(scheme_error, scheme_data.parse, "akskdjdfhezezu")
+
+    def check_parse_04(self):
+        "util.fileuri.scheme_data - data: is not at the first place"
+        self.assertRaises(scheme_error, scheme_data.parse, 'ggdata:sossm')
+
+    def check_parse_05(self):
+        "util.fileuri.scheme_data - no comma in data"
+        self.assertRaises(scheme_error, scheme_data.parse, 'data:sossm')
+
+    def check_parse_06(self):
+        "util.fileuri.scheme_data - encoding is empty"
+        self.assertRaises(scheme_error, scheme_data.parse, 'data:,')
+
+    def check_parse_07(self):
+        "util.fileuri.scheme_data - unknown encoding"
+        self.assertRaises(scheme_error, scheme_data.parse,
+                          'data:somemediatype;unknown,')
+
+    def check_parse_08(self):
+        "util.fileuri.scheme_data - parse ok - empty data"
+        mediatype, encoding, data_start = scheme_data.parse(
+            'data:somemedia;base64,')
+        self.assertEqual(mediatype, 'somemedia')
+        self.assertEqual(encoding, 'base64')
+        self.assertEqual(data_start, 22)
+
+    def check_parse_09(self):
+        "util.fileuri.scheme_data - parse ok - some data"
+        mediatype, encoding, data_start = scheme_data.parse(
+            'data:somemedia;base64,HereComesTheSun')
+        self.assertEqual(mediatype, 'somemedia')
+        self.assertEqual(encoding, 'base64')
+        self.assertEqual(data_start, 22)
+
+    def check_parse_10(self):
+        "util.fileuri.scheme_data - header ok - data error"
+        self.assertRaises(scheme_error, scheme_data.decode,
+               'data:application/octet-stream;base64,H!$ere"Co<mesT>heS_.un')
+
+    def check_cff_file_does_not_exist(self):
+        "util.fileuri.scheme_data - create from file - non existent file"
+        self.assertRaises(scheme_error, scheme_data.create_from_file,
+                          "/there/is/hopefully/no/file/like/this")
+
+    def check_cff_ok(self):
+        "util.fileuri.scheme_data - create from file - ok"
+        tmppath = "/tmp/scheme_data_check_cff_ok"
+        f = open(tmppath, "w")
+        f.write("huhuhu")
+        f.close()
+        d = scheme_data.create_from_file(tmppath)
+        os.unlink(tmppath)
+        self.assertEqual(d, "data:application/octet-stream;base64,aHVodWh1")
+
+
+class scheme_file_unit_tests(unittest.TestCase):
+
+    def check_encode_empty_filename(self):
+        "util.fileuri.scheme_file - encode empty filename"
+        self.assertRaises(scheme_error, scheme_file.encode, "")
+
+    def check_encode_relative_filename(self):
+        "util.fileuri.scheme_file - encode relative filename"
+        self.assertRaises(scheme_error, scheme_file.encode, "../there")
+
+    def check_encode_absolut_filename(self):
+        "util.fileuri.scheme_file - encode absolut filename"
+        self.assertEqual(
+            scheme_file.encode("/here/and/there/again"),
+            'file:///here/and/there/again')
+
+    def check_decode_01(self):
+        "util.fileuri.scheme_file - decode empty data"
+        self.assertRaises(scheme_error, scheme_file.decode, "")
+
+    def check_decode_02(self):
+        "util.fileuri.scheme_file - decode data with no file:// at the 
beginning (1)"
+        self.assertRaises(scheme_error, scheme_file.decode,
+                          "phonehome://bbbb")
+
+    def check_decode_03(self):
+        "util.fileuri.scheme_file - decode data with no file:// at the 
beginning (2)"
+        self.assertRaises(scheme_error, scheme_file.decode,
+                          "file:/bbbb")
+
+    def check_decode_04(self):
+        "util.fileuri.scheme_file - decode empty path"
+        self.assertRaises(scheme_error, scheme_file.decode,
+                          "file://")
+
+    def check_decode_05(self):
+        "util.fileuri.scheme_file - decode empty relative path"
+        self.assertRaises(scheme_error, scheme_file.decode,
+                          "file://somewhere")
+
+    def check_decode_06(self):
+        "util.fileuri.scheme_file - decode ok"
+        path, tmp_file = scheme_file.decode("file:///boot/vmlinuz")
+        self.assertEqual(path, "/boot/vmlinuz")
+        self.assertEqual(tmp_file, False)
+
+class scheme_set_unit_tests(unittest.TestCase):
+
+    def check_data_01(self):
+        "util.fileuri.scheme_set - data with error in media type"
+
+        u = "data:something_wrong,base64:swer"
+        uri, tmp_file = schemes.decode(u)
+        self.assertEqual(uri, u)
+        self.assertEqual(tmp_file, False)
+
+    def check_data_02(self):
+        "util.fileuri.scheme_set - data with error in base64 data"
+
+        u = "data:application/octet-stream;base64,S!VsbG8h"
+        uri, tmp_file = schemes.decode(u)
+        self.assertEqual(uri, u)
+        self.assertEqual(tmp_file, False)
+ 
+    def check_data_03(self):
+        "util.fileuri.scheme_set - data ok"
+
+        u = "data:application/octet-stream;base64,SGVsbG8h"
+        uri, tmp_file = schemes.decode(u)
+
+        # Read file contents
+        f = open(uri, "r")
+        d = f.read()
+        f.close()
+        os.unlink(uri)
+
+        self.assertEqual(d, "Hello!")
+        self.assertEqual(tmp_file, True)
+       
+    def check_file_01(self):
+        "util.fileuri.scheme_set - file ok"
+
+        f = "/The/Path/To/The/File.txt"
+        uri, tmp_file = schemes.decode("file://" + f)
+        self.assertEqual(uri, f)
+        self.assertEqual(tmp_file, False)
+
+    def check_without_scheme_01(self):
+        "util.fileuri.scheme_set - without scheme"
+
+        f = "/The/Path/To/The/File.txt"
+        uri, tmp_file = schemes.decode(f)
+        self.assertEqual(uri, f)
+        self.assertEqual(tmp_file, False)
+
+
+def suite():
+    return unittest.TestSuite(
+        [unittest.makeSuite(scheme_data_unit_tests, 'check_'),
+         unittest.makeSuite(scheme_file_unit_tests, 'check_'),
+         unittest.makeSuite(scheme_set_unit_tests, 'check_'),])
+
+if __name__ == "__main__":
+    testresult = unittest.TextTestRunner(verbosity=3).run(suite())
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/tests/utests/ut_xend/ut_XendConfig.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tests/utests/ut_xend/ut_XendConfig.py       Tue Aug 25 14:56:54 
2009 +0100
@@ -0,0 +1,117 @@
+#===========================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+
+import os
+import unittest
+
+# This does not work because of a cyclic import loop
+#from xen.xend.XendConfig import XendConfig
+import xen.xend.XendDomain
+
+class XendConfigUnitTest(unittest.TestCase):
+
+    def minimal_vmconf(self):
+        return {
+            'memory_dynamic_min': 64,
+            'memory_dynamic_max': 128,
+            'memory_static_max': 128,
+            }
+
+    def check_hf_01(self):
+        "xend.XendConfig.handle_fileutils - PV_kernel/ramdisk not set"
+        vmconf = self.minimal_vmconf()
+        xc = xen.xend.XendConfig.XendConfig(xapi = vmconf)
+
+        self.assert_(not xc.has_key('use_tmp_kernel'))
+        self.assert_(not xc.has_key('use_tmp_ramdisk'))
+
+    def check_hf_02(self):
+        "xend.XendConfig.handle_fileutils - PV_kernel/ramdisk set to some path"
+        vmconf = self.minimal_vmconf()
+        vmconf['PV_kernel'] = '/some/where/under/the/rainbow-kernel'
+        vmconf['PV_ramdisk'] = '/some/where/under/the/rainbow-ramdisk'
+        xc = xen.xend.XendConfig.XendConfig(xapi = vmconf)
+
+        self.assert_(xc.has_key('use_tmp_kernel'))
+        self.assert_(xc.has_key('use_tmp_ramdisk'))
+
+        self.assert_(not xc['use_tmp_kernel'])
+        self.assert_(not xc['use_tmp_ramdisk'])
+
+    def check_hf_03(self):
+        "xend.XendConfig.handle_fileutils - PV_kernel/ramdisk using file: 
scheme"
+        vmconf = self.minimal_vmconf()
+        vmconf['PV_kernel'] = 'file:///some/where/under/the/rainbow-kernel'
+        vmconf['PV_ramdisk'] = 'file:///some/where/under/the/rainbow-ramdisk'
+        xc = xen.xend.XendConfig.XendConfig(xapi = vmconf)
+
+        self.assert_(xc.has_key('use_tmp_kernel'))
+        self.assert_(xc.has_key('use_tmp_ramdisk'))
+
+        self.assert_(not xc['use_tmp_kernel'])
+        self.assert_(not xc['use_tmp_ramdisk'])
+
+        self.assert_('PV_kernel' in xc)
+        self.assert_('PV_ramdisk' in xc)
+
+        self.assertEqual("/some/where/under/the/rainbow-kernel",
+                         xc['PV_kernel'])
+        self.assertEqual("/some/where/under/the/rainbow-ramdisk",
+                         xc['PV_ramdisk'])
+
+    def check_hf_04(self):
+        "xend.XendConfig.handle_fileutils - PV_kernel/ramdisk using data: 
scheme"
+        vmconf = self.minimal_vmconf()
+        vmconf['PV_kernel'] = 
'data:application/octet-stream;base64,VGhpcyBpcyB0aGUga2VybmVsCg=='
+        vmconf['PV_ramdisk'] = 
'data:application/octet-stream;base64,TXkgZ3JlYXQgcmFtZGlzawo='
+        xc = xen.xend.XendConfig.XendConfig(xapi = vmconf)
+
+        self.assert_(xc.has_key('use_tmp_kernel'))
+        self.assert_(xc.has_key('use_tmp_ramdisk'))
+
+        self.assert_(xc['use_tmp_kernel'])
+        self.assert_(xc['use_tmp_ramdisk'])
+
+        self.assert_('PV_kernel' in xc)
+        self.assert_('PV_ramdisk' in xc)
+
+        self.assert_(xc['PV_kernel'].startswith(
+                "/var/run/xend/boot/data_uri_file."))
+        self.assert_(xc['PV_ramdisk'].startswith(
+                "/var/run/xend/boot/data_uri_file."))
+
+        f = file(xc['PV_kernel'])
+        kc = f.read()
+        f.close()
+
+        f = file(xc['PV_ramdisk'])
+        rc = f.read()
+        f.close()
+
+        os.unlink(xc['PV_kernel'])
+        os.unlink(xc['PV_ramdisk'])
+
+        self.assertEqual(kc, "This is the kernel\n")
+        self.assertEqual(rc, "My great ramdisk\n")
+
+def suite():
+    return unittest.TestSuite(
+        [unittest.makeSuite(XendConfigUnitTest, 'check_'),])
+
+if __name__ == "__main__":
+    testresult = unittest.TextTestRunner(verbosity=3).run(suite())
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/tests/utests/ut_xend/ut_image.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tests/utests/ut_xend/ut_image.py    Tue Aug 25 14:56:54 2009 +0100
@@ -0,0 +1,147 @@
+#===========================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+
+import unittest
+import tempfile
+import os
+
+import xen.xend.image
+
+class ImageHandlerUnitTests(unittest.TestCase):
+
+    class ImageHandlerUnitTestsVirtualMachine:
+
+        def __init__(self):
+            self.info = {
+                'name_label': 'ItsMyParty',
+                }
+
+        def storeVm(self, *args):
+            pass
+
+        def permissionsVm(self, *args):
+            pass
+
+        def getDomid(self):
+            return 7
+
+    # Sets up a vm_config with no bootloader.
+    def vm_config_no_bootloader(self):
+        return {
+            'PV_kernel': 'value_of_PV_kernel',
+            'PV_args': 'value_of_PV_args',
+            'PV_ramdisk': 'value_of_PV_ramdisk',
+            'platform': {},
+            'console_refs': [],
+            }
+
+    def check_configure_01(self):
+        # This retests the problem reported by Jun Koi on 24.07.2009
+        # see 
http://lists.xensource.com/archives/html/xen-devel/2009-07/msg01006.html
+        "ImageHandler - call configure with mostly empty vmConfig"
+
+        vmConfig = self.vm_config_no_bootloader()
+        vm = self.ImageHandlerUnitTestsVirtualMachine()
+        ih = xen.xend.image.ImageHandler(vm, vmConfig)
+
+        self.assertEqual(ih.use_tmp_kernel, False)
+        self.assertEqual(ih.use_tmp_ramdisk, False)
+
+    def check_configure_02(self):
+        "ImageHandler - call configure with use_tmp_xxx set to false"
+
+        vmConfig = self.vm_config_no_bootloader()
+        vmConfig['use_tmp_kernel'] = False
+        vmConfig['use_tmp_ramdisk'] = False
+        vm = self.ImageHandlerUnitTestsVirtualMachine()
+        ih = xen.xend.image.ImageHandler(vm, vmConfig)
+
+        self.assertEqual(ih.use_tmp_kernel, False)
+        self.assertEqual(ih.use_tmp_ramdisk, False)
+
+
+    def check_configure_03(self):
+        "ImageHandler - call configure with use_tmp_xxx set to true"
+
+        vmConfig = self.vm_config_no_bootloader()
+        vmConfig['use_tmp_kernel'] = True
+        vmConfig['use_tmp_ramdisk'] = True
+        vm = self.ImageHandlerUnitTestsVirtualMachine()
+        ih = xen.xend.image.ImageHandler(vm, vmConfig)
+
+        self.assertEqual(ih.use_tmp_kernel, True)
+        self.assertEqual(ih.use_tmp_ramdisk, True)
+
+    def cleanup_tmp_images_base(self, vmConfig):
+        vm = self.ImageHandlerUnitTestsVirtualMachine()
+        ih = xen.xend.image.ImageHandler(vm, vmConfig)
+
+        k, ih.kernel = tempfile.mkstemp(
+            prefix = "ImageHandler-cleanupTmpImages-k", dir = "/tmp")
+        r, ih.ramdisk = tempfile.mkstemp(
+            prefix = "ImageHandler-cleanupTmpImages-r", dir = "/tmp")
+
+        ih.cleanupTmpImages()
+
+        kres = os.path.exists(ih.kernel)
+        rres = os.path.exists(ih.ramdisk)
+
+        if not ih.use_tmp_kernel:
+            os.unlink(ih.kernel)
+        if not ih.use_tmp_ramdisk:
+            os.unlink(ih.ramdisk)
+
+        return kres, rres
+
+    def check_cleanup_tmp_images_01(self):
+        "ImageHandler - cleanupTmpImages with use_tmp_xxx unset"
+
+        vmConfig = self.vm_config_no_bootloader()
+        kres, rres = self.cleanup_tmp_images_base(vmConfig)
+
+        self.assertEqual(kres, True)
+        self.assertEqual(rres, True)
+
+    def check_cleanup_tmp_images_02(self):
+        "ImageHandler - cleanupTmpImages with use_tmp_xxx set to false"
+
+        vmConfig = self.vm_config_no_bootloader()
+        vmConfig['use_tmp_kernel'] = False
+        vmConfig['use_tmp_ramdisk'] = False
+        kres, rres = self.cleanup_tmp_images_base(vmConfig)
+
+        self.assertEqual(kres, True)
+        self.assertEqual(rres, True)
+
+    def check_cleanup_tmp_images_03(self):
+        "ImageHandler - cleanupTmpImages with use_tmp_xxx set to true"
+
+        vmConfig = self.vm_config_no_bootloader()
+        vmConfig['use_tmp_kernel'] = True
+        vmConfig['use_tmp_ramdisk'] = True
+        kres, rres = self.cleanup_tmp_images_base(vmConfig)
+
+        self.assertEqual(kres, False)
+        self.assertEqual(rres, False)
+
+def suite():
+    return unittest.TestSuite(
+        [unittest.makeSuite(ImageHandlerUnitTests, 'check_'),])
+
+if __name__ == "__main__":
+    testresult = unittest.TextTestRunner(verbosity=3).run(suite())
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 
tools/xm-test/tests/xapi/04_xapi-data_uri_handling.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/xapi/04_xapi-data_uri_handling.py     Tue Aug 25 
14:56:54 2009 +0100
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2009 flonatel GmbH & Co. KG
+#============================================================================
+#
+# This file contains test cases for checking the data URI
+# functionality:
+# kernel and ramdisk are both checked with original uri,
+# file uri and data uri (in every constallation)
+#
+
+import copy
+
+from xen.util.fileuri import schemes, scheme_data, scheme_file
+
+from XmTestLib import *
+from XmTestLib.network_utils import *
+from XmTestLib.XenAPIDomain import XmTestAPIDomain
+
+kernel_orig_uri = arch.configDefaults['kernel']
+ramdisk_orig_uri = arch.configDefaults['ramdisk']
+kernel_data_uri = scheme_data.create_from_file(kernel_orig_uri)
+ramdisk_data_uri = scheme_data.create_from_file(ramdisk_orig_uri)
+kernel_file_uri = scheme_file.encode(kernel_orig_uri)
+ramdisk_file_uri = scheme_file.encode(ramdisk_orig_uri)
+
+config = copy.copy(arch.configDefaults)
+
+for kernel in (kernel_orig_uri, kernel_data_uri, kernel_file_uri):
+    for ramdisk in (ramdisk_orig_uri, ramdisk_data_uri, ramdisk_file_uri):
+        config['kernel'] = kernel
+        config['ramdisk'] = ramdisk
+        print("Using kernel='%s' ramdisk='%s'" % (kernel[:100], ramdisk[:100]))
+        try:
+            guest = XmTestAPIDomain(baseConfig = config)
+            console = guest.start()
+        except DomainError, e:
+            if verbose:
+                print("Failed to create test domain because: %s" % e.extra)
+            FAIL(str(e))
+
+        try:
+            run = console.runCmd("ls /")
+            if run['return'] > 0:
+                FAIL("Could not start host")
+        except ConsoleError, e:
+            saveLog(console.getHistory())
+            FAIL(str(e))
+            
+        guest.closeConsole()
+        guest.stop()
+
diff -r c5125c0ea051 -r 4fc6ff1e1141 tools/xm-test/tests/xapi/Makefile.am
--- a/tools/xm-test/tests/xapi/Makefile.am      Mon Aug 24 08:27:30 2009 +0100
+++ b/tools/xm-test/tests/xapi/Makefile.am      Tue Aug 25 14:56:54 2009 +0100
@@ -2,7 +2,8 @@ SUBDIRS =
 
 TESTS = 01_xapi-vm_basic.test \
        02_xapi-vbd_basic.test \
-       03_xapi-network_pos.test
+       03_xapi-network_pos.test \
+       04_xapi-data_uri_handling.test
 
 XFAIL_TESTS =
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.