debuggers.hg
changeset 19999:e34975d7d8f1
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
Signed-off-by: Andreas Florath <xen@flonatel.org>
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
Signed-off-by: Andreas Florath <xen@flonatel.org>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Jul 20 10:12:38 2009 +0100 (2009-07-20) |
parents | 62b7fc245d1f |
children | 6d41644623de |
files | docs/xen-api/bibliography.tex docs/xen-api/revision-history.tex docs/xen-api/xenapi-coversheet.tex docs/xen-api/xenapi-datamodel.tex docs/xen-api/xenapi.tex tools/python/xen/util/fileuri.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/docs/xen-api/bibliography.tex Mon Jul 20 10:12:38 2009 +0100 1.3 @@ -0,0 +1,5 @@ 1.4 +\begin{thebibliography}{9} 1.5 +\bibitem[RFC2397]{RFC2397} 1.6 +Masinter L., \textbf{The "data" URL scheme}, RFC 2397, August 1998, 1.7 +Network Working Group, http://www.ietf.org/rfc/rfc2397.txt 1.8 +\end{thebibliography}
2.1 --- a/docs/xen-api/revision-history.tex Mon Jul 20 10:10:15 2009 +0100 2.2 +++ b/docs/xen-api/revision-history.tex Mon Jul 20 10:12:38 2009 +0100 2.3 @@ -1,69 +1,49 @@ 2.4 { \bf Revision History} 2.5 2.6 +% Please do not use minipages in a tabular environment; this results 2.7 +% in bad vertical alignment. 2.8 + 2.9 +\begin{flushleft} 2.10 \begin{center} 2.11 - \begin{tabular}{|l|l|l|l|} 2.12 + \begin{tabular}{|l|l|l|>{\raggedright}p{7cm}|} 2.13 \hline 2.14 1.0.0 & 27th April 07 & Xensource et al. & 2.15 - \begin{minipage}[t][.7cm]{7cm} 2.16 - Initial Revision 2.17 - \end{minipage}\\ 2.18 + Initial Revision\tabularnewline 2.19 \hline 2.20 1.0.1 & 10th Dec. 07 & S. Berger & 2.21 - \begin{minipage}[t]{7cm} 2.22 - \begin{flushleft} 2.23 Added XSPolicy.reset\_xspolicy, VTPM.get\_other\_config, 2.24 - VTPM.set\_otherconfig. ACMPolicy.get\_enforced\_binary methods. 2.25 - \end{flushleft} 2.26 - \end{minipage}\\ 2.27 + VTPM.set\_otherconfig. ACMPolicy.get\_enforced\_binary methods.\tabularnewline 2.28 \hline 2.29 1.0.2 & 25th Jan. 08 & J. Fehlig & 2.30 - \begin{minipage}[t]{7cm} 2.31 - \begin{flushleft} 2.32 - Added Crashed VM power state. 2.33 - \end{flushleft} 2.34 - \end{minipage}\\ 2.35 + Added Crashed VM power state.\tabularnewline 2.36 \hline 2.37 1.0.3 & 11th Feb. 08 & S. Berger & 2.38 - \begin{minipage}[t]{7cm} 2.39 - \begin{flushleft} 2.40 - Added table of contents and hyperlink cross reference. 2.41 - \end{flushleft} 2.42 - \end{minipage}\\ 2.43 + Added table of contents and hyperlink cross reference.\tabularnewline 2.44 \hline 2.45 1.0.4 & 23rd March 08 & S. Berger & 2.46 - \begin{minipage}[t]{7cm} 2.47 - \begin{flushleft} 2.48 - Added XSPolicy.can\_run 2.49 - \end{flushleft} 2.50 - \end{minipage}\\ 2.51 + Added XSPolicy.can\_run\tabularnewline 2.52 \hline 2.53 1.0.5 & 17th Apr. 08 & S. Berger & 2.54 - \begin{minipage}[t]{7cm} 2.55 - \begin{flushleft} 2.56 Added undocumented fields and methods for default\_netmask and 2.57 default\_gateway to the Network class. Removed an unimplemented 2.58 method from the XSPolicy class and removed the 'optional' from 2.59 - 'oldlabel' parameters. 2.60 - \end{flushleft} 2.61 - \end{minipage}\\ 2.62 + 'oldlabel' parameters.\tabularnewline 2.63 \hline 2.64 1.0.6 & 24th Jul. 08 & Y. Iwamatsu & 2.65 - \begin{minipage}[t]{7cm} 2.66 - \begin{flushleft} 2.67 Added definitions of new classes DPCI and PPCI. Updated the table 2.68 and the diagram representing relationships between classes. 2.69 - Added host.PPCIs and VM.DPCIs fields. 2.70 - \end{flushleft} 2.71 - \end{minipage}\\ 2.72 + Added host.PPCIs and VM.DPCIs fields.\tabularnewline 2.73 \hline 2.74 1.0.7 & 20th Oct. 08 & M. Kanno & 2.75 - \begin{minipage}[t]{7cm} 2.76 - \begin{flushleft} 2.77 Added definitions of new classes DSCSI and PSCSI. Updated the table 2.78 and the diagram representing relationships between classes. 2.79 - Added host.PSCSIs and VM.DSCSIs fields. 2.80 - \end{flushleft} 2.81 - \end{minipage}\\ 2.82 + Added host.PSCSIs and VM.DSCSIs fields.\tabularnewline 2.83 + \hline 2.84 + 1.0.8 & 17th Jun. 09 & A. Florath & 2.85 + Updated interactive session example. 2.86 + Added description for \texttt{PV/kernel} and \texttt{PV/ramdisk} 2.87 + parameters using URIs.\tabularnewline 2.88 \hline 2.89 \end{tabular} 2.90 \end{center} 2.91 +\end{flushleft}
3.1 --- a/docs/xen-api/xenapi-coversheet.tex Mon Jul 20 10:10:15 2009 +0100 3.2 +++ b/docs/xen-api/xenapi-coversheet.tex Mon Jul 20 10:12:38 2009 +0100 3.3 @@ -17,12 +17,12 @@ 3.4 \newcommand{\coversheetlogo}{xen.eps} 3.5 3.6 %% Document date 3.7 -\newcommand{\datestring}{20th October 2008} 3.8 +\newcommand{\datestring}{17th June 2009} 3.9 3.10 \newcommand{\releasestatement}{Stable Release} 3.11 3.12 %% Document revision 3.13 -\newcommand{\revstring}{API Revision 1.0.7} 3.14 +\newcommand{\revstring}{API Revision 1.0.8} 3.15 3.16 %% Document authors 3.17 \newcommand{\docauthors}{
4.1 --- a/docs/xen-api/xenapi-datamodel.tex Mon Jul 20 10:10:15 2009 +0100 4.2 +++ b/docs/xen-api/xenapi-datamodel.tex Mon Jul 20 10:12:38 2009 +0100 4.3 @@ -1,5 +1,6 @@ 4.4 % 4.5 % Copyright (c) 2006-2007 XenSource, Inc. 4.6 +% Copyright (c) 2009 flonatel GmbH & Co. KG 4.7 % 4.8 % Permission is granted to copy, distribute and/or modify this document under 4.9 % the terms of the GNU Free Documentation License, Version 1.2 or any later 4.10 @@ -9,6 +10,7 @@ 4.11 % "GNU Free Documentation License" or the file fdl.tex. 4.12 % 4.13 % Authors: Ewan Mellor, Richard Sharp, Dave Scott, Jon Harrop. 4.14 +% Contributor: Andreas Florath 4.15 % 4.16 4.17 \chapter{API Reference} 4.18 @@ -1378,10 +1380,10 @@ the batch of events 4.19 \newpage 4.20 \section{Class: VM} 4.21 \subsection{Fields for class: VM} 4.22 -\begin{longtable}{|lllp{0.38\textwidth}|} 4.23 +\begin{longtable}{|llp{0.21\textwidth}p{0.33\textwidth}|} 4.24 \hline 4.25 \multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VM} \\ 4.26 -\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A 4.27 +\multicolumn{4}{|l|}{\parbox{11cm}{\em Description: A 4.28 virtual machine (or 'guest').}} \\ 4.29 \hline 4.30 Quals & Field & Type & Description \\ 4.31 @@ -1413,8 +1415,8 @@ Quals & Field & Type & Description \\ 4.32 $\mathit{RO}_\mathit{run}$ & {\tt DPCIs} & (DPCI ref) Set & pass-through PCI devices \\ 4.33 $\mathit{RO}_\mathit{run}$ & {\tt DSCSIs} & (DSCSI ref) Set & half-virtualized SCSI devices \\ 4.34 $\mathit{RW}$ & {\tt PV/bootloader} & string & name of or path to bootloader \\ 4.35 -$\mathit{RW}$ & {\tt PV/kernel} & string & path to the kernel \\ 4.36 -$\mathit{RW}$ & {\tt PV/ramdisk} & string & path to the initrd \\ 4.37 +$\mathit{RW}$ & {\tt PV/kernel} & string & URI of kernel \\ 4.38 +$\mathit{RW}$ & {\tt PV/ramdisk} & string & URI of initrd \\ 4.39 $\mathit{RW}$ & {\tt PV/args} & string & kernel command-line arguments \\ 4.40 $\mathit{RW}$ & {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\ 4.41 $\mathit{RW}$ & {\tt HVM/boot\_policy} & string & HVM boot policy \\ 4.42 @@ -1429,6 +1431,87 @@ Quals & Field & Type & Description \\ 4.43 $\mathit{RO}_\mathit{run}$ & {\tt security/label} & string & the VM's security label \\ 4.44 \hline 4.45 \end{longtable} 4.46 +\subsection{Parameter Details} 4.47 +\subsubsection{PV/kernel and PV/ramdisk} 4.48 +The \texttt{PV/kernel} and \texttt{PV/ramdisk} parameters should be 4.49 +specified as URIs with either a \texttt{file} or \texttt{data} scheme. 4.50 + 4.51 +The \texttt{file} scheme must be used when a file on the remote dom0 4.52 +should be used. The remote dom0 is the one where the guest system 4.53 +should be started on. Only absolute filenames are supported, i.e. the 4.54 +string must start with \texttt{file://} appended with the absolute 4.55 +path. This is typically used when the guest system use the same 4.56 +operating systems as the dom0 or there is some kind of shared storage 4.57 +for the images inside the dom0s. 4.58 + 4.59 +Note that for compatibility reasons it is possible --- but not 4.60 +recommended --- to leave out the scheme specification for 4.61 +\texttt{file}, i.e. \texttt{file:///some/path} and \texttt{/some/path} 4.62 +is equivalent. 4.63 + 4.64 +Examples (in python): 4.65 + 4.66 +Use kernel image which resides in the \texttt{/boot} directory: 4.67 +\begin{verbatim} 4.68 +xenapi.VM.create({ ... 4.69 + 'PV_kernel': 'file:///boot/vmlinuz-2.6.26-2-xen-686', 4.70 + ... }) 4.71 +\end{verbatim} 4.72 + 4.73 +Use ramdisk image which resides on a (shared) nfs directory: 4.74 +\begin{verbatim} 4.75 +xenapi.VM.create({ ... 4.76 + 'PV_ramdisk': 'file:///nfs/xen/debian/5.0.1/initrd.img-2.6.26-2-xen-686' 4.77 + ... }) 4.78 +\end{verbatim} 4.79 + 4.80 +When an image should be used which resides on the local system, 4.81 +i.e. the system where the XenAPI call is send from, it is possible to 4.82 +use the \texttt{data} URI scheme as described in \cite{RFC2397}. The 4.83 +media-type must be set to \texttt{application/octet-stream}. 4.84 +Currently only base64 encoding is supported. The URI must therefore 4.85 +start with \texttt{data:application/octet-stream;base64,} followed by 4.86 +the base64 encoded image. 4.87 + 4.88 +The \texttt{xen/util/fileuri.py} provides a helper function which 4.89 +takes a local filename as parameter and build up the correct URI from 4.90 +this. 4.91 + 4.92 +Examples (in python): 4.93 + 4.94 +Use kernel image specified inline: 4.95 +\begin{verbatim} 4.96 +xenapi.VM.create({ ... 4.97 + 'PV_kernel': 'data:application/octet-stream;base64,H4Zu....' 4.98 + # most of base64 encoded data is omitted 4.99 + ... }) 4.100 +\end{verbatim} 4.101 + 4.102 +Using the utility function: 4.103 +\begin{verbatim} 4.104 +from xen.util.fileuri import scheme_data 4.105 +xenapi.VM.create({ ... 4.106 + 'PV_kernel': scheme_data.create_from_file( 4.107 + "/xen/guests/images/debian/5.0.1/vmlinuz-2.6.26-2-xen-686"), 4.108 + ... }) 4.109 +\end{verbatim} 4.110 + 4.111 +Currently when using the \texttt{data} URI scheme, a temporary file is 4.112 +created on the remote dom0 in the directory 4.113 +\texttt{/var/run/xend/boot} which is then used for booting. When not 4.114 +used any longer the file is deleted. (Therefore reading of the 4.115 +\texttt{PV/kernel} or \texttt{PV/ramdisk} parameters when created with 4.116 +a \texttt{data} URI scheme returns a filename to a temporary file --- 4.117 +which might even not exists when querying.) This implementation might 4.118 +change in the way that the data is directly used --- without the 4.119 +indirection using a file. Therefore do not rely on the data resulting 4.120 +from a read of a variables which was set using the \texttt{data} 4.121 +scheme. 4.122 + 4.123 +Note: a mix of different schemes for the parameters is possible; e.g. 4.124 +the kernel can be specified with a \texttt{file} and the ramdisk with 4.125 +the \texttt{data} URI scheme. 4.126 + 4.127 \subsection{RPCs associated with class: VM} 4.128 \subsubsection{RPC name:~clone} 4.129
5.1 --- a/docs/xen-api/xenapi.tex Mon Jul 20 10:10:15 2009 +0100 5.2 +++ b/docs/xen-api/xenapi.tex Mon Jul 20 10:12:38 2009 +0100 5.3 @@ -18,6 +18,7 @@ 5.4 \usepackage{longtable} 5.5 \usepackage{fancyhdr} 5.6 \usepackage{hyperref} 5.7 +\usepackage{array} 5.8 5.9 \setlength\topskip{0cm} 5.10 \setlength\topmargin{0cm} 5.11 @@ -54,5 +55,6 @@ Xen-enabled host. 5.12 \include{vm-lifecycle} 5.13 \include{xenapi-datamodel} 5.14 \include{fdl} 5.15 +\include{bibliography} 5.16 5.17 \end{document}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/tools/python/xen/util/fileuri.py Mon Jul 20 10:12:38 2009 +0100 6.3 @@ -0,0 +1,273 @@ 6.4 +#============================================================================ 6.5 +# This library is free software; you can redistribute it and/or 6.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 6.7 +# License as published by the Free Software Foundation. 6.8 +# 6.9 +# This library is distributed in the hope that it will be useful, 6.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 6.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6.12 +# Lesser General Public License for more details. 6.13 +# 6.14 +# You should have received a copy of the GNU Lesser General Public 6.15 +# License along with this library; if not, write to the Free Software 6.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6.17 +#============================================================================ 6.18 +# Copyright (C) 2009 flonatel GmbH & Co. KG 6.19 +#============================================================================ 6.20 + 6.21 +import logging 6.22 +import os 6.23 +import base64 6.24 +import tempfile 6.25 +import stat 6.26 +from xen.xend.XendLogging import log 6.27 +from xen.util import mkdir 6.28 +# The following are needed for unit-testing only 6.29 +import unittest 6.30 + 6.31 +# 6.32 +# This functions and classes can be used where a filename is expected - 6.33 +# especially in the xenapi.VM.create() for PV_kernel and PV_ramdisk. 6.34 +# 6.35 +# The functions have a backward compatibility mode, i.e. when there is 6.36 +# no appropriate scheme detected, the data is seens as a path to a 6.37 +# (local) file. 6.38 +# 6.39 + 6.40 +class scheme_error(Exception): 6.41 + def __init__(self, value): 6.42 + self.value = value 6.43 + def __str__(self): 6.44 + return repr(self.value) 6.45 + 6.46 +# Data scheme (as defined in RFC 2397): 6.47 +# data:application/octet-stream;base64,<base64 encoded data> 6.48 +# It looks that there is currently no general purpose implementation 6.49 +# available (in python) for this URL scheme - so the very basic is 6.50 +# done here. 6.51 +# 6.52 +# Limitations 6.53 +# o Only base64 is currently supported 6.54 +class scheme_data: 6.55 + 6.56 + @staticmethod 6.57 + def encode(data, mediatype = 'application/octet-stream', 6.58 + encoding = 'base64'): 6.59 + # XXX Limit this to base64 for current implementation 6.60 + if encoding!='base64': 6.61 + raise scheme_error("invalid encoding") 6.62 + return 'data:' + mediatype + ";" + encoding \ 6.63 + + "," + base64.b64encode(data) 6.64 + 6.65 + # Private method: parse encoded data 6.66 + @staticmethod 6.67 + def parse(encoded_data): 6.68 + if not isinstance(encoded_data, str): 6.69 + raise scheme_error("encoded data has wrong type") 6.70 + if not encoded_data.startswith('data:'): 6.71 + raise scheme_error("'data:' scheme declaration missing") 6.72 + comma = encoded_data.find(',', 5) 6.73 + if comma == -1: 6.74 + raise scheme_error("data separator (comma) is missing") 6.75 + # Cut off the media type and encoding 6.76 + mtenc = encoded_data[5:comma] 6.77 + if len(mtenc)==0: 6.78 + raise scheme_error("encoding is empty") 6.79 + # XXX Limit to base64 encoding 6.80 + if not mtenc.endswith(';base64'): 6.81 + raise scheme_error("encoding is not base64") 6.82 + mediatype = mtenc[:-7] 6.83 + return (mediatype, 'base64', comma+1) 6.84 + 6.85 + # Stores the data in a local file and returns the filename 6.86 + # and a flag if this file in temporary only and must be deleted 6.87 + # after starting the VM. 6.88 + @staticmethod 6.89 + def decode(encoded_data): 6.90 + mkdir.parents("/var/run/xend/boot/", stat.S_IRWXU) 6.91 + mediatype, encoding, data_start = scheme_data.parse(encoded_data) 6.92 + fd, filename = tempfile.mkstemp( 6.93 + prefix="data_uri_file.", dir="/var/run/xend/boot") 6.94 + os.write(fd, base64.b64decode(encoded_data[data_start:])) 6.95 + os.close(fd) 6.96 + return filename, True 6.97 + 6.98 + # Utility function which reads in the given (local) file and 6.99 + # creates a data scheme from this. 6.100 + @staticmethod 6.101 + def create_from_file(filename): 6.102 + try: 6.103 + f = open(filename, "r") 6.104 + d = f.read() 6.105 + f.close() 6.106 + return scheme_data.encode(d) 6.107 + except IOError: 6.108 + raise scheme_error("file does not exists") 6.109 + 6.110 +class scheme_data_unit_tests(unittest.TestCase): 6.111 + 6.112 + def check_basic_encoding(self): 6.113 + "scheme_data - basic encoding" 6.114 + sd = scheme_data.encode('Hello!') 6.115 + self.assertEqual(sd, 'data:application/octet-stream;base64,SGVsbG8h') 6.116 + 6.117 + def check_encoding_with_given_mediatype(self): 6.118 + "scheme_data - encoding with given media name" 6.119 + sd = scheme_data.encode('Hello!', 'application/x-my-linux-kernel') 6.120 + self.assertEqual(sd, 6.121 + 'data:application/x-my-linux-kernel;base64,SGVsbG8h') 6.122 + 6.123 + def check_parse_01(self): 6.124 + "scheme_data - parsing of None" 6.125 + self.assertRaises(scheme_error, scheme_data.parse, None) 6.126 + 6.127 + def check_parse_02(self): 6.128 + "scheme_data - parsing of empty string" 6.129 + self.assertRaises(scheme_error, scheme_data.parse, "") 6.130 + 6.131 + def check_parse_03(self): 6.132 + "scheme_data - parsing of unstructured data" 6.133 + self.assertRaises(scheme_error, scheme_data.parse, "akskdjdfhezezu") 6.134 + 6.135 + def check_parse_04(self): 6.136 + "scheme_data - data: is not at the first place" 6.137 + self.assertRaises(scheme_error, scheme_data.parse, 'ggdata:sossm') 6.138 + 6.139 + def check_parse_05(self): 6.140 + "scheme_data - no comma in data" 6.141 + self.assertRaises(scheme_error, scheme_data.parse, 'data:sossm') 6.142 + 6.143 + def check_parse_06(self): 6.144 + "scheme_data - encoding is empty" 6.145 + self.assertRaises(scheme_error, scheme_data.parse, 'data:,') 6.146 + 6.147 + def check_parse_07(self): 6.148 + "scheme_data - unknown encoding" 6.149 + self.assertRaises(scheme_error, scheme_data.parse, 6.150 + 'data:somemediatype;unknown,') 6.151 + 6.152 + def check_parse_08(self): 6.153 + "scheme_data - parse ok - empty data" 6.154 + mediatype, encoding, data_start = scheme_data.parse( 6.155 + 'data:somemedia;base64,') 6.156 + self.assertEqual(mediatype, 'somemedia') 6.157 + self.assertEqual(encoding, 'base64') 6.158 + self.assertEqual(data_start, 22) 6.159 + 6.160 + def check_parse_09(self): 6.161 + "scheme_data - parse ok - some data" 6.162 + mediatype, encoding, data_start = scheme_data.parse( 6.163 + 'data:somemedia;base64,HereComesTheSun') 6.164 + self.assertEqual(mediatype, 'somemedia') 6.165 + self.assertEqual(encoding, 'base64') 6.166 + self.assertEqual(data_start, 22) 6.167 + 6.168 + def check_cff_file_does_not_exist(self): 6.169 + "scheme_data - create from file - non existent file" 6.170 + self.assertRaises(scheme_error, scheme_data.create_from_file, 6.171 + "/there/is/hopefully/no/file/like/this") 6.172 + 6.173 + def check_cff_ok(self): 6.174 + "scheme_data - create from file - ok" 6.175 + tmppath = "/tmp/scheme_data_check_cff_ok" 6.176 + f = open(tmppath, "w") 6.177 + f.write("huhuhu") 6.178 + f.close() 6.179 + d = scheme_data.create_from_file(tmppath) 6.180 + os.unlink(tmppath) 6.181 + self.assertEqual(d, "data:application/octet-stream;base64,aHVodWh1") 6.182 + 6.183 +# File Scheme 6.184 +# This class supports absolut paths only. 6.185 +class scheme_file: 6.186 + 6.187 + @staticmethod 6.188 + def encode(filename): 6.189 + if len(filename) == 0: 6.190 + raise scheme_error("filename is empty") 6.191 + if filename[0] != '/': 6.192 + raise scheme_error("filename is not absolut") 6.193 + return 'file://' + filename 6.194 + 6.195 + @staticmethod 6.196 + def decode(encoded_data): 6.197 + if not encoded_data.startswith("file://"): 6.198 + raise scheme_error("no file:// scheme found") 6.199 + path = encoded_data[7:] 6.200 + if len(path)==0: 6.201 + raise scheme_error("path is empty") 6.202 + if path[0]!='/': 6.203 + raise scheme_error("path is not absolute") 6.204 + return path, False 6.205 + 6.206 +class scheme_file_unit_tests(unittest.TestCase): 6.207 + 6.208 + def check_encode_empty_filename(self): 6.209 + "scheme_file - encode empty filename" 6.210 + self.assertRaises(scheme_error, scheme_file.encode, "") 6.211 + 6.212 + def check_encode_relative_filename(self): 6.213 + "scheme_file - encode relative filename" 6.214 + self.assertRaises(scheme_error, scheme_file.encode, "../there") 6.215 + 6.216 + def check_encode_absolut_filename(self): 6.217 + "scheme_file - encode absolut filename" 6.218 + self.assertEqual( 6.219 + scheme_file.encode("/here/and/there/again"), 6.220 + 'file:///here/and/there/again') 6.221 + 6.222 + def check_decode_01(self): 6.223 + "scheme_file - decode empty data" 6.224 + self.assertRaises(scheme_error, scheme_file.decode, "") 6.225 + 6.226 + def check_decode_02(self): 6.227 + "scheme_file - decode data with no file:// at the beginning (1)" 6.228 + self.assertRaises(scheme_error, scheme_file.decode, 6.229 + "phonehome://bbbb") 6.230 + 6.231 + def check_decode_03(self): 6.232 + "scheme_file - decode data with no file:// at the beginning (2)" 6.233 + self.assertRaises(scheme_error, scheme_file.decode, 6.234 + "file:/bbbb") 6.235 + 6.236 + def check_decode_04(self): 6.237 + "scheme_file - decode empty path" 6.238 + self.assertRaises(scheme_error, scheme_file.decode, 6.239 + "file://") 6.240 + 6.241 + def check_decode_05(self): 6.242 + "scheme_file - decode empty relative path" 6.243 + self.assertRaises(scheme_error, scheme_file.decode, 6.244 + "file://somewhere") 6.245 + 6.246 + def check_decode_06(self): 6.247 + "scheme_file - decode ok" 6.248 + path, tmp_file = scheme_file.decode("file:///boot/vmlinuz") 6.249 + self.assertEqual(path, "/boot/vmlinuz") 6.250 + self.assertEqual(tmp_file, False) 6.251 + 6.252 +class scheme_set: 6.253 + 6.254 + def __init__(self): 6.255 + self.schemes = [scheme_data, scheme_file] 6.256 + 6.257 + def decode(self, uri): 6.258 + for scheme in self.schemes: 6.259 + try: 6.260 + # If this passes, it is the correct scheme 6.261 + return scheme.decode(uri) 6.262 + except scheme_error, se: 6.263 + log.debug("Decode throws an error: '%s'" % se) 6.264 + return uri, False 6.265 + 6.266 +schemes = scheme_set() 6.267 + 6.268 + 6.269 +def suite(): 6.270 + return unittest.TestSuite( 6.271 + [unittest.makeSuite(scheme_data_unit_tests, 'check_'), 6.272 + unittest.makeSuite(scheme_file_unit_tests, 'check_'),]) 6.273 + 6.274 +if __name__ == "__main__": 6.275 + testresult = unittest.TextTestRunner(verbosity=3).run(suite()) 6.276 +
7.1 --- a/tools/python/xen/xend/XendConfig.py Mon Jul 20 10:10:15 2009 +0100 7.2 +++ b/tools/python/xen/xend/XendConfig.py Mon Jul 20 10:12:38 2009 +0100 7.3 @@ -41,6 +41,7 @@ from xen.util.pci import pci_opts_list_f 7.4 from xen.xend.XendSXPDev import dev_dict_to_sxp 7.5 from xen.util import xsconstants 7.6 from xen.util import auxbin 7.7 +import xen.util.fileuri 7.8 7.9 log = logging.getLogger("xend.XendConfig") 7.10 log.setLevel(logging.WARN) 7.11 @@ -338,6 +339,8 @@ class XendConfig(dict): 7.12 # output from xc.domain_getinfo 7.13 self._dominfo_to_xapi(dominfo, update_mem = True) 7.14 7.15 + self.handle_fileuris() 7.16 + 7.17 log.debug('XendConfig.init: %s' % scrub_password(self)) 7.18 7.19 # validators go here 7.20 @@ -1999,10 +2002,14 @@ class XendConfig(dict): 7.21 self['_temp_kernel'] = sxp.child_value(image_sxp, 'kernel','') 7.22 self['_temp_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','') 7.23 self['_temp_args'] = kernel_args 7.24 + self['use_tmp_kernel'] = True 7.25 + self['use_tmp_ramdisk'] = True 7.26 else: 7.27 self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','') 7.28 self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','') 7.29 self['PV_args'] = kernel_args 7.30 + self['use_tmp_kernel'] = False 7.31 + self['use_tmp_ramdisk'] = False 7.32 7.33 self['superpages'] = sxp.child_value(image_sxp, 'superpages',0) 7.34 7.35 @@ -2076,3 +2083,11 @@ class XendConfig(dict): 7.36 pci.append([domain, bus, slot, func, vdevfn, opts]) 7.37 self['platform']['pci'] = pci 7.38 7.39 + 7.40 + def handle_fileuris(self): 7.41 + for arg in [('PV_kernel', 'use_tmp_kernel'), 7.42 + ('PV_ramdisk', 'use_tmp_ramdisk')]: 7.43 + if self[arg[0]] != None: 7.44 + self[arg[0]], self[arg[1]] \ 7.45 + = xen.util.fileuri.schemes.decode(self[arg[0]]) 7.46 + log.debug("fileuri '%s' = '%s'" % (arg[0], self[arg[0]][:100]))
8.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 20 10:10:15 2009 +0100 8.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jul 20 10:12:38 2009 +0100 8.3 @@ -2634,7 +2634,7 @@ class XendDomainInfo: 8.4 8.5 self._createDevices() 8.6 8.7 - self.image.cleanupBootloading() 8.8 + self.image.cleanupTmpImages() 8.9 8.10 self.info['start_time'] = time.time() 8.11 8.12 @@ -2642,12 +2642,12 @@ class XendDomainInfo: 8.13 except VmError, exn: 8.14 log.exception("XendDomainInfo.initDomain: exception occurred") 8.15 if self.image: 8.16 - self.image.cleanupBootloading() 8.17 + self.image.cleanupTmpImages() 8.18 raise exn 8.19 except RuntimeError, exn: 8.20 log.exception("XendDomainInfo.initDomain: exception occurred") 8.21 if self.image: 8.22 - self.image.cleanupBootloading() 8.23 + self.image.cleanupTmpImages() 8.24 raise VmError(str(exn)) 8.25 8.26
9.1 --- a/tools/python/xen/xend/image.py Mon Jul 20 10:10:15 2009 +0100 9.2 +++ b/tools/python/xen/xend/image.py Mon Jul 20 10:12:38 2009 +0100 9.3 @@ -89,6 +89,8 @@ class ImageHandler: 9.4 self.vm = vm 9.5 9.6 self.bootloader = False 9.7 + self.use_tmp_kernel = False 9.8 + self.use_tmp_ramdisk = False 9.9 self.kernel = None 9.10 self.ramdisk = None 9.11 self.cmdline = None 9.12 @@ -106,6 +108,10 @@ class ImageHandler: 9.13 self.kernel = vmConfig['PV_kernel'] 9.14 self.cmdline = vmConfig['PV_args'] 9.15 self.ramdisk = vmConfig['PV_ramdisk'] 9.16 + if vmConfig['use_tmp_kernel']: 9.17 + self.use_tmp_ramdisk = True 9.18 + if vmConfig['use_tmp_ramdisk']: 9.19 + self.use_tmp_kernel = True 9.20 self.vm.storeVm(("image/ostype", self.ostype), 9.21 ("image/kernel", self.kernel), 9.22 ("image/cmdline", self.cmdline), 9.23 @@ -135,9 +141,10 @@ class ImageHandler: 9.24 if 'cpuid_check' in vmConfig: 9.25 self.cpuid_check = vmConfig['cpuid_check'] 9.26 9.27 - def cleanupBootloading(self): 9.28 - if self.bootloader: 9.29 + def cleanupTmpImages(self): 9.30 + if self.use_tmp_kernel: 9.31 self.unlink(self.kernel) 9.32 + if self.use_tmp_ramdisk: 9.33 self.unlink(self.ramdisk) 9.34 9.35