Changeset 84639 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Jun 2, 2020 1:41:42 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp
r84618 r84639 31 31 #include <iprt/file.h> 32 32 #include <VBox/log.h> 33 34 #include <iprt/cpp/path.h> 33 35 34 36 #include "VBoxManage.h" … … 2084 2086 2085 2087 2088 static 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 2104 static 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 2123 static 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 2086 2446 static RTEXITCODE setupCloudNetworkEnv(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts) 2087 2447 { … … 2095 2455 { "--tunnel-network-name", 't', RTGETOPT_REQ_STRING }, 2096 2456 { "--tunnel-network-range", 'r', RTGETOPT_REQ_STRING }, 2457 { "--guest-additions-iso", 'a', RTGETOPT_REQ_STRING }, 2458 { "--local-gateway-iso", 'l', RTGETOPT_REQ_STRING } 2097 2459 }; 2098 2460 RTGETOPTSTATE GetState; … … 2106 2468 Bstr strTunnelNetworkName; 2107 2469 Bstr strTunnelNetworkRange; 2470 Bstr strLocalGatewayIso; 2471 Bstr strGuestAdditionsIso; 2108 2472 2109 2473 int c; … … 2126 2490 case 'r': 2127 2491 strTunnelNetworkRange=ValueUnion.psz; 2492 break; 2493 case 'l': 2494 strLocalGatewayIso=ValueUnion.psz; 2495 break; 2496 case 'a': 2497 strGuestAdditionsIso=ValueUnion.psz; 2128 2498 break; 2129 2499 case VINF_GETOPT_NOT_OPTION: … … 2139 2509 return RTEXITCODE_FAILURE; 2140 2510 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"); 2149 2521 2150 2522 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile; … … 2155 2527 RTEXITCODE_FAILURE); 2156 2528 2157 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;2158 2529 ComPtr<ICloudNetworkEnvironmentInfo> cloudNetworkEnv; 2159 2530 ComPtr<IProgress> progress;
Note:
See TracChangeset
for help on using the changeset viewer.