VirtualBox

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

Last change on this file since 79057 was 79057, checked in by vboxsync, 5 years ago

bugref:9404. Changed the state values to the lower case.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.3 KB
Line 
1/* $Id: VBoxManageCloud.cpp 79057 2019-06-10 09:29:58Z 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.virtualbox.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("run"))
144 machimeStates.push_back(CloudMachineState_Running);
145 else if (strState.equals("stop"))
146 machimeStates.push_back(CloudMachineState_Stopped);
147 else if (strState.equals("terminate"))
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("List of 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 };
251 RTGETOPTSTATE GetState;
252 RTGETOPTUNION ValueUnion;
253 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
254 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
255
256 Utf8Str strCompartmentId;
257 int c;
258 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
259 {
260 switch (c)
261 {
262 case 'c':
263 strCompartmentId = ValueUnion.psz;
264 break;
265 case VINF_GETOPT_NOT_OPTION:
266 return errorUnknownSubcommand(ValueUnion.psz);
267 default:
268 return errorGetOpt(c, &ValueUnion);
269 }
270 }
271
272 HRESULT hrc = S_OK;
273 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
274 ComPtr<ICloudProviderManager> pCloudProviderManager;
275 CHECK_ERROR2_RET(hrc, pVirtualBox,
276 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
277 RTEXITCODE_FAILURE);
278 ComPtr<ICloudProvider> pCloudProvider;
279
280 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
281 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
282 RTEXITCODE_FAILURE);
283 ComPtr<ICloudProfile> pCloudProfile;
284
285 CHECK_ERROR2_RET(hrc, pCloudProvider,
286 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
287 RTEXITCODE_FAILURE);
288 if (strCompartmentId.isNotEmpty())
289 {
290 CHECK_ERROR2_RET(hrc, pCloudProfile,
291 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
292 RTEXITCODE_FAILURE);
293 }
294 else
295 {
296 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
297 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
298 Bstr bStrCompartmentId;
299 CHECK_ERROR2_RET(hrc, pCloudProfile,
300 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
301 RTEXITCODE_FAILURE);
302 strCompartmentId = bStrCompartmentId;
303 if (strCompartmentId.isNotEmpty())
304 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
305 else
306 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
307 }
308
309 Bstr bstrProfileName;
310 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
311
312 ComObjPtr<ICloudClient> oCloudClient;
313 CHECK_ERROR2_RET(hrc, pCloudProfile,
314 CreateCloudClient(oCloudClient.asOutParam()),
315 RTEXITCODE_FAILURE);
316
317 ComPtr<IStringArray> pVMNamesHolder;
318 ComPtr<IStringArray> pVMIdsHolder;
319 com::SafeArray<BSTR> arrayVMNames;
320 com::SafeArray<BSTR> arrayVMIds;
321 ComPtr<IProgress> pProgress;
322
323 RTPrintf("Getting a list of available cloud images...\n");
324 RTPrintf("Reply is in the form \'image name\' = \'image id\'\n");
325 CHECK_ERROR2_RET(hrc, oCloudClient,
326 ListImages(CloudImageState_Available,
327 pVMNamesHolder.asOutParam(),
328 pVMIdsHolder.asOutParam(),
329 pProgress.asOutParam()),
330 RTEXITCODE_FAILURE);
331 showProgress(pProgress);
332 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list images"), RTEXITCODE_FAILURE);
333
334 CHECK_ERROR2_RET(hrc,
335 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
336 RTEXITCODE_FAILURE);
337 CHECK_ERROR2_RET(hrc,
338 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
339 RTEXITCODE_FAILURE);
340
341 RTPrintf("List of available images for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
342 bstrProfileName.raw(), strCompartmentId.c_str());
343 size_t cNames = arrayVMNames.size();
344 size_t cIds = arrayVMIds.size();
345 for (size_t k = 0; k < cNames; k++)
346 {
347 Bstr value;
348 if (k < cIds)
349 value = arrayVMIds[k];
350 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
351 }
352
353 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
354}
355
356/**
357 * General function which handles the "list" commands
358 *
359 * @returns RTEXITCODE
360 * @param a is the list of passed arguments
361 * @param iFirst is the position of the first unparsed argument in the arguments list
362 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
363 * arguments which have been already parsed before
364 */
365static RTEXITCODE handleCloudLists(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
366{
367 if (a->argc < 1)
368 return errorNoSubcommand();
369
370 static const RTGETOPTDEF s_aOptions[] =
371 {
372 { "images", 1000, RTGETOPT_REQ_NOTHING },
373 { "instances", 1001, RTGETOPT_REQ_NOTHING },
374 { "networks", 1002, RTGETOPT_REQ_NOTHING },
375 { "subnets", 1003, RTGETOPT_REQ_NOTHING },
376 { "vcns", 1004, RTGETOPT_REQ_NOTHING },
377 { "objects", 1005, RTGETOPT_REQ_NOTHING }
378 };
379
380 Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
381 Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
382
383 /* check for required options */
384 if (bstrProvider.isEmpty())
385 return errorSyntax(USAGE_S_NEWCMD, "Parameter --provider is required");
386 if (bstrProfile.isEmpty())
387 return errorSyntax(USAGE_S_NEWCMD, "Parameter --profile is required");
388
389 RTGETOPTSTATE GetState;
390 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
391 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
392
393 int c;
394 RTGETOPTUNION ValueUnion;
395 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
396 {
397 switch (c)
398 {
399 case 1000:
400// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_LIST);
401 return listCloudImages(a, GetState.iNext, pCommonOpts);
402 case 1001:
403// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_LIST);
404 return listCloudInstances(a, GetState.iNext, pCommonOpts);
405 case VINF_GETOPT_NOT_OPTION:
406 return errorUnknownSubcommand(ValueUnion.psz);
407
408 default:
409 return errorGetOpt(c, &ValueUnion);
410 }
411 }
412
413 return errorNoSubcommand();
414}
415
416static RTEXITCODE createCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
417{
418 RT_NOREF(a);
419 RT_NOREF(iFirst);
420 RT_NOREF(pCommonOpts);
421 return RTEXITCODE_SUCCESS;
422}
423
424static RTEXITCODE updateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
425{
426 RT_NOREF(a);
427 RT_NOREF(iFirst);
428 RT_NOREF(pCommonOpts);
429 return RTEXITCODE_SUCCESS;
430}
431
432static RTEXITCODE showCloudInstanceInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
433{
434 HRESULT hrc = S_OK;
435
436 hrc = checkAndSetCommonOptions(a, pCommonOpts);
437 if (FAILED(hrc))
438 return RTEXITCODE_FAILURE;
439
440 static const RTGETOPTDEF s_aOptions[] =
441 {
442 { "--id", 'i', RTGETOPT_REQ_STRING }
443 };
444 RTGETOPTSTATE GetState;
445 RTGETOPTUNION ValueUnion;
446 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
447 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
448
449 Utf8Str strInstanceId;
450 int c;
451 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
452 {
453 switch (c)
454 {
455 case 'i':
456 strInstanceId = ValueUnion.psz;
457 break;
458 case VINF_GETOPT_NOT_OPTION:
459 return errorUnknownSubcommand(ValueUnion.psz);
460 default:
461 return errorGetOpt(c, &ValueUnion);
462 }
463 }
464
465 Bstr bstrProfileName;
466 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
467 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
468
469 ComObjPtr<ICloudClient> oCloudClient;
470 CHECK_ERROR2_RET(hrc, pCloudProfile,
471 CreateCloudClient(oCloudClient.asOutParam()),
472 RTEXITCODE_FAILURE);
473 RTPrintf("Getting information about cloud instance with id %s...\n", strInstanceId.c_str());
474 RTPrintf("Reply is in the form \'setting name\' = \'value\'\n");
475
476 ComPtr<IAppliance> pAppliance;
477 CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
478
479 com::SafeIfaceArray<IVirtualSystemDescription> vsdArray;
480 ULONG requestedVSDnums = 1;
481 ULONG newVSDnums = 0;
482 CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(requestedVSDnums, &newVSDnums), RTEXITCODE_FAILURE);
483 if (requestedVSDnums != newVSDnums)
484 return RTEXITCODE_FAILURE;
485
486 CHECK_ERROR2_RET(hrc, pAppliance, COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(vsdArray)), RTEXITCODE_FAILURE);
487 ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
488
489 ComPtr<IProgress> progress;
490 CHECK_ERROR2_RET(hrc, oCloudClient,
491 GetInstanceInfo(Bstr(strInstanceId.c_str()).raw(), instanceDescription, progress.asOutParam()),
492 RTEXITCODE_FAILURE);
493
494 hrc = showProgress(progress);
495 CHECK_PROGRESS_ERROR_RET(progress, ("Getting information about cloud instance failed"), RTEXITCODE_FAILURE);
496
497 RTPrintf("Cloud instance info (provider '%s'):\n",
498 pCommonOpts->provider.pszProviderName);
499
500 struct vsdHReadable {
501 VirtualSystemDescriptionType_T vsdType;
502 Utf8Str strFound;
503 Utf8Str strNotFound;
504 };
505
506 size_t vsdHReadableArraySize = 9;//the number of items in the vsdHReadableArray
507 vsdHReadable vsdHReadableArray[9] = {
508 {VirtualSystemDescriptionType_CloudDomain, "Availability domain = '%ls'\n", "Availability domain wasn't found\n"},
509 {VirtualSystemDescriptionType_Name, "Instance displayed name = '%ls'\n", "Instance displayed name wasn't found\n"},
510 {VirtualSystemDescriptionType_CloudInstanceState, "Instance state = '%ls'\n", "Instance state wasn't found\n"},
511 {VirtualSystemDescriptionType_CloudInstanceId, "Instance Id = '%ls'\n", "Instance Id wasn't found\n"},
512 {VirtualSystemDescriptionType_CloudImageId, "Bootable image Id = '%ls'\n",
513 "Image Id whom the instance is booted up wasn't found\n"},
514 {VirtualSystemDescriptionType_CloudInstanceShape, "Shape of the instance = '%ls'\n",
515 "The shape of the instance wasn't found\n"},
516 {VirtualSystemDescriptionType_OS, "Type of guest OS = '%ls'\n", "Type of guest OS wasn't found.\n"},
517 {VirtualSystemDescriptionType_Memory, "RAM = '%ls MB'\n", "Value for RAM wasn't found\n"},
518 {VirtualSystemDescriptionType_CPU, "CPUs = '%ls'\n", "Numbers of CPUs weren't found\n"}
519 };
520
521 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
522 com::SafeArray<BSTR> aRefs;
523 com::SafeArray<BSTR> aOvfValues;
524 com::SafeArray<BSTR> aVBoxValues;
525 com::SafeArray<BSTR> aExtraConfigValues;
526
527 for (size_t i=0; i<vsdHReadableArraySize ; ++i)
528 {
529 hrc = instanceDescription->GetDescriptionByType(vsdHReadableArray[i].vsdType,
530 ComSafeArrayAsOutParam(retTypes),
531 ComSafeArrayAsOutParam(aRefs),
532 ComSafeArrayAsOutParam(aOvfValues),
533 ComSafeArrayAsOutParam(aVBoxValues),
534 ComSafeArrayAsOutParam(aExtraConfigValues));
535 if (FAILED(hrc) || aVBoxValues.size() == 0)
536 LogRel((vsdHReadableArray[i].strNotFound.c_str()));
537 else
538 RTPrintf(vsdHReadableArray[i].strFound.c_str(), aVBoxValues[0]);
539
540 retTypes.setNull();
541 aRefs.setNull();
542 aOvfValues.setNull();
543 aVBoxValues.setNull();
544 aExtraConfigValues.setNull();
545 }
546
547 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
548}
549
550static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
551{
552 HRESULT hrc = S_OK;
553 hrc = checkAndSetCommonOptions(a, pCommonOpts);
554 if (FAILED(hrc))
555 return RTEXITCODE_FAILURE;
556
557 static const RTGETOPTDEF s_aOptions[] =
558 {
559 { "--id", 'i', RTGETOPT_REQ_STRING }
560 };
561 RTGETOPTSTATE GetState;
562 RTGETOPTUNION ValueUnion;
563 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
564 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
565
566 Utf8Str strInstanceId;
567 int c;
568 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
569 {
570 switch (c)
571 {
572 case 'i':
573 strInstanceId = ValueUnion.psz;
574 break;
575 case VINF_GETOPT_NOT_OPTION:
576 return errorUnknownSubcommand(ValueUnion.psz);
577 default:
578 return errorGetOpt(c, &ValueUnion);
579 }
580 }
581
582 Bstr bstrProfileName;
583 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
584 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
585
586 ComObjPtr<ICloudClient> oCloudClient;
587 CHECK_ERROR2_RET(hrc, pCloudProfile,
588 CreateCloudClient(oCloudClient.asOutParam()),
589 RTEXITCODE_FAILURE);
590 RTPrintf("Starting cloud instance with id %s...\n", strInstanceId.c_str());
591
592 ComPtr<IProgress> progress;
593 CHECK_ERROR2_RET(hrc, oCloudClient,
594 StartInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
595 RTEXITCODE_FAILURE);
596 hrc = showProgress(progress);
597 CHECK_PROGRESS_ERROR_RET(progress, ("Starting the cloud instance failed"), RTEXITCODE_FAILURE);
598
599 if (SUCCEEDED(hrc))
600 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was started\n",
601 strInstanceId.c_str(),
602 pCommonOpts->provider.pszProviderName,
603 pCommonOpts->profile.pszProfileName);
604
605 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
606}
607
608static RTEXITCODE pauseCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
609{
610 HRESULT hrc = S_OK;
611 hrc = checkAndSetCommonOptions(a, pCommonOpts);
612
613 if (FAILED(hrc))
614 return RTEXITCODE_FAILURE;
615
616 static const RTGETOPTDEF s_aOptions[] =
617 {
618 { "--id", 'i', RTGETOPT_REQ_STRING }
619 };
620 RTGETOPTSTATE GetState;
621 RTGETOPTUNION ValueUnion;
622 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
623 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
624
625 Utf8Str strInstanceId;
626 int c;
627 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
628 {
629 switch (c)
630 {
631 case 'i':
632 strInstanceId = ValueUnion.psz;
633 break;
634 case VINF_GETOPT_NOT_OPTION:
635 return errorUnknownSubcommand(ValueUnion.psz);
636 default:
637 return errorGetOpt(c, &ValueUnion);
638 }
639 }
640
641 Bstr bstrProfileName;
642 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
643 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
644
645 ComObjPtr<ICloudClient> oCloudClient;
646 CHECK_ERROR2_RET(hrc, pCloudProfile,
647 CreateCloudClient(oCloudClient.asOutParam()),
648 RTEXITCODE_FAILURE);
649 RTPrintf("Pausing cloud instance with id %s...\n", strInstanceId.c_str());
650
651 ComPtr<IProgress> progress;
652 CHECK_ERROR2_RET(hrc, oCloudClient,
653 PauseInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
654 RTEXITCODE_FAILURE);
655 hrc = showProgress(progress);
656 CHECK_PROGRESS_ERROR_RET(progress, ("Pause the cloud instance failed"), RTEXITCODE_FAILURE);
657
658 if (SUCCEEDED(hrc))
659 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was paused\n",
660 strInstanceId.c_str(),
661 pCommonOpts->provider.pszProviderName,
662 pCommonOpts->profile.pszProfileName);
663
664 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
665}
666
667static RTEXITCODE terminateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
668{
669 HRESULT hrc = S_OK;
670
671 hrc = checkAndSetCommonOptions(a, pCommonOpts);
672 if (FAILED(hrc))
673 return RTEXITCODE_FAILURE;
674
675 static const RTGETOPTDEF s_aOptions[] =
676 {
677 { "--id", 'i', RTGETOPT_REQ_STRING }
678 };
679 RTGETOPTSTATE GetState;
680 RTGETOPTUNION ValueUnion;
681 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
682 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
683
684 Utf8Str strInstanceId;
685 int c;
686 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
687 {
688 switch (c)
689 {
690 case 'i':
691 strInstanceId = ValueUnion.psz;
692 break;
693 case VINF_GETOPT_NOT_OPTION:
694 return errorUnknownSubcommand(ValueUnion.psz);
695 default:
696 return errorGetOpt(c, &ValueUnion);
697 }
698 }
699
700 Bstr bstrProfileName;
701 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
702 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
703
704 ComObjPtr<ICloudClient> oCloudClient;
705 CHECK_ERROR2_RET(hrc, pCloudProfile,
706 CreateCloudClient(oCloudClient.asOutParam()),
707 RTEXITCODE_FAILURE);
708 RTPrintf("Terminating cloud instance with id %s...\n", strInstanceId.c_str());
709
710 ComPtr<IProgress> progress;
711 CHECK_ERROR2_RET(hrc, oCloudClient,
712 TerminateInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
713 RTEXITCODE_FAILURE);
714 hrc = showProgress(progress);
715 CHECK_PROGRESS_ERROR_RET(progress, ("Termination the cloud instance failed"), RTEXITCODE_FAILURE);
716
717 if (SUCCEEDED(hrc))
718 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was terminated\n",
719 strInstanceId.c_str(),
720 pCommonOpts->provider.pszProviderName,
721 pCommonOpts->profile.pszProfileName);
722
723 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
724}
725
726static RTEXITCODE handleCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
727{
728 if (a->argc < 1)
729 return errorNoSubcommand();
730
731 static const RTGETOPTDEF s_aOptions[] =
732 {
733 { "create", 1000, RTGETOPT_REQ_NOTHING },
734 { "start", 1001, RTGETOPT_REQ_NOTHING },
735 { "pause", 1002, RTGETOPT_REQ_NOTHING },
736 { "info", 1003, RTGETOPT_REQ_NOTHING },
737 { "update", 1004, RTGETOPT_REQ_NOTHING },
738 { "terminate", 1005, RTGETOPT_REQ_NOTHING }
739 };
740
741 RTGETOPTSTATE GetState;
742 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
743 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
744
745 int c;
746 RTGETOPTUNION ValueUnion;
747 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
748 {
749 switch (c)
750 {
751 /* Sub-commands: */
752 case 1000:
753// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_CREATE);
754 return createCloudInstance(a, GetState.iNext, pCommonOpts);
755 case 1001:
756 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_START);
757 return startCloudInstance(a, GetState.iNext, pCommonOpts);
758 case 1002:
759 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_PAUSE);
760 return pauseCloudInstance(a, GetState.iNext, pCommonOpts);
761 case 1003:
762 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_INFO);
763 return showCloudInstanceInfo(a, GetState.iNext, pCommonOpts);
764 case 1004:
765// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_UPDATE);
766 return updateCloudInstance(a, GetState.iNext, pCommonOpts);
767 case 1005:
768 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_TERMINATE);
769 return terminateCloudInstance(a, GetState.iNext, pCommonOpts);
770 case VINF_GETOPT_NOT_OPTION:
771 return errorUnknownSubcommand(ValueUnion.psz);
772
773 default:
774 return errorGetOpt(c, &ValueUnion);
775 }
776 }
777
778 return errorNoSubcommand();
779}
780
781RTEXITCODE handleCloud(HandlerArg *a)
782{
783 if (a->argc < 1)
784 return errorNoSubcommand();
785
786 static const RTGETOPTDEF s_aOptions[] =
787 {
788 /* common options */
789 { "--provider", 'v', RTGETOPT_REQ_STRING },
790 { "--profile", 'f', RTGETOPT_REQ_STRING },
791 { "list", 1000, RTGETOPT_REQ_NOTHING },
792 { "image", 1001, RTGETOPT_REQ_NOTHING },
793 { "instance", 1002, RTGETOPT_REQ_NOTHING },
794 { "network", 1003, RTGETOPT_REQ_NOTHING },
795 { "volume", 1004, RTGETOPT_REQ_NOTHING },
796 { "object", 1005, RTGETOPT_REQ_NOTHING }
797 };
798
799 RTGETOPTSTATE GetState;
800 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
801 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
802
803 CLOUDCOMMONOPT commonOpts = { {NULL, NULL}, {NULL, NULL} };
804 int c;
805 RTGETOPTUNION ValueUnion;
806 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
807 {
808 switch (c)
809 {
810 case 'v': // --provider
811 commonOpts.provider.pszProviderName = ValueUnion.psz;
812 break;
813 case 'f': // --profile
814 commonOpts.profile.pszProfileName = ValueUnion.psz;
815 break;
816 /* Sub-commands: */
817 case 1000:
818 return handleCloudLists(a, GetState.iNext, &commonOpts);
819 case 1002:
820 return handleCloudInstance(a, GetState.iNext, &commonOpts);
821 case VINF_GETOPT_NOT_OPTION:
822 return errorUnknownSubcommand(ValueUnion.psz);
823
824 default:
825 return errorGetOpt(c, &ValueUnion);
826 }
827 }
828
829 return errorNoSubcommand();
830}
Note: See TracBrowser for help on using the repository browser.

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