VirtualBox

Changeset 45227 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Mar 28, 2013 12:22:11 PM (12 years ago)
Author:
vboxsync
Message:

Main: OVF 2.0 support. Part 1 - SHA256 digest is supported.

Location:
trunk/src/VBox/Main
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r44528 r45227  
    2828#include <iprt/tar.h>
    2929
     30#include "ovfreader.h"
     31
    3032/* VBox forward declarations */
    3133class Progress;
     
    4345    class OVFReader;
    4446    struct DiskImage;
     47    struct EnvelopeData;
    4548}
    4649
     
    7376    DECLARE_EMPTY_CTOR_DTOR (Appliance)
    7477
    75     enum OVFFormat
    76     {
    77         unspecified,
    78         OVF_0_9,
    79         OVF_1_0,
    80         OVF_2_0
    81     };
     78
    8279
    8380    // public initializer/uninitializer for internal purposes only
     
    200197     ******************************************************************************/
    201198
    202     HRESULT writeImpl(OVFFormat aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
     199    HRESULT writeImpl(ovf::OVFVersion_T aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
    203200
    204201    HRESULT writeFS(TaskOVF *pTask);
     
    209206
    210207    struct XMLStack;
    211     void buildXML(AutoWriteLockBase& writeLock, xml::Document &doc, XMLStack &stack, const Utf8Str &strPath, OVFFormat enFormat);
     208
     209    void buildXML(AutoWriteLockBase& writeLock,
     210                  xml::Document &doc,
     211                  XMLStack &stack,
     212                  const Utf8Str &strPath,
     213                  ovf::OVFVersion_T enFormat);
    212214    void buildXMLForOneVirtualSystem(AutoWriteLockBase& writeLock,
    213215                                     xml::ElementNode &elmToAddVirtualSystemsTo,
    214216                                     std::list<xml::ElementNode*> *pllElementsWithUuidAttributes,
    215217                                     ComObjPtr<VirtualSystemDescription> &vsdescThis,
    216                                      OVFFormat enFormat,
     218                                     ovf::OVFVersion_T enFormat,
    217219                                     XMLStack &stack);
    218 
    219220
    220221    friend class Machine;
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r44528 r45227  
    116116        locInfo(aLocInfo),
    117117        pProgress(aProgress),
    118         enFormat(unspecified),
     118        enFormat(ovf::OVFVersion_unknown),
    119119        rc(S_OK)
    120120    {}
     
    129129    ComObjPtr<Progress> pProgress;
    130130
    131     OVFFormat enFormat;
     131    ovf::OVFVersion_T enFormat;
    132132
    133133    HRESULT rc;
  • trunk/src/VBox/Main/include/ovfreader.h

    r44528 r45227  
    150150};
    151151
     152enum OVFVersion_T
     153{
     154    OVFVersion_unknown,
     155    OVFVersion_0_9,
     156    OVFVersion_1_0,
     157    OVFVersion_2_0
     158};
     159
     160////////////////////////////////////////////////////////////////////////////////
     161//
     162// Envelope data
     163//
     164////////////////////////////////////////////////////////////////////////////////
     165struct EnvelopeData
     166{
     167    RTCString version;//OVF standard version, it is used internally only by VirtualBox
     168    RTCString lang;//language
     169
     170    OVFVersion_T getOVFVersion() const
     171    {
     172        if(version == "0.9")
     173            return OVFVersion_0_9;
     174        else if(version == "1.0")
     175            return OVFVersion_1_0;
     176        else if(version == "2.0")
     177            return OVFVersion_2_0;
     178        else
     179            return OVFVersion_unknown;
     180    }
     181};
    152182
    153183////////////////////////////////////////////////////////////////////////////////
     
    412442
    413443    // Data fields
    414     RTCString            m_strPath;            // file name given to constructor
     444    EnvelopeData                m_envelopeData;       //data of root element "Envelope"
     445    RTCString                   m_strPath;            // file name given to constructor
    415446    DiskImagesMap               m_mapDisks;           // map of DiskImage structs, sorted by DiskImage.strDiskId
    416447    std::list<VirtualSystem>    m_llVirtualSystems;   // list of virtual systems, created by and valid after read()
  • trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp

    r45068 r45227  
    553553    m->fManifest = !!fManifest;
    554554    Utf8Str strFormat(format);
    555     OVFFormat ovfF;
     555
     556    ovf::OVFVersion_T ovfF;
    556557    if (strFormat == "ovf-0.9")
    557         ovfF = OVF_0_9;
     558    {
     559        ovfF = ovf::OVFVersion_0_9;
     560    }
    558561    else if (strFormat == "ovf-1.0")
    559         ovfF = OVF_1_0;
     562    {
     563        ovfF = ovf::OVFVersion_1_0;
     564    }
    560565    else if (strFormat == "ovf-2.0")
    561         ovfF = OVF_2_0;
     566    {
     567        ovfF = ovf::OVFVersion_2_0;
     568    }
    562569    else
    563570        return setError(VBOX_E_FILE_ERROR,
     
    565572
    566573    /* as of OVF 2.0 we have to use SHA256 */
    567     m->fSha256 = ovfF >= OVF_2_0;
     574    m->fSha256 = ovfF >= ovf::OVFVersion_2_0;
    568575
    569576    ComObjPtr<Progress> progress;
     
    615622 * @return
    616623 */
    617 HRESULT Appliance::writeImpl(OVFFormat aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress)
     624HRESULT Appliance::writeImpl(ovf::OVFVersion_T aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress)
    618625{
    619626    HRESULT rc = S_OK;
     
    659666                         XMLStack &stack,
    660667                         const Utf8Str &strPath,
    661                          OVFFormat enFormat)
     668                         ovf::OVFVersion_T enFormat)
    662669{
    663670    xml::ElementNode *pelmRoot = doc.createRootElement("Envelope");
    664671
    665     pelmRoot->setAttribute("ovf:version", enFormat == OVF_2_0 ? "2.0"
    666                                         : enFormat == OVF_1_0 ? "1.0"
     672    pelmRoot->setAttribute("ovf:version", enFormat == ovf::OVFVersion_2_0 ? "2.0"
     673                                        : enFormat == ovf::OVFVersion_1_0 ? "1.0"
    667674                                        :                       "0.9");
    668675    pelmRoot->setAttribute("xml:lang", "en-US");
    669676
    670     Utf8Str strNamespace = (enFormat == OVF_0_9)
    671         ? "http://www.vmware.com/schema/ovf/1/envelope"     // 0.9
    672         : "http://schemas.dmtf.org/ovf/envelope/1";         // 1.0
     677    Utf8Str strNamespace;
     678
     679    if (enFormat == ovf::OVFVersion_0_9)
     680    {
     681        strNamespace = "http://www.vmware.com/schema/ovf/1/envelope";
     682    }
     683    else if (enFormat == ovf::OVFVersion_1_0)
     684    {
     685        strNamespace = "http://schemas.dmtf.org/ovf/envelope/1";
     686    }
     687    else
     688    {
     689        strNamespace = "http://schemas.dmtf.org/ovf/envelope/2";
     690    }
     691
    673692    pelmRoot->setAttribute("xmlns", strNamespace);
    674693    pelmRoot->setAttribute("xmlns:ovf", strNamespace);
     
    690709       </DiskSection> */
    691710    xml::ElementNode *pelmDiskSection;
    692     if (enFormat == OVF_0_9)
     711    if (enFormat == ovf::OVFVersion_0_9)
    693712    {
    694713        // <Section xsi:type="ovf:DiskSection_Type">
     
    710729       </NetworkSection> */
    711730    xml::ElementNode *pelmNetworkSection;
    712     if (enFormat == OVF_0_9)
     731    if (enFormat == ovf::OVFVersion_0_9)
    713732    {
    714733        // <Section xsi:type="ovf:NetworkSection_Type">
     
    730749    if (m->virtualSystemDescriptions.size() > 1)
    731750    {
    732         if (enFormat == OVF_0_9)
     751        if (enFormat == ovf::OVFVersion_0_9)
    733752            throw setError(VBOX_E_FILE_ERROR,
    734753                           tr("Cannot export more than one virtual system with OVF 0.9, use OVF 1.0"));
     
    845864        pelmDisk->setAttribute("ovf:fileRef", strFileRef);
    846865        pelmDisk->setAttribute("ovf:format",
    847                                (enFormat == OVF_0_9)
     866                               (enFormat == ovf::OVFVersion_0_9)
    848867                               ?  "http://www.vmware.com/specifications/vmdk.html#sparse"      // must be sparse or ovftool chokes
    849868                               :  "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"
     
    892911                                            std::list<xml::ElementNode*> *pllElementsWithUuidAttributes,
    893912                                            ComObjPtr<VirtualSystemDescription> &vsdescThis,
    894                                             OVFFormat enFormat,
     913                                            ovf::OVFVersion_T enFormat,
    895914                                            XMLStack &stack)
    896915{
     
    898917
    899918    xml::ElementNode *pelmVirtualSystem;
    900     if (enFormat == OVF_0_9)
     919    if (enFormat == ovf::OVFVersion_0_9)
    901920    {
    902921        // <Section xsi:type="ovf:NetworkSection_Type">
     
    942961        </Section> */
    943962        xml::ElementNode *pelmAnnotationSection;
    944         if (enFormat == OVF_0_9)
     963        if (enFormat == ovf::OVFVersion_0_9)
    945964        {
    946965            // <Section ovf:required="false" xsi:type="ovf:ProductSection_Type">
     
    974993            </Section> */
    975994        xml::ElementNode *pelmAnnotationSection;
    976         if (enFormat == OVF_0_9)
     995        if (enFormat == ovf::OVFVersion_0_9)
    977996        {
    978997            // <Section ovf:required="false" xsi:type="ovf:AnnotationSection_Type">
     
    9971016            </EulaSection> */
    9981017        xml::ElementNode *pelmEulaSection;
    999         if (enFormat == OVF_0_9)
     1018        if (enFormat == ovf::OVFVersion_0_9)
    10001019        {
    10011020            pelmEulaSection = pelmVirtualSystem->createChild("Section");
     
    10201039    VirtualSystemDescriptionEntry *pvsdeOS = llOS.front();
    10211040    xml::ElementNode *pelmOperatingSystemSection;
    1022     if (enFormat == OVF_0_9)
     1041    if (enFormat == ovf::OVFVersion_0_9)
    10231042    {
    10241043        pelmOperatingSystemSection = pelmVirtualSystem->createChild("Section");
     
    10401059    // <VirtualHardwareSection ovf:id="hw1" ovf:transport="iso">
    10411060    xml::ElementNode *pelmVirtualHardwareSection;
    1042     if (enFormat == OVF_0_9)
     1061    if (enFormat == ovf::OVFVersion_0_9)
    10431062    {
    10441063        // <Section xsi:type="ovf:VirtualHardwareSection_Type">
     
    10631082
    10641083    // <vssd:InstanceId>0</vssd:InstanceId>
    1065     if (enFormat == OVF_0_9)
     1084    if (enFormat == ovf::OVFVersion_0_9)
    10661085        pelmSystem->createChild("vssd:InstanceId")->addContent("0");
    10671086    else // capitalization changed...
     
    10721091    // <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType>
    10731092    const char *pcszHardware = "virtualbox-2.2";
    1074     if (enFormat == OVF_0_9)
     1093    if (enFormat == ovf::OVFVersion_0_9)
    10751094        // pretend to be vmware compatible then
    10761095        pcszHardware = "vmx-6";
     
    14991518
    15001519                if (lBusNumber != -1)
    1501                     if (enFormat == OVF_0_9) // BusNumber is invalid OVF 1.0 so only write it in 0.9 mode for OVFTool compatibility
     1520                    if (enFormat == ovf::OVFVersion_0_9) // BusNumber is invalid OVF 1.0 so only write it in 0.9 mode for OVFTool y
    15021521                        pItem->createChild("rasd:BusNumber")->addContent(Utf8StrFmt("%d", lBusNumber));
    15031522
     
    15121531
    15131532                if (!strCaption.isEmpty())
    1514                     if (enFormat == OVF_1_0)
     1533                    if (enFormat == ovf::OVFVersion_1_0)
    15151534                        pItem->createChild("rasd:ElementName")->addContent(strCaption);
    15161535
     
    15201539                // <rasd:InstanceID>1</rasd:InstanceID>
    15211540                xml::ElementNode *pelmInstanceID;
    1522                 if (enFormat == OVF_0_9)
     1541                if (enFormat == ovf::OVFVersion_0_9)
    15231542                    pelmInstanceID = pItem->createChild("rasd:InstanceId");
    15241543                else
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r45068 r45227  
    819819
    820820    HRESULT rc = S_OK;
     821    int vrc = VINF_SUCCESS;
    821822
    822823    PVDINTERFACEIO pShaIo = 0;
     
    824825    do
    825826    {
    826         pShaIo = ShaCreateInterface();
    827         if (!pShaIo)
     827        try
    828828        {
    829             rc = E_OUTOFMEMORY;
    830             break;
     829            /* Create the necessary file access interfaces. */
     830            pFileIo = FileCreateInterface();
     831            if (!pFileIo)
     832            {
     833                rc = E_OUTOFMEMORY;
     834                break;
     835            }
     836
     837            Utf8Str strMfFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".mf");
     838
     839            if (RTFileExists(strMfFile.c_str()))
     840            {
     841                SHASTORAGE storage;
     842                RT_ZERO(storage);
     843
     844                pShaIo = ShaCreateInterface();
     845                if (!pShaIo)
     846                {
     847                    rc = E_OUTOFMEMORY;
     848                    break;
     849                }
     850
     851                //read the manifest file and find a type of used digest
     852                RTFILE pFile = NULL;
     853                RTFileOpen(&pFile, strMfFile.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
     854                if(RT_SUCCESS(vrc) && pFile != NULL)
     855                {
     856                    uint64_t size = 0;
     857                    uint64_t readed = 0;
     858                    void  *pBuf;
     859
     860                    vrc = RTFileGetSize(pFile, &size);
     861                    if(RT_SUCCESS(vrc) && size > 0)
     862                       pBuf = RTMemAllocZ(size);
     863                    else
     864                        throw vrc;
     865
     866                    vrc = RTFileRead(pFile, pBuf, size, &readed);
     867
     868                    if (RT_FAILURE(vrc))
     869                    {
     870                        if (pBuf)
     871                            RTMemFree(pBuf);
     872                        throw setError(VBOX_E_FILE_ERROR,
     873                               tr("Could not read manifest file '%s' (%Rrc)"),
     874                               RTPathFilename(strMfFile.c_str()), vrc);
     875                    }
     876
     877                    RTDIGESTTYPE digestType = RTDIGESTTYPE_UNKNOWN;
     878                    vrc = RTManifestVerifyDigestType(pBuf, readed, digestType);
     879
     880                    if (RT_FAILURE(vrc))
     881                    {
     882                        if (pBuf)
     883                            RTMemFree(pBuf);
     884                        throw setError(VBOX_E_FILE_ERROR,
     885                               tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"),
     886                               RTPathFilename(strMfFile.c_str()), vrc);
     887                    }
     888
     889                    storage.fCreateDigest = true;
     890
     891                    if (digestType == RTDIGESTTYPE_SHA256)
     892                    {
     893                        storage.fSha256 = true;
     894                    }
     895                    else
     896                    {
     897                        storage.fSha256 = false;
     898                    }
     899                }
     900                   
     901                ///////////////////////////////////////////
     902
     903                vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
     904                                         VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
     905                                         &storage.pVDImageIfaces);
     906                if (RT_FAILURE(vrc))
     907                    rc = setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
     908
     909                storage.fCreateDigest = true;
     910
     911                rc = readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
     912            }
     913            else
     914                rc = readFSImpl(pTask, pTask->locInfo.strPath, pFileIo, NULL);
    831915        }
    832         pFileIo = FileCreateInterface();
    833         if (!pFileIo)
     916        catch (HRESULT rc2)
    834917        {
    835             rc = E_OUTOFMEMORY;
    836             break;
     918            rc = rc2;
    837919        }
    838         SHASTORAGE storage;
    839         RT_ZERO(storage);
    840         int vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
    841                                  VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
    842                                  &storage.pVDImageIfaces);
    843         if (RT_FAILURE(vrc))
     920        catch (int rc2)
    844921        {
    845             rc = setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
    846             break;
     922            rc = rc2;
    847923        }
    848924
    849         rc = readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
    850925    }while(0);
    851926
     
    28372912    // if pReader != NULL
    28382913    const ovf::OVFReader &reader = *m->pReader;
     2914    const ovf::OVFVersion_T ovfVersion = reader.m_envelopeData.getOVFVersion();
     2915
     2916    if ( ovfVersion == ovf::OVFVersion_2_0)
     2917        pStorage->fSha256 = true;
    28392918
    28402919    // create a session for the machine + disks we manipulate below
  • trunk/src/VBox/Main/xml/ovfreader.cpp

    r44528 r45227  
    6565{
    6666    const xml::ElementNode *pRootElem = m_doc.getRootElement();
     67    const xml::AttributeNode *pTypeAttr;
     68    const char *pcszTypeAttr = "";
     69
    6770    if (    !pRootElem
    6871         || strcmp(pRootElem->getName(), "Envelope")
    6972       )
    7073        throw OVFLogicError(N_("Root element in OVF file must be \"Envelope\"."));
     74
     75    if ((pTypeAttr = pRootElem->findAttribute("version")))
     76    {
     77        pcszTypeAttr = pTypeAttr->getValue();
     78        m_envelopeData.version = pcszTypeAttr;
     79    }
     80    else
     81    {
     82//        throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'Envelope' element, line %d"),
     83//                            m_strPath.c_str(),
     84//                            "version",
     85//                            pRootElem->getLineNumber());
     86    }
     87
     88    if ((pTypeAttr = pRootElem->findAttribute("xml:lang")))
     89    {
     90        pcszTypeAttr = pTypeAttr->getValue();
     91        m_envelopeData.lang = pcszTypeAttr;
     92    }
    7193
    7294    // OVF has the following rough layout:
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