WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xend: Add support for URI ('file:' and 'd

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xend: Add support for URI ('file:' and 'data:' scheme) for PV/kernel
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 25 Aug 2009 07:05:23 -0700
Delivery-date: Tue, 25 Aug 2009 07:05:39 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xend: Add support for URI ('file:' and 'data:' scheme) for PV/kernel, Xen patchbot-unstable <=