VirtualBox

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

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

bugref:9481. API function ICloudClient::exportImage makes the export of VBox image into the Cloud. OCICloudClient::i_launchInstance returns oci::compute::Instance.

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