Changeset 59577 in vbox for trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
- Timestamp:
- Feb 4, 2016 2:18:36 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 105389
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
r58005 r59577 729 729 * Appliance::taskThreadWriteOVF(). 730 730 * 731 * This is in a separate private method because it is used from two locations:731 * This is in a separate private method because it is used from one location: 732 732 * 733 733 * 1) from the public Appliance::Write(). … … 735 735 * 2) in a second worker thread; in that case, Appliance::Write() called Appliance::i_writeImpl(), which 736 736 * called Appliance::i_writeFSOVA(), which called Appliance::i_writeImpl(), which then called this again. 737 *738 * 3) from Appliance::i_writeS3(), which got called from a previous instance of Appliance::taskThreadWriteOVF().739 737 * 740 738 * @param aFormat … … 1926 1924 /** 1927 1925 * Actual worker code for writing out OVF/OVA to disk. This is called from Appliance::taskThreadWriteOVF() 1928 * and therefore runs on the OVF/OVA write worker thread. This runs in two contexts: 1926 * and therefore runs on the OVF/OVA write worker thread. 1927 * 1928 * This runs in one context: 1929 1929 * 1930 1930 * 1) in a first worker thread; in that case, Appliance::Write() called Appliance::i_writeImpl(); 1931 *1932 * 2) in a second worker thread; in that case, Appliance::Write() called Appliance::i_writeImpl(), which1933 * called Appliance::i_writeS3(), which called Appliance::i_writeImpl(), which then called this. In other1934 * words, to write to the cloud, the first worker thread first starts a second worker thread to create1935 * temporary files and then uploads them to the S3 cloud server.1936 1931 * 1937 1932 * @param pTask … … 2390 2385 } 2391 2386 2392 #ifdef VBOX_WITH_S32393 /**2394 * Worker code for writing out OVF to the cloud. This is called from Appliance::taskThreadWriteOVF()2395 * in S3 mode and therefore runs on the OVF write worker thread. This then starts a second worker2396 * thread to create temporary files (see Appliance::i_writeFS()).2397 *2398 * @param pTask2399 * @return2400 */2401 HRESULT Appliance::i_writeS3(TaskOVF *pTask)2402 {2403 LogFlowFuncEnter();2404 LogFlowFunc(("Appliance %p\n", this));2405 2406 AutoCaller autoCaller(this);2407 if (FAILED(autoCaller.rc())) return autoCaller.rc();2408 2409 HRESULT rc = S_OK;2410 2411 AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);2412 2413 int vrc = VINF_SUCCESS;2414 RTS3 hS3 = NIL_RTS3;2415 char szOSTmpDir[RTPATH_MAX];2416 RTPathTemp(szOSTmpDir, sizeof(szOSTmpDir));2417 /* The template for the temporary directory created below */2418 char *pszTmpDir = RTPathJoinA(szOSTmpDir, "vbox-ovf-XXXXXX");2419 list< pair<Utf8Str, ULONG> > filesList;2420 2421 // todo:2422 // - usable error codes2423 // - seems snapshot filenames are problematic {uuid}.vdi2424 try2425 {2426 /* Extract the bucket */2427 Utf8Str tmpPath = pTask->locInfo.strPath;2428 Utf8Str bucket;2429 i_parseBucket(tmpPath, bucket);2430 2431 /* We need a temporary directory which we can put the OVF file & all2432 * disk images in */2433 vrc = RTDirCreateTemp(pszTmpDir, 0700);2434 if (RT_FAILURE(vrc))2435 throw setError(VBOX_E_FILE_ERROR,2436 tr("Cannot create temporary directory '%s' (%Rrc)"), pszTmpDir, vrc);2437 2438 /* The temporary name of the target OVF file */2439 Utf8StrFmt strTmpOvf("%s/%s", pszTmpDir, RTPathFilename(tmpPath.c_str()));2440 2441 /* Prepare the temporary writing of the OVF */2442 ComObjPtr<Progress> progress;2443 /* Create a temporary file based location info for the sub task */2444 LocationInfo li;2445 li.strPath = strTmpOvf;2446 rc = i_writeImpl(pTask->enFormat, li, progress);2447 if (FAILED(rc)) throw rc;2448 2449 /* Unlock the appliance for the writing thread */2450 appLock.release();2451 /* Wait until the writing is done, but report the progress back to the2452 caller */2453 ComPtr<IProgress> progressInt(progress);2454 i_waitForAsyncProgress(pTask->pProgress, progressInt); /* Any errors will be thrown */2455 2456 /* Again lock the appliance for the next steps */2457 appLock.acquire();2458 2459 vrc = RTPathExists(strTmpOvf.c_str()); /* Paranoid check */2460 if (RT_FAILURE(vrc))2461 throw setError(VBOX_E_FILE_ERROR,2462 tr("Cannot find source file '%s' (%Rrc)"), strTmpOvf.c_str(), vrc);2463 /* Add the OVF file */2464 filesList.push_back(pair<Utf8Str, ULONG>(strTmpOvf, m->ulWeightForXmlOperation)); /* Use 1% of the2465 total for the OVF file upload */2466 /* Add the manifest file */2467 if (m->fManifest)2468 {2469 Utf8Str strMfFile = Utf8Str(strTmpOvf).stripSuffix().append(".mf");2470 filesList.push_back(pair<Utf8Str, ULONG>(strMfFile , m->ulWeightForXmlOperation)); /* Use 1% of the total2471 for the manifest file upload */2472 }2473 2474 /* Now add every disks of every virtual system */2475 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;2476 for (it = m->virtualSystemDescriptions.begin();2477 it != m->virtualSystemDescriptions.end();2478 ++it)2479 {2480 ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);2481 std::list<VirtualSystemDescriptionEntry*> avsdeHDs =2482 vsdescThis->i_findByType(VirtualSystemDescriptionType_HardDiskImage);2483 std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;2484 for (itH = avsdeHDs.begin();2485 itH != avsdeHDs.end();2486 ++itH)2487 {2488 const Utf8Str &strTargetFileNameOnly = (*itH)->strOvf;2489 /* Target path needs to be composed from where the output OVF is */2490 Utf8Str strTargetFilePath(strTmpOvf);2491 strTargetFilePath.stripFilename();2492 strTargetFilePath.append("/");2493 strTargetFilePath.append(strTargetFileNameOnly);2494 vrc = RTPathExists(strTargetFilePath.c_str()); /* Paranoid check */2495 if (RT_FAILURE(vrc))2496 throw setError(VBOX_E_FILE_ERROR,2497 tr("Cannot find source file '%s' (%Rrc)"), strTargetFilePath.c_str(), vrc);2498 filesList.push_back(pair<Utf8Str, ULONG>(strTargetFilePath, (*itH)->ulSizeMB));2499 }2500 }2501 /* Next we have to upload the OVF & all disk images */2502 vrc = RTS3Create(&hS3, pTask->locInfo.strUsername.c_str(), pTask->locInfo.strPassword.c_str(),2503 pTask->locInfo.strHostname.c_str(), "virtualbox-agent/" VBOX_VERSION_STRING);2504 if (RT_FAILURE(vrc))2505 throw setError(VBOX_E_IPRT_ERROR,2506 tr("Cannot create S3 service handler"));2507 RTS3SetProgressCallback(hS3, pTask->updateProgress, &pTask);2508 2509 /* Upload all files */2510 for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)2511 {2512 const pair<Utf8Str, ULONG> &s = (*it1);2513 char *pszFilename = RTPathFilename(s.first.c_str());2514 /* Advance to the next operation */2515 pTask->pProgress->SetNextOperation(BstrFmt(tr("Uploading file '%s'"), pszFilename).raw(), s.second);2516 vrc = RTS3PutKey(hS3, bucket.c_str(), pszFilename, s.first.c_str());2517 if (RT_FAILURE(vrc))2518 {2519 if (vrc == VERR_S3_CANCELED)2520 break;2521 else if (vrc == VERR_S3_ACCESS_DENIED)2522 throw setError(E_ACCESSDENIED,2523 tr("Cannot upload file '%s' to S3 storage server (Access denied). Make sure that your credentials are right. Also check that your host clock is properly synced"), pszFilename);2524 else if (vrc == VERR_S3_NOT_FOUND)2525 throw setError(VBOX_E_FILE_ERROR,2526 tr("Cannot upload file '%s' to S3 storage server (File not found)"), pszFilename);2527 else2528 throw setError(VBOX_E_IPRT_ERROR,2529 tr("Cannot upload file '%s' to S3 storage server (%Rrc)"), pszFilename, vrc);2530 }2531 }2532 }2533 catch(HRESULT aRC)2534 {2535 rc = aRC;2536 }2537 /* Cleanup */2538 RTS3Destroy(hS3);2539 /* Delete all files which where temporary created */2540 for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)2541 {2542 const char *pszFilePath = (*it1).first.c_str();2543 if (RTPathExists(pszFilePath))2544 {2545 vrc = RTFileDelete(pszFilePath);2546 if (RT_FAILURE(vrc))2547 rc = setError(VBOX_E_FILE_ERROR,2548 tr("Cannot delete file '%s' (%Rrc)"), pszFilePath, vrc);2549 }2550 }2551 /* Delete the temporary directory */2552 if (RTPathExists(pszTmpDir))2553 {2554 vrc = RTDirRemove(pszTmpDir);2555 if (RT_FAILURE(vrc))2556 rc = setError(VBOX_E_FILE_ERROR,2557 tr("Cannot delete temporary directory '%s' (%Rrc)"), pszTmpDir, vrc);2558 }2559 if (pszTmpDir)2560 RTStrFree(pszTmpDir);2561 2562 LogFlowFunc(("rc=%Rhrc\n", rc));2563 LogFlowFuncLeave();2564 2565 return rc;2566 }2567 #endif /* VBOX_WITH_S3 */
Note:
See TracChangeset
for help on using the changeset viewer.