VirtualBox

Changeset 84639 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Jun 2, 2020 1:41:42 PM (5 years ago)
Author:
vboxsync
Message:

OCI: (bugref:9469) cloud network environment setup (local part).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp

    r84618 r84639  
    3131#include <iprt/file.h>
    3232#include <VBox/log.h>
     33
     34#include <iprt/cpp/path.h>
    3335
    3436#include "VBoxManage.h"
     
    20842086
    20852087
     2088static bool errorOccured(HRESULT hrc, const char *pszFormat, ...)
     2089{
     2090    if (FAILED(hrc))
     2091    {
     2092        va_list va;
     2093        va_start(va, pszFormat);
     2094        Utf8Str strError(pszFormat, va);
     2095        va_end(va);
     2096        RTStrmPrintf(g_pStdErr, "%s (rc=%x)\n", strError.c_str(), hrc);
     2097        RTStrmFlush(g_pStdErr);
     2098        return true;
     2099    }
     2100    return false;
     2101}
     2102
     2103
     2104static int composeTemplatePath(const char *pcszTemplate, Bstr& strFullPath)
     2105{
     2106    com::Utf8Str strTemplatePath;
     2107    int rc = RTPathAppPrivateNoArchCxx(strTemplatePath);
     2108    if (RT_SUCCESS(rc))
     2109        rc = RTPathAppendCxx(strTemplatePath, "UnattendedTemplates");
     2110    if (RT_SUCCESS(rc))
     2111        rc = RTPathAppendCxx(strTemplatePath, pcszTemplate);
     2112    if (RT_FAILURE(rc))
     2113    {
     2114        RTStrmPrintf(g_pStdErr, "Failed to compose path to the unattended installer script templates (%Rrc)", rc);
     2115        RTStrmFlush(g_pStdErr);
     2116    }
     2117    else
     2118        strFullPath = strTemplatePath;
     2119
     2120    return rc;
     2121}
     2122
     2123static HRESULT createLocalGatewayImage(ComPtr<IVirtualBox> virtualBox, const Bstr& aGatewayIso, const Bstr& aGuestAdditionsIso)
     2124{
     2125    /* Check if the image already exists. */
     2126    HRESULT hrc;
     2127
     2128    Bstr strGatewayVM = "lgw";
     2129    Bstr strUser = "vbox";          /* @todo Remove?! */
     2130    Bstr strPassword = "vbox";      /* @todo Remove?! */
     2131
     2132    Bstr strInstallerScript;
     2133    Bstr strPostInstallScript;
     2134
     2135    if (RT_FAILURE(composeTemplatePath("lgw_ks.cfg", strInstallerScript)))
     2136        return E_FAIL;
     2137    if (RT_FAILURE(composeTemplatePath("lgw_postinstall.sh", strPostInstallScript)))
     2138        return E_FAIL;
     2139
     2140    ComPtr<ISystemProperties> systemProperties;
     2141    ComPtr<IMedium> hd;
     2142    Bstr defaultMachineFolder;
     2143    Bstr guestAdditionsISO;
     2144    hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
     2145    if (errorOccured(hrc, "Failed to obtain system properties."))
     2146        return hrc;
     2147    hrc = systemProperties->COMGETTER(DefaultMachineFolder)(defaultMachineFolder.asOutParam());
     2148    if (errorOccured(hrc, "Failed to obtain default machine folder."))
     2149        return hrc;
     2150    if (aGuestAdditionsIso.isEmpty())
     2151    {
     2152        hrc = systemProperties->COMGETTER(DefaultAdditionsISO)(guestAdditionsISO.asOutParam());
     2153        if (errorOccured(hrc, "Failed to obtain default guest additions ISO path."))
     2154            return hrc;
     2155        if (guestAdditionsISO.isEmpty())
     2156        {
     2157            errorOccured(E_INVALIDARG, "The default guest additions ISO path is empty nor it is provided as --guest-additions-iso parameter. Cannot proceed without it.");
     2158            return E_INVALIDARG;
     2159        }
     2160    }
     2161    else
     2162        guestAdditionsISO = aGuestAdditionsIso;
     2163
     2164    BstrFmt strGatewayImage("%ls\\gateways\\lgw.vdi", defaultMachineFolder.raw());
     2165    hrc = virtualBox->OpenMedium(strGatewayImage.raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE, hd.asOutParam());
     2166    /* If the image is already in place, there is nothing for us to do. */
     2167    if (SUCCEEDED(hrc))
     2168    {
     2169        RTPrintf("Local gateway image already exists, skipping image preparation step.\n");
     2170        return hrc;
     2171    }
     2172
     2173    RTPrintf("Preparing unattended install of temporary local gateway machine from %ls...\n", aGatewayIso.raw());
     2174    /* The image does not exist, let's try to open the provided ISO file. */
     2175    ComPtr<IMedium> iso;
     2176    hrc = virtualBox->OpenMedium(aGatewayIso.raw(), DeviceType_DVD, AccessMode_ReadOnly, FALSE, iso.asOutParam());
     2177    if (errorOccured(hrc, "Failed to open %ls.", aGatewayIso.raw()))
     2178        return hrc;
     2179
     2180    ComPtr<IMachine> machine;
     2181    SafeArray<IN_BSTR> groups;
     2182    groups.push_back(Bstr("/gateways").mutableRaw());
     2183    hrc = virtualBox->CreateMachine(NULL, strGatewayVM.raw(), ComSafeArrayAsInParam(groups), Bstr("Oracle_64").raw(), Bstr("").raw(), machine.asOutParam());
     2184    if (errorOccured(hrc, "Failed to create '%ls'.", strGatewayVM.raw()))
     2185        return hrc;
     2186    /* Initial configuration */
     2187    hrc = machine->ApplyDefaults(NULL);
     2188    if (errorOccured(hrc, "Failed to apply defaults to '%ls'.", strGatewayVM.raw()))
     2189        return hrc;
     2190
     2191    hrc = machine->COMSETTER(MemorySize)(512/*MB*/);
     2192    if (errorOccured(hrc, "Failed to adjust memory size for '%ls'.", strGatewayVM.raw()))
     2193        return hrc;
     2194
     2195    /* No need for audio -- disable it. */
     2196    ComPtr<IAudioAdapter> audioAdapter;
     2197    hrc = machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
     2198    if (errorOccured(hrc, "Failed to set attachment type for the second network adapter."))
     2199        return hrc;
     2200
     2201    hrc = audioAdapter->COMSETTER(Enabled)(FALSE);
     2202    if (errorOccured(hrc, "Failed to disable the audio adapter."))
     2203        return hrc;
     2204    audioAdapter.setNull();
     2205
     2206    hrc = virtualBox->RegisterMachine(machine);
     2207    if (errorOccured(hrc, "Failed to register '%ls'.", strGatewayVM.raw()))
     2208        return hrc;
     2209
     2210    hrc = virtualBox->CreateMedium(Bstr("VDI").raw(), strGatewayImage.raw(), AccessMode_ReadWrite, DeviceType_HardDisk, hd.asOutParam());
     2211    if (errorOccured(hrc, "Failed to create %ls.", strGatewayImage.raw()))
     2212        return hrc;
     2213
     2214    ComPtr<IProgress> progress;
     2215    com::SafeArray<MediumVariant_T>  mediumVariant;
     2216    mediumVariant.push_back(MediumVariant_Standard);
     2217
     2218    /* Kick off the creation of a dynamic growing disk image with the given capacity. */
     2219    hrc = hd->CreateBaseStorage(8ll * 1000 * 1000 * 1000 /* 8GB */,
     2220                                ComSafeArrayAsInParam(mediumVariant),
     2221                                progress.asOutParam());
     2222    if (errorOccured(hrc, "Failed to create base storage for local gateway image."))
     2223        return hrc;
     2224
     2225    hrc = showProgress(progress);
     2226    CHECK_PROGRESS_ERROR_RET(progress, ("Failed to create base storage for local gateway image."), hrc);
     2227
     2228    ComPtr<ISession> session;
     2229    hrc = session.createInprocObject(CLSID_Session);
     2230    hrc = machine->LockMachine(session, LockType_Write);
     2231    if (errorOccured(hrc, "Failed to lock '%ls' for modifications.", strGatewayVM.raw()))
     2232        return hrc;
     2233
     2234    ComPtr<IMachine> sessionMachine;
     2235    hrc = session->COMGETTER(Machine)(sessionMachine.asOutParam());
     2236    if (errorOccured(hrc, "Failed to obtain a mutable machine."))
     2237        return hrc;
     2238
     2239    hrc = sessionMachine->AttachDevice(Bstr("SATA").raw(), 0, 0, DeviceType_HardDisk, hd);
     2240    if (errorOccured(hrc, "Failed to attach HD to '%ls'.", strGatewayVM.raw()))
     2241        return hrc;
     2242
     2243    hrc = sessionMachine->AttachDevice(Bstr("IDE").raw(), 0, 0, DeviceType_DVD, iso);
     2244    if (errorOccured(hrc, "Failed to attach ISO to '%ls'.", strGatewayVM.raw()))
     2245        return hrc;
     2246
     2247    /* Save settings */
     2248    hrc = sessionMachine->SaveSettings();
     2249    if (errorOccured(hrc, "Failed to save '%ls' settings.", strGatewayVM.raw()))
     2250        return hrc;
     2251    session->UnlockMachine();
     2252
     2253    /* Prepare unattended install */
     2254    ComPtr<IUnattended> unattended;
     2255    hrc = virtualBox->CreateUnattendedInstaller(unattended.asOutParam());
     2256    if (errorOccured(hrc, "Failed to create unattended installer."))
     2257        return hrc;
     2258
     2259    hrc = unattended->COMSETTER(Machine)(machine);
     2260    if (errorOccured(hrc, "Failed to set machine for the unattended installer."))
     2261        return hrc;
     2262
     2263    hrc = unattended->COMSETTER(IsoPath)(aGatewayIso.raw());
     2264    if (errorOccured(hrc, "Failed to set machine for the unattended installer."))
     2265        return hrc;
     2266
     2267    hrc = unattended->COMSETTER(User)(strUser.raw());
     2268    if (errorOccured(hrc, "Failed to set user for the unattended installer."))
     2269        return hrc;
     2270
     2271    hrc = unattended->COMSETTER(Password)(strPassword.raw());
     2272    if (errorOccured(hrc, "Failed to set password for the unattended installer."))
     2273        return hrc;
     2274
     2275    hrc = unattended->COMSETTER(FullUserName)(strUser.raw());
     2276    if (errorOccured(hrc, "Failed to set full user name for the unattended installer."))
     2277        return hrc;
     2278
     2279    hrc = unattended->COMSETTER(InstallGuestAdditions)(TRUE);
     2280    if (errorOccured(hrc, "Failed to enable guest addtions for the unattended installer."))
     2281        return hrc;
     2282
     2283    hrc = unattended->COMSETTER(AdditionsIsoPath)(guestAdditionsISO.raw());
     2284    if (errorOccured(hrc, "Failed to set guest addtions ISO path for the unattended installer."))
     2285        return hrc;
     2286
     2287    hrc = unattended->COMSETTER(ScriptTemplatePath)(strInstallerScript.raw());
     2288    if (errorOccured(hrc, "Failed to set script template for the unattended installer."))
     2289        return hrc;
     2290
     2291    hrc = unattended->COMSETTER(PostInstallScriptTemplatePath)(strPostInstallScript.raw());
     2292    if (errorOccured(hrc, "Failed to set post install script template for the unattended installer."))
     2293        return hrc;
     2294
     2295    hrc = unattended->Prepare();
     2296    if (errorOccured(hrc, "Failed to prepare unattended installation."))
     2297        return hrc;
     2298
     2299    hrc = unattended->ConstructMedia();
     2300    if (errorOccured(hrc, "Failed to construct media for unattended installation."))
     2301        return hrc;
     2302
     2303    hrc = unattended->ReconfigureVM();
     2304    if (errorOccured(hrc, "Failed to reconfigure %ls for unattended installation.", strGatewayVM.raw()))
     2305        return hrc;
     2306
     2307#define SHOW_ATTR(a_Attr, a_szText, a_Type, a_szFmt) do { \
     2308            a_Type Value; \
     2309            HRESULT hrc2 = unattended->COMGETTER(a_Attr)(&Value); \
     2310            if (SUCCEEDED(hrc2)) \
     2311                RTPrintf("  %32s = " a_szFmt "\n", a_szText, Value); \
     2312            else \
     2313                RTPrintf("  %32s = failed: %Rhrc\n", a_szText, hrc2); \
     2314        } while (0)
     2315#define SHOW_STR_ATTR(a_Attr, a_szText) do { \
     2316            Bstr bstrString; \
     2317            HRESULT hrc2 = unattended->COMGETTER(a_Attr)(bstrString.asOutParam()); \
     2318            if (SUCCEEDED(hrc2)) \
     2319                RTPrintf("  %32s = %ls\n", a_szText, bstrString.raw()); \
     2320            else \
     2321                RTPrintf("  %32s = failed: %Rhrc\n", a_szText, hrc2); \
     2322        } while (0)
     2323
     2324    SHOW_STR_ATTR(IsoPath,                       "isoPath");
     2325    SHOW_STR_ATTR(User,                          "user");
     2326    SHOW_STR_ATTR(Password,                      "password");
     2327    SHOW_STR_ATTR(FullUserName,                  "fullUserName");
     2328    SHOW_STR_ATTR(ProductKey,                    "productKey");
     2329    SHOW_STR_ATTR(AdditionsIsoPath,              "additionsIsoPath");
     2330    SHOW_ATTR(    InstallGuestAdditions,         "installGuestAdditions",    BOOL, "%RTbool");
     2331    SHOW_STR_ATTR(ValidationKitIsoPath,          "validationKitIsoPath");
     2332    SHOW_ATTR(    InstallTestExecService,        "installTestExecService",   BOOL, "%RTbool");
     2333    SHOW_STR_ATTR(Locale,                        "locale");
     2334    SHOW_STR_ATTR(Country,                       "country");
     2335    SHOW_STR_ATTR(TimeZone,                      "timeZone");
     2336    SHOW_STR_ATTR(Proxy,                         "proxy");
     2337    SHOW_STR_ATTR(Hostname,                      "hostname");
     2338    SHOW_STR_ATTR(PackageSelectionAdjustments,   "packageSelectionAdjustments");
     2339    SHOW_STR_ATTR(AuxiliaryBasePath,             "auxiliaryBasePath");
     2340    SHOW_ATTR(    ImageIndex,                    "imageIndex",               ULONG, "%u");
     2341    SHOW_STR_ATTR(ScriptTemplatePath,            "scriptTemplatePath");
     2342    SHOW_STR_ATTR(PostInstallScriptTemplatePath, "postInstallScriptTemplatePath");
     2343    SHOW_STR_ATTR(PostInstallCommand,            "postInstallCommand");
     2344    SHOW_STR_ATTR(ExtraInstallKernelParameters,  "extraInstallKernelParameters");
     2345    SHOW_STR_ATTR(Language,                      "language");
     2346    SHOW_STR_ATTR(DetectedOSTypeId,              "detectedOSTypeId");
     2347    SHOW_STR_ATTR(DetectedOSVersion,             "detectedOSVersion");
     2348    SHOW_STR_ATTR(DetectedOSFlavor,              "detectedOSFlavor");
     2349    SHOW_STR_ATTR(DetectedOSLanguages,           "detectedOSLanguages");
     2350    SHOW_STR_ATTR(DetectedOSHints,               "detectedOSHints");
     2351
     2352#undef SHOW_STR_ATTR
     2353#undef SHOW_ATTR
     2354
     2355    /* 'unattended' is no longer needed. */
     2356    unattended.setNull();
     2357
     2358    RTPrintf("Performing unattended install of temporary local gateway...\n");
     2359
     2360    hrc = machine->LaunchVMProcess(session, Bstr("gui").raw(), ComSafeArrayNullInParam(), progress.asOutParam());
     2361    if (errorOccured(hrc, "Failed to launch '%ls'.", strGatewayVM.raw()))
     2362        return hrc;
     2363
     2364    hrc = progress->WaitForCompletion(-1);
     2365    if (errorOccured(hrc, "Failed to launch '%ls'.", strGatewayVM.raw()))
     2366        return hrc;
     2367
     2368    unsigned i = 0;
     2369    const char progressChars[] = { '|', '/', '-', '\\'};
     2370    MachineState machineState;
     2371    uint64_t u64Started = RTTimeMilliTS();
     2372    do
     2373    {
     2374        RTThreadSleep(1000); /* One second */
     2375        hrc = machine->COMGETTER(State)(&machineState);
     2376        if (errorOccured(hrc, "Failed to get machine state."))
     2377            break;
     2378        RTPrintf("\r%c", progressChars[i++ % sizeof(progressChars)]);
     2379        if (machineState == MachineState_Aborted)
     2380        {
     2381            errorOccured(E_ABORT, "Temporary local gateway VM has aborted.");
     2382            return E_ABORT;
     2383        }
     2384    }
     2385    while (machineState != MachineState_PoweredOff && RTTimeMilliTS() - u64Started < 40 * 60 * 1000);
     2386
     2387    if (machineState != MachineState_PoweredOff)
     2388    {
     2389        errorOccured(E_ABORT, "Timed out (40min) while waiting for unattended install to finish.");
     2390        return E_ABORT;
     2391    }
     2392    /* Machine will still be immutable for a short while after powering off, let's wait a little. */
     2393    RTThreadSleep(5000); /* Five seconds */
     2394
     2395    RTPrintf("\rDone.\n");
     2396
     2397    hrc = machine->LockMachine(session, LockType_Write);
     2398    if (errorOccured(hrc, "Failed to lock '%ls' for modifications.", strGatewayVM.raw()))
     2399        return hrc;
     2400
     2401    RTPrintf("Detaching local gateway image...\n");
     2402    hrc = session->COMGETTER(Machine)(sessionMachine.asOutParam());
     2403    if (errorOccured(hrc, "Failed to obtain a mutable machine."))
     2404        return hrc;
     2405
     2406    hrc = sessionMachine->DetachDevice(Bstr("SATA").raw(), 0, 0);
     2407    if (errorOccured(hrc, "Failed to detach HD to '%ls'.", strGatewayVM.raw()))
     2408        return hrc;
     2409
     2410    /* Remove the image from the media registry. */
     2411    hd->Close();
     2412
     2413    /* Save settings */
     2414    hrc = sessionMachine->SaveSettings();
     2415    if (errorOccured(hrc, "Failed to save '%ls' settings.", strGatewayVM.raw()))
     2416        return hrc;
     2417    session->UnlockMachine();
     2418
     2419#if 0
     2420    /* @todo Unregistering the temporary VM makes the image mutable again. Find out the way around it! */
     2421    RTPrintf("Unregistering temporary local gateway machine...\n");
     2422    SafeIfaceArray<IMedium> media;
     2423    hrc = machine->Unregister(CleanupMode_DetachAllReturnNone, ComSafeArrayAsOutParam(media));
     2424    if (errorOccured(hrc, "Failed to unregister '%ls'.", strGatewayVM.raw()))
     2425        return hrc;
     2426    hrc = machine->DeleteConfig(ComSafeArrayAsInParam(media), progress.asOutParam());
     2427    if (errorOccured(hrc, "Failed to delete config for '%ls'.", strGatewayVM.raw()))
     2428        return hrc;
     2429    hrc = progress->WaitForCompletion(-1);
     2430    if (errorOccured(hrc, "Failed to delete config for '%ls'.", strGatewayVM.raw()))
     2431        return hrc;
     2432#endif
     2433
     2434    RTPrintf("Making local gateway image immutable...\n");
     2435    hrc = virtualBox->OpenMedium(strGatewayImage.raw(), DeviceType_HardDisk, AccessMode_ReadWrite, FALSE, hd.asOutParam());
     2436    if (errorOccured(hrc, "Failed to open '%ls'.", strGatewayImage.raw()))
     2437        return hrc;
     2438    hd->COMSETTER(Type)(MediumType_Immutable);
     2439    if (errorOccured(hrc, "Failed to make '%ls' immutable.", strGatewayImage.raw()))
     2440        return hrc;
     2441
     2442    return S_OK;
     2443}
     2444
     2445
    20862446static RTEXITCODE setupCloudNetworkEnv(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
    20872447{
     
    20952455        { "--tunnel-network-name",  't', RTGETOPT_REQ_STRING },
    20962456        { "--tunnel-network-range", 'r', RTGETOPT_REQ_STRING },
     2457        { "--guest-additions-iso",  'a', RTGETOPT_REQ_STRING },
     2458        { "--local-gateway-iso",    'l', RTGETOPT_REQ_STRING }
    20972459    };
    20982460    RTGETOPTSTATE GetState;
     
    21062468    Bstr strTunnelNetworkName;
    21072469    Bstr strTunnelNetworkRange;
     2470    Bstr strLocalGatewayIso;
     2471    Bstr strGuestAdditionsIso;
    21082472
    21092473    int c;
     
    21262490            case 'r':
    21272491                strTunnelNetworkRange=ValueUnion.psz;
     2492                break;
     2493            case 'l':
     2494                strLocalGatewayIso=ValueUnion.psz;
     2495                break;
     2496            case 'a':
     2497                strGuestAdditionsIso=ValueUnion.psz;
    21282498                break;
    21292499            case VINF_GETOPT_NOT_OPTION:
     
    21392509        return RTEXITCODE_FAILURE;
    21402510
    2141     // if (strGatewayOsName.isEmpty())
    2142     //     return errorArgument("Missing --gateway-os-name parameter");
    2143     // if (strGatewayOsVersion.isEmpty())
    2144     //     return errorArgument("Missing --gateway-os-version parameter");
    2145     // if (strGatewayShape.isEmpty())
    2146     //     return errorArgument("Missing --gateway-shape parameter");
    2147     // if (strTunnelNetworkName.isEmpty())
    2148     //     strTunnelNetworkName = "VirtualBox Tunneling Network";
     2511    if (strLocalGatewayIso.isEmpty())
     2512        return errorArgument("Missing --local-gateway-iso parameter");
     2513
     2514    ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
     2515
     2516    hrc = createLocalGatewayImage(pVirtualBox, strLocalGatewayIso, strGuestAdditionsIso);
     2517    if (FAILED(hrc))
     2518        return RTEXITCODE_FAILURE;
     2519
     2520    RTPrintf("Setting up tunnel network in the cloud...\n");
    21492521
    21502522    ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
     
    21552527                     RTEXITCODE_FAILURE);
    21562528
    2157     ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
    21582529    ComPtr<ICloudNetworkEnvironmentInfo> cloudNetworkEnv;
    21592530    ComPtr<IProgress> progress;
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