VirtualBox

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

Last change on this file since 79033 was 79033, checked in by vboxsync, 6 years ago

bugref:9404. Changed the command \'list instances\'. Now the requested states can be combined together in the array.

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