VirtualBox

Changeset 33417 in vbox


Ignore:
Timestamp:
Oct 25, 2010 12:32:50 PM (14 years ago)
Author:
vboxsync
Message:

FE;Main;OVF: On export name the disks like the ovf + disk + number.

Location:
trunk
Files:
10 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/en_US/SDKRef.xml

    r33300 r33417  
    34993499
    35003500        <listitem>
     3501          <para><xref linkend="IMachine__export"
     3502          xreflabel="IMachine::export()" /> received an extra parameter
     3503          <computeroutput>location</computeroutput>, which is used to decide
     3504          for the disk nameing.</para>
     3505        </listitem>
     3506        <listitem>
    35013507          <para><xref linkend="IAppliance__write"
    35023508          xreflabel="IAppliance::write()" /> received an extra parameter
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp

    r33406 r33417  
    927927        CHECK_ERROR_BREAK(a->virtualBox, CreateAppliance(pAppliance.asOutParam()));
    928928
     929        char *pszAbsFilePath = 0;
     930        if (strOutputFile.startsWith("S3://", iprt::MiniString::CaseInsensitive) ||
     931            strOutputFile.startsWith("SunCloud://", iprt::MiniString::CaseInsensitive) ||
     932            strOutputFile.startsWith("webdav://", iprt::MiniString::CaseInsensitive))
     933            pszAbsFilePath = RTStrDup(strOutputFile.c_str());
     934        else
     935            pszAbsFilePath = RTPathAbsDup(strOutputFile.c_str());
     936
    929937        std::list< ComPtr<IMachine> >::iterator itM;
    930938        uint32_t i=0;
     
    935943            ComPtr<IMachine> pMachine = *itM;
    936944            ComPtr<IVirtualSystemDescription> pVSD;
    937             CHECK_ERROR_BREAK(pMachine, Export(pAppliance, pVSD.asOutParam()));
     945            CHECK_ERROR_BREAK(pMachine, Export(pAppliance, Bstr(pszAbsFilePath).raw(), pVSD.asOutParam()));
    938946            // Add additional info to the virtal system description if the user wants so
    939947            ArgsMap *pmapArgs = NULL;
     
    10011009
    10021010        ComPtr<IProgress> progress;
    1003         char *pszAbsFilePath;
    1004         if (strOutputFile.startsWith("S3://", iprt::MiniString::CaseInsensitive) ||
    1005             strOutputFile.startsWith("SunCloud://", iprt::MiniString::CaseInsensitive) ||
    1006             strOutputFile.startsWith("webdav://", iprt::MiniString::CaseInsensitive))
    1007             pszAbsFilePath = RTStrDup(strOutputFile.c_str());
    1008         else
    1009             pszAbsFilePath = RTPathAbsDup(strOutputFile.c_str());
    10101011        CHECK_ERROR_BREAK(pAppliance, Write(Bstr(strOvfFormat).raw(),
    10111012                                            fManifest,
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.cpp

    r33294 r33417  
    152152}
    153153
     154int UIExportApplianceWzdPage1::nextId() const
     155{
     156    /* Skip next (3rd, storage-type) page for now! */
     157    return wizard()->page(QIWizardPage::nextId())->nextId();
     158}
     159
    154160void UIExportApplianceWzdPage1::sltSelectedVMChanged()
    155161{
     
    204210    /* Decorate page */
    205211    Ui::UIExportApplianceWzdPage2::setupUi(this);
    206 
    207     /* Register ExportAppliancePointer class */
    208     qRegisterMetaType<ExportAppliancePointer>();
    209 
    210     /* Register 'applianceWidget' field! */
    211     registerField("applianceWidget", this, "applianceWidget");
    212     m_pApplianceWidget = m_pSettingsCnt;
    213 }
    214 
    215 void UIExportApplianceWzdPage2::retranslateUi()
    216 {
    217     /* Translate uic generated strings */
    218     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    219 
    220     /* Wizard page 2 title */
    221     setTitle(tr("Appliance Export Settings"));
    222 }
    223 
    224 void UIExportApplianceWzdPage2::initializePage()
    225 {
    226     /* Fill and translate */
    227     retranslateUi();
    228 
    229     /* We propose a filename the first time the second page is displayed */
    230     prepareSettingsWidget();
    231 }
    232 
    233 void UIExportApplianceWzdPage2::cleanupPage()
    234 {
    235     /* Do NOT call superclass method, it will clean defailt (initially set) field - 'applianceWidget'! */
    236 }
    237 
    238 int UIExportApplianceWzdPage2::nextId() const
    239 {
    240     /* Skip next (3rd, storage-type) page for now! */
    241     return wizard()->page(QIWizardPage::nextId())->nextId();
    242 }
    243 
    244 bool UIExportApplianceWzdPage2::prepareSettingsWidget()
    245 {
    246     CVirtualBox vbox = vboxGlobal().virtualBox();
    247     CAppliance *appliance = m_pSettingsCnt->init();
    248     bool fResult = appliance->isOk();
    249     if (fResult)
    250     {
    251         /* Iterate over all the selected machine ids */
    252         QStringList uuids = field("machineIDs").toStringList();
    253         foreach (const QString &uuid, uuids)
    254         {
    255             /* Get the machine with the uuid */
    256             CMachine m = vbox.FindMachine(uuid);
    257             fResult = m.isOk();
    258             if (fResult)
    259             {
    260                 /* Add the export description to our appliance object */
    261                 CVirtualSystemDescription vsd = m.Export(*appliance);
    262                 fResult = m.isOk();
    263                 if (!fResult)
    264                 {
    265                     vboxProblem().cannotExportAppliance(m, appliance, this);
    266                     return false;
    267                 }
    268                 /* Now add some new fields the user may change */
    269                 vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    270                 vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
    271                 vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
    272                 vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
    273                 vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
    274                 vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
    275             }
    276             else
    277                 break;
    278         }
    279         /* Make sure the settings widget get the new descriptions */
    280         m_pSettingsCnt->populate();
    281     }
    282     if (!fResult)
    283         vboxProblem().cannotExportAppliance(appliance, this);
    284     return fResult;
    285 }
    286 
    287 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    288 {
    289     /* Decorate page */
    290     Ui::UIExportApplianceWzdPage3::setupUi(this);
    291212
    292213    /* Register StorageType class */
     
    330251}
    331252
    332 void UIExportApplianceWzdPage3::retranslateUi()
     253void UIExportApplianceWzdPage2::retranslateUi()
    333254{
    334255    /* Translate uic generated strings */
    335     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
     256    Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    336257
    337258    /* Wizard page 3 title */
     
    339260}
    340261
    341 void UIExportApplianceWzdPage3::initializePage()
     262void UIExportApplianceWzdPage2::initializePage()
    342263{
    343264    /* Fill and translate */
     
    348269}
    349270
    350 void UIExportApplianceWzdPage3::sltStorageTypeChanged()
     271void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    351272{
    352273    /* Update selected storage-type */
     
    363284}
    364285
    365 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
     286UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    366287{
    367288    /* Decorate page */
    368     Ui::UIExportApplianceWzdPage4::setupUi(this);
     289    Ui::UIExportApplianceWzdPage3::setupUi(this);
    369290
    370291    /* Configure the file selector */
     
    381302    connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    382303
     304    /* Register 'target' fields! */
     305    registerField("OVF09Selected", this, "OVF09Selected");
     306    registerField("manifestSelected", this, "manifestSelected");
     307    registerField("username", this, "username");
     308    registerField("password", this, "password");
     309    registerField("hostname", this, "hostname");
     310    registerField("bucket", this, "bucket");
     311    registerField("path", this, "path");
     312
    383313#if 0
    384314    /* Load default attributes from GUI extra data */
     
    389319}
    390320
    391 void UIExportApplianceWzdPage4::retranslateUi()
     321void UIExportApplianceWzdPage3::retranslateUi()
    392322{
    393323    /* Translate uic generated strings */
    394     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
     324    Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    395325
    396326    /* Wizard page 4 title */
     
    405335}
    406336
    407 void UIExportApplianceWzdPage4::initializePage()
     337void UIExportApplianceWzdPage3::initializePage()
    408338{
    409339    /* Fill and translate */
     
    489419}
    490420
    491 bool UIExportApplianceWzdPage4::isComplete() const
     421bool UIExportApplianceWzdPage3::isComplete() const
    492422{
    493423    const QString &strFile = m_pFileSelector->path().toLower();
     
    510440}
    511441
     442bool UIExportApplianceWzdPage3::validatePage()
     443{
     444    return true;
     445//    return exportAppliance();
     446}
     447
     448UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
     449{
     450    /* Decorate page */
     451    Ui::UIExportApplianceWzdPage4::setupUi(this);
     452
     453    /* Register ExportAppliancePointer class */
     454    qRegisterMetaType<ExportAppliancePointer>();
     455
     456    /* Register 'applianceWidget' field! */
     457    registerField("applianceWidget", this, "applianceWidget");
     458    m_pApplianceWidget = m_pSettingsCnt;
     459}
     460
     461void UIExportApplianceWzdPage4::retranslateUi()
     462{
     463    /* Translate uic generated strings */
     464    Ui::UIExportApplianceWzdPage4::retranslateUi(this);
     465
     466    /* Wizard page 2 title */
     467    setTitle(tr("Appliance Export Settings"));
     468}
     469
     470void UIExportApplianceWzdPage4::initializePage()
     471{
     472    /* Fill and translate */
     473    retranslateUi();
     474
     475    /* We propose a filename the first time the second page is displayed */
     476    prepareSettingsWidget();
     477}
     478
     479void UIExportApplianceWzdPage4::cleanupPage()
     480{
     481    /* Do NOT call superclass method, it will clean defailt (initially set) field - 'applianceWidget'! */
     482}
     483
    512484bool UIExportApplianceWzdPage4::validatePage()
    513485{
    514486    return exportAppliance();
     487}
     488
     489bool UIExportApplianceWzdPage4::prepareSettingsWidget()
     490{
     491    CVirtualBox vbox = vboxGlobal().virtualBox();
     492    CAppliance *appliance = m_pSettingsCnt->init();
     493    bool fResult = appliance->isOk();
     494    if (fResult)
     495    {
     496        /* Iterate over all the selected machine ids */
     497        QStringList uuids = field("machineIDs").toStringList();
     498        foreach (const QString &uuid, uuids)
     499        {
     500            /* Get the machine with the uuid */
     501            CMachine m = vbox.FindMachine(uuid);
     502            fResult = m.isOk();
     503            if (fResult)
     504            {
     505                /* Add the export description to our appliance object */
     506                CVirtualSystemDescription vsd = m.Export(*appliance, uri());
     507                fResult = m.isOk();
     508                if (!fResult)
     509                {
     510                    vboxProblem().cannotExportAppliance(m, appliance, this);
     511                    return false;
     512                }
     513                /* Now add some new fields the user may change */
     514                vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
     515                vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
     516                vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
     517                vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
     518                vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
     519                vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
     520            }
     521            else
     522                break;
     523        }
     524        /* Make sure the settings widget get the new descriptions */
     525        m_pSettingsCnt->populate();
     526    }
     527    if (!fResult)
     528        vboxProblem().cannotExportAppliance(appliance, this);
     529    return fResult;
    515530}
    516531
     
    525540     * HardDiskImage. Also add the manifest file to the check. In the ova
    526541     * case only the target file itself get checked. */
    527     QFileInfo fi(m_pFileSelector->path());
     542    QFileInfo fi(field("path").toString());
    528543    QVector<QString> files;
    529544    files << fi.fileName();
    530545    if (fi.suffix().toLower() == "ovf")
    531546    {
    532         if (m_pSelectManifest->isChecked())
     547        if (field("manifestSelected").toBool())
    533548            files << fi.baseName() + ".mf";
    534549        CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
     
    600615{
    601616    /* Write the appliance */
    602     const QString version = m_pSelectOVF09->isChecked() ? "ovf-0.9" : "ovf-1.0";
    603     CProgress progress = appliance.Write(version, m_pSelectManifest->isChecked() /* fManifest */, uri());
     617    const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
     618    CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
    604619    bool fResult = appliance.isOk();
    605620    if (fResult)
     
    629644        case Filesystem:
    630645        {
    631             return m_pFileSelector->path();
     646            return field("path").toString();
    632647        }
    633648        case SunCloud:
    634649        {
    635650            QString uri("SunCloud://");
    636             if (!m_pLeUsername->text().isEmpty())
    637                 uri = QString("%1%2").arg(uri).arg(m_pLeUsername->text());
    638             if (!m_pLePassword->text().isEmpty())
    639                 uri = QString("%1:%2").arg(uri).arg(m_pLePassword->text());
    640             if (!m_pLeUsername->text().isEmpty() || !m_pLePassword->text().isEmpty())
     651            if (!field("username").toString().isEmpty())
     652                uri = QString("%1%2").arg(uri).arg(field("username").toString());
     653            if (!field("password").toString().isEmpty())
     654                uri = QString("%1:%2").arg(uri).arg(field("password").toString());
     655            if (!field("username").toString().isEmpty() || !field("username").toString().isEmpty())
    641656                uri = QString("%1@").arg(uri);
    642             uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(m_pLeBucket->text()).arg(m_pFileSelector->path());
     657            uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(field("bucket").toString()).arg(field("path").toString());
    643658            return uri;
    644659        }
     
    646661        {
    647662            QString uri("S3://");
    648             if (!m_pLeUsername->text().isEmpty())
    649                 uri = QString("%1%2").arg(uri).arg(m_pLeUsername->text());
    650             if (!m_pLePassword->text().isEmpty())
    651                 uri = QString("%1:%2").arg(uri).arg(m_pLePassword->text());
    652             if (!m_pLeUsername->text().isEmpty() || !m_pLePassword->text().isEmpty())
     663            if (!field("username").toString().isEmpty())
     664                uri = QString("%1%2").arg(uri).arg(field("username").toString());
     665            if (!field("password").toString().isEmpty())
     666                uri = QString("%1:%2").arg(uri).arg(field("password").toString());
     667            if (!field("username").toString().isEmpty() || !field("password").toString().isEmpty())
    653668                uri = QString("%1@").arg(uri);
    654             uri = QString("%1%2/%3/%4").arg(uri).arg(m_pLeHostname->text()).arg(m_pLeBucket->text()).arg(m_pFileSelector->path());
     669            uri = QString("%1%2/%3/%4").arg(uri).arg(field("hostname").toString()).arg(field("bucket").toString()).arg(field("path").toString());
    655670            return uri;
    656671        }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzd.h

    r28800 r33417  
    7878    bool isComplete() const;
    7979
     80    int nextId() const;
     81
    8082private slots:
    8183
     
    102104{
    103105    Q_OBJECT;
     106    Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
     107
     108public:
     109
     110    UIExportApplianceWzdPage2();
     111
     112protected:
     113
     114    void retranslateUi();
     115
     116    void initializePage();
     117
     118private slots:
     119
     120    void sltStorageTypeChanged();
     121
     122private:
     123
     124    StorageType storageType() const { return m_StorageType; }
     125    void setStorageType(StorageType storageType) { m_StorageType = storageType; }
     126    StorageType m_StorageType;
     127};
     128
     129class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
     130{
     131    Q_OBJECT;
     132
     133    Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
     134    Q_PROPERTY(bool manifestSelected READ isManifestSelected);
     135    Q_PROPERTY(QString username READ username);
     136    Q_PROPERTY(QString password READ password);
     137    Q_PROPERTY(QString hostname READ hostname);
     138    Q_PROPERTY(QString bucket READ bucket);
     139    Q_PROPERTY(QString path READ path);
     140
     141public:
     142
     143    UIExportApplianceWzdPage3();
     144
     145protected:
     146
     147    void retranslateUi();
     148
     149    void initializePage();
     150
     151    bool isComplete() const;
     152    bool validatePage();
     153
     154private:
     155
     156    bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
     157    bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
     158    QString username() const { return m_pLeUsername->text(); }
     159    QString password() const { return m_pLePassword->text(); }
     160    QString hostname() const { return m_pLeHostname->text(); }
     161    QString bucket() const { return m_pLeBucket->text(); }
     162    QString path() const { return m_pFileSelector->path(); }
     163
     164    QString m_strDefaultApplianceName;
     165};
     166
     167class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
     168{
     169    Q_OBJECT;
    104170    Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    105171
    106172public:
    107173
    108     UIExportApplianceWzdPage2();
     174    UIExportApplianceWzdPage4();
    109175
    110176protected:
     
    115181    void cleanupPage();
    116182
    117     int nextId() const;
     183    bool validatePage();
    118184
    119185private:
    120186
    121187    bool prepareSettingsWidget();
     188
     189    bool exportAppliance();
     190    bool exportVMs(CAppliance &appliance);
     191    QString uri() const;
    122192
    123193    ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
     
    126196};
    127197
    128 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    129 {
    130     Q_OBJECT;
    131     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
    132 
    133 public:
    134 
    135     UIExportApplianceWzdPage3();
    136 
    137 protected:
    138 
    139     void retranslateUi();
    140 
    141     void initializePage();
    142 
    143 private slots:
    144 
    145     void sltStorageTypeChanged();
    146 
    147 private:
    148 
    149     StorageType storageType() const { return m_StorageType; }
    150     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    151     StorageType m_StorageType;
    152 };
    153 
    154 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    155 {
    156     Q_OBJECT;
    157 
    158 public:
    159 
    160     UIExportApplianceWzdPage4();
    161 
    162 protected:
    163 
    164     void retranslateUi();
    165 
    166     void initializePage();
    167 
    168     bool isComplete() const;
    169     bool validatePage();
    170 
    171 private:
    172 
    173     bool exportAppliance();
    174     bool exportVMs(CAppliance &appliance);
    175     QString uri() const;
    176 
    177     QString m_strDefaultApplianceName;
    178 };
    179198
    180199#endif /* __UIExportApplianceWzd_h__ */
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzdPage2.ui

    r33404 r33417  
    1414     hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1515 </comment>
    16  <class>UIExportApplianceWzdPage3</class>
    17  <widget class="QWidget" name="UIExportApplianceWzdPage3">
     16 <class>UIExportApplianceWzdPage2</class>
     17 <widget class="QWidget" name="UIExportApplianceWzdPage2">
    1818  <property name="geometry">
    1919   <rect>
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzdPage3.ui

    r33404 r33417  
    1414     hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1515 </comment>
    16  <class>UIExportApplianceWzdPage4</class>
    17  <widget class="QWidget" name="UIExportApplianceWzdPage4">
     16 <class>UIExportApplianceWzdPage3</class>
     17 <widget class="QWidget" name="UIExportApplianceWzdPage3">
    1818  <property name="geometry">
    1919   <rect>
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIExportApplianceWzdPage4.ui

    r33404 r33417  
    1414     hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1515 </comment>
    16  <class>UIExportApplianceWzdPage2</class>
    17  <widget class="QWidget" name="UIExportApplianceWzdPage2">
     16 <class>UIExportApplianceWzdPage4</class>
     17 <widget class="QWidget" name="UIExportApplianceWzdPage4">
    1818  <property name="geometry">
    1919   <rect>
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r33289 r33417  
    854854}
    855855
    856 void Appliance::parseURI(Utf8Str strUri, LocationInfo &locInfo) const
     856void Appliance::parseBucket(Utf8Str &aPath, Utf8Str &aBucket)
     857{
     858    /* Buckets are S3 specific. So parse the bucket out of the file path */
     859    if (!aPath.startsWith("/"))
     860        throw setError(E_INVALIDARG,
     861                       tr("The path '%s' must start with /"), aPath.c_str());
     862    size_t bpos = aPath.find("/", 1);
     863    if (bpos != Utf8Str::npos)
     864    {
     865        aBucket = aPath.substr(1, bpos - 1); /* The bucket without any slashes */
     866        aPath = aPath.substr(bpos); /* The rest of the file path */
     867    }
     868    /* If there is no bucket name provided reject it */
     869    if (aBucket.isEmpty())
     870        throw setError(E_INVALIDARG,
     871                       tr("You doesn't provide a bucket name in the URI '%s'"), aPath.c_str());
     872}
     873
     874/**
     875 *
     876 * @return
     877 */
     878int Appliance::TaskOVF::startThread()
     879{
     880    int vrc = RTThreadCreate(NULL, Appliance::taskThreadImportOrExport, this,
     881                             0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
     882                             "Appliance::Task");
     883
     884    if (RT_FAILURE(vrc))
     885        return Appliance::setErrorStatic(E_FAIL,
     886                                         Utf8StrFmt("Could not create OVF task thread (%Rrc)\n", vrc));
     887
     888    return S_OK;
     889}
     890
     891/**
     892 * Thread function for the thread started in Appliance::readImpl() and Appliance::importImpl()
     893 * and Appliance::writeImpl().
     894 * This will in turn call Appliance::readFS() or Appliance::readS3() or Appliance::importFS()
     895 * or Appliance::importS3() or Appliance::writeFS() or Appliance::writeS3().
     896 *
     897 * @param aThread
     898 * @param pvUser
     899 */
     900/* static */
     901DECLCALLBACK(int) Appliance::taskThreadImportOrExport(RTTHREAD /* aThread */, void *pvUser)
     902{
     903    std::auto_ptr<TaskOVF> task(static_cast<TaskOVF*>(pvUser));
     904    AssertReturn(task.get(), VERR_GENERAL_FAILURE);
     905
     906    Appliance *pAppliance = task->pAppliance;
     907
     908    LogFlowFuncEnter();
     909    LogFlowFunc(("Appliance %p\n", pAppliance));
     910
     911    HRESULT taskrc = S_OK;
     912
     913    switch (task->taskType)
     914    {
     915        case TaskOVF::Read:
     916            if (task->locInfo.storageType == VFSType_File)
     917                taskrc = pAppliance->readFS(task.get());
     918            else if (task->locInfo.storageType == VFSType_S3)
     919                taskrc = pAppliance->readS3(task.get());
     920        break;
     921
     922        case TaskOVF::Import:
     923            if (task->locInfo.storageType == VFSType_File)
     924                taskrc = pAppliance->importFS(task.get());
     925            else if (task->locInfo.storageType == VFSType_S3)
     926                taskrc = pAppliance->importS3(task.get());
     927        break;
     928
     929        case TaskOVF::Write:
     930            if (task->locInfo.storageType == VFSType_File)
     931                taskrc = pAppliance->writeFS(task.get());
     932            else if (task->locInfo.storageType == VFSType_S3)
     933                taskrc = pAppliance->writeS3(task.get());
     934        break;
     935    }
     936
     937    task->rc = taskrc;
     938
     939    if (!task->pProgress.isNull())
     940        task->pProgress->notifyComplete(taskrc);
     941
     942    LogFlowFuncLeave();
     943
     944    return VINF_SUCCESS;
     945}
     946
     947/* static */
     948int Appliance::TaskOVF::updateProgress(unsigned uPercent, void *pvUser)
     949{
     950    Appliance::TaskOVF* pTask = *(Appliance::TaskOVF**)pvUser;
     951
     952    if (    pTask
     953         && !pTask->pProgress.isNull())
     954    {
     955        BOOL fCanceled;
     956        pTask->pProgress->COMGETTER(Canceled)(&fCanceled);
     957        if (fCanceled)
     958            return -1;
     959        pTask->pProgress->SetCurrentOperationProgress(uPercent);
     960    }
     961    return VINF_SUCCESS;
     962}
     963
     964void parseURI(Utf8Str strUri, LocationInfo &locInfo)
    857965{
    858966    /* Check the URI for the protocol */
     
    9011009}
    9021010
    903 void Appliance::parseBucket(Utf8Str &aPath, Utf8Str &aBucket)
    904 {
    905     /* Buckets are S3 specific. So parse the bucket out of the file path */
    906     if (!aPath.startsWith("/"))
    907         throw setError(E_INVALIDARG,
    908                        tr("The path '%s' must start with /"), aPath.c_str());
    909     size_t bpos = aPath.find("/", 1);
    910     if (bpos != Utf8Str::npos)
    911     {
    912         aBucket = aPath.substr(1, bpos - 1); /* The bucket without any slashes */
    913         aPath = aPath.substr(bpos); /* The rest of the file path */
    914     }
    915     /* If there is no bucket name provided reject it */
    916     if (aBucket.isEmpty())
    917         throw setError(E_INVALIDARG,
    918                        tr("You doesn't provide a bucket name in the URI '%s'"), aPath.c_str());
    919 }
    920 
    921 /**
    922  *
    923  * @return
    924  */
    925 int Appliance::TaskOVF::startThread()
    926 {
    927     int vrc = RTThreadCreate(NULL, Appliance::taskThreadImportOrExport, this,
    928                              0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
    929                              "Appliance::Task");
    930 
    931     if (RT_FAILURE(vrc))
    932         return Appliance::setErrorStatic(E_FAIL,
    933                                          Utf8StrFmt("Could not create OVF task thread (%Rrc)\n", vrc));
    934 
    935     return S_OK;
    936 }
    937 
    938 /**
    939  * Thread function for the thread started in Appliance::readImpl() and Appliance::importImpl()
    940  * and Appliance::writeImpl().
    941  * This will in turn call Appliance::readFS() or Appliance::readS3() or Appliance::importFS()
    942  * or Appliance::importS3() or Appliance::writeFS() or Appliance::writeS3().
    943  *
    944  * @param aThread
    945  * @param pvUser
    946  */
    947 /* static */
    948 DECLCALLBACK(int) Appliance::taskThreadImportOrExport(RTTHREAD /* aThread */, void *pvUser)
    949 {
    950     std::auto_ptr<TaskOVF> task(static_cast<TaskOVF*>(pvUser));
    951     AssertReturn(task.get(), VERR_GENERAL_FAILURE);
    952 
    953     Appliance *pAppliance = task->pAppliance;
    954 
    955     LogFlowFuncEnter();
    956     LogFlowFunc(("Appliance %p\n", pAppliance));
    957 
    958     HRESULT taskrc = S_OK;
    959 
    960     switch (task->taskType)
    961     {
    962         case TaskOVF::Read:
    963             if (task->locInfo.storageType == VFSType_File)
    964                 taskrc = pAppliance->readFS(task.get());
    965             else if (task->locInfo.storageType == VFSType_S3)
    966                 taskrc = pAppliance->readS3(task.get());
    967         break;
    968 
    969         case TaskOVF::Import:
    970             if (task->locInfo.storageType == VFSType_File)
    971                 taskrc = pAppliance->importFS(task.get());
    972             else if (task->locInfo.storageType == VFSType_S3)
    973                 taskrc = pAppliance->importS3(task.get());
    974         break;
    975 
    976         case TaskOVF::Write:
    977             if (task->locInfo.storageType == VFSType_File)
    978                 taskrc = pAppliance->writeFS(task.get());
    979             else if (task->locInfo.storageType == VFSType_S3)
    980                 taskrc = pAppliance->writeS3(task.get());
    981         break;
    982     }
    983 
    984     task->rc = taskrc;
    985 
    986     if (!task->pProgress.isNull())
    987         task->pProgress->notifyComplete(taskrc);
    988 
    989     LogFlowFuncLeave();
    990 
    991     return VINF_SUCCESS;
    992 }
    993 
    994 /* static */
    995 int Appliance::TaskOVF::updateProgress(unsigned uPercent, void *pvUser)
    996 {
    997     Appliance::TaskOVF* pTask = *(Appliance::TaskOVF**)pvUser;
    998 
    999     if (    pTask
    1000          && !pTask->pProgress.isNull())
    1001     {
    1002         BOOL fCanceled;
    1003         pTask->pProgress->COMGETTER(Canceled)(&fCanceled);
    1004         if (fCanceled)
    1005             return -1;
    1006         pTask->pProgress->SetCurrentOperationProgress(uPercent);
    1007     }
    1008     return VINF_SUCCESS;
    1009 }
    1010 
    10111011////////////////////////////////////////////////////////////////////////////////
    10121012//
  • trunk/src/VBox/Main/ApplianceImplExport.cpp

    r33320 r33417  
    5757* @return
    5858*/
    59 
    60 STDMETHODIMP Machine::Export(IAppliance *aAppliance, IVirtualSystemDescription **aDescription)
     59STDMETHODIMP Machine::Export(IAppliance *aAppliance, IN_BSTR location, IVirtualSystemDescription **aDescription)
    6160{
    6261    HRESULT rc = S_OK;
     
    7271    try
    7372    {
     73        Appliance *pAppliance = static_cast<Appliance*>(aAppliance);
     74        AutoCaller autoCaller1(pAppliance);
     75        if (FAILED(autoCaller1.rc())) return autoCaller1.rc();
     76
     77        LocationInfo locInfo;
     78        parseURI(location, locInfo);
    7479        // create a new virtual system to store in the appliance
    7580        rc = pNewDesc.createObject();
     
    342347                if (FAILED(rc)) throw rc;
    343348
    344                 strTargetVmdkName = bstrBaseName;
    345                 strTargetVmdkName.stripExt();
    346                 strTargetVmdkName.append(".vmdk");
     349                Utf8Str strTargetName = Utf8Str(locInfo.strPath).stripPath().stripExt();
     350                strTargetVmdkName = Utf8StrFmt("%s-disk%d.vmdk", strTargetName.c_str(), ++pAppliance->m->cDisks);
    347351
    348352                // force reading state, or else size will be returned as 0
     
    521525                               Utf8StrFmt("%RI32", audioController));
    522526
    523         // finally, add the virtual system to the appliance
    524         Appliance *pAppliance = static_cast<Appliance*>(aAppliance);
    525         AutoCaller autoCaller1(pAppliance);
    526         if (FAILED(autoCaller1.rc())) return autoCaller1.rc();
    527 
    528527        /* We return the new description to the caller */
    529528        ComPtr<IVirtualSystemDescription> copy(pNewDesc);
     
    531530
    532531        AutoWriteLock alock(pAppliance COMMA_LOCKVAL_SRC_POS);
    533 
     532        // finally, add the virtual system to the appliance
    534533        pAppliance->m->virtualSystemDescriptions.push_back(pNewDesc);
    535534    }
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r33386 r33417  
    33793379  <interface
    33803380     name="IMachine" extends="$unknown"
    3381      uuid="8934e426-1c09-459f-bbc4-58dba016fbbe"
     3381     uuid="cc4fec9a-3150-45df-9ee9-f00ba54d6ac3"
    33823382     wsmap="managed"
    33833383     >
     
    50935093      <param name="aAppliance" type="IAppliance" dir="in">
    50945094        <desc>Appliance to export this machine to.</desc>
     5095      </param>
     5096      <param name="location" type="wstring" dir="in">
     5097        <desc>The target location.</desc>
    50955098      </param>
    50965099      <param name="aDescription" type="IVirtualSystemDescription" dir="return">
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r33368 r33417  
    3232class VirtualSystemDescription;
    3333struct VirtualSystemDescriptionEntry;
     34struct LocationInfo;
    3435typedef struct VDINTERFACE   *PVDINTERFACE;
    3536typedef struct VDINTERFACEIO *PVDINTERFACEIO;
     
    120121    struct ImportStack;
    121122    struct TaskOVF;
    122     struct LocationInfo;
    123123    struct Data;            // opaque, defined in ApplianceImpl.cpp
    124124    Data *m;
     
    139139    void addWarning(const char* aWarning, ...);
    140140    void disksWeight();
    141     void parseURI(Utf8Str strUri, LocationInfo &locInfo) const;
    142141    void parseBucket(Utf8Str &aPath, Utf8Str &aBucket);
    143142
     
    223222};
    224223
     224void parseURI(Utf8Str strUri, LocationInfo &locInfo);
     225
    225226struct VirtualSystemDescriptionEntry
    226227{
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r33289 r33417  
    3333/* Describe a location for the import/export. The location could be a file on a
    3434 * local hard disk or a remote target based on the supported inet protocols. */
    35 struct Appliance::LocationInfo
     35struct LocationInfo
    3636{
    3737    LocationInfo()
     
    5353      , fManifest(true)
    5454      , pReader(NULL)
     55      , ulWeightForXmlOperation(0)
     56      , ulWeightForManifestOperation(0)
     57      , ulTotalDisksMB(0)
     58      , cDisks(0)
    5559    {
    5660    }
  • trunk/src/VBox/Main/include/MachineImpl.h

    r33386 r33417  
    490490    STDMETHOD(Unregister)(CleanupMode_T cleanupMode, ComSafeArrayOut(IMedium*, aMedia));
    491491    STDMETHOD(Delete)(ComSafeArrayIn(IMedium*, aMedia), IProgress **aProgress);
    492     STDMETHOD(Export)(IAppliance *aAppliance, IVirtualSystemDescription **aDescription);
     492    STDMETHOD(Export)(IAppliance *aAppliance, IN_BSTR location, IVirtualSystemDescription **aDescription);
    493493    STDMETHOD(FindSnapshot)(IN_BSTR aNameOrId, ISnapshot **aSnapshot);
    494494    STDMETHOD(CreateSharedFolder)(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable, BOOL aAutoMount);
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