VirtualBox

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

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

bugre:9404. Added parameter '--state' for the 'VBoxManage cloud list images' command. 3 general states are possible: available, disabled, deleted.

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