VirtualBox

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


Ignore:
Timestamp:
May 26, 2009 3:44:07 PM (16 years ago)
Author:
vboxsync
Message:

Main-S3: backed out r47779 because of Win (mkdtemp)

Location:
trunk/src/VBox/Main
Files:
2 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r20044 r20045  
    2121 */
    2222
     23#include <VBox/param.h>
    2324#include <iprt/stream.h>
    2425#include <iprt/path.h>
    2526#include <iprt/dir.h>
    2627#include <iprt/file.h>
    27 #include <iprt/s3.h>
    28 
    29 #include <VBox/param.h>
    30 #include <VBox/version.h>
    3128
    3229#include "ApplianceImpl.h"
    33 #include "VFSExplorerImpl.h"
    3430#include "VirtualBoxImpl.h"
    3531#include "GuestOSTypeImpl.h"
     
    464460 * @return
    465461 */
     462
    466463HRESULT Appliance::init(VirtualBox *aVirtualBox)
    467464{
     
    25042501struct Appliance::TaskWriteOVF
    25052502{
    2506     enum OVFFormat
    2507     {
    2508         unspecified,
    2509         OVF_0_9,
    2510         OVF_1_0
    2511     };
    2512     enum TaskType
    2513     {
    2514         Write
    2515     };
    2516 
    2517     TaskWriteOVF(OVFFormat aFormat, Appliance *aThat)
    2518         : taskType(Write),
    2519           storageType(VFSType_File),
    2520           enFormat(aFormat),
    2521           pAppliance(aThat),
     2503    TaskWriteOVF(Appliance *aThat, Progress *aProgress)
     2504        : pAppliance(aThat),
     2505          enFormat(unspecified),
     2506          progress(aProgress),
    25222507          rc(S_OK)
    25232508    {}
    25242509    ~TaskWriteOVF() {}
    25252510
    2526     int startThread();
    2527     static int uploadProgress(unsigned uPercent, void *pvUser);
    2528 
    2529     TaskType taskType;
    2530     VFSType_T storageType;
    2531     Utf8Str filepath;
    2532     Utf8Str hostname;
    2533     Utf8Str username;
    2534     Utf8Str password;
    2535     OVFFormat enFormat;
     2511    HRESULT startThread();
     2512
    25362513    Appliance *pAppliance;
     2514    enum { unspecified, OVF_0_9, OVF_1_0 }
     2515        enFormat;
     2516
    25372517    ComObjPtr<Progress> progress;
    25382518    HRESULT rc;
    25392519};
    25402520
    2541 int Appliance::TaskWriteOVF::startThread()
     2521HRESULT Appliance::TaskWriteOVF::startThread()
    25422522{
    25432523    int vrc = RTThreadCreate(NULL, Appliance::taskThreadWriteOVF, this,
    25442524                             0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
    25452525                             "Appliance::Task");
    2546 
    25472526    ComAssertMsgRCRet(vrc,
    2548                       ("Could not create taskThreadWriteOVF (%Rrc)\n", vrc), E_FAIL);
    2549 
    2550     return vrc;
     2527                      ("Could not create taskThreadExportOVF (%Rrc)\n", vrc), E_FAIL);
     2528
     2529    return S_OK;
    25512530}
    25522531
    2553 /* static */
    2554 int Appliance::TaskWriteOVF::uploadProgress(unsigned uPercent, void *pvUser)
    2555 {
    2556     Appliance::TaskWriteOVF* pTask = *(Appliance::TaskWriteOVF**)pvUser;
    2557 
    2558     if (pTask &&
    2559         !pTask->progress.isNull())
    2560     {
    2561         BOOL fCanceled;
    2562         pTask->progress->COMGETTER(Canceled)(&fCanceled);
    2563         if (fCanceled)
    2564             return -1;
    2565         pTask->progress->setCurrentOperationProgress(uPercent);
    2566     }
    2567     RTPrintf ("%u%%\n", uPercent);
    2568     return VINF_SUCCESS;
    2569 }
    2570 
    2571 STDMETHODIMP Appliance::CreateVFSExplorer(IN_BSTR aURI, IVFSExplorer **aExplorer)
     2532STDMETHODIMP Appliance::Write(IN_BSTR format, IN_BSTR path, IProgress **aProgress)
    25722533{
    25732534    HRESULT rc = S_OK;
    25742535
    2575     CheckComArgOutPointerValid(aExplorer);
     2536    CheckComArgOutPointerValid(aProgress);
    25762537
    25772538    AutoCaller autoCaller(this);
    2578     CheckComRCReturnRC(autoCaller.rc());
    2579 
    2580     AutoReadLock(this);
    2581 
    2582     Utf8Str uri(aURI);
    2583     /* Check which kind of export the user has requested */
    2584     VFSType_T type = VFSType_File;
    2585     Utf8Str strProtocol = "";
    2586     /* Check the URI for the target format */
    2587     if (uri.startsWith("SunCloud://", Utf8Str::CaseInsensitive)) /* Sun Cloud service */
    2588     {
    2589         type = VFSType_S3;
    2590         strProtocol = "SunCloud://";
    2591     }
    2592     else if (uri.startsWith("S3://", Utf8Str::CaseInsensitive)) /* S3 service */
    2593     {
    2594         type = VFSType_S3;
    2595         strProtocol = "S3://";
    2596     }
    2597     else if (uri.startsWith("webdav://", Utf8Str::CaseInsensitive)) /* webdav service */
    2598         throw E_NOTIMPL;
    2599 
    2600     Utf8Str strFilepath;
    2601     Utf8Str strHostname;
    2602     Utf8Str strUsername;
    2603     Utf8Str strPassword;
    2604     parseURI(uri, strProtocol, strFilepath, strHostname, strUsername, strPassword);
    2605 
    2606     ComObjPtr<VFSExplorer> explorer;
    2607     explorer.createObject();
    2608 
    2609     rc = explorer->init(type, strFilepath, strHostname, strUsername, strPassword, mVirtualBox);
    2610 
    2611     if (SUCCEEDED(rc))
    2612         /* Return explorer to the caller */
    2613         explorer.queryInterfaceTo(aExplorer);
    2614 
    2615     return rc;
    2616 }
    2617 
    2618 STDMETHODIMP Appliance::Write(IN_BSTR format, IN_BSTR path, IProgress **aProgress)
    2619 {
    2620     HRESULT rc = S_OK;
    2621 
    2622     CheckComArgOutPointerValid(aProgress);
    2623 
    2624     AutoCaller autoCaller(this);
    2625     CheckComRCReturnRC(autoCaller.rc());
     2539    if (FAILED(rc = autoCaller.rc())) return rc;
    26262540
    26272541    AutoWriteLock(this);
    26282542
    26292543    // see if we can handle this file; for now we insist it has an ".ovf" extension
    2630     Utf8Str strPath = path;
    2631     if (!strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))
     2544    m->strPath = path;
     2545    if (!m->strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))
    26322546        return setError(VBOX_E_FILE_ERROR,
    26332547                        tr("Appliance file must have .ovf extension"));
    26342548
    26352549    ComObjPtr<Progress> progress;
    2636     Utf8Str strFormat(format);
    2637     TaskWriteOVF::OVFFormat ovfF;
    2638     if (strFormat == "ovf-0.9")
    2639         ovfF = TaskWriteOVF::OVF_0_9;
    2640     else if (strFormat == "ovf-1.0")
    2641         ovfF = TaskWriteOVF::OVF_1_0;
    2642     else
    2643         return setError(VBOX_E_FILE_ERROR,
    2644                         tr("Invalid format \"%s\" specified"), strFormat.c_str());
    2645 
    2646     rc = writeImpl(ovfF, strPath, progress);
    2647 
    2648     if (SUCCEEDED(rc))
    2649         /* Return progress to the caller */
    2650         progress.queryInterfaceTo(aProgress);
    2651 
    2652     return rc;
    2653 }
    2654 
    2655 void Appliance::parseURI(Utf8Str strUri, const Utf8Str &strProtocol, Utf8Str &strFilepath, Utf8Str &strHostname, Utf8Str &strUsername, Utf8Str &strPassword)
    2656 {
    2657     /* Remove the protocol */
    2658     if (strUri.startsWith(strProtocol, Utf8Str::CaseInsensitive))
    2659         strUri = strUri.substr(strProtocol.length());
    2660     size_t uppos = strUri.find("@");
    2661     if (uppos != Utf8Str::npos)
    2662     {
    2663         strUsername = strUri.substr(0, uppos);
    2664         strUri = strUri.substr(uppos + 1);
    2665         size_t upos = strUsername.find(":");
    2666         if (upos != Utf8Str::npos)
    2667         {
    2668             strPassword = strUsername.substr(upos + 1);
    2669             strUsername = strUsername.substr(0, upos);
    2670         }
    2671     }
    2672     size_t hpos = strUri.find("/");
    2673     if (hpos != Utf8Str::npos)
    2674     {
    2675         strHostname = strUri.substr(0, hpos);
    2676         strUri = strUri.substr(hpos);
    2677     }
    2678     strFilepath = strUri;
    2679     RTPrintf("%s - %s - %s - %s\n", strUsername.c_str(), strPassword.c_str(), strHostname.c_str(), strFilepath.c_str());
    2680 }
    2681 
    2682 HRESULT Appliance::writeImpl(int aFormat, Utf8Str aPath, ComObjPtr<Progress> &aProgress)
    2683 {
    2684     HRESULT rc = S_OK;
    26852550    try
    26862551    {
    2687         m->strPath = aPath;
     2552        Bstr progressDesc = BstrFmt(tr("Export appliance '%s'"),
     2553                                    m->strPath.raw());
     2554        rc = setUpProgress(progress, progressDesc);
     2555        if (FAILED(rc)) throw rc;
    26882556
    26892557        /* Initialize our worker task */
    2690         std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF((TaskWriteOVF::OVFFormat)aFormat, this));
    2691 
    2692         /* Check which kind of export the user has requested */
    2693         Utf8Str strProtocol = "";
    2694         /* Check the URI for the target format */
    2695         if (m->strPath.startsWith("SunCloud://", Utf8Str::CaseInsensitive)) /* Sun Cloud service */
    2696         {
    2697             task->storageType = VFSType_S3;
    2698             strProtocol = "SunCloud://";
    2699         }
    2700         else if (m->strPath.startsWith("S3://", Utf8Str::CaseInsensitive)) /* S3 service */
    2701         {
    2702             task->storageType = VFSType_S3;
    2703             strProtocol = "S3://";
    2704         }
    2705         else if (m->strPath.startsWith("webdav://", Utf8Str::CaseInsensitive)) /* webdav service */
    2706             throw E_NOTIMPL;
    2707 
    2708         parseURI(m->strPath, strProtocol, task->filepath, task->hostname, task->username, task->password);
    2709         Bstr progressDesc = BstrFmt(tr("Export appliance '%s'"),
    2710                                     task->filepath.c_str());
    2711 
    2712         /* todo: This progress init stuff should be done a little bit more generic */
    2713         if (task->storageType == VFSType_S3)
    2714             rc = setUpProgressUpload(aProgress, progressDesc);
     2558        std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF(this, progress));
     2559        //AssertComRCThrowRC (task->autoCaller.rc());
     2560
     2561        Utf8Str strFormat(format);
     2562        if (strFormat == "ovf-0.9")
     2563            task->enFormat = TaskWriteOVF::OVF_0_9;
     2564        else if (strFormat == "ovf-1.0")
     2565            task->enFormat = TaskWriteOVF::OVF_1_0;
    27152566        else
    2716             rc = setUpProgress(aProgress, progressDesc);
    2717         if (FAILED(rc)) throw rc;
    2718 
    2719         task->progress = aProgress;
     2567            return setError(VBOX_E_FILE_ERROR,
     2568                            tr("Invalid format \"%s\" specified"), strFormat.c_str());
    27202569
    27212570        rc = task->startThread();
     
    27292578    }
    27302579
     2580    if (SUCCEEDED(rc))
     2581        /* Return progress to the caller */
     2582        progress.queryInterfaceTo(aProgress);
     2583
    27312584    return rc;
    2732 }
    2733 
    2734 DECLCALLBACK(int) Appliance::taskThreadWriteOVF(RTTHREAD /* aThread */, void *pvUser)
    2735 {
    2736     std::auto_ptr<TaskWriteOVF> task(static_cast<TaskWriteOVF*>(pvUser));
    2737     AssertReturn(task.get(), VERR_GENERAL_FAILURE);
    2738 
    2739     Appliance *pAppliance = task->pAppliance;
    2740 
    2741     LogFlowFuncEnter();
    2742     LogFlowFunc(("Appliance %p\n", pAppliance));
    2743 
    2744     HRESULT rc = S_OK;
    2745 
    2746     switch(task->taskType)
    2747     {
    2748         case TaskWriteOVF::Write:
    2749         {
    2750             if (task->storageType == VFSType_File)
    2751                 rc = pAppliance->writeFS(task.get());
    2752             else if (task->storageType == VFSType_S3)
    2753                 rc = pAppliance->writeS3(task.get());
    2754             break;
    2755         }
    2756     }
    2757 
    2758     task->rc = rc;
    2759 
    2760     LogFlowFunc(("rc=%Rhrc\n", rc));
    2761     LogFlowFuncLeave();
    2762 
    2763     return VINF_SUCCESS;
    27642585}
    27652586
     
    27702591 */
    27712592/* static */
    2772 int Appliance::writeFS(TaskWriteOVF *pTask)
    2773 {
     2593DECLCALLBACK(int) Appliance::taskThreadWriteOVF(RTTHREAD /* aThread */, void *pvUser)
     2594{
     2595    std::auto_ptr<TaskWriteOVF> task(static_cast<TaskWriteOVF*>(pvUser));
     2596    AssertReturn(task.get(), VERR_GENERAL_FAILURE);
     2597
     2598    Appliance *pAppliance = task->pAppliance;
     2599
    27742600    LogFlowFuncEnter();
    2775     LogFlowFunc(("Appliance %p\n", this));
    2776 
    2777     AutoCaller autoCaller(this);
     2601    LogFlowFunc(("Appliance %p\n", pAppliance));
     2602
     2603    AutoCaller autoCaller(pAppliance);
    27782604    CheckComRCReturnRC(autoCaller.rc());
    27792605
    2780     AutoWriteLock appLock(this);
     2606    AutoWriteLock appLock(pAppliance);
    27812607
    27822608    HRESULT rc = S_OK;
     2609
     2610    ComPtr<IVirtualBox> pVirtualBox(pAppliance->mVirtualBox);
    27832611
    27842612    try
     
    27872615        xml::ElementNode *pelmRoot = doc.createRootElement("Envelope");
    27882616
    2789         pelmRoot->setAttribute("ovf:version", (pTask->enFormat == TaskWriteOVF::OVF_1_0) ? "1.0" : "0.9");
     2617        pelmRoot->setAttribute("ovf:version", (task->enFormat == TaskWriteOVF::OVF_1_0) ? "1.0" : "0.9");
    27902618        pelmRoot->setAttribute("xml:lang", "en-US");
    27912619
     
    27962624        pelmRoot->setAttribute("xmlns:ovf", strNamespace);
    27972625
    2798          pelmRoot->setAttribute("xmlns:ovfstr", "http://schema.dmtf.org/ovf/strings/1");
     2626//         pelmRoot->setAttribute("xmlns:ovfstr", "http://schema.dmtf.org/ovf/strings/1");
    27992627        pelmRoot->setAttribute("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData");
    28002628        pelmRoot->setAttribute("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData");
    28012629        pelmRoot->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    2802          pelmRoot->setAttribute("xsi:schemaLocation", "http://schemas.dmtf.org/ovf/envelope/1 ../ovf-envelope.xsd");
     2630//         pelmRoot->setAttribute("xsi:schemaLocation", "http://schemas.dmtf.org/ovf/envelope/1 ../ovf-envelope.xsd");
    28032631
    28042632        // <Envelope>/<References>
     
    28112639            </DiskSection> */
    28122640        xml::ElementNode *pelmDiskSection;
    2813         if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2641        if (task->enFormat == TaskWriteOVF::OVF_0_9)
    28142642        {
    28152643            // <Section xsi:type="ovf:DiskSection_Type">
     
    28342662            </NetworkSection> */
    28352663        xml::ElementNode *pelmNetworkSection;
    2836         if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2664        if (task->enFormat == TaskWriteOVF::OVF_0_9)
    28372665        {
    28382666            // <Section xsi:type="ovf:NetworkSection_Type">
     
    28562684        // one machine, it seems
    28572685        xml::ElementNode *pelmToAddVirtualSystemsTo;
    2858         if (m->virtualSystemDescriptions.size() > 1)
     2686        if (pAppliance->m->virtualSystemDescriptions.size() > 1)
    28592687        {
    2860             if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2688            if (task->enFormat == TaskWriteOVF::OVF_0_9)
    28612689                throw setError(VBOX_E_FILE_ERROR,
    28622690                               tr("Cannot export more than one virtual system with OVF 0.9, use OVF 1.0"));
     
    28702698        list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
    28712699        /* Iterate through all virtual systems of that appliance */
    2872         for (it = m->virtualSystemDescriptions.begin();
    2873              it != m->virtualSystemDescriptions.end();
     2700        for (it = pAppliance->m->virtualSystemDescriptions.begin();
     2701             it != pAppliance->m->virtualSystemDescriptions.end();
    28742702             ++it)
    28752703        {
     
    28772705
    28782706            xml::ElementNode *pelmVirtualSystem;
    2879             if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2707            if (task->enFormat == TaskWriteOVF::OVF_0_9)
    28802708            {
    28812709                // <Section xsi:type="ovf:NetworkSection_Type">
     
    29212749                </Section> */
    29222750                xml::ElementNode *pelmAnnotationSection;
    2923                 if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2751                if (task->enFormat == TaskWriteOVF::OVF_0_9)
    29242752                {
    29252753                    // <Section ovf:required="false" xsi:type="ovf:ProductSection_Type">
     
    29532781                    </Section> */
    29542782                xml::ElementNode *pelmAnnotationSection;
    2955                 if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2783                if (task->enFormat == TaskWriteOVF::OVF_0_9)
    29562784                {
    29572785                    // <Section ovf:required="false" xsi:type="ovf:AnnotationSection_Type">
     
    29762804                   </EulaSection> */
    29772805                xml::ElementNode *pelmEulaSection;
    2978                 if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2806                if (task->enFormat == TaskWriteOVF::OVF_0_9)
    29792807                {
    29802808                    pelmEulaSection = pelmVirtualSystem->createChild("Section");
     
    29982826                </OperatingSystemSection> */
    29992827            xml::ElementNode *pelmOperatingSystemSection;
    3000             if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2828            if (task->enFormat == TaskWriteOVF::OVF_0_9)
    30012829            {
    30022830                pelmOperatingSystemSection = pelmVirtualSystem->createChild("Section");
     
    30142842            // <VirtualHardwareSection ovf:id="hw1" ovf:transport="iso">
    30152843            xml::ElementNode *pelmVirtualHardwareSection;
    3016             if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2844            if (task->enFormat == TaskWriteOVF::OVF_0_9)
    30172845            {
    30182846                // <Section xsi:type="ovf:VirtualHardwareSection_Type">
     
    30402868            // <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType>
    30412869            const char *pcszHardware = "virtualbox-2.2";
    3042             if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     2870            if (task->enFormat == TaskWriteOVF::OVF_0_9)
    30432871                // pretend to be vmware compatible then
    30442872                pcszHardware = "vmx-6";
     
    33983226                        // <rasd:InstanceID>1</rasd:InstanceID>
    33993227                        xml::ElementNode *pelmInstanceID;
    3400                         if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
     3228                        if (task->enFormat == TaskWriteOVF::OVF_0_9)
    34013229                            pelmInstanceID = pItem->createChild("rasd:InstanceId");
    34023230                        else
     
    34743302            const Utf8Str &strTargetFileNameOnly = pDiskEntry->strOvf;
    34753303            // target path needs to be composed from where the output OVF is
    3476             Utf8Str strTargetFilePath = stripFilename(m->strPath);
     3304            Utf8Str strTargetFilePath = stripFilename(pAppliance->m->strPath);
    34773305            strTargetFilePath.append("/");
    34783306            strTargetFilePath.append(strTargetFileNameOnly);
     
    34843312
    34853313            Log(("Finding source disk \"%ls\"\n", bstrSrcFilePath.raw()));
    3486             rc = mVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam());
     3314            rc = pVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam());
    34873315            if (FAILED(rc)) throw rc;
    34883316
     
    34923320            // create a new hard disk interface for the destination disk image
    34933321            Log(("Creating target disk \"%s\"\n", strTargetFilePath.raw()));
    3494             rc = mVirtualBox->CreateHardDisk(bstrSrcFormat, Bstr(strTargetFilePath), pTargetDisk.asOutParam());
     3322            rc = pVirtualBox->CreateHardDisk(bstrSrcFormat, Bstr(strTargetFilePath), pTargetDisk.asOutParam());
    34953323            if (FAILED(rc)) throw rc;
    34963324
     
    35043332
    35053333                // advance to the next operation
    3506                 if (!pTask->progress.isNull())
    3507                     pTask->progress->setNextOperation(BstrFmt(tr("Exporting virtual disk image '%s'"), strSrcFilePath.c_str()),
     3334                if (!task->progress.isNull())
     3335                    task->progress->setNextOperation(BstrFmt(tr("Exporting virtual disk image '%s'"), strSrcFilePath.c_str()),
    35083336                                                     pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
    35093337
    35103338                // now wait for the background disk operation to complete; this throws HRESULTs on error
    3511                 waitForAsyncProgress(pTask->progress, pProgress2);
     3339                pAppliance->waitForAsyncProgress(task->progress, pProgress2);
    35123340            }
    35133341            catch (HRESULT rc3)
     
    35163344                // it'll stick in the registry forever
    35173345                pTargetDisk->Close();
    3518                 throw;
     3346                throw rc3;
    35193347            }
    35203348
     
    35533381        // now go write the XML
    35543382        xml::XmlFileWriter writer(doc);
    3555         writer.write(m->strPath.c_str());
     3383        writer.write(pAppliance->m->strPath.c_str());
    35563384    }
    35573385    catch(xml::Error &x)
     
    35653393    }
    35663394
    3567     pTask->rc = rc;
    3568 
    3569     if (!pTask->progress.isNull())
    3570         pTask->progress->notifyComplete(rc);
    3571 
    3572     LogFlowFunc(("rc=%Rhrc\n", rc));
    3573     LogFlowFuncLeave();
    3574 
    3575     return VINF_SUCCESS;
    3576 }
    3577 
    3578 /**
    3579  * Worker thread implementation for Upload() (ovf uploader).
    3580  * @param aThread
    3581  * @param pvUser
    3582  */
    3583 /* static */
    3584 int Appliance::writeS3(TaskWriteOVF *pTask)
    3585 {
    3586     LogFlowFuncEnter();
    3587     LogFlowFunc(("Appliance %p\n", this));
    3588 
    3589     AutoCaller autoCaller(this);
    3590     CheckComRCReturnRC(autoCaller.rc());
    3591 
    3592     HRESULT rc = S_OK;
    3593 
    3594     AutoWriteLock appLock(this);
    3595 
    3596     /* Buckets are S3 specific. So parse the bucket out of the file path */
    3597     Utf8Str tmpPath = pTask->filepath;
    3598     if (!tmpPath.startsWith("/"))
    3599         return setError(E_INVALIDARG,
    3600                         tr("The path '%s' must start with /"), tmpPath.c_str());
    3601     Utf8Str bucket;
    3602     size_t bpos = tmpPath.find("/", 1);
    3603     if (bpos != Utf8Str::npos)
    3604     {
    3605         bucket = tmpPath.substr(1, bpos - 1); /* The bucket without any slashes */
    3606         tmpPath = tmpPath.substr(bpos); /* The rest of the file path */
    3607     }
    3608     /* If there is no bucket name provided reject the upload */
    3609     if (bucket.isEmpty())
    3610         return setError(E_INVALIDARG,
    3611                         tr("You doesn't provide a bucket name in the URI"), tmpPath.c_str());
    3612 
    3613     int vrc = VINF_SUCCESS;
    3614     RTS3 hS3 = NULL;
    3615     char szOSTmpDir[RTPATH_MAX];
    3616     RTPathTemp(szOSTmpDir, sizeof(szOSTmpDir));
    3617     /* The template for the temporary directory created below */
    3618     char *pszTmpDir;
    3619     RTStrAPrintf(&pszTmpDir, "%s/vbox-ovf-XXXXXX", szOSTmpDir);
    3620     list< pair<Utf8Str, ULONG> > filesList;
    3621 
    3622     // todo:
    3623     // - getting the tmp directory (especially on win)
    3624     // - usable error codes
    3625     // - seems snapshot filenames are problematic {uuid}.vdi
    3626     try
    3627     {
    3628         /* We need a temporary directory which we can put the OVF file & all
    3629          * disk images in */
    3630         if (!mkdtemp(pszTmpDir))
    3631             throw setError(VBOX_E_FILE_ERROR,
    3632                            tr("Cannot create temporary directory '%s'"), pszTmpDir);
    3633 
    3634         /* The temporary name of the target OVF file */
    3635         Utf8StrFmt strTmpOvf("%s/%s", pszTmpDir, RTPathFilename(tmpPath));
    3636 
    3637         /* Prepare the temporary writing of the OVF */
    3638         ComObjPtr<Progress> progress;
    3639         rc = writeImpl(pTask->enFormat, strTmpOvf.c_str(), progress);
    3640         if (FAILED(rc)) throw rc;
    3641 
    3642         /* Unlock the appliance for the writing thread */
    3643         appLock.unlock();
    3644         /* Wait until the writing is done, but report the progress back to the
    3645            caller */
    3646         ComPtr<IProgress> progressInt(progress);
    3647         waitForAsyncProgress(pTask->progress, progressInt); /* Any errors will be thrown */
    3648 
    3649         /* Again lock the appliance for the next steps */
    3650         appLock.lock();
    3651 
    3652         vrc = RTPathExists(strTmpOvf.c_str()); /* Paranoid check */
    3653         if(RT_FAILURE(vrc))
    3654             throw setError(VBOX_E_FILE_ERROR,
    3655                            tr("Cannot find source file '%s'"), strTmpOvf.c_str());
    3656         /* Add the OVF file */
    3657         filesList.push_back(pair<Utf8Str, ULONG>(strTmpOvf, m->ulWeightPerOperation)); /* Use 1% of the total for the OVF file upload */
    3658 
    3659         /* Now add every disks of every virtual system */
    3660         list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
    3661         for (it = m->virtualSystemDescriptions.begin();
    3662              it != m->virtualSystemDescriptions.end();
    3663              ++it)
    3664         {
    3665             ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
    3666             std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
    3667             std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;
    3668             for (itH = avsdeHDs.begin();
    3669                  itH != avsdeHDs.end();
    3670                  ++itH)
    3671             {
    3672                 const Utf8Str &strTargetFileNameOnly = (*itH)->strOvf;
    3673                 /* Target path needs to be composed from where the output OVF is */
    3674                 Utf8Str strTargetFilePath = stripFilename(m->strPath);
    3675                 strTargetFilePath.append("/");
    3676                 strTargetFilePath.append(strTargetFileNameOnly);
    3677                 vrc = RTPathExists(strTargetFilePath.c_str()); /* Paranoid check */
    3678                 if(RT_FAILURE(vrc))
    3679                     throw setError(VBOX_E_FILE_ERROR,
    3680                                    tr("Cannot find source file '%s'"), strTargetFilePath.c_str());
    3681                 filesList.push_back(pair<Utf8Str, ULONG>(strTargetFilePath, (*itH)->ulSizeMB));
    3682             }
    3683         }
    3684         /* Next we have to upload the OVF & all disk images */
    3685         vrc = RTS3Create(&hS3, pTask->username.c_str(), pTask->password.c_str(), pTask->hostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
    3686         if(RT_FAILURE(vrc))
    3687             throw setError(VBOX_E_IPRT_ERROR,
    3688                            tr("Cannot create S3 service handler"));
    3689         RTS3SetProgressCallback(hS3, pTask->uploadProgress, &pTask);
    3690 
    3691         /* Upload all files */
    3692         for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)
    3693         {
    3694             const pair<Utf8Str, ULONG> &s = (*it1);
    3695             char *pszFilename = RTPathFilename(s.first.c_str());
    3696             /* Advance to the next operation */
    3697             if (!pTask->progress.isNull())
    3698                 pTask->progress->setNextOperation(BstrFmt(tr("Uploading file '%s'"), pszFilename), s.second);
    3699             vrc = RTS3PutKey(hS3, bucket.c_str(), pszFilename, s.first.c_str());
    3700             if (RT_FAILURE(vrc))
    3701             {
    3702                 if(vrc == VERR_S3_CANCELED)
    3703                     break;
    3704                 else if(vrc == VERR_S3_ACCESS_DENIED)
    3705                     throw setError(E_ACCESSDENIED,
    3706                                    tr("Cannot upload file '%s' to S3 storage server (Access denied)"), pszFilename);
    3707                 else if(vrc == VERR_S3_NOT_FOUND)
    3708                     throw setError(VBOX_E_FILE_ERROR,
    3709                                    tr("Cannot upload file '%s' to S3 storage server (File not found)"), pszFilename);
    3710                 else
    3711                     throw setError(VBOX_E_IPRT_ERROR,
    3712                                    tr("Cannot upload file '%s' to S3 storage server (%Rrc)"), pszFilename, vrc);
    3713             }
    3714         }
    3715 
    3716     }
    3717     catch(HRESULT aRC)
    3718     {
    3719         rc = aRC;
    3720     }
    3721     /* Cleanup */
    3722     if (hS3)
    3723         RTS3Destroy(hS3);
    3724     /* Delete all files which where temporary created */
    3725     for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)
    3726     {
    3727         const pair<Utf8Str, ULONG> &s = (*it1);
    3728         vrc = RTFileDelete(s.first.c_str());
    3729         if(RT_FAILURE(vrc))
    3730             rc = setError(VBOX_E_FILE_ERROR,
    3731                           tr("Cannot delete file '%s'"), s.first.c_str());
    3732     }
    3733     /* Delete the temporary directory */
    3734     if (RTPathExists(pszTmpDir))
    3735     {
    3736         vrc = RTDirRemove(pszTmpDir);
    3737         if(RT_FAILURE(vrc))
    3738             rc = setError(VBOX_E_FILE_ERROR,
    3739                           tr("Cannot delete temporary directory '%s'"), pszTmpDir);
    3740     }
    3741     if (pszTmpDir)
    3742         RTStrFree(pszTmpDir);
    3743 
    3744     pTask->rc = rc;
    3745 
    3746     if (!pTask->progress.isNull())
    3747         pTask->progress->notifyComplete(rc);
     3395    task->rc = rc;
     3396
     3397    if (!task->progress.isNull())
     3398        task->progress->notifyComplete(rc);
    37483399
    37493400    LogFlowFunc(("rc=%Rhrc\n", rc));
     
    38943545}
    38953546
    3896 HRESULT Appliance::setUpProgressUpload(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription)
    3897 {
    3898     HRESULT rc;
    3899 
    3900     /* Create the progress object */
    3901     pProgress.createObject();
    3902 
    3903     // weigh the disk images according to their sizes
    3904     uint32_t ulTotalMB = 0;
    3905     uint32_t cDisks = 0;
    3906     list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
    3907     for (it = m->virtualSystemDescriptions.begin();
    3908          it != m->virtualSystemDescriptions.end();
    3909          ++it)
    3910     {
    3911         ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
    3912         /* One for every hard disk of the Virtual System */
    3913         std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
    3914         std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;
    3915         for (itH = avsdeHDs.begin();
    3916              itH != avsdeHDs.end();
    3917              ++itH)
    3918         {
    3919             const VirtualSystemDescriptionEntry *pHD = *itH;
    3920             ulTotalMB += pHD->ulSizeMB;
    3921             ++cDisks;
    3922         }
    3923     }
    3924 
    3925     ULONG cOperations = 1 + 1 + cDisks;     // one op per disk plus 1 for the OVF & 1 plus to the temporary creation */
    3926 
    3927     ULONG ulTotalOperationsWeight;
    3928     if (ulTotalMB)
    3929     {
    3930         m->ulWeightPerOperation = (ULONG)((double)ulTotalMB * 1  / 100);    // use 1% of the progress for OVF file upload (we didn't know the size at this point)
    3931         ulTotalOperationsWeight = ulTotalMB + m->ulWeightPerOperation;
    3932     }
    3933     else
    3934     {
    3935         // no disks to export:
    3936         ulTotalOperationsWeight = 1;
    3937         m->ulWeightPerOperation = 1;
    3938     }
    3939     ULONG ulOVFCreationWeight = ((double)ulTotalOperationsWeight * 50.0 / 100.0); /* Use 50% for the creation of the OVF & the disks */
    3940     ulTotalOperationsWeight += ulOVFCreationWeight;
    3941 
    3942     Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",
    3943          ulTotalMB, cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightPerOperation));
    3944 
    3945     rc = pProgress->init(mVirtualBox, static_cast<IAppliance*>(this),
    3946                          bstrDescription,
    3947                          TRUE /* aCancelable */,
    3948                          cOperations, // ULONG cOperations,
    3949                          ulTotalOperationsWeight, // ULONG ulTotalOperationsWeight,
    3950                          bstrDescription, // CBSTR bstrFirstOperationDescription,
    3951                          ulOVFCreationWeight); // ULONG ulFirstOperationWeight,
    3952     return rc;
    3953 }
    3954 
    39553547/**
    39563548 * Called from the import and export background threads to synchronize the second
  • trunk/src/VBox/Main/Makefile.kmk

    r20044 r20045  
    285285        VirtualBoxImplExtra.cpp \
    286286        ApplianceImpl.cpp \
    287         VFSExplorerImpl.cpp \
    288287        MachineImpl.cpp \
    289288        SnapshotImpl.cpp \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r20044 r20045  
    28902890    </method>
    28912891
    2892   </interface>
    2893 
    2894   <!--
    2895   // IVFSExplorer
    2896   /////////////////////////////////////////////////////////////////////////
    2897   -->
    2898 
    2899   <enum
    2900     name="VFSType"
    2901     uuid="813999ba-b949-48a8-9230-aadc6285e2f2"
    2902   >
    2903     <desc>
    2904     </desc>
    2905 
    2906     <const name="File" value="1" />
    2907     <const name="Cloud" value="2" />
    2908     <const name="S3" value="3" />
    2909     <const name="WebDav" value="4" />
    2910   </enum>
    2911 
    2912   <enum
    2913     name="FileType"
    2914     uuid="714333cd-44e2-415f-a245-d378fa9b1242"
    2915   >
    2916     <desc>
    2917     </desc>
    2918 
    2919     <const name="Unknown" value="1" />
    2920     <const name="Fifo" value="2" />
    2921     <const name="DevChar" value="3" />
    2922     <const name="Directory" value="4" />
    2923     <const name="DevBlock" value="5" />
    2924     <const name="File" value="6" />
    2925     <const name="SymLink" value="7" />
    2926     <const name="Socket" value="8" />
    2927     <const name="WhiteOut" value="9" />
    2928   </enum>
    2929 
    2930   <interface
    2931      name="IVFSExplorer" extends="$unknown"
    2932      uuid="fd7da337-80ef-4a5c-9122-918435e33003"
    2933      wsmap="managed"
    2934      >
    2935     <desc />
    2936 
    2937     <attribute name="path" type="wstring" readonly="yes">
    2938       <desc />
    2939     </attribute>
    2940 
    2941     <attribute name="type" type="VFSType" readonly="yes">
    2942       <desc />
    2943     </attribute>
    2944 
    2945     <method name="update">
    2946       <desc />
    2947 
    2948       <param name="aProgress" type="IProgress" dir="return">
    2949         <desc />
    2950       </param>
    2951     </method>
    2952 
    2953     <method name="entryList">
    2954       <desc />
    2955 
    2956       <param name="aNames" type="wstring" safearray="yes" dir="out">
    2957         <desc />
    2958       </param>
    2959 
    2960       <param name="aTypes" type="unsigned long" safearray="yes" dir="out">
    2961         <desc />
    2962       </param>
    2963     </method>
    2964 
    2965     <method name="exists">
    2966       <desc />
    2967 
    2968       <param name="aNames" type="wstring" safearray="yes" dir="in">
    2969         <desc />
    2970       </param>
    2971 
    2972       <param name="aExists" type="wstring" safearray="yes" dir="return">
    2973         <desc />
    2974       </param>
    2975     </method>
    2976 
    2977     <method name="remove">
    2978       <desc />
    2979 
    2980       <param name="aNames" type="wstring" safearray="yes" dir="in">
    2981         <desc />
    2982       </param>
    2983 
    2984       <param name="aProgress" type="IProgress" dir="return">
    2985         <desc />
    2986       </param>
    2987     </method>
    2988    
    29892892  </interface>
    29902893
     
    31403043  <interface
    31413044     name="IAppliance" extends="$unknown"
    3142      uuid="07495095-d16c-4911-8964-5914341ced5d"
     3045     uuid="30bfa6b8-9eda-4b0a-b218-a86813248ccd"
    31433046     wsmap="managed"
    31443047     >
     
    33233226      <param name="aProgress" type="IProgress" dir="return">
    33243227        <desc></desc>
    3325       </param>
    3326     </method>
    3327 
    3328     <method name="createVFSExplorer">
    3329       <desc />
    3330 
    3331       <param name="aUri" type="wstring" dir="in">
    3332         <desc />
    3333       </param>
    3334 
    3335       <param name="aExplorer" type="IVFSExplorer" dir="return">
    3336         <desc />
    33373228      </param>
    33383229    </method>
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r20044 r20045  
    7575
    7676    /* IAppliance methods */
    77     /* Import methods */
    7877    STDMETHOD(Read)(IN_BSTR path);
    7978    STDMETHOD(Interpret)(void);
    8079    STDMETHOD(ImportMachines)(IProgress **aProgress);
    81     /* Export methods */
    82     STDMETHOD(CreateVFSExplorer)(IN_BSTR aURI, IVFSExplorer **aExplorer);
    8380    STDMETHOD(Write)(IN_BSTR format, IN_BSTR path, IProgress **aProgress);
    84 
    8581    STDMETHOD(GetWarnings)(ComSafeArrayOut(BSTR, aWarnings));
    8682
     
    10399    HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const;
    104100    HRESULT setUpProgress(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription);
    105     HRESULT setUpProgressUpload(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription);
    106101    void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync);
    107102    void addWarning(const char* aWarning, ...);
    108103
    109     void parseURI(Utf8Str strUri, const Utf8Str &strProtocol, Utf8Str &strFilepath, Utf8Str &strHostname, Utf8Str &strUsername, Utf8Str &strPassword);
    110     HRESULT writeImpl(int aFormat, Utf8Str aPath, ComObjPtr<Progress> &aProgress);
    111 
    112104    struct TaskImportMachines;  /* Worker thread for import */
    113105    static DECLCALLBACK(int) taskThreadImportMachines(RTTHREAD thread, void *pvUser);
    114106
    115     struct TaskWriteOVF;        /* Worker threads for export */
    116     static DECLCALLBACK(int) taskThreadWriteOVF(RTTHREAD aThread, void *pvUser);
    117 
    118     int writeFS(TaskWriteOVF *pTask);
    119     int writeS3(TaskWriteOVF *pTask);
     107    struct TaskWriteOVF;       /* Worker thread for export */
     108    static DECLCALLBACK(int) taskThreadWriteOVF(RTTHREAD thread, void *pvUser);
    120109
    121110    friend class Machine;
  • trunk/src/VBox/Main/xpcom/server.cpp

    r20044 r20045  
    7474#include <VirtualBoxImpl.h>
    7575#include <MachineImpl.h>
    76 #include <VFSExplorerImpl.h>
    7776#include <ApplianceImpl.h>
    7877#include <SnapshotImpl.h>
     
    111110NS_DECL_CLASSINFO(Machine)
    112111NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Machine, IMachine)
    113 
    114 NS_DECL_CLASSINFO(VFSExplorer)
    115 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VFSExplorer, IVFSExplorer)
    116112
    117113NS_DECL_CLASSINFO(Appliance)
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