VirtualBox

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

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

bugre:9481. OCICloudClient::getImageInfo(): removed the parameter "const std::vector<com::Utf8Str> &aParameters". It's not needed for now. OCICloudClient::importImage(): added the parameter "const com::Utf8Str &aUid" - OCI image id. It's better than pass the image id in the "const std::vector<com::Utf8Str> &aParameters".

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.7 KB
Line 
1/* $Id: VBoxManageCloud.cpp 79727 2019-07-12 11:37:46Z 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> machineStates;
141 if (strState.isNotEmpty())
142 {
143 if (strState.equals("running"))
144 machineStates.push_back(CloudMachineState_Running);
145 else if (strState.equals("paused"))
146 machineStates.push_back(CloudMachineState_Stopped);
147 else if (strState.equals("terminated"))
148 machineStates.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(machineStates),
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 else if (strState.equals("exporting"))
287 imageStates.push_back(CloudImageState_Exporting);
288 else if (strState.equals("importing"))
289 imageStates.push_back(CloudImageState_Importing);
290 }
291
292 HRESULT hrc = S_OK;
293 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
294 ComPtr<ICloudProviderManager> pCloudProviderManager;
295 CHECK_ERROR2_RET(hrc, pVirtualBox,
296 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
297 RTEXITCODE_FAILURE);
298 ComPtr<ICloudProvider> pCloudProvider;
299
300 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
301 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
302 RTEXITCODE_FAILURE);
303 ComPtr<ICloudProfile> pCloudProfile;
304
305 CHECK_ERROR2_RET(hrc, pCloudProvider,
306 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
307 RTEXITCODE_FAILURE);
308 if (strCompartmentId.isNotEmpty())
309 {
310 CHECK_ERROR2_RET(hrc, pCloudProfile,
311 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
312 RTEXITCODE_FAILURE);
313 }
314 else
315 {
316 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
317 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
318 Bstr bStrCompartmentId;
319 CHECK_ERROR2_RET(hrc, pCloudProfile,
320 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
321 RTEXITCODE_FAILURE);
322 strCompartmentId = bStrCompartmentId;
323 if (strCompartmentId.isNotEmpty())
324 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
325 else
326 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
327 }
328
329 Bstr bstrProfileName;
330 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
331
332 ComObjPtr<ICloudClient> oCloudClient;
333 CHECK_ERROR2_RET(hrc, pCloudProfile,
334 CreateCloudClient(oCloudClient.asOutParam()),
335 RTEXITCODE_FAILURE);
336
337 ComPtr<IStringArray> pVMNamesHolder;
338 ComPtr<IStringArray> pVMIdsHolder;
339 com::SafeArray<BSTR> arrayVMNames;
340 com::SafeArray<BSTR> arrayVMIds;
341 ComPtr<IProgress> pProgress;
342
343 RTPrintf("Reply is in the form \'image name\' = \'image id\'\n");
344 CHECK_ERROR2_RET(hrc, oCloudClient,
345 ListImages(ComSafeArrayAsInParam(imageStates),
346 pVMNamesHolder.asOutParam(),
347 pVMIdsHolder.asOutParam(),
348 pProgress.asOutParam()),
349 RTEXITCODE_FAILURE);
350 showProgress(pProgress);
351 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list images"), RTEXITCODE_FAILURE);
352
353 CHECK_ERROR2_RET(hrc,
354 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
355 RTEXITCODE_FAILURE);
356 CHECK_ERROR2_RET(hrc,
357 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
358 RTEXITCODE_FAILURE);
359
360 RTPrintf("The list of the images for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
361 bstrProfileName.raw(), strCompartmentId.c_str());
362 size_t cNames = arrayVMNames.size();
363 size_t cIds = arrayVMIds.size();
364 for (size_t k = 0; k < cNames; k++)
365 {
366 Bstr value;
367 if (k < cIds)
368 value = arrayVMIds[k];
369 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
370 }
371
372 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
373}
374
375/**
376 * General function which handles the "list" commands
377 *
378 * @returns RTEXITCODE
379 * @param a is the list of passed arguments
380 * @param iFirst is the position of the first unparsed argument in the arguments list
381 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
382 * arguments which have been already parsed before
383 */
384static RTEXITCODE handleCloudLists(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
385{
386 if (a->argc < 1)
387 return errorNoSubcommand();
388
389 static const RTGETOPTDEF s_aOptions[] =
390 {
391 { "images", 1000, RTGETOPT_REQ_NOTHING },
392 { "instances", 1001, RTGETOPT_REQ_NOTHING },
393 { "networks", 1002, RTGETOPT_REQ_NOTHING },
394 { "subnets", 1003, RTGETOPT_REQ_NOTHING },
395 { "vcns", 1004, RTGETOPT_REQ_NOTHING },
396 { "objects", 1005, RTGETOPT_REQ_NOTHING }
397 };
398
399 Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
400 Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
401
402 /* check for required options */
403 if (bstrProvider.isEmpty())
404 return errorSyntax(USAGE_S_NEWCMD, "Parameter --provider is required");
405 if (bstrProfile.isEmpty())
406 return errorSyntax(USAGE_S_NEWCMD, "Parameter --profile is required");
407
408 RTGETOPTSTATE GetState;
409 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
410 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
411
412 int c;
413 RTGETOPTUNION ValueUnion;
414 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
415 {
416 switch (c)
417 {
418 case 1000:
419// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_LIST);
420 return listCloudImages(a, GetState.iNext, pCommonOpts);
421 case 1001:
422// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_LIST);
423 return listCloudInstances(a, GetState.iNext, pCommonOpts);
424 case VINF_GETOPT_NOT_OPTION:
425 return errorUnknownSubcommand(ValueUnion.psz);
426
427 default:
428 return errorGetOpt(c, &ValueUnion);
429 }
430 }
431
432 return errorNoSubcommand();
433}
434
435static RTEXITCODE createCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
436{
437 RT_NOREF(a);
438 RT_NOREF(iFirst);
439 RT_NOREF(pCommonOpts);
440 return RTEXITCODE_SUCCESS;
441}
442
443static RTEXITCODE updateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
444{
445 RT_NOREF(a);
446 RT_NOREF(iFirst);
447 RT_NOREF(pCommonOpts);
448 return RTEXITCODE_SUCCESS;
449}
450
451static RTEXITCODE showCloudInstanceInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
452{
453 HRESULT hrc = S_OK;
454
455 hrc = checkAndSetCommonOptions(a, pCommonOpts);
456 if (FAILED(hrc))
457 return RTEXITCODE_FAILURE;
458
459 static const RTGETOPTDEF s_aOptions[] =
460 {
461 { "--id", 'i', RTGETOPT_REQ_STRING }
462 };
463 RTGETOPTSTATE GetState;
464 RTGETOPTUNION ValueUnion;
465 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
466 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
467
468 Utf8Str strInstanceId;
469 int c;
470 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
471 {
472 switch (c)
473 {
474 case 'i':
475 strInstanceId = ValueUnion.psz;
476 break;
477 case VINF_GETOPT_NOT_OPTION:
478 return errorUnknownSubcommand(ValueUnion.psz);
479 default:
480 return errorGetOpt(c, &ValueUnion);
481 }
482 }
483
484 Bstr bstrProfileName;
485 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
486 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
487
488 ComObjPtr<ICloudClient> oCloudClient;
489 CHECK_ERROR2_RET(hrc, pCloudProfile,
490 CreateCloudClient(oCloudClient.asOutParam()),
491 RTEXITCODE_FAILURE);
492 RTPrintf("Getting information about cloud instance with id %s...\n", strInstanceId.c_str());
493 RTPrintf("Reply is in the form \'setting name\' = \'value\'\n");
494
495 ComPtr<IAppliance> pAppliance;
496 CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
497
498 com::SafeIfaceArray<IVirtualSystemDescription> vsdArray;
499 ULONG requestedVSDnums = 1;
500 ULONG newVSDnums = 0;
501 CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(requestedVSDnums, &newVSDnums), RTEXITCODE_FAILURE);
502 if (requestedVSDnums != newVSDnums)
503 return RTEXITCODE_FAILURE;
504
505 CHECK_ERROR2_RET(hrc, pAppliance, COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(vsdArray)), RTEXITCODE_FAILURE);
506 ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
507
508 ComPtr<IProgress> progress;
509 CHECK_ERROR2_RET(hrc, oCloudClient,
510 GetInstanceInfo(Bstr(strInstanceId.c_str()).raw(), instanceDescription, progress.asOutParam()),
511 RTEXITCODE_FAILURE);
512
513 hrc = showProgress(progress);
514 CHECK_PROGRESS_ERROR_RET(progress, ("Getting information about cloud instance failed"), RTEXITCODE_FAILURE);
515
516 RTPrintf("Cloud instance info (provider '%s'):\n",
517 pCommonOpts->provider.pszProviderName);
518
519 struct vsdHReadable {
520 VirtualSystemDescriptionType_T vsdType;
521 Utf8Str strFound;
522 Utf8Str strNotFound;
523 };
524
525 size_t vsdHReadableArraySize = 9;//the number of items in the vsdHReadableArray
526 vsdHReadable vsdHReadableArray[9] = {
527 {VirtualSystemDescriptionType_CloudDomain, "Availability domain = '%ls'\n", "Availability domain wasn't found\n"},
528 {VirtualSystemDescriptionType_Name, "Instance displayed name = '%ls'\n", "Instance displayed name wasn't found\n"},
529 {VirtualSystemDescriptionType_CloudInstanceState, "Instance state = '%ls'\n", "Instance state wasn't found\n"},
530 {VirtualSystemDescriptionType_CloudInstanceId, "Instance Id = '%ls'\n", "Instance Id wasn't found\n"},
531 {VirtualSystemDescriptionType_CloudImageId, "Bootable image Id = '%ls'\n",
532 "Image Id whom the instance is booted up wasn't found\n"},
533 {VirtualSystemDescriptionType_CloudInstanceShape, "Shape of the instance = '%ls'\n",
534 "The shape of the instance wasn't found\n"},
535 {VirtualSystemDescriptionType_OS, "Type of guest OS = '%ls'\n", "Type of guest OS wasn't found.\n"},
536 {VirtualSystemDescriptionType_Memory, "RAM = '%ls MB'\n", "Value for RAM wasn't found\n"},
537 {VirtualSystemDescriptionType_CPU, "CPUs = '%ls'\n", "Numbers of CPUs weren't found\n"}
538 };
539
540 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
541 com::SafeArray<BSTR> aRefs;
542 com::SafeArray<BSTR> aOvfValues;
543 com::SafeArray<BSTR> aVBoxValues;
544 com::SafeArray<BSTR> aExtraConfigValues;
545
546 for (size_t i=0; i<vsdHReadableArraySize ; ++i)
547 {
548 hrc = instanceDescription->GetDescriptionByType(vsdHReadableArray[i].vsdType,
549 ComSafeArrayAsOutParam(retTypes),
550 ComSafeArrayAsOutParam(aRefs),
551 ComSafeArrayAsOutParam(aOvfValues),
552 ComSafeArrayAsOutParam(aVBoxValues),
553 ComSafeArrayAsOutParam(aExtraConfigValues));
554 if (FAILED(hrc) || aVBoxValues.size() == 0)
555 LogRel((vsdHReadableArray[i].strNotFound.c_str()));
556 else
557 RTPrintf(vsdHReadableArray[i].strFound.c_str(), aVBoxValues[0]);
558
559 retTypes.setNull();
560 aRefs.setNull();
561 aOvfValues.setNull();
562 aVBoxValues.setNull();
563 aExtraConfigValues.setNull();
564 }
565
566 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
567}
568
569static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
570{
571 HRESULT hrc = S_OK;
572 hrc = checkAndSetCommonOptions(a, pCommonOpts);
573 if (FAILED(hrc))
574 return RTEXITCODE_FAILURE;
575
576 static const RTGETOPTDEF s_aOptions[] =
577 {
578 { "--id", 'i', RTGETOPT_REQ_STRING }
579 };
580 RTGETOPTSTATE GetState;
581 RTGETOPTUNION ValueUnion;
582 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
583 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
584
585 Utf8Str strInstanceId;
586 int c;
587 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
588 {
589 switch (c)
590 {
591 case 'i':
592 strInstanceId = ValueUnion.psz;
593 break;
594 case VINF_GETOPT_NOT_OPTION:
595 return errorUnknownSubcommand(ValueUnion.psz);
596 default:
597 return errorGetOpt(c, &ValueUnion);
598 }
599 }
600
601 Bstr bstrProfileName;
602 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
603 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
604
605 ComObjPtr<ICloudClient> oCloudClient;
606 CHECK_ERROR2_RET(hrc, pCloudProfile,
607 CreateCloudClient(oCloudClient.asOutParam()),
608 RTEXITCODE_FAILURE);
609 RTPrintf("Starting cloud instance with id %s...\n", strInstanceId.c_str());
610
611 ComPtr<IProgress> progress;
612 CHECK_ERROR2_RET(hrc, oCloudClient,
613 StartInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
614 RTEXITCODE_FAILURE);
615 hrc = showProgress(progress);
616 CHECK_PROGRESS_ERROR_RET(progress, ("Starting the cloud instance failed"), RTEXITCODE_FAILURE);
617
618 if (SUCCEEDED(hrc))
619 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was started\n",
620 strInstanceId.c_str(),
621 pCommonOpts->provider.pszProviderName,
622 pCommonOpts->profile.pszProfileName);
623
624 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
625}
626
627static RTEXITCODE pauseCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
628{
629 HRESULT hrc = S_OK;
630 hrc = checkAndSetCommonOptions(a, pCommonOpts);
631
632 if (FAILED(hrc))
633 return RTEXITCODE_FAILURE;
634
635 static const RTGETOPTDEF s_aOptions[] =
636 {
637 { "--id", 'i', RTGETOPT_REQ_STRING }
638 };
639 RTGETOPTSTATE GetState;
640 RTGETOPTUNION ValueUnion;
641 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
642 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
643
644 Utf8Str strInstanceId;
645 int c;
646 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
647 {
648 switch (c)
649 {
650 case 'i':
651 strInstanceId = ValueUnion.psz;
652 break;
653 case VINF_GETOPT_NOT_OPTION:
654 return errorUnknownSubcommand(ValueUnion.psz);
655 default:
656 return errorGetOpt(c, &ValueUnion);
657 }
658 }
659
660 Bstr bstrProfileName;
661 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
662 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
663
664 ComObjPtr<ICloudClient> oCloudClient;
665 CHECK_ERROR2_RET(hrc, pCloudProfile,
666 CreateCloudClient(oCloudClient.asOutParam()),
667 RTEXITCODE_FAILURE);
668 RTPrintf("Pausing cloud instance with id %s...\n", strInstanceId.c_str());
669
670 ComPtr<IProgress> progress;
671 CHECK_ERROR2_RET(hrc, oCloudClient,
672 PauseInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
673 RTEXITCODE_FAILURE);
674 hrc = showProgress(progress);
675 CHECK_PROGRESS_ERROR_RET(progress, ("Pause the cloud instance failed"), RTEXITCODE_FAILURE);
676
677 if (SUCCEEDED(hrc))
678 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was paused\n",
679 strInstanceId.c_str(),
680 pCommonOpts->provider.pszProviderName,
681 pCommonOpts->profile.pszProfileName);
682
683 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
684}
685
686static RTEXITCODE terminateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
687{
688 HRESULT hrc = S_OK;
689
690 hrc = checkAndSetCommonOptions(a, pCommonOpts);
691 if (FAILED(hrc))
692 return RTEXITCODE_FAILURE;
693
694 static const RTGETOPTDEF s_aOptions[] =
695 {
696 { "--id", 'i', RTGETOPT_REQ_STRING }
697 };
698 RTGETOPTSTATE GetState;
699 RTGETOPTUNION ValueUnion;
700 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
701 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
702
703 Utf8Str strInstanceId;
704 int c;
705 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
706 {
707 switch (c)
708 {
709 case 'i':
710 strInstanceId = ValueUnion.psz;
711 break;
712 case VINF_GETOPT_NOT_OPTION:
713 return errorUnknownSubcommand(ValueUnion.psz);
714 default:
715 return errorGetOpt(c, &ValueUnion);
716 }
717 }
718
719 Bstr bstrProfileName;
720 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
721 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
722
723 ComObjPtr<ICloudClient> oCloudClient;
724 CHECK_ERROR2_RET(hrc, pCloudProfile,
725 CreateCloudClient(oCloudClient.asOutParam()),
726 RTEXITCODE_FAILURE);
727 RTPrintf("Terminating cloud instance with id %s...\n", strInstanceId.c_str());
728
729 ComPtr<IProgress> progress;
730 CHECK_ERROR2_RET(hrc, oCloudClient,
731 TerminateInstance(Bstr(strInstanceId.c_str()).raw(), progress.asOutParam()),
732 RTEXITCODE_FAILURE);
733 hrc = showProgress(progress);
734 CHECK_PROGRESS_ERROR_RET(progress, ("Termination the cloud instance failed"), RTEXITCODE_FAILURE);
735
736 if (SUCCEEDED(hrc))
737 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was terminated\n",
738 strInstanceId.c_str(),
739 pCommonOpts->provider.pszProviderName,
740 pCommonOpts->profile.pszProfileName);
741
742 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
743}
744
745static RTEXITCODE handleCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
746{
747 if (a->argc < 1)
748 return errorNoSubcommand();
749
750 static const RTGETOPTDEF s_aOptions[] =
751 {
752 { "create", 1000, RTGETOPT_REQ_NOTHING },
753 { "start", 1001, RTGETOPT_REQ_NOTHING },
754 { "pause", 1002, RTGETOPT_REQ_NOTHING },
755 { "info", 1003, RTGETOPT_REQ_NOTHING },
756 { "update", 1004, RTGETOPT_REQ_NOTHING },
757 { "terminate", 1005, RTGETOPT_REQ_NOTHING }
758 };
759
760 RTGETOPTSTATE GetState;
761 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
762 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
763
764 int c;
765 RTGETOPTUNION ValueUnion;
766 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
767 {
768 switch (c)
769 {
770 /* Sub-commands: */
771 case 1000:
772// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_CREATE);
773 return createCloudInstance(a, GetState.iNext, pCommonOpts);
774 case 1001:
775 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_START);
776 return startCloudInstance(a, GetState.iNext, pCommonOpts);
777 case 1002:
778 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_PAUSE);
779 return pauseCloudInstance(a, GetState.iNext, pCommonOpts);
780 case 1003:
781 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_INFO);
782 return showCloudInstanceInfo(a, GetState.iNext, pCommonOpts);
783 case 1004:
784// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_UPDATE);
785 return updateCloudInstance(a, GetState.iNext, pCommonOpts);
786 case 1005:
787 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_TERMINATE);
788 return terminateCloudInstance(a, GetState.iNext, pCommonOpts);
789 case VINF_GETOPT_NOT_OPTION:
790 return errorUnknownSubcommand(ValueUnion.psz);
791
792 default:
793 return errorGetOpt(c, &ValueUnion);
794 }
795 }
796
797 return errorNoSubcommand();
798}
799
800
801static RTEXITCODE createCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
802{
803 HRESULT hrc = S_OK;
804 hrc = checkAndSetCommonOptions(a, pCommonOpts);
805 if (FAILED(hrc))
806 return RTEXITCODE_FAILURE;
807
808 static const RTGETOPTDEF s_aOptions[] =
809 {
810 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
811 { "--instance-id", 'i', RTGETOPT_REQ_STRING },
812 { "--display-name", 'd', RTGETOPT_REQ_STRING }
813 };
814 RTGETOPTSTATE GetState;
815 RTGETOPTUNION ValueUnion;
816 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
817 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
818
819 Utf8Str strCompartmentId;
820 Utf8Str strInstanceId;
821 Utf8Str strDisplayName;
822 com::SafeArray<BSTR> parameters;
823
824 int c;
825 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
826 {
827 switch (c)
828 {
829 case 'c':
830 strCompartmentId=ValueUnion.psz;
831 Bstr(Utf8Str("compartment-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
832 break;
833 case 'i':
834 strInstanceId=ValueUnion.psz;
835 Bstr(Utf8Str("instance-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
836 break;
837 case 'd':
838 strDisplayName=ValueUnion.psz;
839 Bstr(Utf8Str("display-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
840 break;
841 case VINF_GETOPT_NOT_OPTION:
842 return errorUnknownSubcommand(ValueUnion.psz);
843 default:
844 return errorGetOpt(c, &ValueUnion);
845 }
846 }
847
848 Bstr bstrProfileName;
849 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
850 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
851
852 ComObjPtr<ICloudClient> oCloudClient;
853 CHECK_ERROR2_RET(hrc, pCloudProfile,
854 CreateCloudClient(oCloudClient.asOutParam()),
855 RTEXITCODE_FAILURE);
856 RTPrintf("Creating cloud image with name \'%s\' from the instance \'%s\'...\n",
857 strDisplayName.c_str(), strInstanceId.c_str());
858
859 ComPtr<IProgress> progress;
860 CHECK_ERROR2_RET(hrc, oCloudClient,
861 CreateImage(ComSafeArrayAsInParam(parameters), progress.asOutParam()),
862 RTEXITCODE_FAILURE);
863 hrc = showProgress(progress);
864 CHECK_PROGRESS_ERROR_RET(progress, ("Creating cloud image failed"), RTEXITCODE_FAILURE);
865
866 if (SUCCEEDED(hrc))
867 RTPrintf("Cloud image was created successfully\n");
868
869 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
870}
871
872
873static RTEXITCODE exportCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
874{
875 HRESULT hrc = S_OK;
876 hrc = checkAndSetCommonOptions(a, pCommonOpts);
877 if (FAILED(hrc))
878 return RTEXITCODE_FAILURE;
879
880 static const RTGETOPTDEF s_aOptions[] =
881 {
882 { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
883 { "--object-name", 'o', RTGETOPT_REQ_STRING },
884 { "--id", 'i', RTGETOPT_REQ_STRING }
885 };
886 RTGETOPTSTATE GetState;
887 RTGETOPTUNION ValueUnion;
888 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
889 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
890
891 Utf8Str strBucketName;
892 Utf8Str strObjectName;
893 Utf8Str strImageId;
894 com::SafeArray<BSTR> parameters;
895
896 int c;
897 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
898 {
899 switch (c)
900 {
901 case 'b':
902 strBucketName=ValueUnion.psz;
903 Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
904 break;
905 case 'o':
906 strObjectName=ValueUnion.psz;
907 Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
908 break;
909 case 'i':
910 strImageId=ValueUnion.psz;
911 Bstr(Utf8Str("image-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
912 break;
913 case VINF_GETOPT_NOT_OPTION:
914 return errorUnknownSubcommand(ValueUnion.psz);
915 default:
916 return errorGetOpt(c, &ValueUnion);
917 }
918 }
919
920 Bstr bstrProfileName;
921 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
922 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
923
924 ComObjPtr<ICloudClient> oCloudClient;
925 CHECK_ERROR2_RET(hrc, pCloudProfile,
926 CreateCloudClient(oCloudClient.asOutParam()),
927 RTEXITCODE_FAILURE);
928 RTPrintf("Exporting image \'%s\' to the Cloud with name \'%s\'...\n", strImageId.c_str(), strObjectName.c_str());
929
930 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
931 SafeIfaceArray<IMedium> aImageList;
932 CHECK_ERROR2_RET(hrc, pVirtualBox,
933 COMGETTER(HardDisks)(ComSafeArrayAsOutParam(aImageList)),
934 RTEXITCODE_FAILURE);
935
936 ComPtr<IMedium> pImage;
937 size_t cImages = aImageList.size();
938 bool fFound = false;
939 for (size_t i = 0; i < cImages; ++i)
940 {
941 pImage = aImageList[i];
942 Bstr bstrImageId;
943 hrc = pImage->COMGETTER(Id)(bstrImageId.asOutParam());
944 if (FAILED(hrc))
945 continue;
946
947 com::Guid imageId(bstrImageId);
948
949 if (!imageId.isValid() || imageId.isZero())
950 continue;
951
952 if (!strImageId.compare(imageId.toString()))
953 {
954 fFound = true;
955 RTPrintf("Image %s was found\n", strImageId.c_str());
956 break;
957 }
958 }
959
960 if (!fFound)
961 {
962 RTPrintf("Process of exporting the image to the Cloud was interrupted. The image wasn't found.\n");
963 return RTEXITCODE_FAILURE;
964 }
965
966 ComPtr<IProgress> progress;
967 CHECK_ERROR2_RET(hrc, oCloudClient,
968 ExportImage(pImage, pVirtualBox, ComSafeArrayAsInParam(parameters), progress.asOutParam()),
969 RTEXITCODE_FAILURE);
970 hrc = showProgress(progress);
971 CHECK_PROGRESS_ERROR_RET(progress, ("Export the image to the Cloud failed"), RTEXITCODE_FAILURE);
972
973 if (SUCCEEDED(hrc))
974 RTPrintf("Export the image to the Cloud was successfull\n");
975
976 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
977}
978
979static RTEXITCODE importCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
980{
981 HRESULT hrc = S_OK;
982 hrc = checkAndSetCommonOptions(a, pCommonOpts);
983 if (FAILED(hrc))
984 return RTEXITCODE_FAILURE;
985
986 static const RTGETOPTDEF s_aOptions[] =
987 {
988 { "--id", 'i', RTGETOPT_REQ_STRING },
989 { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
990 { "--object-name", 'o', RTGETOPT_REQ_STRING }
991 };
992 RTGETOPTSTATE GetState;
993 RTGETOPTUNION ValueUnion;
994 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
995 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
996
997 Utf8Str strImageId;
998 Utf8Str strCompartmentId;
999 Utf8Str strBucketName;
1000 Utf8Str strObjectName;
1001 Utf8Str strDisplayName;
1002 com::SafeArray<BSTR> parameters;
1003
1004 int c;
1005 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1006 {
1007 switch (c)
1008 {
1009 case 'i':
1010 strImageId=ValueUnion.psz;
1011 break;
1012 case 'b':
1013 strBucketName=ValueUnion.psz;
1014 Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
1015 break;
1016 case 'o':
1017 strObjectName=ValueUnion.psz;
1018 Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
1019 break;
1020 case VINF_GETOPT_NOT_OPTION:
1021 return errorUnknownSubcommand(ValueUnion.psz);
1022 default:
1023 return errorGetOpt(c, &ValueUnion);
1024 }
1025 }
1026
1027 Bstr bstrProfileName;
1028 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1029 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
1030
1031 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
1032 ComObjPtr<ICloudClient> oCloudClient;
1033 CHECK_ERROR2_RET(hrc, pCloudProfile,
1034 CreateCloudClient(oCloudClient.asOutParam()),
1035 RTEXITCODE_FAILURE);
1036 RTPrintf("Creating an object \'%s\' from the cloud image \'%s\'...\n", strObjectName.c_str(), strImageId.c_str());
1037
1038 ComPtr<IProgress> progress;
1039 CHECK_ERROR2_RET(hrc, oCloudClient,
1040 ImportImage(Bstr(strImageId.c_str()).raw(), pVirtualBox, ComSafeArrayAsInParam(parameters), progress.asOutParam()),
1041 RTEXITCODE_FAILURE);
1042 hrc = showProgress(progress);
1043 CHECK_PROGRESS_ERROR_RET(progress, ("Cloud image import failed"), RTEXITCODE_FAILURE);
1044
1045 if (SUCCEEDED(hrc))
1046 {
1047 RTPrintf("Cloud image was imported successfully. Find the downloaded object with the name %s "
1048 "in the system temp folder (find the possible environment variables like TEMP, TMP and etc.)\n",
1049 strObjectName.c_str());
1050 }
1051
1052 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1053}
1054
1055static RTEXITCODE showCloudImageInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1056{
1057 HRESULT hrc = S_OK;
1058 hrc = checkAndSetCommonOptions(a, pCommonOpts);
1059 if (FAILED(hrc))
1060 return RTEXITCODE_FAILURE;
1061
1062 static const RTGETOPTDEF s_aOptions[] =
1063 {
1064 { "--id", 'i', RTGETOPT_REQ_STRING }
1065 };
1066 RTGETOPTSTATE GetState;
1067 RTGETOPTUNION ValueUnion;
1068 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1069 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1070
1071 Utf8Str strImageId;
1072
1073 int c;
1074 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1075 {
1076 switch (c)
1077 {
1078 case 'i':
1079 strImageId = ValueUnion.psz;
1080 break;
1081 case VINF_GETOPT_NOT_OPTION:
1082 return errorUnknownSubcommand(ValueUnion.psz);
1083 default:
1084 return errorGetOpt(c, &ValueUnion);
1085 }
1086 }
1087
1088 Bstr bstrProfileName;
1089 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1090 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
1091
1092 ComObjPtr<ICloudClient> oCloudClient;
1093 CHECK_ERROR2_RET(hrc, pCloudProfile,
1094 CreateCloudClient(oCloudClient.asOutParam()),
1095 RTEXITCODE_FAILURE);
1096 RTPrintf("Getting information about the cloud image with id \'%s\'...\n", strImageId.c_str());
1097
1098 ComPtr<IStringArray> infoArray;
1099 com::SafeArray<BSTR> pStrInfoArray;
1100 ComPtr<IProgress> pProgress;
1101
1102 RTPrintf("Reply is in the form \'image property\' = \'value\'\n");
1103 CHECK_ERROR2_RET(hrc, oCloudClient,
1104 GetImageInfo(Bstr(strImageId.c_str()).raw(),
1105 infoArray.asOutParam(),
1106 pProgress.asOutParam()),
1107 RTEXITCODE_FAILURE);
1108
1109 hrc = showProgress(pProgress);
1110 CHECK_PROGRESS_ERROR_RET(pProgress, ("Getting information about the cloud image failed"), RTEXITCODE_FAILURE);
1111
1112 CHECK_ERROR2_RET(hrc,
1113 infoArray, COMGETTER(Values)(ComSafeArrayAsOutParam(pStrInfoArray)),
1114 RTEXITCODE_FAILURE);
1115
1116 RTPrintf("General information about the image:\n");
1117 size_t cParamNames = pStrInfoArray.size();
1118 for (size_t k = 0; k < cParamNames; k++)
1119 {
1120 Utf8Str data(pStrInfoArray[k]);
1121 RTPrintf("\t%s\n", data.c_str());
1122 }
1123
1124 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1125}
1126
1127static RTEXITCODE updateCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1128{
1129 RT_NOREF(a);
1130 RT_NOREF(iFirst);
1131 RT_NOREF(pCommonOpts);
1132 return RTEXITCODE_SUCCESS;
1133}
1134
1135static RTEXITCODE deleteCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1136{
1137 HRESULT hrc = S_OK;
1138 hrc = checkAndSetCommonOptions(a, pCommonOpts);
1139 if (FAILED(hrc))
1140 return RTEXITCODE_FAILURE;
1141
1142 static const RTGETOPTDEF s_aOptions[] =
1143 {
1144 { "--id", 'i', RTGETOPT_REQ_STRING }
1145 };
1146 RTGETOPTSTATE GetState;
1147 RTGETOPTUNION ValueUnion;
1148 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1149 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1150
1151 Utf8Str strImageId;
1152
1153 int c;
1154 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1155 {
1156 switch (c)
1157 {
1158 case 'i':
1159 strImageId = ValueUnion.psz;
1160 break;
1161 case VINF_GETOPT_NOT_OPTION:
1162 return errorUnknownSubcommand(ValueUnion.psz);
1163 default:
1164 return errorGetOpt(c, &ValueUnion);
1165 }
1166 }
1167
1168 Bstr bstrProfileName;
1169 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1170 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
1171
1172 ComObjPtr<ICloudClient> oCloudClient;
1173 CHECK_ERROR2_RET(hrc, pCloudProfile,
1174 CreateCloudClient(oCloudClient.asOutParam()),
1175 RTEXITCODE_FAILURE);
1176 RTPrintf("Deleting cloud image with id %s...\n", strImageId.c_str());
1177
1178 ComPtr<IProgress> progress;
1179 CHECK_ERROR2_RET(hrc, oCloudClient,
1180 DeleteImage(Bstr(strImageId.c_str()).raw(), progress.asOutParam()),
1181 RTEXITCODE_FAILURE);
1182 hrc = showProgress(progress);
1183 CHECK_PROGRESS_ERROR_RET(progress, ("Deleting cloud image failed"), RTEXITCODE_FAILURE);
1184
1185 if (SUCCEEDED(hrc))
1186 RTPrintf("Cloud image with was deleted successfully\n");
1187
1188 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1189}
1190
1191static RTEXITCODE handleCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1192{
1193 if (a->argc < 1)
1194 return errorNoSubcommand();
1195
1196 static const RTGETOPTDEF s_aOptions[] =
1197 {
1198 { "create", 1000, RTGETOPT_REQ_NOTHING },
1199 { "export", 1001, RTGETOPT_REQ_NOTHING },
1200 { "import", 1002, RTGETOPT_REQ_NOTHING },
1201 { "info", 1003, RTGETOPT_REQ_NOTHING },
1202 { "update", 1004, RTGETOPT_REQ_NOTHING },
1203 { "delete", 1005, RTGETOPT_REQ_NOTHING }
1204 };
1205
1206 RTGETOPTSTATE GetState;
1207 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1208 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1209
1210 int c;
1211 RTGETOPTUNION ValueUnion;
1212 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1213 {
1214 switch (c)
1215 {
1216 /* Sub-commands: */
1217 case 1000:
1218// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_CREATE);
1219 return createCloudImage(a, GetState.iNext, pCommonOpts);
1220 case 1001:
1221// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_EXPORT);
1222 return exportCloudImage(a, GetState.iNext, pCommonOpts);
1223 case 1002:
1224// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_IMPORT);
1225 return importCloudImage(a, GetState.iNext, pCommonOpts);
1226 case 1003:
1227// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_INFO);
1228 return showCloudImageInfo(a, GetState.iNext, pCommonOpts);
1229 case 1004:
1230// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_UPDATE);
1231 return updateCloudImage(a, GetState.iNext, pCommonOpts);
1232 case 1005:
1233// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_DELETE);
1234 return deleteCloudImage(a, GetState.iNext, pCommonOpts);
1235 case VINF_GETOPT_NOT_OPTION:
1236 return errorUnknownSubcommand(ValueUnion.psz);
1237
1238 default:
1239 return errorGetOpt(c, &ValueUnion);
1240 }
1241 }
1242
1243 return errorNoSubcommand();
1244}
1245
1246RTEXITCODE handleCloud(HandlerArg *a)
1247{
1248 if (a->argc < 1)
1249 return errorNoSubcommand();
1250
1251 static const RTGETOPTDEF s_aOptions[] =
1252 {
1253 /* common options */
1254 { "--provider", 'v', RTGETOPT_REQ_STRING },
1255 { "--profile", 'f', RTGETOPT_REQ_STRING },
1256 { "list", 1000, RTGETOPT_REQ_NOTHING },
1257 { "image", 1001, RTGETOPT_REQ_NOTHING },
1258 { "instance", 1002, RTGETOPT_REQ_NOTHING },
1259 { "network", 1003, RTGETOPT_REQ_NOTHING },
1260 { "volume", 1004, RTGETOPT_REQ_NOTHING },
1261 { "object", 1005, RTGETOPT_REQ_NOTHING }
1262 };
1263
1264 RTGETOPTSTATE GetState;
1265 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
1266 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1267
1268 CLOUDCOMMONOPT commonOpts = { {NULL, NULL}, {NULL, NULL} };
1269 int c;
1270 RTGETOPTUNION ValueUnion;
1271 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1272 {
1273 switch (c)
1274 {
1275 case 'v': // --provider
1276 commonOpts.provider.pszProviderName = ValueUnion.psz;
1277 break;
1278 case 'f': // --profile
1279 commonOpts.profile.pszProfileName = ValueUnion.psz;
1280 break;
1281 /* Sub-commands: */
1282 case 1000:
1283 return handleCloudLists(a, GetState.iNext, &commonOpts);
1284 case 1001:
1285 return handleCloudImage(a, GetState.iNext, &commonOpts);
1286 case 1002:
1287 return handleCloudInstance(a, GetState.iNext, &commonOpts);
1288 case VINF_GETOPT_NOT_OPTION:
1289 return errorUnknownSubcommand(ValueUnion.psz);
1290
1291 default:
1292 return errorGetOpt(c, &ValueUnion);
1293 }
1294 }
1295
1296 return errorNoSubcommand();
1297}
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