Changeset 78428 in vbox for trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
- Timestamp:
- May 7, 2019 11:03:49 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
r76553 r78428 146 146 { "--disk", 'D', RTGETOPT_REQ_STRING }, 147 147 { "--options", 'O', RTGETOPT_REQ_STRING }, 148 149 { "--cloud", 'j', RTGETOPT_REQ_NOTHING}, 150 { "--cloudprofile", 'k', RTGETOPT_REQ_STRING }, 151 { "--cloudinstanceid", 'l', RTGETOPT_REQ_STRING } 148 152 }; 153 154 enum 155 { 156 NOT_SET, LOCAL, CLOUD 157 } actionType; 149 158 150 159 RTEXITCODE handleImportAppliance(HandlerArg *arg) 151 160 { 152 161 HRESULT rc = S_OK; 153 162 bool fCloud = false; // the default 163 actionType = NOT_SET; 154 164 Utf8Str strOvfFilename; 155 165 bool fExecute = true; // if true, then we actually do the import … … 182 192 183 193 case 's': // --vsys 194 if (fCloud == false && actionType == NOT_SET) 195 actionType = LOCAL; 196 197 if (actionType != LOCAL) 198 return errorSyntax(USAGE_EXPORTAPPLIANCE, 199 "Option \"%s\" can't be used together with \"--cloud\" argument.", 200 GetState.pDef->pszLong); 201 184 202 ulCurVsys = ValueUnion.u32; 185 203 ulCurUnit = (uint32_t)-1; … … 187 205 188 206 case 'o': // --ostype 189 if ( ulCurVsys == (uint32_t)-1)190 return errorSyntax(USAGE_ IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong);207 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 208 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 191 209 mapArgsMapsPerVsys[ulCurVsys]["ostype"] = ValueUnion.psz; 192 210 break; 193 211 194 212 case 'V': // --vmname 195 if ( ulCurVsys == (uint32_t)-1)213 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 196 214 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 197 215 mapArgsMapsPerVsys[ulCurVsys]["vmname"] = ValueUnion.psz; … … 199 217 200 218 case 'S': // --settingsfile 201 if ( ulCurVsys == (uint32_t)-1)219 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 202 220 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 203 221 mapArgsMapsPerVsys[ulCurVsys]["settingsfile"] = ValueUnion.psz; … … 205 223 206 224 case 'p': // --basefolder 207 if ( ulCurVsys == (uint32_t)-1)225 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 208 226 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 209 227 mapArgsMapsPerVsys[ulCurVsys]["basefolder"] = ValueUnion.psz; … … 211 229 212 230 case 'g': // --group 213 if ( ulCurVsys == (uint32_t)-1)231 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 214 232 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 215 233 mapArgsMapsPerVsys[ulCurVsys]["group"] = ValueUnion.psz; … … 217 235 218 236 case 'd': // --description 219 if ( ulCurVsys == (uint32_t)-1)237 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 220 238 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 221 239 mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz; … … 223 241 224 242 case 'L': // --eula 225 if ( ulCurVsys == (uint32_t)-1)243 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 226 244 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 227 245 mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz; … … 229 247 230 248 case 'm': // --memory 231 if ( ulCurVsys == (uint32_t)-1)249 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 232 250 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 233 251 mapArgsMapsPerVsys[ulCurVsys]["memory"] = ValueUnion.psz; … … 235 253 236 254 case 'c': // --cpus 237 if ( ulCurVsys == (uint32_t)-1)255 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 238 256 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 239 257 mapArgsMapsPerVsys[ulCurVsys]["cpus"] = ValueUnion.psz; … … 245 263 246 264 case 'x': // --ignore 247 if ( ulCurVsys == (uint32_t)-1)265 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 248 266 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 249 267 if (ulCurUnit == (uint32_t)-1) … … 253 271 254 272 case 'T': // --scsitype 255 if ( ulCurVsys == (uint32_t)-1)273 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 256 274 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 257 275 if (ulCurUnit == (uint32_t)-1) … … 261 279 262 280 case 'C': // --controller 263 if ( ulCurVsys == (uint32_t)-1)281 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 264 282 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 265 283 if (ulCurUnit == (uint32_t)-1) … … 269 287 270 288 case 'D': // --disk 271 if ( ulCurVsys == (uint32_t)-1)289 if (actionType == LOCAL && ulCurVsys == (uint32_t)-1) 272 290 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 273 291 if (ulCurUnit == (uint32_t)-1) … … 279 297 if (RT_FAILURE(parseImportOptions(ValueUnion.psz, &options))) 280 298 return errorArgument("Invalid import options '%s'\n", ValueUnion.psz); 299 break; 300 301 /*--cloud and --vsys are orthogonal, only one must be presented*/ 302 case 'j': // --cloud 303 if (fCloud == false && actionType == NOT_SET) 304 { 305 fCloud = true; 306 actionType = CLOUD; 307 } 308 309 if (actionType != CLOUD) 310 return errorSyntax(USAGE_IMPORTAPPLIANCE, 311 "Option \"%s\" can't be used together with \"--vsys\" argument.", 312 GetState.pDef->pszLong); 313 314 ulCurVsys = 0; 315 break; 316 317 /* Cloud export settings */ 318 case 'k': // --cloudprofile 319 if (actionType != CLOUD) 320 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 321 GetState.pDef->pszLong); 322 mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"] = ValueUnion.psz; 323 break; 324 325 case 'l': // --cloudinstanceid 326 if (actionType != CLOUD) 327 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 328 GetState.pDef->pszLong); 329 mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"] = ValueUnion.psz; 281 330 break; 282 331 … … 305 354 } 306 355 307 if ( strOvfFilename.isEmpty())356 if (actionType == LOCAL && strOvfFilename.isEmpty()) 308 357 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Not enough arguments for \"import\" command."); 309 358 … … 313 362 CHECK_ERROR_BREAK(arg->virtualBox, CreateAppliance(pAppliance.asOutParam())); 314 363 364 //in the case of Cloud, append the instance id here because later it's harder to do 365 if (actionType == CLOUD && 366 mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"].isNotEmpty() && 367 mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"].isNotEmpty()) 368 { 369 strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudprofile"]); 370 strOvfFilename.append("/"); 371 strOvfFilename.append(mapArgsMapsPerVsys[ulCurVsys]["cloudinstanceid"]); 372 } 373 else 374 return errorSyntax(USAGE_IMPORTAPPLIANCE, "Not enough arguments for import from the Cloud."); 375 315 376 char *pszAbsFilePath; 316 377 if (strOvfFilename.startsWith("S3://", RTCString::CaseInsensitive) || 317 378 strOvfFilename.startsWith("SunCloud://", RTCString::CaseInsensitive) || 318 strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive)) 379 strOvfFilename.startsWith("webdav://", RTCString::CaseInsensitive) || 380 strOvfFilename.startsWith("OCI://", RTCString::CaseInsensitive)) 319 381 pszAbsFilePath = RTStrDup(strOvfFilename.c_str()); 320 382 else 321 383 pszAbsFilePath = RTPathAbsDup(strOvfFilename.c_str()); 384 322 385 ComPtr<IProgress> progressRead; 323 386 CHECK_ERROR_BREAK(pAppliance, Read(Bstr(pszAbsFilePath).raw(), … … 330 393 Bstr path; /* fetch the path, there is stuff like username/password removed if any */ 331 394 CHECK_ERROR_BREAK(pAppliance, COMGETTER(Path)(path.asOutParam())); 332 // call interpret(); this can yield both warnings and errors, so we need333 // to tinker with the error info a bit334 RTStrmPrintf(g_pStdErr, "Interpreting %ls...\n", path.raw());335 rc = pAppliance->Interpret();336 com::ErrorInfo info0(pAppliance, COM_IIDOF(IAppliance));337 338 com::SafeArray<BSTR> aWarnings;339 if (SUCCEEDED(pAppliance->GetWarnings(ComSafeArrayAsOutParam(aWarnings))))340 {341 size_t cWarnings = aWarnings.size();342 for (unsigned i = 0; i < cWarnings; ++i)343 {344 Bstr bstrWarning(aWarnings[i]);345 RTMsgWarning("%ls.", bstrWarning.raw());346 }347 }348 349 if (FAILED(rc)) // during interpret, after printing warnings350 {351 com::GluePrintErrorInfo(info0);352 com::GluePrintErrorContext("Interpret", __FILE__, __LINE__);353 break;354 }355 356 RTStrmPrintf(g_pStdErr, "OK.\n");357 358 // fetch all disks359 com::SafeArray<BSTR> retDisks;360 CHECK_ERROR_BREAK(pAppliance,361 COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks)));362 if (retDisks.size() > 0)363 {364 RTPrintf("Disks:\n");365 for (unsigned i = 0; i < retDisks.size(); i++)366 RTPrintf(" %ls\n", retDisks[i]);367 RTPrintf("\n");368 }369 395 370 396 // fetch virtual system descriptions … … 375 401 size_t cVirtualSystemDescriptions = aVirtualSystemDescriptions.size(); 376 402 377 // match command line arguments with virtual system descriptions; 378 // this is only to sort out invalid indices at this time 379 ArgsMapsMap::const_iterator it; 380 for (it = mapArgsMapsPerVsys.begin(); 381 it != mapArgsMapsPerVsys.end(); 382 ++it) 403 if (actionType == LOCAL) 383 404 { 384 uint32_t ulVsys = it->first; 385 if (ulVsys >= cVirtualSystemDescriptions) 386 return errorSyntax(USAGE_IMPORTAPPLIANCE, 387 "Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).", 388 ulVsys, cVirtualSystemDescriptions); 405 // call interpret(); this can yield both warnings and errors, so we need 406 // to tinker with the error info a bit 407 RTStrmPrintf(g_pStdErr, "Interpreting %ls...\n", path.raw()); 408 rc = pAppliance->Interpret(); 409 com::ErrorInfo info0(pAppliance, COM_IIDOF(IAppliance)); 410 411 com::SafeArray<BSTR> aWarnings; 412 if (SUCCEEDED(pAppliance->GetWarnings(ComSafeArrayAsOutParam(aWarnings)))) 413 { 414 size_t cWarnings = aWarnings.size(); 415 for (unsigned i = 0; i < cWarnings; ++i) 416 { 417 Bstr bstrWarning(aWarnings[i]); 418 RTMsgWarning("%ls.", bstrWarning.raw()); 419 } 420 } 421 422 if (FAILED(rc)) // during interpret, after printing warnings 423 { 424 com::GluePrintErrorInfo(info0); 425 com::GluePrintErrorContext("Interpret", __FILE__, __LINE__); 426 break; 427 } 428 429 RTStrmPrintf(g_pStdErr, "OK.\n"); 430 431 // fetch all disks 432 com::SafeArray<BSTR> retDisks; 433 CHECK_ERROR_BREAK(pAppliance, 434 COMGETTER(Disks)(ComSafeArrayAsOutParam(retDisks))); 435 if (retDisks.size() > 0) 436 { 437 RTPrintf("Disks:\n"); 438 for (unsigned i = 0; i < retDisks.size(); i++) 439 RTPrintf(" %ls\n", retDisks[i]); 440 RTPrintf("\n"); 441 } 442 443 // match command line arguments with virtual system descriptions; 444 // this is only to sort out invalid indices at this time 445 ArgsMapsMap::const_iterator it; 446 for (it = mapArgsMapsPerVsys.begin(); 447 it != mapArgsMapsPerVsys.end(); 448 ++it) 449 { 450 uint32_t ulVsys = it->first; 451 if (ulVsys >= cVirtualSystemDescriptions) 452 return errorSyntax(USAGE_IMPORTAPPLIANCE, 453 "Invalid index %RI32 with -vsys option; the OVF contains only %zu virtual system(s).", 454 ulVsys, cVirtualSystemDescriptions); 455 } 389 456 } 390 457 … … 920 987 case VirtualSystemDescriptionType_CloudKeepObject: 921 988 case VirtualSystemDescriptionType_CloudLaunchInstance: 989 case VirtualSystemDescriptionType_CloudInstanceId: 990 case VirtualSystemDescriptionType_CloudImageId: 922 991 case VirtualSystemDescriptionType_Miscellaneous: 923 992 /** @todo VirtualSystemDescriptionType_Miscellaneous? */ … … 1041 1110 }; 1042 1111 1043 enum1044 {1045 NOT_SET, LOCAL, CLOUD1046 } exportType;1047 1048 1112 RTEXITCODE handleExportAppliance(HandlerArg *a) 1049 1113 { … … 1054 1118 bool fManifest = false; // the default 1055 1119 bool fCloud = false; // the default 1056 exportType = NOT_SET;1120 actionType = NOT_SET; 1057 1121 bool fExportISOImages = false; // the default 1058 1122 com::SafeArray<ExportOptions_T> options; … … 1109 1173 1110 1174 case 's': // --vsys 1111 if (fCloud == false && exportType == NOT_SET)1112 exportType = LOCAL;1113 1114 if ( exportType != LOCAL)1175 if (fCloud == false && actionType == NOT_SET) 1176 actionType = LOCAL; 1177 1178 if (actionType != LOCAL) 1115 1179 return errorSyntax(USAGE_EXPORTAPPLIANCE, 1116 1180 "Option \"%s\" can't be used together with \"--cloud\" argument.", … … 1121 1185 1122 1186 case 'V': // --vmname 1123 if ( exportType == NOT_SET || ulCurVsys == (uint32_t)-1)1187 if (actionType == NOT_SET || ulCurVsys == (uint32_t)-1) 1124 1188 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys or --cloud argument.", 1125 1189 GetState.pDef->pszLong); … … 1128 1192 1129 1193 case 'p': // --product 1130 if ( exportType != LOCAL)1194 if (actionType != LOCAL) 1131 1195 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1132 1196 mapArgsMapsPerVsys[ulCurVsys]["product"] = ValueUnion.psz; … … 1134 1198 1135 1199 case 'P': // --producturl 1136 if ( exportType != LOCAL)1200 if (actionType != LOCAL) 1137 1201 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1138 1202 mapArgsMapsPerVsys[ulCurVsys]["producturl"] = ValueUnion.psz; … … 1140 1204 1141 1205 case 'n': // --vendor 1142 if ( exportType != LOCAL)1206 if (actionType != LOCAL) 1143 1207 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1144 1208 mapArgsMapsPerVsys[ulCurVsys]["vendor"] = ValueUnion.psz; … … 1146 1210 1147 1211 case 'N': // --vendorurl 1148 if ( exportType != LOCAL)1212 if (actionType != LOCAL) 1149 1213 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1150 1214 mapArgsMapsPerVsys[ulCurVsys]["vendorurl"] = ValueUnion.psz; … … 1152 1216 1153 1217 case 'v': // --version 1154 if ( exportType != LOCAL)1218 if (actionType != LOCAL) 1155 1219 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1156 1220 mapArgsMapsPerVsys[ulCurVsys]["version"] = ValueUnion.psz; … … 1158 1222 1159 1223 case 'd': // --description 1160 if ( exportType != LOCAL)1224 if (actionType != LOCAL) 1161 1225 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1162 1226 mapArgsMapsPerVsys[ulCurVsys]["description"] = ValueUnion.psz; … … 1164 1228 1165 1229 case 'e': // --eula 1166 if ( exportType != LOCAL)1230 if (actionType != LOCAL) 1167 1231 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1168 1232 mapArgsMapsPerVsys[ulCurVsys]["eula"] = ValueUnion.psz; … … 1170 1234 1171 1235 case 'E': // --eulafile 1172 if ( exportType != LOCAL)1236 if (actionType != LOCAL) 1173 1237 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --vsys argument.", GetState.pDef->pszLong); 1174 1238 mapArgsMapsPerVsys[ulCurVsys]["eulafile"] = ValueUnion.psz; … … 1182 1246 /*--cloud and --vsys are orthogonal, only one must be presented*/ 1183 1247 case 'C': // --cloud 1184 if (fCloud == false && exportType == NOT_SET)1248 if (fCloud == false && actionType == NOT_SET) 1185 1249 { 1186 1250 fCloud = true; 1187 exportType = CLOUD;1251 actionType = CLOUD; 1188 1252 } 1189 1253 1190 if ( exportType != CLOUD)1254 if (actionType != CLOUD) 1191 1255 return errorSyntax(USAGE_EXPORTAPPLIANCE, 1192 1256 "Option \"%s\" can't be used together with \"--vsys\" argument.", … … 1198 1262 /* Cloud export settings */ 1199 1263 case 'S': // --cloudshape 1200 if ( exportType != CLOUD)1264 if (actionType != CLOUD) 1201 1265 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1202 1266 GetState.pDef->pszLong); … … 1205 1269 1206 1270 case 'D': // --clouddomain 1207 if ( exportType != CLOUD)1271 if (actionType != CLOUD) 1208 1272 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1209 1273 GetState.pDef->pszLong); … … 1212 1276 1213 1277 case 'R': // --clouddisksize 1214 if ( exportType != CLOUD)1278 if (actionType != CLOUD) 1215 1279 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1216 1280 GetState.pDef->pszLong); … … 1219 1283 1220 1284 case 'B': // --cloudbucket 1221 if ( exportType != CLOUD)1285 if (actionType != CLOUD) 1222 1286 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1223 1287 GetState.pDef->pszLong); … … 1226 1290 1227 1291 case 'Q': // --cloudocivcn 1228 if ( exportType != CLOUD)1292 if (actionType != CLOUD) 1229 1293 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1230 1294 GetState.pDef->pszLong); … … 1233 1297 1234 1298 case 'A': // --cloudpublicip 1235 if ( exportType != CLOUD)1299 if (actionType != CLOUD) 1236 1300 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1237 1301 GetState.pDef->pszLong); … … 1240 1304 1241 1305 case 'F': // --cloudprofile 1242 if ( exportType != CLOUD)1306 if (actionType != CLOUD) 1243 1307 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1244 1308 GetState.pDef->pszLong); … … 1247 1311 1248 1312 case 'T': // --cloudocisubnet 1249 if ( exportType != CLOUD)1313 if (actionType != CLOUD) 1250 1314 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1251 1315 GetState.pDef->pszLong); … … 1254 1318 1255 1319 case 'K': // --cloudkeepobject 1256 if ( exportType != CLOUD)1320 if (actionType != CLOUD) 1257 1321 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1258 1322 GetState.pDef->pszLong); … … 1261 1325 1262 1326 case 'L': // --cloudlaunchinstance 1263 if ( exportType != CLOUD)1327 if (actionType != CLOUD) 1264 1328 return errorSyntax(USAGE_EXPORTAPPLIANCE, "Option \"%s\" requires preceding --cloud argument.", 1265 1329 GetState.pDef->pszLong);
Note:
See TracChangeset
for help on using the changeset viewer.