VirtualBox

Changeset 16662 in vbox for trunk


Ignore:
Timestamp:
Feb 11, 2009 1:01:48 PM (16 years ago)
Author:
vboxsync
Message:

OVF: create new IAppliance::read() method instead of reading in constructor; IVirtualBox::openAppliance -> createAppliance; IAppliance->importAppliance -> importMachines

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageImport.cpp

    r16606 r16662  
    155155        Bstr bstrOvfFilename(strOvfFilename);
    156156        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));
    158160
    159161        RTPrintf("Interpreting %s... ", strOvfFilename.c_str());
     
    434436                ComPtr<IProgress> progress;
    435437                CHECK_ERROR_BREAK(appliance,
    436                                   ImportAppliance(progress.asOutParam()));
     438                                  ImportMachines(progress.asOutParam()));
    437439
    438440                showProgress(progress);
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxImportAppliance.cpp

    r16618 r16662  
    954954        CVirtualBox vbox = vboxGlobal().virtualBox();
    955955        /* Open the appliance */
    956         CAppliance appliance = vbox.OpenAppliance (file);
     956        CAppliance appliance = vbox.CreateAppliance();
    957957        if (appliance.isOk())
    958958        {
     959            appliance.Read(file); // @todo error handling
    959960            /* Now we have to interpret that stuff */
    960961            appliance.Interpret();
     
    967968                    /* Start the import asynchronously */
    968969                    CProgress progress;
    969                     progress = appliance.ImportAppliance();
     970                    progress = appliance.ImportMachines();
    970971                    if (!appliance.isOk())
    971972                    {
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r16655 r16662  
    239239
    240240/**
    241  * Implementation for IVirtualBox::openAppliance. Loads the given appliance (see API reference).
     241 * Implementation for IVirtualBox::createAppliance.
    242242 *
    243  * @param bstrPath Appliance to open (either .ovf or .ova file, see API reference)
    244243 * @param anAppliance IAppliance object created if S_OK is returned.
    245244 * @return S_OK or error.
    246245 */
    247 STDMETHODIMP VirtualBox::OpenAppliance(IN_BSTR bstrPath, IAppliance** anAppliance)
     246STDMETHODIMP VirtualBox::CreateAppliance(IAppliance** anAppliance)
    248247{
    249248    HRESULT rc;
     
    251250    ComObjPtr<Appliance> appliance;
    252251    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);
    260253//     ComAssertComRCThrowRC(rc);
    261254
     
    861854 */
    862855
    863 HRESULT Appliance::init(VirtualBox *aVirtualBox, IN_BSTR &path)
     856HRESULT Appliance::init(VirtualBox *aVirtualBox)
    864857{
    865858    HRESULT rc;
     
    869862    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    870863
    871     /* Weakly reference to a VirtualBox object */
     864    /* Weak reference to a VirtualBox object */
    872865    unconst(mVirtualBox) = aVirtualBox;
    873866
    874867    // initialize data
    875868    m = new Data;
    876     m->bstrPath = path;
    877 
    878     // see if we can handle this file; for now we insist it has an ".ovf" extension
    879     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     try
    890     {
    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 images
    904             -- Metadata, comprised of several section commands
    905             -- virtual machines, either a single <VirtualSystem>, or a <VirtualSystemCollection>
    906             -- optionally <Strings> for localization
    907         */
    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 files
    911         xml::NodesList listFileElements;      // receives all /Envelope/References/File nodes
    912         const xml::Node *pReferencesElem;
    913         if ((pReferencesElem = pRootElem->findChildElement("References")))
    914             pReferencesElem->getChildElements(listFileElements, "File");
    915 
    916         // now go though the sections
    917         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     }
    925869
    926870    /* Confirm a successful initialization */
     
    12021146}
    12031147
     1148STDMETHODIMP 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
    12041212STDMETHODIMP Appliance::Interpret()
    12051213{
     
    15371545}
    15381546
    1539 STDMETHODIMP Appliance::ImportAppliance(IProgress **aProgress)
     1547STDMETHODIMP Appliance::ImportMachines(IProgress **aProgress)
    15401548{
    15411549    CheckComArgOutPointerValid(aProgress);
     
    17101718            if (!task->progress.isNull())
    17111719            {
    1712                 rc = task->progress->notifyProgress(opCountMax * opCount++);
     1720                rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++));
    17131721                CheckComRCThrowRC(rc);
    17141722            }
     
    17361744            if (!task->progress.isNull())
    17371745            {
    1738                 rc = task->progress->notifyProgress(opCountMax * opCount++);
     1746                rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++));
    17391747                CheckComRCThrowRC(rc);
    17401748            }
     
    17731781            if (!task->progress.isNull())
    17741782            {
    1775                 rc = task->progress->notifyProgress(opCountMax * opCount++);
     1783                rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++));
    17761784                CheckComRCThrowRC(rc);
    17771785            }
     
    18251833            if (!task->progress.isNull())
    18261834            {
    1827                 rc = task->progress->notifyProgress(opCountMax * opCount++);
     1835                rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++));
    18281836                CheckComRCThrowRC(rc);
    18291837            }
     
    18921900            if (!task->progress.isNull())
    18931901            {
    1894                 rc = task->progress->notifyProgress(opCountMax * opCount++);
     1902                rc = task->progress->notifyProgress((uint32_t)(opCountMax * opCount++));
    18951903                CheckComRCThrowRC(rc);
    18961904            }
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r16601 r16662  
    17271727    </method>
    17281728
    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">
    17631736        <desc>New appliance.</desc>
    17641737      </param>
     
    28822855    <desc>
    28832856        Represents an appliance in OVF format. An instance of this is returned by
    2884         <link to="IVirtualBox::openAppliance" />.
     2857        <link to="IVirtualBox::createAppliance" />.
    28852858
    28862859        Importing an OVF appliance into VirtualBox is a three-step process:
     
    28882861        <ol>
    28892862          <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.
    28942870          </li>
    28952871
     
    29032879          </li>
    29042880
    2905           <li>Finally, the caller should invoke <link to="#importAppliance" />, which will
     2881          <li>Finally, the caller should invoke <link to="#importMachines" />, which will
    29062882          create virtual machines in VirtualBox as instances of <link to="IMachine" /> that
    29072883          match the information in the virtual system descriptions.
     
    29132889    <attribute name="path" type="wstring" readonly="yes">
    29142890      <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>
    29162892    </attribute>
    29172893
     
    29562932    </attribute>
    29572933
     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
    29582962    <method name="interpret">
    29592963      <desc>
     
    29692973    </method>
    29702974
    2971     <method name="importAppliance">
     2975    <method name="importMachines">
    29722976      <desc>
    29732977        Imports the appliance into VirtualBox by creating instances of <link to="IMachine" />
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r16601 r16662  
    6262    void FinalRelease() { uninit(); }
    6363
    64     HRESULT init(VirtualBox *aVirtualBox, IN_BSTR &path);
     64    HRESULT init(VirtualBox *aVirtualBox);
    6565    void uninit();
    6666
     
    7474
    7575    /* IAppliance methods */
    76     /* void interpret (); */
     76    STDMETHOD(Read)(IN_BSTR path);
    7777    STDMETHOD(Interpret)(void);
    78     STDMETHOD(ImportAppliance)(IProgress **aProgress);
     78    STDMETHOD(ImportMachines)(IProgress **aProgress);
    7979
    8080    /* public methods only for internal purposes */
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r16560 r16662  
    145145    STDMETHOD(FindMachine) (IN_BSTR aName, IMachine **aMachine);
    146146    STDMETHOD(UnregisterMachine) (IN_GUID aId, IMachine **aMachine);
    147     STDMETHOD(OpenAppliance) (IN_BSTR aName, IAppliance **anAppliance);
     147    STDMETHOD(CreateAppliance) (IAppliance **anAppliance);
    148148
    149149    STDMETHOD(CreateHardDisk2) (IN_BSTR aFormat, IN_BSTR aLocation,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette