- Timestamp:
- Mar 3, 2022 12:03:34 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp
r94070 r94071 2272 2272 } 2273 2273 2274 static HRESULT createLocalGatewayImage(ComPtr<IVirtualBox> virtualBox, const Bstr& aGatewayIso, const Bstr& aGuestAdditionsIso, const Bstr& aProxy)2275 {2276 /* Check if the image already exists. */2277 HRESULT hrc;2278 2279 Bstr strGatewayVM = "lgw";2280 Bstr strUser = "vbox";2281 Bstr strPassword = "vbox";2282 2283 Bstr strInstallerScript;2284 Bstr strPostInstallScript;2285 2286 if (RT_FAILURE(composeTemplatePath("lgw_ks.cfg", strInstallerScript)))2287 return E_FAIL;2288 if (RT_FAILURE(composeTemplatePath("lgw_postinstall.sh", strPostInstallScript)))2289 return E_FAIL;2290 2291 ComPtr<ISystemProperties> systemProperties;2292 ProxyMode_T enmProxyMode;2293 Bstr strProxy;2294 ComPtr<IMedium> hd;2295 Bstr defaultMachineFolder;2296 Bstr guestAdditionsISO;2297 hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());2298 if (errorOccured(hrc, Cloud::tr("Failed to obtain system properties.")))2299 return hrc;2300 if (aProxy.isNotEmpty())2301 strProxy = aProxy;2302 else2303 {2304 hrc = systemProperties->COMGETTER(ProxyMode)(&enmProxyMode);2305 if (errorOccured(hrc, Cloud::tr("Failed to obtain proxy mode.")))2306 return hrc;2307 switch (enmProxyMode)2308 {2309 case ProxyMode_NoProxy:2310 strProxy.setNull();2311 break;2312 case ProxyMode_Manual:2313 hrc = systemProperties->COMGETTER(ProxyURL)(strProxy.asOutParam());2314 if (errorOccured(hrc, Cloud::tr("Failed to obtain proxy URL.")))2315 return hrc;2316 break;2317 case ProxyMode_System:2318 hrc = getSystemProxyForUrl("https://dl.fedoraproject.org", strProxy);2319 if (FAILED(hrc))2320 errorOccured(hrc, Cloud::tr("Failed to get system proxy for https://dl.fedoraproject.org. Will use direct connection."));2321 break;2322 default: /* To get rid of ProxyMode_32BitHack 'warning' */2323 AssertFailed();2324 break;2325 }2326 2327 }2328 hrc = systemProperties->COMGETTER(DefaultMachineFolder)(defaultMachineFolder.asOutParam());2329 if (errorOccured(hrc, Cloud::tr("Failed to obtain default machine folder.")))2330 return hrc;2331 if (aGuestAdditionsIso.isEmpty())2332 {2333 hrc = systemProperties->COMGETTER(DefaultAdditionsISO)(guestAdditionsISO.asOutParam());2334 if (errorOccured(hrc, Cloud::tr("Failed to obtain default guest additions ISO path.")))2335 return hrc;2336 if (guestAdditionsISO.isEmpty())2337 {2338 errorOccured(E_INVALIDARG, Cloud::tr("The default guest additions ISO path is empty nor it is provided as --guest-additions-iso parameter. Cannot proceed without it."));2339 return E_INVALIDARG;2340 }2341 }2342 else2343 guestAdditionsISO = aGuestAdditionsIso;2344 2345 Bstr strGatewayImage;2346 int rc = localGatewayImagePath(defaultMachineFolder, strGatewayImage);2347 if (RT_FAILURE(rc))2348 {2349 RTStrmPrintf(g_pStdErr, Cloud::tr("Failed to compose a path to the local gateway image (%Rrc)"), rc);2350 RTStrmFlush(g_pStdErr);2351 return E_FAIL;2352 }2353 hrc = virtualBox->OpenMedium(strGatewayImage.raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE, hd.asOutParam());2354 /* If the image is already in place, there is nothing for us to do. */2355 if (SUCCEEDED(hrc))2356 {2357 RTPrintf(Cloud::tr("Local gateway image already exists, skipping image preparation step.\n"));2358 return hrc;2359 }2360 2361 RTPrintf(Cloud::tr("Preparing unattended install of temporary local gateway machine from %ls...\n"), aGatewayIso.raw());2362 /* The image does not exist, let's try to open the provided ISO file. */2363 ComPtr<IMedium> iso;2364 hrc = virtualBox->OpenMedium(aGatewayIso.raw(), DeviceType_DVD, AccessMode_ReadOnly, FALSE, iso.asOutParam());2365 if (errorOccured(hrc, Cloud::tr("Failed to open %ls."), aGatewayIso.raw()))2366 return hrc;2367 2368 ComPtr<IMachine> machine;2369 SafeArray<IN_BSTR> groups;2370 groups.push_back(Bstr("/gateways").mutableRaw());2371 hrc = virtualBox->CreateMachine(NULL, strGatewayVM.raw(), ComSafeArrayAsInParam(groups), Bstr("Oracle_64").raw(), Bstr("").raw(), machine.asOutParam());2372 if (errorOccured(hrc, Cloud::tr("Failed to create '%ls'."), strGatewayVM.raw()))2373 return hrc;2374 /* Initial configuration */2375 hrc = machine->ApplyDefaults(NULL);2376 if (errorOccured(hrc, Cloud::tr("Failed to apply defaults to '%ls'."), strGatewayVM.raw()))2377 return hrc;2378 2379 hrc = machine->COMSETTER(CPUCount)(2);2380 if (errorOccured(hrc, Cloud::tr("Failed to adjust CPU count for '%ls'."), strGatewayVM.raw()))2381 return hrc;2382 2383 hrc = machine->COMSETTER(MemorySize)(512/*MB*/);2384 if (errorOccured(hrc, Cloud::tr("Failed to adjust memory size for '%ls'."), strGatewayVM.raw()))2385 return hrc;2386 2387 /* No need for audio -- disable it. */2388 ComPtr<IAudioAdapter> audioAdapter;2389 hrc = machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());2390 if (errorOccured(hrc, Cloud::tr("Failed to set attachment type for the second network adapter.")))2391 return hrc;2392 2393 hrc = audioAdapter->COMSETTER(Enabled)(FALSE);2394 if (errorOccured(hrc, Cloud::tr("Failed to disable the audio adapter.")))2395 return hrc;2396 audioAdapter.setNull();2397 2398 hrc = virtualBox->RegisterMachine(machine);2399 if (errorOccured(hrc, Cloud::tr("Failed to register '%ls'."), strGatewayVM.raw()))2400 return hrc;2401 2402 hrc = virtualBox->CreateMedium(Bstr("VDI").raw(), strGatewayImage.raw(), AccessMode_ReadWrite, DeviceType_HardDisk, hd.asOutParam());2403 if (errorOccured(hrc, Cloud::tr("Failed to create %ls."), strGatewayImage.raw()))2404 return hrc;2405 2406 ComPtr<IProgress> progress;2407 com::SafeArray<MediumVariant_T> mediumVariant;2408 mediumVariant.push_back(MediumVariant_Standard);2409 2410 /* Kick off the creation of a dynamic growing disk image with the given capacity. */2411 hrc = hd->CreateBaseStorage(8ll * 1000 * 1000 * 1000 /* 8GB */,2412 ComSafeArrayAsInParam(mediumVariant),2413 progress.asOutParam());2414 if (errorOccured(hrc, Cloud::tr("Failed to create base storage for local gateway image.")))2415 return hrc;2416 2417 hrc = showProgress(progress);2418 CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Failed to create base storage for local gateway image.")), hrc);2419 2420 ComPtr<ISession> session;2421 hrc = session.createInprocObject(CLSID_Session);2422 hrc = machine->LockMachine(session, LockType_Write);2423 if (errorOccured(hrc, Cloud::tr("Failed to lock '%ls' for modifications."), strGatewayVM.raw()))2424 return hrc;2425 2426 ComPtr<IMachine> sessionMachine;2427 hrc = session->COMGETTER(Machine)(sessionMachine.asOutParam());2428 if (errorOccured(hrc, Cloud::tr("Failed to obtain a mutable machine.")))2429 return hrc;2430 2431 hrc = sessionMachine->AttachDevice(Bstr("SATA").raw(), 0, 0, DeviceType_HardDisk, hd);2432 if (errorOccured(hrc, Cloud::tr("Failed to attach HD to '%ls'."), strGatewayVM.raw()))2433 return hrc;2434 2435 hrc = sessionMachine->AttachDevice(Bstr("IDE").raw(), 0, 0, DeviceType_DVD, iso);2436 if (errorOccured(hrc, Cloud::tr("Failed to attach ISO to '%ls'."), strGatewayVM.raw()))2437 return hrc;2438 2439 /* Save settings */2440 hrc = sessionMachine->SaveSettings();2441 if (errorOccured(hrc, Cloud::tr("Failed to save '%ls' settings."), strGatewayVM.raw()))2442 return hrc;2443 session->UnlockMachine();2444 2445 /* Prepare unattended install */2446 ComPtr<IUnattended> unattended;2447 hrc = virtualBox->CreateUnattendedInstaller(unattended.asOutParam());2448 if (errorOccured(hrc, Cloud::tr("Failed to create unattended installer.")))2449 return hrc;2450 2451 hrc = unattended->COMSETTER(Machine)(machine);2452 if (errorOccured(hrc, Cloud::tr("Failed to set machine for the unattended installer.")))2453 return hrc;2454 2455 hrc = unattended->COMSETTER(IsoPath)(aGatewayIso.raw());2456 if (errorOccured(hrc, Cloud::tr("Failed to set machine for the unattended installer.")))2457 return hrc;2458 2459 hrc = unattended->COMSETTER(User)(strUser.raw());2460 if (errorOccured(hrc, Cloud::tr("Failed to set user for the unattended installer.")))2461 return hrc;2462 2463 hrc = unattended->COMSETTER(Password)(strPassword.raw());2464 if (errorOccured(hrc, Cloud::tr("Failed to set password for the unattended installer.")))2465 return hrc;2466 2467 hrc = unattended->COMSETTER(FullUserName)(strUser.raw());2468 if (errorOccured(hrc, Cloud::tr("Failed to set full user name for the unattended installer.")))2469 return hrc;2470 2471 hrc = unattended->COMSETTER(InstallGuestAdditions)(TRUE);2472 if (errorOccured(hrc, Cloud::tr("Failed to enable guest addtions for the unattended installer.")))2473 return hrc;2474 2475 hrc = unattended->COMSETTER(AdditionsIsoPath)(guestAdditionsISO.raw());2476 if (errorOccured(hrc, Cloud::tr("Failed to set guest addtions ISO path for the unattended installer.")))2477 return hrc;2478 2479 hrc = unattended->COMSETTER(ScriptTemplatePath)(strInstallerScript.raw());2480 if (errorOccured(hrc, Cloud::tr("Failed to set script template for the unattended installer.")))2481 return hrc;2482 2483 hrc = unattended->COMSETTER(PostInstallScriptTemplatePath)(strPostInstallScript.raw());2484 if (errorOccured(hrc, Cloud::tr("Failed to set post install script template for the unattended installer.")))2485 return hrc;2486 2487 if (strProxy.isNotEmpty())2488 {2489 hrc = unattended->COMSETTER(Proxy)(strProxy.raw());2490 if (errorOccured(hrc, Cloud::tr("Failed to set post install script template for the unattended installer.")))2491 return hrc;2492 }2493 2494 hrc = unattended->Prepare();2495 if (errorOccured(hrc, Cloud::tr("Failed to prepare unattended installation.")))2496 return hrc;2497 2498 hrc = unattended->ConstructMedia();2499 if (errorOccured(hrc, Cloud::tr("Failed to construct media for unattended installation.")))2500 return hrc;2501 2502 hrc = unattended->ReconfigureVM();2503 if (errorOccured(hrc, Cloud::tr("Failed to reconfigure %ls for unattended installation."), strGatewayVM.raw()))2504 return hrc;2505 2506 #define SHOW_ATTR(a_Attr, a_szText, a_Type, a_szFmt) do { \2507 a_Type Value; \2508 HRESULT hrc2 = unattended->COMGETTER(a_Attr)(&Value); \2509 if (SUCCEEDED(hrc2)) \2510 RTPrintf(" %32s = " a_szFmt "\n", a_szText, Value); \2511 else \2512 RTPrintf(Cloud::tr(" %32s = failed: %Rhrc\n"), a_szText, hrc2); \2513 } while (0)2514 #define SHOW_STR_ATTR(a_Attr, a_szText) do { \2515 Bstr bstrString; \2516 HRESULT hrc2 = unattended->COMGETTER(a_Attr)(bstrString.asOutParam()); \2517 if (SUCCEEDED(hrc2)) \2518 RTPrintf(" %32s = %ls\n", a_szText, bstrString.raw()); \2519 else \2520 RTPrintf(Cloud::tr(" %32s = failed: %Rhrc\n"), a_szText, hrc2); \2521 } while (0)2522 2523 SHOW_STR_ATTR(IsoPath, "isoPath");2524 SHOW_STR_ATTR(User, "user");2525 SHOW_STR_ATTR(Password, "password");2526 SHOW_STR_ATTR(FullUserName, "fullUserName");2527 SHOW_STR_ATTR(ProductKey, "productKey");2528 SHOW_STR_ATTR(AdditionsIsoPath, "additionsIsoPath");2529 SHOW_ATTR( InstallGuestAdditions, "installGuestAdditions", BOOL, "%RTbool");2530 SHOW_STR_ATTR(ValidationKitIsoPath, "validationKitIsoPath");2531 SHOW_ATTR( InstallTestExecService, "installTestExecService", BOOL, "%RTbool");2532 SHOW_STR_ATTR(Locale, "locale");2533 SHOW_STR_ATTR(Country, "country");2534 SHOW_STR_ATTR(TimeZone, "timeZone");2535 SHOW_STR_ATTR(Proxy, "proxy");2536 SHOW_STR_ATTR(Hostname, "hostname");2537 SHOW_STR_ATTR(PackageSelectionAdjustments, "packageSelectionAdjustments");2538 SHOW_STR_ATTR(AuxiliaryBasePath, "auxiliaryBasePath");2539 SHOW_ATTR( ImageIndex, "imageIndex", ULONG, "%u");2540 SHOW_STR_ATTR(ScriptTemplatePath, "scriptTemplatePath");2541 SHOW_STR_ATTR(PostInstallScriptTemplatePath, "postInstallScriptTemplatePath");2542 SHOW_STR_ATTR(PostInstallCommand, "postInstallCommand");2543 SHOW_STR_ATTR(ExtraInstallKernelParameters, "extraInstallKernelParameters");2544 SHOW_STR_ATTR(Language, "language");2545 SHOW_STR_ATTR(DetectedOSTypeId, "detectedOSTypeId");2546 SHOW_STR_ATTR(DetectedOSVersion, "detectedOSVersion");2547 SHOW_STR_ATTR(DetectedOSFlavor, "detectedOSFlavor");2548 SHOW_STR_ATTR(DetectedOSLanguages, "detectedOSLanguages");2549 SHOW_STR_ATTR(DetectedOSHints, "detectedOSHints");2550 2551 #undef SHOW_STR_ATTR2552 #undef SHOW_ATTR2553 2554 /* 'unattended' is no longer needed. */2555 unattended.setNull();2556 2557 RTPrintf(Cloud::tr("Performing unattended install of temporary local gateway...\n"));2558 2559 hrc = machine->LaunchVMProcess(session, Bstr("gui").raw(), ComSafeArrayNullInParam(), progress.asOutParam());2560 if (errorOccured(hrc, Cloud::tr("Failed to launch '%ls'."), strGatewayVM.raw()))2561 return hrc;2562 2563 hrc = progress->WaitForCompletion(-1);2564 if (errorOccured(hrc, Cloud::tr("Failed to launch '%ls'."), strGatewayVM.raw()))2565 return hrc;2566 2567 unsigned i = 0;2568 const char progressChars[] = { '|', '/', '-', '\\'};2569 MachineState_T machineState;2570 uint64_t u64Started = RTTimeMilliTS();2571 do2572 {2573 RTThreadSleep(1000); /* One second */2574 hrc = machine->COMGETTER(State)(&machineState);2575 if (errorOccured(hrc, Cloud::tr("Failed to get machine state.")))2576 break;2577 RTPrintf("\r%c", progressChars[i++ % sizeof(progressChars)]);2578 if (machineState == MachineState_Aborted)2579 {2580 errorOccured(E_ABORT, Cloud::tr("Temporary local gateway VM has aborted."));2581 return E_ABORT;2582 }2583 }2584 while (machineState != MachineState_PoweredOff && RTTimeMilliTS() - u64Started < 40 * 60 * 1000);2585 2586 if (machineState != MachineState_PoweredOff)2587 {2588 errorOccured(E_ABORT, Cloud::tr("Timed out (40min) while waiting for unattended install to finish."));2589 return E_ABORT;2590 }2591 /* Machine will still be immutable for a short while after powering off, let's wait a little. */2592 RTThreadSleep(5000); /* Five seconds */2593 2594 RTPrintf(Cloud::tr("\rDone.\n"));2595 2596 hrc = machine->LockMachine(session, LockType_Write);2597 if (errorOccured(hrc, Cloud::tr("Failed to lock '%ls' for modifications."), strGatewayVM.raw()))2598 return hrc;2599 2600 RTPrintf(Cloud::tr("Detaching local gateway image...\n"));2601 hrc = session->COMGETTER(Machine)(sessionMachine.asOutParam());2602 if (errorOccured(hrc, Cloud::tr("Failed to obtain a mutable machine.")))2603 return hrc;2604 2605 hrc = sessionMachine->DetachDevice(Bstr("SATA").raw(), 0, 0);2606 if (errorOccured(hrc, Cloud::tr("Failed to detach HD to '%ls'."), strGatewayVM.raw()))2607 return hrc;2608 2609 /* Remove the image from the media registry. */2610 hd->Close();2611 2612 /* Save settings */2613 hrc = sessionMachine->SaveSettings();2614 if (errorOccured(hrc, Cloud::tr("Failed to save '%ls' settings."), strGatewayVM.raw()))2615 return hrc;2616 session->UnlockMachine();2617 2618 #if 02619 /** @todo Unregistering the temporary VM makes the image mutable again. Find out the way around it! */2620 RTPrintf(Cloud::tr("Unregistering temporary local gateway machine...\n"));2621 SafeIfaceArray<IMedium> media;2622 hrc = machine->Unregister(CleanupMode_DetachAllReturnNone, ComSafeArrayAsOutParam(media));2623 if (errorOccured(hrc, Cloud::tr("Failed to unregister '%ls'."), strGatewayVM.raw()))2624 return hrc;2625 hrc = machine->DeleteConfig(ComSafeArrayAsInParam(media), progress.asOutParam());2626 if (errorOccured(hrc, Cloud::tr("Failed to delete config for '%ls'."), strGatewayVM.raw()))2627 return hrc;2628 hrc = progress->WaitForCompletion(-1);2629 if (errorOccured(hrc, Cloud::tr("Failed to delete config for '%ls'."), strGatewayVM.raw()))2630 return hrc;2631 #endif2632 2633 RTPrintf(Cloud::tr("Making local gateway image immutable...\n"));2634 hrc = virtualBox->OpenMedium(strGatewayImage.raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE, hd.asOutParam());2635 if (errorOccured(hrc, Cloud::tr("Failed to open '%ls'."), strGatewayImage.raw()))2636 return hrc;2637 hd->COMSETTER(Type)(MediumType_Immutable);2638 if (errorOccured(hrc, Cloud::tr("Failed to make '%ls' immutable."), strGatewayImage.raw()))2639 return hrc;2640 2641 return S_OK;2642 }2643 2644 2645 2274 static RTEXITCODE setupCloudNetworkEnv(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts) 2646 2275 {
Note:
See TracChangeset
for help on using the changeset viewer.