- Timestamp:
- Feb 11, 2009 1:01:48 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageImport.cpp
r16606 r16662 155 155 Bstr bstrOvfFilename(strOvfFilename); 156 156 ComPtr<IAppliance> appliance; 157 CHECK_ERROR_BREAK(a->virtualBox, OpenAppliance(bstrOvfFilename, appliance.asOutParam())); 157 CHECK_ERROR_BREAK(a->virtualBox, CreateAppliance(appliance.asOutParam())); 158 159 CHECK_ERROR_BREAK(appliance, Read(bstrOvfFilename)); 158 160 159 161 RTPrintf("Interpreting %s... ", strOvfFilename.c_str()); … … 434 436 ComPtr<IProgress> progress; 435 437 CHECK_ERROR_BREAK(appliance, 436 Import Appliance(progress.asOutParam()));438 ImportMachines(progress.asOutParam())); 437 439 438 440 showProgress(progress); -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxImportAppliance.cpp
r16618 r16662 954 954 CVirtualBox vbox = vboxGlobal().virtualBox(); 955 955 /* Open the appliance */ 956 CAppliance appliance = vbox. OpenAppliance (file);956 CAppliance appliance = vbox.CreateAppliance(); 957 957 if (appliance.isOk()) 958 958 { 959 appliance.Read(file); // @todo error handling 959 960 /* Now we have to interpret that stuff */ 960 961 appliance.Interpret(); … … 967 968 /* Start the import asynchronously */ 968 969 CProgress progress; 969 progress = appliance.Import Appliance();970 progress = appliance.ImportMachines(); 970 971 if (!appliance.isOk()) 971 972 { -
trunk/src/VBox/Main/ApplianceImpl.cpp
r16655 r16662 239 239 240 240 /** 241 * Implementation for IVirtualBox:: openAppliance. Loads the given appliance (see API reference).241 * Implementation for IVirtualBox::createAppliance. 242 242 * 243 * @param bstrPath Appliance to open (either .ovf or .ova file, see API reference)244 243 * @param anAppliance IAppliance object created if S_OK is returned. 245 244 * @return S_OK or error. 246 245 */ 247 STDMETHODIMP VirtualBox:: OpenAppliance(IN_BSTR bstrPath,IAppliance** anAppliance)246 STDMETHODIMP VirtualBox::CreateAppliance(IAppliance** anAppliance) 248 247 { 249 248 HRESULT rc; … … 251 250 ComObjPtr<Appliance> appliance; 252 251 appliance.createObject(); 253 /* @todo r=poetzsch: We should consider to split the creation & opening of 254 the appliance into two calls. Now the returned appliance is null in the 255 case of an error. But at the same time the error message is in the 256 appliance object which isn't returned. So I propose: createAppliance in 257 IVirtualBox & OpenAppliance in IAppliance. Such an error could easily 258 produced if you set an invalid path to the open call. */ 259 rc = appliance->init(this, bstrPath); 252 rc = appliance->init(this); 260 253 // ComAssertComRCThrowRC(rc); 261 254 … … 861 854 */ 862 855 863 HRESULT Appliance::init(VirtualBox *aVirtualBox , IN_BSTR &path)856 HRESULT Appliance::init(VirtualBox *aVirtualBox) 864 857 { 865 858 HRESULT rc; … … 869 862 AssertReturn(autoInitSpan.isOk(), E_FAIL); 870 863 871 /* Weak lyreference to a VirtualBox object */864 /* Weak reference to a VirtualBox object */ 872 865 unconst(mVirtualBox) = aVirtualBox; 873 866 874 867 // initialize data 875 868 m = new Data; 876 m->bstrPath = path;877 878 // see if we can handle this file; for now we insist it has an ".ovf" extension879 Utf8Str utf8Path(path);880 const char *pcszLastDot = strrchr(utf8Path, '.');881 if ( (!pcszLastDot)882 || ( strcmp(pcszLastDot, ".ovf")883 && strcmp(pcszLastDot, ".OVF")884 )885 )886 return setError(VBOX_E_FILE_ERROR,887 tr("Appliance file must have .ovf extension"));888 889 try890 {891 xml::XmlFileParser parser;892 xml::Document doc;893 parser.read(utf8Path.raw(),894 doc);895 896 const xml::Node *pRootElem = doc.getRootElement();897 if (strcmp(pRootElem->getName(), "Envelope"))898 return setError(VBOX_E_FILE_ERROR,899 tr("Root element in OVF file must be \"Envelope\"."));900 901 // OVF has the following rough layout:902 /*903 -- <References> .... files referenced from other parts of the file, such as VMDK images904 -- Metadata, comprised of several section commands905 -- virtual machines, either a single <VirtualSystem>, or a <VirtualSystemCollection>906 -- optionally <Strings> for localization907 */908 909 // get all "File" child elements of "References" section so we can look up files easily;910 // first find the "References" sections so we can look up files911 xml::NodesList listFileElements; // receives all /Envelope/References/File nodes912 const xml::Node *pReferencesElem;913 if ((pReferencesElem = pRootElem->findChildElement("References")))914 pReferencesElem->getChildElements(listFileElements, "File");915 916 // now go though the sections917 if (!(SUCCEEDED(rc = LoopThruSections(utf8Path.raw(), pReferencesElem, pRootElem))))918 return rc;919 }920 catch(xml::Error &x)921 {922 return setError(VBOX_E_FILE_ERROR,923 x.what());924 }925 869 926 870 /* Confirm a successful initialization */ … … 1202 1146 } 1203 1147 1148 STDMETHODIMP Appliance::Read(IN_BSTR path) 1149 { 1150 HRESULT rc = S_OK; 1151 1152 if (!path) 1153 return E_POINTER; 1154 1155 AutoCaller autoCaller(this); 1156 CheckComRCReturnRC(autoCaller.rc()); 1157 1158 AutoWriteLock alock(this); 1159 m->bstrPath = path; 1160 1161 // see if we can handle this file; for now we insist it has an ".ovf" extension 1162 Utf8Str utf8Path(path); 1163 const char *pcszLastDot = strrchr(utf8Path, '.'); 1164 if ( (!pcszLastDot) 1165 || ( strcmp(pcszLastDot, ".ovf") 1166 && strcmp(pcszLastDot, ".OVF") 1167 ) 1168 ) 1169 return setError(VBOX_E_FILE_ERROR, 1170 tr("Appliance file must have .ovf extension")); 1171 1172 try 1173 { 1174 xml::XmlFileParser parser; 1175 xml::Document doc; 1176 parser.read(utf8Path.raw(), 1177 doc); 1178 1179 const xml::Node *pRootElem = doc.getRootElement(); 1180 if (strcmp(pRootElem->getName(), "Envelope")) 1181 return setError(VBOX_E_FILE_ERROR, 1182 tr("Root element in OVF file must be \"Envelope\".")); 1183 1184 // OVF has the following rough layout: 1185 /* 1186 -- <References> .... files referenced from other parts of the file, such as VMDK images 1187 -- Metadata, comprised of several section commands 1188 -- virtual machines, either a single <VirtualSystem>, or a <VirtualSystemCollection> 1189 -- optionally <Strings> for localization 1190 */ 1191 1192 // get all "File" child elements of "References" section so we can look up files easily; 1193 // first find the "References" sections so we can look up files 1194 xml::NodesList listFileElements; // receives all /Envelope/References/File nodes 1195 const xml::Node *pReferencesElem; 1196 if ((pReferencesElem = pRootElem->findChildElement("References"))) 1197 pReferencesElem->getChildElements(listFileElements, "File"); 1198 1199 // now go though the sections 1200 if (!(SUCCEEDED(rc = LoopThruSections(utf8Path.raw(), pReferencesElem, pRootElem)))) 1201 return rc; 1202 } 1203 catch(xml::Error &x) 1204 { 1205 return setError(VBOX_E_FILE_ERROR, 1206 x.what()); 1207 } 1208 1209 return S_OK; 1210 } 1211 1204 1212 STDMETHODIMP Appliance::Interpret() 1205 1213 { … … 1537 1545 } 1538 1546 1539 STDMETHODIMP Appliance::Import Appliance(IProgress **aProgress)1547 STDMETHODIMP Appliance::ImportMachines(IProgress **aProgress) 1540 1548 { 1541 1549 CheckComArgOutPointerValid(aProgress); … … 1710 1718 if (!task->progress.isNull()) 1711 1719 { 1712 rc = task->progress->notifyProgress( opCountMax * opCount++);1720 rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++)); 1713 1721 CheckComRCThrowRC(rc); 1714 1722 } … … 1736 1744 if (!task->progress.isNull()) 1737 1745 { 1738 rc = task->progress->notifyProgress( opCountMax * opCount++);1746 rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++)); 1739 1747 CheckComRCThrowRC(rc); 1740 1748 } … … 1773 1781 if (!task->progress.isNull()) 1774 1782 { 1775 rc = task->progress->notifyProgress( opCountMax * opCount++);1783 rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++)); 1776 1784 CheckComRCThrowRC(rc); 1777 1785 } … … 1825 1833 if (!task->progress.isNull()) 1826 1834 { 1827 rc = task->progress->notifyProgress( opCountMax * opCount++);1835 rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++)); 1828 1836 CheckComRCThrowRC(rc); 1829 1837 } … … 1892 1900 if (!task->progress.isNull()) 1893 1901 { 1894 rc = task->progress->notifyProgress( opCountMax * opCount++);1902 rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++)); 1895 1903 CheckComRCThrowRC(rc); 1896 1904 } -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r16601 r16662 1727 1727 </method> 1728 1728 1729 <method name="openAppliance"> 1730 <desc> 1731 Attempts to open the given appliance, which must be in Open Virtual Machine Format (OVF). 1732 1733 As prescribed by the OVF standard, VirtualBox supports OVF in two formats: 1734 1735 <ol> 1736 <li>If the OVF is distributed as a set of files, then @a file must be a fully qualified 1737 path name to an existing OVF descriptor file with an <tt>.ovf</tt> file extension. If 1738 this descriptor file references other files, as OVF appliances distributed as a set of 1739 files most likely do, those files must be in the same directory as the descriptor file.</li> 1740 1741 <li>If the OVF is distributed as a single file, it must be in TAR format and have the 1742 <tt>.ova</tt> file extension. This TAR file must then contain at least the OVF descriptor 1743 files and optionally other files.</li> 1744 </ol> 1745 1746 In both cases, VirtualBox will open the OVF descriptor file, parse its contents and create a 1747 new instance of IAppliance representing the OVF file. 1748 1749 This method succeeds if the OVF is syntactically valid and, by itself, without errors. The 1750 returned IAppliance object can then be used to retrieve information about the appliance and 1751 import it into VirtualBox. The mere fact that this method returns successfully does not mean 1752 that VirtualBox supports all features requested by the appliance; see the documentation for 1753 <link to="IAppliance" /> for details. 1754 1755 </desc> 1756 <param name="file" type="wstring" dir="in"> 1757 <desc> 1758 Name of appliance file to open (either with an <tt>.ovf</tt> or <tt>.ova</tt> extension, depending 1759 on whether the appliance is distributed as a set of files or as a single file, respectively). 1760 </desc> 1761 </param> 1762 <param name="machine" type="IAppliance" dir="return"> 1729 <method name="createAppliance"> 1730 <desc> 1731 Creates a new appliance object, which represents an appliance in the Open Virtual Machine 1732 Format (OVF). This can then be used to import an OVF appliance into VirtualBox; see the 1733 documentation for <link to="IAppliance" /> for details. 1734 </desc> 1735 <param name="appliance" type="IAppliance" dir="return"> 1763 1736 <desc>New appliance.</desc> 1764 1737 </param> … … 2882 2855 <desc> 2883 2856 Represents an appliance in OVF format. An instance of this is returned by 2884 <link to="IVirtualBox:: openAppliance" />.2857 <link to="IVirtualBox::createAppliance" />. 2885 2858 2886 2859 Importing an OVF appliance into VirtualBox is a three-step process: … … 2888 2861 <ol> 2889 2862 <li> 2890 Call <link to="IVirtualBox::openAppliance" /> with the full path of the OVF 2891 file. So long as the appliance file is syntactically valid, this will succeed 2892 and return an instance of IAppliance that contains the parsed data from the 2893 OVF file. 2863 Call <link to="IVirtualBox::createAppliance" />. This will create an empty IAppliance object. 2864 </li> 2865 2866 <li> 2867 Call <link to="#open" /> with the full path of the OVF file you would like to 2868 import. So long as this file is syntactically valid, this will succeed and return 2869 an instance of IAppliance that contains the parsed data from the OVF file. 2894 2870 </li> 2895 2871 … … 2903 2879 </li> 2904 2880 2905 <li>Finally, the caller should invoke <link to="#import Appliance" />, which will2881 <li>Finally, the caller should invoke <link to="#importMachines" />, which will 2906 2882 create virtual machines in VirtualBox as instances of <link to="IMachine" /> that 2907 2883 match the information in the virtual system descriptions. … … 2913 2889 <attribute name="path" type="wstring" readonly="yes"> 2914 2890 <desc>Path to the main file of the OVF appliance, which is either the <tt>.ovf</tt> or 2915 the <tt>.ova</tt> file passed to <link to="IVirtualBox:: openAppliance" />.</desc>2891 the <tt>.ova</tt> file passed to <link to="IVirtualBox::read" />.</desc> 2916 2892 </attribute> 2917 2893 … … 2956 2932 </attribute> 2957 2933 2934 <method name="read"> 2935 <desc> 2936 The OVF standard suggests two different file formats: 2937 2938 <ol> 2939 <li>If the OVF is distributed as a set of files, then @a file must be a fully qualified 2940 path name to an existing OVF descriptor file with an <tt>.ovf</tt> file extension. If 2941 this descriptor file references other files, as OVF appliances distributed as a set of 2942 files most likely do, those files must be in the same directory as the descriptor file.</li> 2943 2944 <li>If the OVF is distributed as a single file, it must be in TAR format and have the 2945 <tt>.ova</tt> file extension. This TAR file must then contain at least the OVF descriptor 2946 files and optionally other files. This variant is not yet supported by VirtualBox; 2947 support will be added in a later version.</li> 2948 </ol> 2949 2950 This method succeeds if the OVF is syntactically valid and, by itself, without errors. The 2951 mere fact that this method returns successfully does not mean that VirtualBox supports all 2952 features requested by the appliance; this can be examined after a call to <link to="#interpret" />. 2953 </desc> 2954 <param name="file" type="wstring" dir="in"> 2955 <desc> 2956 Name of appliance file to open (either with an <tt>.ovf</tt> or <tt>.ova</tt> extension, depending 2957 on whether the appliance is distributed as a set of files or as a single file, respectively). 2958 </desc> 2959 </param> 2960 </method> 2961 2958 2962 <method name="interpret"> 2959 2963 <desc> … … 2969 2973 </method> 2970 2974 2971 <method name="import Appliance">2975 <method name="importMachines"> 2972 2976 <desc> 2973 2977 Imports the appliance into VirtualBox by creating instances of <link to="IMachine" /> -
trunk/src/VBox/Main/include/ApplianceImpl.h
r16601 r16662 62 62 void FinalRelease() { uninit(); } 63 63 64 HRESULT init(VirtualBox *aVirtualBox , IN_BSTR &path);64 HRESULT init(VirtualBox *aVirtualBox); 65 65 void uninit(); 66 66 … … 74 74 75 75 /* IAppliance methods */ 76 /* void interpret (); */76 STDMETHOD(Read)(IN_BSTR path); 77 77 STDMETHOD(Interpret)(void); 78 STDMETHOD(Import Appliance)(IProgress **aProgress);78 STDMETHOD(ImportMachines)(IProgress **aProgress); 79 79 80 80 /* public methods only for internal purposes */ -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r16560 r16662 145 145 STDMETHOD(FindMachine) (IN_BSTR aName, IMachine **aMachine); 146 146 STDMETHOD(UnregisterMachine) (IN_GUID aId, IMachine **aMachine); 147 STDMETHOD( OpenAppliance) (IN_BSTR aName,IAppliance **anAppliance);147 STDMETHOD(CreateAppliance) (IAppliance **anAppliance); 148 148 149 149 STDMETHOD(CreateHardDisk2) (IN_BSTR aFormat, IN_BSTR aLocation,
Note:
See TracChangeset
for help on using the changeset viewer.