VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp@ 79169

最後變更 在這個檔案從79169是 79169,由 vboxsync 提交於 6 年 前

removed and corrected the couple RTPrintf()

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 30.9 KB
 
1/* $Id: VBoxManageCloud.cpp 79169 2019-06-17 06:46:41Z vboxsync $ */
2/** @file
3 * VBoxManageCloud - The cloud related commands.
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <VBox/com/com.h>
19#include <VBox/com/string.h>
20#include <VBox/com/Guid.h>
21#include <VBox/com/array.h>
22#include <VBox/com/ErrorInfo.h>
23#include <VBox/com/errorprint.h>
24#include <VBox/com/VirtualBox.h>
25
26#include <iprt/ctype.h>
27#include <iprt/getopt.h>
28#include <iprt/stream.h>
29#include <iprt/string.h>
30#include <iprt/uuid.h>
31#include <iprt/file.h>
32#include <VBox/log.h>
33
34#include "VBoxManage.h"
35
36#include <list>
37
38using namespace com;//at least for Bstr
39
40/**
41 * Common Cloud options.
42 */
43typedef struct
44{
45 struct {
46 const char *pszProviderName;
47 ComPtr<ICloudProvider> pCloudProvider;
48 }provider;
49 struct {
50 const char *pszProfileName;
51 ComPtr<ICloudProfile> pCloudProfile;
52 }profile;
53
54} CLOUDCOMMONOPT;
55typedef CLOUDCOMMONOPT *PCLOUDCOMMONOPT;
56
57static HRESULT checkAndSetCommonOptions(HandlerArg *a, PCLOUDCOMMONOPT pCommonOpts)
58{
59 HRESULT hrc = S_OK;
60
61 Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
62 Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
63
64 /* check for required options */
65 if (bstrProvider.isEmpty())
66 {
67 errorSyntax(USAGE_S_NEWCMD, "Parameter --provider is required");
68 return E_FAIL;
69 }
70 if (bstrProfile.isEmpty())
71 {
72 errorSyntax(USAGE_S_NEWCMD, "Parameter --profile is required");
73 return E_FAIL;
74 }
75
76 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
77 ComPtr<ICloudProviderManager> pCloudProviderManager;
78 CHECK_ERROR2_RET(hrc, pVirtualBox,
79 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
80 RTEXITCODE_FAILURE);
81
82 ComPtr<ICloudProvider> pCloudProvider;
83 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
84 GetProviderByShortName(bstrProvider.raw(), pCloudProvider.asOutParam()),
85 RTEXITCODE_FAILURE);
86 pCommonOpts->provider.pCloudProvider = pCloudProvider;
87
88 ComPtr<ICloudProfile> pCloudProfile;
89 CHECK_ERROR2_RET(hrc, pCloudProvider,
90 GetProfileByName(bstrProfile.raw(), pCloudProfile.asOutParam()),
91 RTEXITCODE_FAILURE);
92 pCommonOpts->profile.pCloudProfile = pCloudProfile;
93
94 return hrc;
95}
96
97/**
98 * List all available cloud instances for the specified cloud provider.
99 * Available cloud instance is one which state whether "running" or "stopped".
100 *
101 * @returns RTEXITCODE
102 * @param a is the list of passed arguments
103 * @param iFirst is the position of the first unparsed argument in the arguments list
104 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
105 * arguments which have been already parsed before
106 */
107static RTEXITCODE listCloudInstances(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
108{
109 static const RTGETOPTDEF s_aOptions[] =
110 {
111 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
112 { "--state", 's', RTGETOPT_REQ_STRING }
113 };
114 RTGETOPTSTATE GetState;
115 RTGETOPTUNION ValueUnion;
116 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
117 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
118
119 Utf8Str strCompartmentId;
120 Utf8Str strState;
121
122 int c;
123 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
124 {
125 switch (c)
126 {
127 case 'c':
128 strCompartmentId = ValueUnion.psz;
129 break;
130 case 's':
131 strState = ValueUnion.psz;
132 break;
133 case VINF_GETOPT_NOT_OPTION:
134 return errorUnknownSubcommand(ValueUnion.psz);
135 default:
136 return errorGetOpt(c, &ValueUnion);
137 }
138 }
139
140 com::SafeArray<CloudMachineState_T> machimeStates;
141 if (strState.isNotEmpty())
142 {
143 if (strState.equals("running"))
144 machimeStates.push_back(CloudMachineState_Running);
145 else if (strState.equals("paused"))
146 machimeStates.push_back(CloudMachineState_Stopped);
147 else if (strState.equals("terminated"))
148 machimeStates.push_back(CloudMachineState_Terminated);
149 }
150
151 HRESULT hrc = S_OK;
152 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
153 ComPtr<ICloudProviderManager> pCloudProviderManager;
154 CHECK_ERROR2_RET(hrc, pVirtualBox,
155 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
156 RTEXITCODE_FAILURE);
157 ComPtr<ICloudProvider> pCloudProvider;
158
159 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
160 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
161 RTEXITCODE_FAILURE);
162 ComPtr<ICloudProfile> pCloudProfile;
163
164 CHECK_ERROR2_RET(hrc, pCloudProvider,
165 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
166 RTEXITCODE_FAILURE);
167
168 if (strCompartmentId.isNotEmpty())
169 {
170 CHECK_ERROR2_RET(hrc, pCloudProfile,
171 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),
172 RTEXITCODE_FAILURE);
173 }
174 else
175 {
176 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
177 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
178 Bstr bStrCompartmentId;
179 CHECK_ERROR2_RET(hrc, pCloudProfile,
180 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
181 RTEXITCODE_FAILURE);
182 strCompartmentId = bStrCompartmentId;
183 if (strCompartmentId.isNotEmpty())
184 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
185 else
186 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
187 }
188
189 Bstr bstrProfileName;
190 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
191
192 ComObjPtr<ICloudClient> oCloudClient;
193 CHECK_ERROR2_RET(hrc, pCloudProfile,
194 CreateCloudClient(oCloudClient.asOutParam()),
195 RTEXITCODE_FAILURE);
196
197 ComPtr<IStringArray> pVMNamesHolder;
198 ComPtr<IStringArray> pVMIdsHolder;
199 com::SafeArray<BSTR> arrayVMNames;
200 com::SafeArray<BSTR> arrayVMIds;
201 ComPtr<IProgress> pProgress;
202
203 RTPrintf("Reply is in the form \'instance name\' = \'instance id\'\n");
204
205 CHECK_ERROR2_RET(hrc, oCloudClient,
206 ListInstances(ComSafeArrayAsInParam(machimeStates),
207 pVMNamesHolder.asOutParam(),
208 pVMIdsHolder.asOutParam(),
209 pProgress.asOutParam()),
210 RTEXITCODE_FAILURE);
211 showProgress(pProgress);
212 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list instances"), RTEXITCODE_FAILURE);
213
214 CHECK_ERROR2_RET(hrc,
215 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
216 RTEXITCODE_FAILURE);
217 CHECK_ERROR2_RET(hrc,
218 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
219 RTEXITCODE_FAILURE);
220
221 RTPrintf("The list of the instances for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
222 bstrProfileName.raw(), strCompartmentId.c_str());
223 size_t cIds = arrayVMIds.size();
224 size_t cNames = arrayVMNames.size();
225 for (size_t k = 0; k < cNames; k++)
226 {
227 Bstr value;
228 if (k < cIds)
229 value = arrayVMIds[k];
230 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
231 }
232
233 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
234}
235
236/**
237 * List all available cloud images for the specified cloud provider.
238 *
239 * @returns RTEXITCODE
240 * @param a is the list of passed arguments
241 * @param iFirst is the position of the first unparsed argument in the arguments list
242 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
243 * arguments which have been already parsed before
244 */
245static RTEXITCODE listCloudImages(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
246{
247 static const RTGETOPTDEF s_aOptions[] =
248 {
249 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
250 { "--state", 's', RTGETOPT_REQ_STRING }
251 };
252 RTGETOPTSTATE GetState;
253 RTGETOPTUNION ValueUnion;
254 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
255 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
256
257 Utf8Str strCompartmentId;
258 Utf8Str strState;
259 int c;
260 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
261 {
262 switch (c)
263 {
264 case 'c':
265 strCompartmentId = ValueUnion.psz;
266 break;
267 case 's':
268 strState = ValueUnion.psz;
269 break;
270 case VINF_GETOPT_NOT_OPTION:
271 return errorUnknownSubcommand(ValueUnion.psz);
272 default:
273 return errorGetOpt(c, &ValueUnion);
274 }
275 }
276
277 com::SafeArray<CloudImageState_T> imageStates;
278 if (strState.isNotEmpty())
279 {
280 if (strState.equals("available"))
281 imageStates.push_back(CloudImageState_Available);
282 else if (strState.equals("disabled"))
283 imageStates.push_back(CloudImageState_Disabled);
284 else if (strState.equals("deleted"))
285 imageStates.push_back(CloudImageState_Deleted);
286 }
287
288 HRESULT hrc = S_OK;
289 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
290 ComPtr<ICloudProviderManager> pCloudProviderManager;
291 CHECK_ERROR2_RET(hrc, pVirtualBox,
292 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
293 RTEXITCODE_FAILURE);
294 ComPtr<ICloudProvider> pCloudProvider;
295
296 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
297 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
298 RTEXITCODE_FAILURE);
299 ComPtr<ICloudProfile> pCloudProfile;
300
301 CHECK_ERROR2_RET(hrc, pCloudProvider,
302 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
303 RTEXITCODE_FAILURE);
304 if (strCompartmentId.isNotEmpty())
305 {
306 CHECK_ERROR2_RET(hrc, pCloudProfile,
307 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
308 RTEXITCODE_FAILURE);
309 }
310 else
311 {
312 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
313 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
314 Bstr bStrCompartmentId;
315 CHECK_ERROR2_RET(hrc, pCloudProfile,
316 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
317 RTEXITCODE_FAILURE);
318 strCompartmentId = bStrCompartmentId;
319 if (strCompartmentId.isNotEmpty())
320 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
321 else
322 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
323 }
324
325 Bstr bstrProfileName;
326 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
327
328 ComObjPtr<ICloudClient> oCloudClient;
329 CHECK_ERROR2_RET(hrc, pCloudProfile,
330 CreateCloudClient(oCloudClient.asOutParam()),
331 RTEXITCODE_FAILURE);
332
333 ComPtr<IStringArray> pVMNamesHolder;
334 ComPtr<IStringArray> pVMIdsHolder;
335 com::SafeArray<BSTR> arrayVMNames;
336 com::SafeArray<BSTR> arrayVMIds;
337 ComPtr<IProgress> pProgress;
338
339 RTPrintf("Reply is in the form \'image name\' = \'image id\'\n");
340 CHECK_ERROR2_RET(hrc, oCloudClient,
341 ListImages(ComSafeArrayAsInParam(imageStates),
342 pVMNamesHolder.asOutParam(),
343 pVMIdsHolder.asOutParam(),
344 pProgress.asOutParam()),
345 RTEXITCODE_FAILURE);
346 showProgress(pProgress);
347 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list images"), RTEXITCODE_FAILURE);
348
349 CHECK_ERROR2_RET(hrc,
350 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
351 RTEXITCODE_FAILURE);
352 CHECK_ERROR2_RET(hrc,
353 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
354 RTEXITCODE_FAILURE);
355
356 RTPrintf("The list of the images for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
357 bstrProfileName.raw(), strCompartmentId.c_str());
358 size_t cNames = arrayVMNames.size();
359 size_t cIds = arrayVMIds.size();
360 for (size_t k = 0; k < cNames; k++)
361 {
362 Bstr value;
363 if (k < cIds)
364 value = arrayVMIds[k];
365 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
366 }
367
368 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
369}
370
371/**
372 * General function which handles the "list" commands
373 *
374 * @returns RTEXITCODE
375 * @param a is the list of passed arguments
376 * @param iFirst is the position of the first unparsed argument in the arguments list
377 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
378 * arguments which have been already parsed before
379 */
380static RTEXITCODE handleCloudLists(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
381{
382 if (a->argc < 1)
383 return errorNoSubcommand();
384
385 static const RTGETOPTDEF s_aOptions[] =
386 {
387 { "images", 1000, RTGETOPT_REQ_NOTHING },
388 { "instances", 1001, RTGETOPT_REQ_NOTHING },
389 { "networks", 1002, RTGETOPT_REQ_NOTHING },
390 { "subnets", 1003, RTGETOPT_REQ_NOTHING },
391 { "vcns", 1004, RTGETOPT_REQ_NOTHING },
392 { "objects", 1005, RTGETOPT_REQ_NOTHING }
393 };
394
395 Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
396 Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
397
398 /* check for required options */
399 if (bstrProvider.isEmpty())
400 return errorSyntax(USAGE_S_NEWCMD, "Parameter --provider is required");
401 if (bstrProfile.isEmpty())
402 return errorSyntax(USAGE_S_NEWCMD, "Parameter --profile is required");
403
404 RTGETOPTSTATE GetState;
405 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
406 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
407
408 int c;
409 RTGETOPTUNION ValueUnion;
410 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
411 {
412 switch (c)
413 {
414 case 1000:
415// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_LIST);
416 return listCloudImages(a, GetState.iNext, pCommonOpts);
417 case 1001:
418// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_LIST);
419 return listCloudInstances(a, GetState.iNext, pCommonOpts);
420 case VINF_GETOPT_NOT_OPTION:
421 return errorUnknownSubcommand(ValueUnion.psz);
422
423 default:
424 return errorGetOpt(c, &ValueUnion);
425 }
426 }
427
428 return errorNoSubcommand();
429}
430
431static RTEXITCODE createCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
432{
433 RT_NOREF(a);
434 RT_NOREF(iFirst);
435 RT_NOREF(pCommonOpts);
436 return RTEXITCODE_SUCCESS;
437}
438
439static RTEXITCODE updateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
440{
441 RT_NOREF(a);
442 RT_NOREF(iFirst);
443 RT_NOREF(pCommonOpts);
444 return RTEXITCODE_SUCCESS;
445}
446
447static RTEXITCODE showCloudInstanceInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
448{
449 HRESULT hrc = S_OK;
450
451 hrc = checkAndSetCommonOptions(a, pCommonOpts);
452 if (FAILED(hrc))
453 return RTEXITCODE_FAILURE;
454
455 static const RTGETOPTDEF s_aOptions[] =
456 {
457 { "--id", 'i', RTGETOPT_REQ_STRING }
458 };
459 RTGETOPTSTATE GetState;
460 RTGETOPTUNION ValueUnion;
461 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
462 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
463
464 Utf8Str strInstanceId;
465 int c;
466 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
467 {
468 switch (c)
469 {
470 case 'i':
471 strInstanceId = ValueUnion.psz;
472 break;
473 case VINF_GETOPT_NOT_OPTION:
474 return errorUnknownSubcommand(ValueUnion.psz);
475 default:
476 return errorGetOpt(c, &ValueUnion);
477 }
478 }
479
480 Bstr bstrProfileName;
481 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
482 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
483
484 ComObjPtr<ICloudClient> oCloudClient;
485 CHECK_ERROR2_RET(hrc, pCloudProfile,
486 CreateCloudClient(oCloudClient.asOutParam()),
487 RTEXITCODE_FAILURE);
488 RTPrintf("Getting information about cloud instance with id %s...\n", strInstanceId.c_str());
489 RTPrintf("Reply is in the form \'setting name\' = \'value\'\n");
490
491 ComPtr<IAppliance> pAppliance;
492 CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
493
494 com::SafeIfaceArray<IVirtualSystemDescription> vsdArray;
495 ULONG requestedVSDnums = 1;
496 ULONG newVSDnums = 0;
497 CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(requestedVSDnums, &newVSDnums), RTEXITCODE_FAILURE);
498 if (requestedVSDnums != newVSDnums)
499 return RTEXITCODE_FAILURE;
500
501 CHECK_ERROR2_RET(hrc, pAppliance, COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(vsdArray)), RTEXITCODE_FAILURE);
502 ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
503
504 ComPtr<IProgress> progress;
505 CHECK_ERROR2_RET(hrc, oCloudClient,
506 GetInstanceInfo(Bstr(strInstanceId.c_str()).raw(), instanceDescription, progress.asOutParam()),
507 RTEXITCODE_FAILURE);
508
509 hrc = showProgress(progress);
510 CHECK_PROGRESS_ERROR_RET(progress, ("Getting information about cloud instance failed"), RTEXITCODE_FAILURE);
511
512 RTPrintf("Cloud instance info (provider '%s'):\n",
513 pCommonOpts->provider.pszProviderName);
514
515 struct vsdHReadable {
516 VirtualSystemDescriptionType_T vsdType;
517 Utf8Str strFound;
518 Utf8Str strNotFound;
519 };
520
521 size_t vsdHReadableArraySize = 9;//the number of items in the vsdHReadableArray
522 vsdHReadable vsdHReadableArray[9] = {
523 {VirtualSystemDescriptionType_CloudDomain, "Availability domain = '%ls'\n", "Availability domain wasn't found\n"},
524 {VirtualSystemDescriptionType_Name, "Instance displayed name = '%ls'\n", "Instance displayed name wasn't found\n"},
525 {VirtualSystemDescriptionType_CloudInstanceState, "Instance state = '%ls'\n", "Instance state wasn't found\n"},
526 {VirtualSystemDescriptionType_CloudInstanceId, "Instance Id = '%ls'\n", "Instance Id wasn't found\n"},
527 {VirtualSystemDescriptionType_CloudImageId, "Bootable image Id = '%ls'\n",
528 "Image Id whom the instance is booted up wasn't found\n"},
529 {VirtualSystemDescriptionType_CloudInstanceShape, "Shape of the instance = '%ls'\n",
530 "The shape of the instance wasn't found\n"},
531 {VirtualSystemDescriptionType_OS, "Type of guest OS = '%ls'\n", "Type of guest OS wasn't found.\n"},
532 {VirtualSystemDescriptionType_Memory, "RAM = '%ls MB'\n", "Value for RAM wasn't found\n"},
533 {VirtualSystemDescriptionType_CPU, "CPUs = '%ls'\n", "Numbers of CPUs weren't found\n"}
534 };
535
536 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
537 com::SafeArray<BSTR> aRefs;
538 com::SafeArray<BSTR> aOvfValues;
539 com::SafeArray<BSTR> aVBoxValues;
540 com::SafeArray<BSTR> aExtraConfigValues;
541
542 for (size_t i=0; i<vsdHReadableArraySize ; ++i)
543 {
544 hrc = instanceDescription->GetDescriptionByType(vsdHReadableArray[i].vsdType,
545 ComSafeArrayAsOutParam(retTypes),
546 ComSafeArrayAsOutParam(aRefs),
547 ComSafeArrayAsOutParam(aOvfValues),
548 ComSafeArrayAsOutParam(aVBoxValues),
549 ComSafeArrayAsOutParam(aExtraConfigValues));
550 if (FAILED(hrc) || aVBoxValues.size() == 0)
551 LogRel((vsdHReadableArray[i].strNotFound.c_str()));
552 else
553 RTPrintf(vsdHReadableArray[i].strFound.c_str(), aVBoxValues[0]);
554
555 retTypes.setNull();
556 aRefs.setNull();
557 aOvfValues.setNull();
558 aVBoxValues.setNull();
559 aExtraConfigValues.setNull();
560 }
561
562 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
563}
564
565static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
566{
567 HRESULT hrc = S_OK;
568 hrc = checkAndSetCommonOptions(a, pCommonOpts);
569 if (FAILED(hrc))
570 return RTEXITCODE_FAILURE;
571
572 static const RTGETOPTDEF s_aOptions[] =
573 {
574 { "--id", 'i', RTGETOPT_REQ_STRING }
575 };
576 RTGETOPTSTATE GetState;
577 RTGETOPTUNION ValueUnion;
578 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
579 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
580
581 Utf8Str strInstanceId;
582 int c;
583 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
584 {
585 switch (c)
586 {
587 case 'i':
588 strInstanceId = ValueUnion.psz;
589 break;
590 case VINF_GETOPT_NOT_OPTION:
591 return errorUnknownSubcommand(ValueUnion.psz);
592 default:
593 return errorGetOpt(c, &ValueUnion);
594 }
595 }
596
597 Bstr bstrProfileName;
598 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
599 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
600
601 ComObjPtr<ICloudClient> oCloudClient;
602 CHECK_ERROR2_RET(hrc, pCloudProfile,
603 CreateCloudClient(oCloudClient.asOutParam()),
604 RTEXITCODE_FAILURE);
605 RTPrintf("Starting cloud instance with id %s...\n", strInstanceId.c_str());
606
607 ComPtr<IProgress> progress;
608 CHECK_ERROR2_RET(hrc, oCloudClient,
609 StartInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
610 RTEXITCODE_FAILURE);
611 hrc = showProgress(progress);
612 CHECK_PROGRESS_ERROR_RET(progress, ("Starting the cloud instance failed"), RTEXITCODE_FAILURE);
613
614 if (SUCCEEDED(hrc))
615 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was started\n",
616 strInstanceId.c_str(),
617 pCommonOpts->provider.pszProviderName,
618 pCommonOpts->profile.pszProfileName);
619
620 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
621}
622
623static RTEXITCODE pauseCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
624{
625 HRESULT hrc = S_OK;
626 hrc = checkAndSetCommonOptions(a, pCommonOpts);
627
628 if (FAILED(hrc))
629 return RTEXITCODE_FAILURE;
630
631 static const RTGETOPTDEF s_aOptions[] =
632 {
633 { "--id", 'i', RTGETOPT_REQ_STRING }
634 };
635 RTGETOPTSTATE GetState;
636 RTGETOPTUNION ValueUnion;
637 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
638 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
639
640 Utf8Str strInstanceId;
641 int c;
642 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
643 {
644 switch (c)
645 {
646 case 'i':
647 strInstanceId = ValueUnion.psz;
648 break;
649 case VINF_GETOPT_NOT_OPTION:
650 return errorUnknownSubcommand(ValueUnion.psz);
651 default:
652 return errorGetOpt(c, &ValueUnion);
653 }
654 }
655
656 Bstr bstrProfileName;
657 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
658 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
659
660 ComObjPtr<ICloudClient> oCloudClient;
661 CHECK_ERROR2_RET(hrc, pCloudProfile,
662 CreateCloudClient(oCloudClient.asOutParam()),
663 RTEXITCODE_FAILURE);
664 RTPrintf("Pausing cloud instance with id %s...\n", strInstanceId.c_str());
665
666 ComPtr<IProgress> progress;
667 CHECK_ERROR2_RET(hrc, oCloudClient,
668 PauseInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
669 RTEXITCODE_FAILURE);
670 hrc = showProgress(progress);
671 CHECK_PROGRESS_ERROR_RET(progress, ("Pause the cloud instance failed"), RTEXITCODE_FAILURE);
672
673 if (SUCCEEDED(hrc))
674 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was paused\n",
675 strInstanceId.c_str(),
676 pCommonOpts->provider.pszProviderName,
677 pCommonOpts->profile.pszProfileName);
678
679 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
680}
681
682static RTEXITCODE terminateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
683{
684 HRESULT hrc = S_OK;
685
686 hrc = checkAndSetCommonOptions(a, pCommonOpts);
687 if (FAILED(hrc))
688 return RTEXITCODE_FAILURE;
689
690 static const RTGETOPTDEF s_aOptions[] =
691 {
692 { "--id", 'i', RTGETOPT_REQ_STRING }
693 };
694 RTGETOPTSTATE GetState;
695 RTGETOPTUNION ValueUnion;
696 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
697 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
698
699 Utf8Str strInstanceId;
700 int c;
701 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
702 {
703 switch (c)
704 {
705 case 'i':
706 strInstanceId = ValueUnion.psz;
707 break;
708 case VINF_GETOPT_NOT_OPTION:
709 return errorUnknownSubcommand(ValueUnion.psz);
710 default:
711 return errorGetOpt(c, &ValueUnion);
712 }
713 }
714
715 Bstr bstrProfileName;
716 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
717 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
718
719 ComObjPtr<ICloudClient> oCloudClient;
720 CHECK_ERROR2_RET(hrc, pCloudProfile,
721 CreateCloudClient(oCloudClient.asOutParam()),
722 RTEXITCODE_FAILURE);
723 RTPrintf("Terminating cloud instance with id %s...\n", strInstanceId.c_str());
724
725 ComPtr<IProgress> progress;
726 CHECK_ERROR2_RET(hrc, oCloudClient,
727 TerminateInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
728 RTEXITCODE_FAILURE);
729 hrc = showProgress(progress);
730 CHECK_PROGRESS_ERROR_RET(progress, ("Termination the cloud instance failed"), RTEXITCODE_FAILURE);
731
732 if (SUCCEEDED(hrc))
733 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was terminated\n",
734 strInstanceId.c_str(),
735 pCommonOpts->provider.pszProviderName,
736 pCommonOpts->profile.pszProfileName);
737
738 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
739}
740
741static RTEXITCODE handleCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
742{
743 if (a->argc < 1)
744 return errorNoSubcommand();
745
746 static const RTGETOPTDEF s_aOptions[] =
747 {
748 { "create", 1000, RTGETOPT_REQ_NOTHING },
749 { "start", 1001, RTGETOPT_REQ_NOTHING },
750 { "pause", 1002, RTGETOPT_REQ_NOTHING },
751 { "info", 1003, RTGETOPT_REQ_NOTHING },
752 { "update", 1004, RTGETOPT_REQ_NOTHING },
753 { "terminate", 1005, RTGETOPT_REQ_NOTHING }
754 };
755
756 RTGETOPTSTATE GetState;
757 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
758 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
759
760 int c;
761 RTGETOPTUNION ValueUnion;
762 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
763 {
764 switch (c)
765 {
766 /* Sub-commands: */
767 case 1000:
768// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_CREATE);
769 return createCloudInstance(a, GetState.iNext, pCommonOpts);
770 case 1001:
771 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_START);
772 return startCloudInstance(a, GetState.iNext, pCommonOpts);
773 case 1002:
774 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_PAUSE);
775 return pauseCloudInstance(a, GetState.iNext, pCommonOpts);
776 case 1003:
777 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_INFO);
778 return showCloudInstanceInfo(a, GetState.iNext, pCommonOpts);
779 case 1004:
780// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_UPDATE);
781 return updateCloudInstance(a, GetState.iNext, pCommonOpts);
782 case 1005:
783 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_TERMINATE);
784 return terminateCloudInstance(a, GetState.iNext, pCommonOpts);
785 case VINF_GETOPT_NOT_OPTION:
786 return errorUnknownSubcommand(ValueUnion.psz);
787
788 default:
789 return errorGetOpt(c, &ValueUnion);
790 }
791 }
792
793 return errorNoSubcommand();
794}
795
796RTEXITCODE handleCloud(HandlerArg *a)
797{
798 if (a->argc < 1)
799 return errorNoSubcommand();
800
801 static const RTGETOPTDEF s_aOptions[] =
802 {
803 /* common options */
804 { "--provider", 'v', RTGETOPT_REQ_STRING },
805 { "--profile", 'f', RTGETOPT_REQ_STRING },
806 { "list", 1000, RTGETOPT_REQ_NOTHING },
807 { "image", 1001, RTGETOPT_REQ_NOTHING },
808 { "instance", 1002, RTGETOPT_REQ_NOTHING },
809 { "network", 1003, RTGETOPT_REQ_NOTHING },
810 { "volume", 1004, RTGETOPT_REQ_NOTHING },
811 { "object", 1005, RTGETOPT_REQ_NOTHING }
812 };
813
814 RTGETOPTSTATE GetState;
815 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
816 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
817
818 CLOUDCOMMONOPT commonOpts = { {NULL, NULL}, {NULL, NULL} };
819 int c;
820 RTGETOPTUNION ValueUnion;
821 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
822 {
823 switch (c)
824 {
825 case 'v': // --provider
826 commonOpts.provider.pszProviderName = ValueUnion.psz;
827 break;
828 case 'f': // --profile
829 commonOpts.profile.pszProfileName = ValueUnion.psz;
830 break;
831 /* Sub-commands: */
832 case 1000:
833 return handleCloudLists(a, GetState.iNext, &commonOpts);
834 case 1002:
835 return handleCloudInstance(a, GetState.iNext, &commonOpts);
836 case VINF_GETOPT_NOT_OPTION:
837 return errorUnknownSubcommand(ValueUnion.psz);
838
839 default:
840 return errorGetOpt(c, &ValueUnion);
841 }
842 }
843
844 return errorNoSubcommand();
845}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette