VirtualBox

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

最後變更 在這個檔案從80824是 80743,由 vboxsync 提交於 6 年 前

bugref:9318. Added 3 parameters \'launch-mode\', \'bucket-name\', \'object-name\' for the command \'VBoxManage cloud image create\'.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 52.7 KB
 
1/* $Id: VBoxManageCloud.cpp 80743 2019-09-12 05:54: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.alldomusa.eu.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/**
99 * List all available cloud instances for the specified cloud provider.
100 * Available cloud instance is one which state whether "running" or "stopped".
101 *
102 * @returns RTEXITCODE
103 * @param a is the list of passed arguments
104 * @param iFirst is the position of the first unparsed argument in the arguments list
105 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
106 * arguments which have been already parsed before
107 */
108static RTEXITCODE listCloudInstances(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
109{
110 static const RTGETOPTDEF s_aOptions[] =
111 {
112 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
113 { "--state", 's', RTGETOPT_REQ_STRING }
114 };
115 RTGETOPTSTATE GetState;
116 RTGETOPTUNION ValueUnion;
117 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
118 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
119
120 Utf8Str strCompartmentId;
121 com::SafeArray<CloudMachineState_T> machineStates;
122
123 int c;
124 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
125 {
126 switch (c)
127 {
128 case 'c':
129 strCompartmentId = ValueUnion.psz;
130 break;
131
132 case 's':
133 {
134 const char * const pszState = ValueUnion.psz;
135
136 if (RTStrICmp(pszState, "creatingimage") == 0)
137 machineStates.push_back(CloudMachineState_CreatingImage);
138 else if (RTStrICmp(pszState, "paused") == 0) /* XXX */
139 machineStates.push_back(CloudMachineState_Stopped);
140 else if (RTStrICmp(pszState, "provisioning") == 0)
141 machineStates.push_back(CloudMachineState_Provisioning);
142 else if (RTStrICmp(pszState, "running") == 0)
143 machineStates.push_back(CloudMachineState_Running);
144 else if (RTStrICmp(pszState, "starting") == 0)
145 machineStates.push_back(CloudMachineState_Starting);
146 else if (RTStrICmp(pszState, "stopped") == 0)
147 machineStates.push_back(CloudMachineState_Stopped);
148 else if (RTStrICmp(pszState, "stopping") == 0)
149 machineStates.push_back(CloudMachineState_Stopping);
150 else if (RTStrICmp(pszState, "terminated") == 0)
151 machineStates.push_back(CloudMachineState_Terminated);
152 else if (RTStrICmp(pszState, "terminating") == 0)
153 machineStates.push_back(CloudMachineState_Terminating);
154 else
155 return errorArgument("Unknown cloud instance state \"%s\"", pszState);
156 break;
157 }
158
159 case VINF_GETOPT_NOT_OPTION:
160 return errorUnknownSubcommand(ValueUnion.psz);
161
162 default:
163 return errorGetOpt(c, &ValueUnion);
164 }
165 }
166
167 HRESULT hrc = S_OK;
168 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
169
170 ComPtr<ICloudProviderManager> pCloudProviderManager;
171 CHECK_ERROR2_RET(hrc, pVirtualBox,
172 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
173 RTEXITCODE_FAILURE);
174
175 ComPtr<ICloudProvider> pCloudProvider;
176 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
177 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
178 RTEXITCODE_FAILURE);
179
180 ComPtr<ICloudProfile> pCloudProfile;
181 CHECK_ERROR2_RET(hrc, pCloudProvider,
182 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
183 RTEXITCODE_FAILURE);
184
185 if (strCompartmentId.isNotEmpty())
186 {
187 CHECK_ERROR2_RET(hrc, pCloudProfile,
188 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),
189 RTEXITCODE_FAILURE);
190 }
191 else
192 {
193 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
194 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
195 Bstr bStrCompartmentId;
196 CHECK_ERROR2_RET(hrc, pCloudProfile,
197 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
198 RTEXITCODE_FAILURE);
199 strCompartmentId = bStrCompartmentId;
200 if (strCompartmentId.isNotEmpty())
201 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
202 else
203 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
204 }
205
206 Bstr bstrProfileName;
207 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
208
209 ComObjPtr<ICloudClient> oCloudClient;
210 CHECK_ERROR2_RET(hrc, pCloudProfile,
211 CreateCloudClient(oCloudClient.asOutParam()),
212 RTEXITCODE_FAILURE);
213
214 ComPtr<IStringArray> pVMNamesHolder;
215 ComPtr<IStringArray> pVMIdsHolder;
216 com::SafeArray<BSTR> arrayVMNames;
217 com::SafeArray<BSTR> arrayVMIds;
218 ComPtr<IProgress> pProgress;
219
220 RTPrintf("Reply is in the form \'instance name\' = \'instance id\'\n");
221
222 CHECK_ERROR2_RET(hrc, oCloudClient,
223 ListInstances(ComSafeArrayAsInParam(machineStates),
224 pVMNamesHolder.asOutParam(),
225 pVMIdsHolder.asOutParam(),
226 pProgress.asOutParam()),
227 RTEXITCODE_FAILURE);
228 showProgress(pProgress);
229 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list instances"), RTEXITCODE_FAILURE);
230
231 CHECK_ERROR2_RET(hrc,
232 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
233 RTEXITCODE_FAILURE);
234 CHECK_ERROR2_RET(hrc,
235 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
236 RTEXITCODE_FAILURE);
237
238 RTPrintf("The list of the instances for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
239 bstrProfileName.raw(), strCompartmentId.c_str());
240 size_t cIds = arrayVMIds.size();
241 size_t cNames = arrayVMNames.size();
242 for (size_t k = 0; k < cNames; k++)
243 {
244 Bstr value;
245 if (k < cIds)
246 value = arrayVMIds[k];
247 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
248 }
249
250 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
251}
252
253
254/**
255 * List all available cloud images for the specified cloud provider.
256 *
257 * @returns RTEXITCODE
258 * @param a is the list of passed arguments
259 * @param iFirst is the position of the first unparsed argument in the arguments list
260 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
261 * arguments which have been already parsed before
262 */
263static RTEXITCODE listCloudImages(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
264{
265 static const RTGETOPTDEF s_aOptions[] =
266 {
267 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
268 { "--state", 's', RTGETOPT_REQ_STRING }
269 };
270 RTGETOPTSTATE GetState;
271 RTGETOPTUNION ValueUnion;
272 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
273 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
274
275 Utf8Str strCompartmentId;
276 com::SafeArray<CloudImageState_T> imageStates;
277
278 int c;
279 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
280 {
281 switch (c)
282 {
283 case 'c':
284 strCompartmentId = ValueUnion.psz;
285 break;
286
287 case 's':
288 {
289 const char * const pszState = ValueUnion.psz;
290
291 if (RTStrICmp(pszState, "available") == 0)
292 imageStates.push_back(CloudImageState_Available);
293 else if (RTStrICmp(pszState, "deleted") == 0)
294 imageStates.push_back(CloudImageState_Deleted);
295 else if (RTStrICmp(pszState, "disabled") == 0)
296 imageStates.push_back(CloudImageState_Disabled);
297 else if (RTStrICmp(pszState, "exporting") == 0)
298 imageStates.push_back(CloudImageState_Exporting);
299 else if (RTStrICmp(pszState, "importing") == 0)
300 imageStates.push_back(CloudImageState_Importing);
301 else if (RTStrICmp(pszState, "provisioning") == 0)
302 imageStates.push_back(CloudImageState_Provisioning);
303 else
304 return errorArgument("Unknown cloud image state \"%s\"", pszState);
305 break;
306 }
307
308 case VINF_GETOPT_NOT_OPTION:
309 return errorUnknownSubcommand(ValueUnion.psz);
310
311 default:
312 return errorGetOpt(c, &ValueUnion);
313 }
314 }
315
316
317 HRESULT hrc = S_OK;
318 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
319
320 ComPtr<ICloudProviderManager> pCloudProviderManager;
321 CHECK_ERROR2_RET(hrc, pVirtualBox,
322 COMGETTER(CloudProviderManager)(pCloudProviderManager.asOutParam()),
323 RTEXITCODE_FAILURE);
324
325 ComPtr<ICloudProvider> pCloudProvider;
326 CHECK_ERROR2_RET(hrc, pCloudProviderManager,
327 GetProviderByShortName(Bstr(pCommonOpts->provider.pszProviderName).raw(), pCloudProvider.asOutParam()),
328 RTEXITCODE_FAILURE);
329
330 ComPtr<ICloudProfile> pCloudProfile;
331 CHECK_ERROR2_RET(hrc, pCloudProvider,
332 GetProfileByName(Bstr(pCommonOpts->profile.pszProfileName).raw(), pCloudProfile.asOutParam()),
333 RTEXITCODE_FAILURE);
334
335 if (strCompartmentId.isNotEmpty())
336 {
337 CHECK_ERROR2_RET(hrc, pCloudProfile,
338 SetProperty(Bstr("compartment").raw(), Bstr(strCompartmentId).raw()),\
339 RTEXITCODE_FAILURE);
340 }
341 else
342 {
343 RTPrintf("Parameter \'compartment\' is empty or absent.\n"
344 "Trying to get the compartment from the passed cloud profile \'%s\'\n", pCommonOpts->profile.pszProfileName);
345 Bstr bStrCompartmentId;
346 CHECK_ERROR2_RET(hrc, pCloudProfile,
347 GetProperty(Bstr("compartment").raw(), bStrCompartmentId.asOutParam()),
348 RTEXITCODE_FAILURE);
349 strCompartmentId = bStrCompartmentId;
350 if (strCompartmentId.isNotEmpty())
351 RTPrintf("Found the compartment \'%s\':\n", strCompartmentId.c_str());
352 else
353 return errorSyntax(USAGE_S_NEWCMD, "Parameter --compartment-id is required");
354 }
355
356 Bstr bstrProfileName;
357 pCloudProfile->COMGETTER(Name)(bstrProfileName.asOutParam());
358
359 ComObjPtr<ICloudClient> oCloudClient;
360 CHECK_ERROR2_RET(hrc, pCloudProfile,
361 CreateCloudClient(oCloudClient.asOutParam()),
362 RTEXITCODE_FAILURE);
363
364 ComPtr<IStringArray> pVMNamesHolder;
365 ComPtr<IStringArray> pVMIdsHolder;
366 com::SafeArray<BSTR> arrayVMNames;
367 com::SafeArray<BSTR> arrayVMIds;
368 ComPtr<IProgress> pProgress;
369
370 RTPrintf("Reply is in the form \'image name\' = \'image id\'\n");
371 CHECK_ERROR2_RET(hrc, oCloudClient,
372 ListImages(ComSafeArrayAsInParam(imageStates),
373 pVMNamesHolder.asOutParam(),
374 pVMIdsHolder.asOutParam(),
375 pProgress.asOutParam()),
376 RTEXITCODE_FAILURE);
377 showProgress(pProgress);
378 CHECK_PROGRESS_ERROR_RET(pProgress, ("Failed to list images"), RTEXITCODE_FAILURE);
379
380 CHECK_ERROR2_RET(hrc,
381 pVMNamesHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMNames)),
382 RTEXITCODE_FAILURE);
383 CHECK_ERROR2_RET(hrc,
384 pVMIdsHolder, COMGETTER(Values)(ComSafeArrayAsOutParam(arrayVMIds)),
385 RTEXITCODE_FAILURE);
386
387 RTPrintf("The list of the images for the cloud profile \'%ls\' \nand compartment \'%s\':\n",
388 bstrProfileName.raw(), strCompartmentId.c_str());
389 size_t cNames = arrayVMNames.size();
390 size_t cIds = arrayVMIds.size();
391 for (size_t k = 0; k < cNames; k++)
392 {
393 Bstr value;
394 if (k < cIds)
395 value = arrayVMIds[k];
396 RTPrintf("\t%ls = %ls\n", arrayVMNames[k], value.raw());
397 }
398
399 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
400}
401
402/**
403 * General function which handles the "list" commands
404 *
405 * @returns RTEXITCODE
406 * @param a is the list of passed arguments
407 * @param iFirst is the position of the first unparsed argument in the arguments list
408 * @param pCommonOpts is a pointer to the structure CLOUDCOMMONOPT with some common
409 * arguments which have been already parsed before
410 */
411static RTEXITCODE handleCloudLists(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
412{
413 if (a->argc < 1)
414 return errorNoSubcommand();
415
416 static const RTGETOPTDEF s_aOptions[] =
417 {
418 { "images", 1000, RTGETOPT_REQ_NOTHING },
419 { "instances", 1001, RTGETOPT_REQ_NOTHING },
420 { "networks", 1002, RTGETOPT_REQ_NOTHING },
421 { "subnets", 1003, RTGETOPT_REQ_NOTHING },
422 { "vcns", 1004, RTGETOPT_REQ_NOTHING },
423 { "objects", 1005, RTGETOPT_REQ_NOTHING }
424 };
425
426 Bstr bstrProvider(pCommonOpts->provider.pszProviderName);
427 Bstr bstrProfile(pCommonOpts->profile.pszProfileName);
428
429 /* check for required options */
430 if (bstrProvider.isEmpty())
431 return errorSyntax(USAGE_S_NEWCMD, "Parameter --provider is required");
432 if (bstrProfile.isEmpty())
433 return errorSyntax(USAGE_S_NEWCMD, "Parameter --profile is required");
434
435 RTGETOPTSTATE GetState;
436 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
437 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
438
439 int c;
440 RTGETOPTUNION ValueUnion;
441 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
442 {
443 switch (c)
444 {
445 case 1000:
446// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_LIST);
447 return listCloudImages(a, GetState.iNext, pCommonOpts);
448 case 1001:
449// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_LIST);
450 return listCloudInstances(a, GetState.iNext, pCommonOpts);
451 case VINF_GETOPT_NOT_OPTION:
452 return errorUnknownSubcommand(ValueUnion.psz);
453
454 default:
455 return errorGetOpt(c, &ValueUnion);
456 }
457 }
458
459 return errorNoSubcommand();
460}
461
462static RTEXITCODE createCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
463{
464 RT_NOREF(a);
465 RT_NOREF(iFirst);
466 RT_NOREF(pCommonOpts);
467 return RTEXITCODE_SUCCESS;
468}
469
470static RTEXITCODE updateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
471{
472 RT_NOREF(a);
473 RT_NOREF(iFirst);
474 RT_NOREF(pCommonOpts);
475 return RTEXITCODE_SUCCESS;
476}
477
478static RTEXITCODE showCloudInstanceInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
479{
480 HRESULT hrc = S_OK;
481
482 hrc = checkAndSetCommonOptions(a, pCommonOpts);
483 if (FAILED(hrc))
484 return RTEXITCODE_FAILURE;
485
486 static const RTGETOPTDEF s_aOptions[] =
487 {
488 { "--id", 'i', RTGETOPT_REQ_STRING }
489 };
490 RTGETOPTSTATE GetState;
491 RTGETOPTUNION ValueUnion;
492 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
493 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
494
495 Utf8Str strInstanceId;
496
497 int c;
498 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
499 {
500 switch (c)
501 {
502 case 'i':
503 {
504 if (strInstanceId.isNotEmpty())
505 return errorArgument("Duplicate parameter: --id");
506
507 strInstanceId = ValueUnion.psz;
508 if (strInstanceId.isEmpty())
509 return errorArgument("Empty parameter: --id");
510
511 break;
512 }
513
514 case VINF_GETOPT_NOT_OPTION:
515 return errorUnknownSubcommand(ValueUnion.psz);
516
517 default:
518 return errorGetOpt(c, &ValueUnion);
519 }
520 }
521
522 if (strInstanceId.isEmpty())
523 return errorArgument("Missing parameter: --id");
524
525
526 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
527
528 ComObjPtr<ICloudClient> oCloudClient;
529 CHECK_ERROR2_RET(hrc, pCloudProfile,
530 CreateCloudClient(oCloudClient.asOutParam()),
531 RTEXITCODE_FAILURE);
532 RTPrintf("Getting information about cloud instance with id %s...\n", strInstanceId.c_str());
533 RTPrintf("Reply is in the form \'setting name\' = \'value\'\n");
534
535 ComPtr<IAppliance> pAppliance;
536 CHECK_ERROR2_RET(hrc, a->virtualBox, CreateAppliance(pAppliance.asOutParam()), RTEXITCODE_FAILURE);
537
538 com::SafeIfaceArray<IVirtualSystemDescription> vsdArray;
539 ULONG requestedVSDnums = 1;
540 ULONG newVSDnums = 0;
541 CHECK_ERROR2_RET(hrc, pAppliance, CreateVirtualSystemDescriptions(requestedVSDnums, &newVSDnums), RTEXITCODE_FAILURE);
542 if (requestedVSDnums != newVSDnums)
543 return RTEXITCODE_FAILURE;
544
545 CHECK_ERROR2_RET(hrc, pAppliance, COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(vsdArray)), RTEXITCODE_FAILURE);
546 ComPtr<IVirtualSystemDescription> instanceDescription = vsdArray[0];
547
548 ComPtr<IProgress> progress;
549 CHECK_ERROR2_RET(hrc, oCloudClient,
550 GetInstanceInfo(Bstr(strInstanceId).raw(), instanceDescription, progress.asOutParam()),
551 RTEXITCODE_FAILURE);
552
553 hrc = showProgress(progress);
554 CHECK_PROGRESS_ERROR_RET(progress, ("Getting information about cloud instance failed"), RTEXITCODE_FAILURE);
555
556 RTPrintf("Cloud instance info (provider '%s'):\n",
557 pCommonOpts->provider.pszProviderName);
558
559 struct vsdHReadable {
560 VirtualSystemDescriptionType_T vsdType;
561 Utf8Str strFound;
562 Utf8Str strNotFound;
563 };
564
565 size_t vsdHReadableArraySize = 9;//the number of items in the vsdHReadableArray
566 vsdHReadable vsdHReadableArray[9] = {
567 {VirtualSystemDescriptionType_CloudDomain, "Availability domain = '%ls'\n", "Availability domain wasn't found\n"},
568 {VirtualSystemDescriptionType_Name, "Instance displayed name = '%ls'\n", "Instance displayed name wasn't found\n"},
569 {VirtualSystemDescriptionType_CloudInstanceState, "Instance state = '%ls'\n", "Instance state wasn't found\n"},
570 {VirtualSystemDescriptionType_CloudInstanceId, "Instance Id = '%ls'\n", "Instance Id wasn't found\n"},
571 {VirtualSystemDescriptionType_CloudImageId, "Bootable image Id = '%ls'\n",
572 "Image Id whom the instance is booted up wasn't found\n"},
573 {VirtualSystemDescriptionType_CloudInstanceShape, "Shape of the instance = '%ls'\n",
574 "The shape of the instance wasn't found\n"},
575 {VirtualSystemDescriptionType_OS, "Type of guest OS = '%ls'\n", "Type of guest OS wasn't found.\n"},
576 {VirtualSystemDescriptionType_Memory, "RAM = '%ls MB'\n", "Value for RAM wasn't found\n"},
577 {VirtualSystemDescriptionType_CPU, "CPUs = '%ls'\n", "Numbers of CPUs weren't found\n"}
578 };
579
580 com::SafeArray<VirtualSystemDescriptionType_T> retTypes;
581 com::SafeArray<BSTR> aRefs;
582 com::SafeArray<BSTR> aOvfValues;
583 com::SafeArray<BSTR> aVBoxValues;
584 com::SafeArray<BSTR> aExtraConfigValues;
585
586 for (size_t i=0; i<vsdHReadableArraySize ; ++i)
587 {
588 hrc = instanceDescription->GetDescriptionByType(vsdHReadableArray[i].vsdType,
589 ComSafeArrayAsOutParam(retTypes),
590 ComSafeArrayAsOutParam(aRefs),
591 ComSafeArrayAsOutParam(aOvfValues),
592 ComSafeArrayAsOutParam(aVBoxValues),
593 ComSafeArrayAsOutParam(aExtraConfigValues));
594 if (FAILED(hrc) || aVBoxValues.size() == 0)
595 LogRel((vsdHReadableArray[i].strNotFound.c_str()));
596 else
597 RTPrintf(vsdHReadableArray[i].strFound.c_str(), aVBoxValues[0]);
598
599 retTypes.setNull();
600 aRefs.setNull();
601 aOvfValues.setNull();
602 aVBoxValues.setNull();
603 aExtraConfigValues.setNull();
604 }
605
606 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
607}
608
609static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
610{
611 HRESULT hrc = S_OK;
612 hrc = checkAndSetCommonOptions(a, pCommonOpts);
613 if (FAILED(hrc))
614 return RTEXITCODE_FAILURE;
615
616 static const RTGETOPTDEF s_aOptions[] =
617 {
618 { "--id", 'i', RTGETOPT_REQ_STRING }
619 };
620 RTGETOPTSTATE GetState;
621 RTGETOPTUNION ValueUnion;
622 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
623 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
624
625 Utf8Str strInstanceId;
626
627 int c;
628 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
629 {
630 switch (c)
631 {
632 case 'i':
633 {
634 if (strInstanceId.isNotEmpty())
635 return errorArgument("Duplicate parameter: --id");
636
637 strInstanceId = ValueUnion.psz;
638 if (strInstanceId.isEmpty())
639 return errorArgument("Empty parameter: --id");
640
641 break;
642 }
643
644 case VINF_GETOPT_NOT_OPTION:
645 return errorUnknownSubcommand(ValueUnion.psz);
646
647 default:
648 return errorGetOpt(c, &ValueUnion);
649 }
650 }
651
652 if (strInstanceId.isEmpty())
653 return errorArgument("Missing parameter: --id");
654
655
656 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
657
658 ComObjPtr<ICloudClient> oCloudClient;
659 CHECK_ERROR2_RET(hrc, pCloudProfile,
660 CreateCloudClient(oCloudClient.asOutParam()),
661 RTEXITCODE_FAILURE);
662 RTPrintf("Starting cloud instance with id %s...\n", strInstanceId.c_str());
663
664 ComPtr<IProgress> progress;
665 CHECK_ERROR2_RET(hrc, oCloudClient,
666 StartInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
667 RTEXITCODE_FAILURE);
668 hrc = showProgress(progress);
669 CHECK_PROGRESS_ERROR_RET(progress, ("Starting the cloud instance failed"), RTEXITCODE_FAILURE);
670
671 if (SUCCEEDED(hrc))
672 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was started\n",
673 strInstanceId.c_str(),
674 pCommonOpts->provider.pszProviderName,
675 pCommonOpts->profile.pszProfileName);
676
677 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
678}
679
680static RTEXITCODE pauseCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
681{
682 HRESULT hrc = S_OK;
683 hrc = checkAndSetCommonOptions(a, pCommonOpts);
684
685 if (FAILED(hrc))
686 return RTEXITCODE_FAILURE;
687
688 static const RTGETOPTDEF s_aOptions[] =
689 {
690 { "--id", 'i', RTGETOPT_REQ_STRING }
691 };
692 RTGETOPTSTATE GetState;
693 RTGETOPTUNION ValueUnion;
694 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
695 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
696
697 Utf8Str strInstanceId;
698
699 int c;
700 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
701 {
702 switch (c)
703 {
704 case 'i':
705 {
706 if (strInstanceId.isNotEmpty())
707 return errorArgument("Duplicate parameter: --id");
708
709 strInstanceId = ValueUnion.psz;
710 if (strInstanceId.isEmpty())
711 return errorArgument("Empty parameter: --id");
712
713 break;
714 }
715
716 case VINF_GETOPT_NOT_OPTION:
717 return errorUnknownSubcommand(ValueUnion.psz);
718
719 default:
720 return errorGetOpt(c, &ValueUnion);
721 }
722 }
723
724 if (strInstanceId.isEmpty())
725 return errorArgument("Missing parameter: --id");
726
727
728 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
729
730 ComObjPtr<ICloudClient> oCloudClient;
731 CHECK_ERROR2_RET(hrc, pCloudProfile,
732 CreateCloudClient(oCloudClient.asOutParam()),
733 RTEXITCODE_FAILURE);
734 RTPrintf("Pausing cloud instance with id %s...\n", strInstanceId.c_str());
735
736 ComPtr<IProgress> progress;
737 CHECK_ERROR2_RET(hrc, oCloudClient,
738 PauseInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
739 RTEXITCODE_FAILURE);
740 hrc = showProgress(progress);
741 CHECK_PROGRESS_ERROR_RET(progress, ("Pause the cloud instance failed"), RTEXITCODE_FAILURE);
742
743 if (SUCCEEDED(hrc))
744 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was paused\n",
745 strInstanceId.c_str(),
746 pCommonOpts->provider.pszProviderName,
747 pCommonOpts->profile.pszProfileName);
748
749 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
750}
751
752static RTEXITCODE terminateCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
753{
754 HRESULT hrc = S_OK;
755
756 hrc = checkAndSetCommonOptions(a, pCommonOpts);
757 if (FAILED(hrc))
758 return RTEXITCODE_FAILURE;
759
760 static const RTGETOPTDEF s_aOptions[] =
761 {
762 { "--id", 'i', RTGETOPT_REQ_STRING }
763 };
764 RTGETOPTSTATE GetState;
765 RTGETOPTUNION ValueUnion;
766 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
767 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
768
769 Utf8Str strInstanceId;
770
771 int c;
772 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
773 {
774 switch (c)
775 {
776 case 'i':
777 {
778 if (strInstanceId.isNotEmpty())
779 return errorArgument("Duplicate parameter: --id");
780
781 strInstanceId = ValueUnion.psz;
782 if (strInstanceId.isEmpty())
783 return errorArgument("Empty parameter: --id");
784
785 break;
786 }
787
788 case VINF_GETOPT_NOT_OPTION:
789 return errorUnknownSubcommand(ValueUnion.psz);
790
791 default:
792 return errorGetOpt(c, &ValueUnion);
793 }
794 }
795
796 if (strInstanceId.isEmpty())
797 return errorArgument("Missing parameter: --id");
798
799
800 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
801
802 ComObjPtr<ICloudClient> oCloudClient;
803 CHECK_ERROR2_RET(hrc, pCloudProfile,
804 CreateCloudClient(oCloudClient.asOutParam()),
805 RTEXITCODE_FAILURE);
806 RTPrintf("Terminating cloud instance with id %s...\n", strInstanceId.c_str());
807
808 ComPtr<IProgress> progress;
809 CHECK_ERROR2_RET(hrc, oCloudClient,
810 TerminateInstance(Bstr(strInstanceId).raw(), progress.asOutParam()),
811 RTEXITCODE_FAILURE);
812 hrc = showProgress(progress);
813 CHECK_PROGRESS_ERROR_RET(progress, ("Termination the cloud instance failed"), RTEXITCODE_FAILURE);
814
815 if (SUCCEEDED(hrc))
816 RTPrintf("Cloud instance with id %s (provider = '%s', profile = '%s') was terminated\n",
817 strInstanceId.c_str(),
818 pCommonOpts->provider.pszProviderName,
819 pCommonOpts->profile.pszProfileName);
820
821 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
822}
823
824static RTEXITCODE handleCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
825{
826 if (a->argc < 1)
827 return errorNoSubcommand();
828
829 static const RTGETOPTDEF s_aOptions[] =
830 {
831 { "create", 1000, RTGETOPT_REQ_NOTHING },
832 { "start", 1001, RTGETOPT_REQ_NOTHING },
833 { "pause", 1002, RTGETOPT_REQ_NOTHING },
834 { "info", 1003, RTGETOPT_REQ_NOTHING },
835 { "update", 1004, RTGETOPT_REQ_NOTHING },
836 { "terminate", 1005, RTGETOPT_REQ_NOTHING }
837 };
838
839 RTGETOPTSTATE GetState;
840 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
841 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
842
843 int c;
844 RTGETOPTUNION ValueUnion;
845 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
846 {
847 switch (c)
848 {
849 /* Sub-commands: */
850 case 1000:
851// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_CREATE);
852 return createCloudInstance(a, GetState.iNext, pCommonOpts);
853 case 1001:
854 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_START);
855 return startCloudInstance(a, GetState.iNext, pCommonOpts);
856 case 1002:
857 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_PAUSE);
858 return pauseCloudInstance(a, GetState.iNext, pCommonOpts);
859 case 1003:
860 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_INFO);
861 return showCloudInstanceInfo(a, GetState.iNext, pCommonOpts);
862 case 1004:
863// setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_UPDATE);
864 return updateCloudInstance(a, GetState.iNext, pCommonOpts);
865 case 1005:
866 setCurrentSubcommand(HELP_SCOPE_CLOUDINSTANCE_TERMINATE);
867 return terminateCloudInstance(a, GetState.iNext, pCommonOpts);
868 case VINF_GETOPT_NOT_OPTION:
869 return errorUnknownSubcommand(ValueUnion.psz);
870
871 default:
872 return errorGetOpt(c, &ValueUnion);
873 }
874 }
875
876 return errorNoSubcommand();
877}
878
879
880static RTEXITCODE createCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
881{
882 HRESULT hrc = S_OK;
883 hrc = checkAndSetCommonOptions(a, pCommonOpts);
884 if (FAILED(hrc))
885 return RTEXITCODE_FAILURE;
886
887 static const RTGETOPTDEF s_aOptions[] =
888 {
889 { "--object-name", 'o', RTGETOPT_REQ_STRING },
890 { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
891 { "--compartment-id", 'c', RTGETOPT_REQ_STRING },
892 { "--instance-id", 'i', RTGETOPT_REQ_STRING },
893 { "--display-name", 'd', RTGETOPT_REQ_STRING },
894 { "--launch-mode", 'm', RTGETOPT_REQ_STRING },
895 };
896 RTGETOPTSTATE GetState;
897 RTGETOPTUNION ValueUnion;
898 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
899 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
900
901 Utf8Str strCompartmentId;
902 Utf8Str strInstanceId;
903 Utf8Str strDisplayName;
904 Utf8Str strBucketName;
905 Utf8Str strObjectName;
906 com::SafeArray<BSTR> parameters;
907
908 int c;
909 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
910 {
911 switch (c)
912 {
913 case 'c':
914 strCompartmentId=ValueUnion.psz;
915 Bstr(Utf8Str("compartment-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
916 break;
917 case 'i':
918 strInstanceId=ValueUnion.psz;
919 Bstr(Utf8Str("instance-id=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
920 break;
921 case 'd':
922 strDisplayName=ValueUnion.psz;
923 Bstr(Utf8Str("display-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
924 break;
925 case 'o':
926 strObjectName=ValueUnion.psz;
927 Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
928 break;
929 case 'b':
930 strBucketName=ValueUnion.psz;
931 Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
932 break;
933 case 'm':
934 strBucketName=ValueUnion.psz;
935 Bstr(Utf8Str("launch-mode=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
936 break;
937 case VINF_GETOPT_NOT_OPTION:
938 return errorUnknownSubcommand(ValueUnion.psz);
939 default:
940 return errorGetOpt(c, &ValueUnion);
941 }
942 }
943
944 if (strInstanceId.isNotEmpty() && strObjectName.isNotEmpty())
945 return errorArgument("Conflicting parameters: --instance-id and --object-name can't be used together. Choose one.");
946
947 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
948
949 ComObjPtr<ICloudClient> oCloudClient;
950 CHECK_ERROR2_RET(hrc, pCloudProfile,
951 CreateCloudClient(oCloudClient.asOutParam()),
952 RTEXITCODE_FAILURE);
953 if (strInstanceId.isNotEmpty())
954 RTPrintf("Creating cloud image with name \'%s\' from the instance \'%s\'...\n",
955 strDisplayName.c_str(), strInstanceId.c_str());
956 else
957 RTPrintf("Creating cloud image with name \'%s\' from the object \'%s\' in the bucket \'%s\'...\n",
958 strDisplayName.c_str(), strObjectName.c_str(), strBucketName.c_str());
959
960 ComPtr<IProgress> progress;
961 CHECK_ERROR2_RET(hrc, oCloudClient,
962 CreateImage(ComSafeArrayAsInParam(parameters), progress.asOutParam()),
963 RTEXITCODE_FAILURE);
964 hrc = showProgress(progress);
965 CHECK_PROGRESS_ERROR_RET(progress, ("Creating cloud image failed"), RTEXITCODE_FAILURE);
966
967 if (SUCCEEDED(hrc))
968 RTPrintf("Cloud image was created successfully\n");
969
970 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
971}
972
973
974static RTEXITCODE exportCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
975{
976 HRESULT hrc = S_OK;
977 hrc = checkAndSetCommonOptions(a, pCommonOpts);
978 if (FAILED(hrc))
979 return RTEXITCODE_FAILURE;
980
981 static const RTGETOPTDEF s_aOptions[] =
982 {
983 { "--id", 'i', RTGETOPT_REQ_STRING },
984 { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
985 { "--object-name", 'o', RTGETOPT_REQ_STRING },
986 { "--display-name", 'd', RTGETOPT_REQ_STRING },
987 { "--launch-mode", 'm', 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 strImageId; /* XXX: this is vbox "image", i.e. medium */
995 Utf8Str strBucketName;
996 Utf8Str strObjectName;
997 Utf8Str strDisplayName;
998 Utf8Str strLaunchMode;
999 com::SafeArray<BSTR> parameters;
1000
1001 int c;
1002 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1003 {
1004 switch (c)
1005 {
1006 case 'b': /* --bucket-name */
1007 {
1008 if (strBucketName.isNotEmpty())
1009 return errorArgument("Duplicate parameter: --bucket-name");
1010
1011 strBucketName = ValueUnion.psz;
1012 if (strBucketName.isEmpty())
1013 return errorArgument("Empty parameter: --bucket-name");
1014
1015 break;
1016 }
1017
1018 case 'o': /* --object-name */
1019 {
1020 if (strObjectName.isNotEmpty())
1021 return errorArgument("Duplicate parameter: --object-name");
1022
1023 strObjectName = ValueUnion.psz;
1024 if (strObjectName.isEmpty())
1025 return errorArgument("Empty parameter: --object-name");
1026
1027 break;
1028 }
1029
1030 case 'i': /* --id */
1031 {
1032 if (strImageId.isNotEmpty())
1033 return errorArgument("Duplicate parameter: --id");
1034
1035 strImageId = ValueUnion.psz;
1036 if (strImageId.isEmpty())
1037 return errorArgument("Empty parameter: --id");
1038
1039 break;
1040 }
1041
1042 case 'd': /* --display-name */
1043 {
1044 if (strDisplayName.isNotEmpty())
1045 return errorArgument("Duplicate parameter: --display-name");
1046
1047 strDisplayName = ValueUnion.psz;
1048 if (strDisplayName.isEmpty())
1049 return errorArgument("Empty parameter: --display-name");
1050
1051 break;
1052 }
1053
1054 case 'm': /* --launch-mode */
1055 {
1056 if (strLaunchMode.isNotEmpty())
1057 return errorArgument("Duplicate parameter: --launch-mode");
1058
1059 strLaunchMode = ValueUnion.psz;
1060 if (strLaunchMode.isEmpty())
1061 return errorArgument("Empty parameter: --launch-mode");
1062
1063 break;
1064 }
1065
1066 case VINF_GETOPT_NOT_OPTION:
1067 return errorUnknownSubcommand(ValueUnion.psz);
1068
1069 default:
1070 return errorGetOpt(c, &ValueUnion);
1071 }
1072 }
1073
1074 if (strImageId.isNotEmpty())
1075 BstrFmt("image-id=%s", strImageId.c_str()).detachTo(parameters.appendedRaw());
1076 else
1077 return errorArgument("Missing parameter: --id");
1078
1079 if (strBucketName.isNotEmpty())
1080 BstrFmt("bucket-name=%s", strBucketName.c_str()).detachTo(parameters.appendedRaw());
1081 else
1082 return errorArgument("Missing parameter: --bucket-name");
1083
1084 if (strObjectName.isNotEmpty())
1085 BstrFmt("object-name=%s", strObjectName.c_str()).detachTo(parameters.appendedRaw());
1086
1087 if (strDisplayName.isNotEmpty())
1088 BstrFmt("display-name=%s", strDisplayName.c_str()).detachTo(parameters.appendedRaw());
1089
1090 if (strLaunchMode.isNotEmpty())
1091 BstrFmt("launch-mode=%s", strLaunchMode.c_str()).detachTo(parameters.appendedRaw());
1092
1093
1094 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1095
1096 ComObjPtr<ICloudClient> oCloudClient;
1097 CHECK_ERROR2_RET(hrc, pCloudProfile,
1098 CreateCloudClient(oCloudClient.asOutParam()),
1099 RTEXITCODE_FAILURE);
1100
1101 if (strObjectName.isNotEmpty())
1102 RTPrintf("Exporting image \'%s\' to the Cloud with name \'%s\'...\n",
1103 strImageId.c_str(), strObjectName.c_str());
1104 else
1105 RTPrintf("Exporting image \'%s\' to the Cloud with default name\n",
1106 strImageId.c_str());
1107
1108 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
1109 SafeIfaceArray<IMedium> aImageList;
1110 CHECK_ERROR2_RET(hrc, pVirtualBox,
1111 COMGETTER(HardDisks)(ComSafeArrayAsOutParam(aImageList)),
1112 RTEXITCODE_FAILURE);
1113
1114 ComPtr<IMedium> pImage;
1115 size_t cImages = aImageList.size();
1116 bool fFound = false;
1117 for (size_t i = 0; i < cImages; ++i)
1118 {
1119 pImage = aImageList[i];
1120 Bstr bstrImageId;
1121 hrc = pImage->COMGETTER(Id)(bstrImageId.asOutParam());
1122 if (FAILED(hrc))
1123 continue;
1124
1125 com::Guid imageId(bstrImageId);
1126
1127 if (!imageId.isValid() || imageId.isZero())
1128 continue;
1129
1130 if (!strImageId.compare(imageId.toString()))
1131 {
1132 fFound = true;
1133 RTPrintf("Image %s was found\n", strImageId.c_str());
1134 break;
1135 }
1136 }
1137
1138 if (!fFound)
1139 {
1140 RTPrintf("Process of exporting the image to the Cloud was interrupted. The image wasn't found.\n");
1141 return RTEXITCODE_FAILURE;
1142 }
1143
1144 ComPtr<IProgress> progress;
1145 CHECK_ERROR2_RET(hrc, oCloudClient,
1146 ExportImage(pImage, pVirtualBox, ComSafeArrayAsInParam(parameters), progress.asOutParam()),
1147 RTEXITCODE_FAILURE);
1148 hrc = showProgress(progress);
1149 CHECK_PROGRESS_ERROR_RET(progress, ("Export the image to the Cloud failed"), RTEXITCODE_FAILURE);
1150
1151 if (SUCCEEDED(hrc))
1152 RTPrintf("Export the image to the Cloud was successfull\n");
1153
1154 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1155}
1156
1157static RTEXITCODE importCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1158{
1159 HRESULT hrc = S_OK;
1160 hrc = checkAndSetCommonOptions(a, pCommonOpts);
1161 if (FAILED(hrc))
1162 return RTEXITCODE_FAILURE;
1163
1164 static const RTGETOPTDEF s_aOptions[] =
1165 {
1166 { "--id", 'i', RTGETOPT_REQ_STRING },
1167 { "--bucket-name", 'b', RTGETOPT_REQ_STRING },
1168 { "--object-name", 'o', RTGETOPT_REQ_STRING }
1169 };
1170 RTGETOPTSTATE GetState;
1171 RTGETOPTUNION ValueUnion;
1172 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1173 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1174
1175 Utf8Str strImageId;
1176 Utf8Str strCompartmentId;
1177 Utf8Str strBucketName;
1178 Utf8Str strObjectName;
1179 Utf8Str strDisplayName;
1180 com::SafeArray<BSTR> parameters;
1181
1182 int c;
1183 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1184 {
1185 switch (c)
1186 {
1187 case 'i':
1188 strImageId=ValueUnion.psz;
1189 break;
1190 case 'b':
1191 strBucketName=ValueUnion.psz;
1192 Bstr(Utf8Str("bucket-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
1193 break;
1194 case 'o':
1195 strObjectName=ValueUnion.psz;
1196 Bstr(Utf8Str("object-name=").append(ValueUnion.psz)).detachTo(parameters.appendedRaw());
1197 break;
1198 case VINF_GETOPT_NOT_OPTION:
1199 return errorUnknownSubcommand(ValueUnion.psz);
1200 default:
1201 return errorGetOpt(c, &ValueUnion);
1202 }
1203 }
1204
1205 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1206
1207 ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
1208 ComObjPtr<ICloudClient> oCloudClient;
1209 CHECK_ERROR2_RET(hrc, pCloudProfile,
1210 CreateCloudClient(oCloudClient.asOutParam()),
1211 RTEXITCODE_FAILURE);
1212 RTPrintf("Creating an object \'%s\' from the cloud image \'%s\'...\n", strObjectName.c_str(), strImageId.c_str());
1213
1214 ComPtr<IProgress> progress;
1215 CHECK_ERROR2_RET(hrc, oCloudClient,
1216 ImportImage(Bstr(strImageId).raw(), pVirtualBox, ComSafeArrayAsInParam(parameters), progress.asOutParam()),
1217 RTEXITCODE_FAILURE);
1218 hrc = showProgress(progress);
1219 CHECK_PROGRESS_ERROR_RET(progress, ("Cloud image import failed"), RTEXITCODE_FAILURE);
1220
1221 if (SUCCEEDED(hrc))
1222 {
1223 RTPrintf("Cloud image was imported successfully. Find the downloaded object with the name %s "
1224 "in the system temp folder (find the possible environment variables like TEMP, TMP and etc.)\n",
1225 strObjectName.c_str());
1226 }
1227
1228 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1229}
1230
1231static RTEXITCODE showCloudImageInfo(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1232{
1233 HRESULT hrc = S_OK;
1234 hrc = checkAndSetCommonOptions(a, pCommonOpts);
1235 if (FAILED(hrc))
1236 return RTEXITCODE_FAILURE;
1237
1238 static const RTGETOPTDEF s_aOptions[] =
1239 {
1240 { "--id", 'i', RTGETOPT_REQ_STRING }
1241 };
1242 RTGETOPTSTATE GetState;
1243 RTGETOPTUNION ValueUnion;
1244 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1245 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1246
1247 Utf8Str strImageId;
1248
1249 int c;
1250 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1251 {
1252 switch (c)
1253 {
1254 case 'i':
1255 strImageId = ValueUnion.psz;
1256 break;
1257 case VINF_GETOPT_NOT_OPTION:
1258 return errorUnknownSubcommand(ValueUnion.psz);
1259 default:
1260 return errorGetOpt(c, &ValueUnion);
1261 }
1262 }
1263
1264 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1265
1266 ComObjPtr<ICloudClient> oCloudClient;
1267 CHECK_ERROR2_RET(hrc, pCloudProfile,
1268 CreateCloudClient(oCloudClient.asOutParam()),
1269 RTEXITCODE_FAILURE);
1270 RTPrintf("Getting information about the cloud image with id \'%s\'...\n", strImageId.c_str());
1271
1272 ComPtr<IStringArray> infoArray;
1273 com::SafeArray<BSTR> pStrInfoArray;
1274 ComPtr<IProgress> pProgress;
1275
1276 RTPrintf("Reply is in the form \'image property\' = \'value\'\n");
1277 CHECK_ERROR2_RET(hrc, oCloudClient,
1278 GetImageInfo(Bstr(strImageId).raw(),
1279 infoArray.asOutParam(),
1280 pProgress.asOutParam()),
1281 RTEXITCODE_FAILURE);
1282
1283 hrc = showProgress(pProgress);
1284 CHECK_PROGRESS_ERROR_RET(pProgress, ("Getting information about the cloud image failed"), RTEXITCODE_FAILURE);
1285
1286 CHECK_ERROR2_RET(hrc,
1287 infoArray, COMGETTER(Values)(ComSafeArrayAsOutParam(pStrInfoArray)),
1288 RTEXITCODE_FAILURE);
1289
1290 RTPrintf("General information about the image:\n");
1291 size_t cParamNames = pStrInfoArray.size();
1292 for (size_t k = 0; k < cParamNames; k++)
1293 {
1294 Utf8Str data(pStrInfoArray[k]);
1295 RTPrintf("\t%s\n", data.c_str());
1296 }
1297
1298 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1299}
1300
1301static RTEXITCODE updateCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1302{
1303 RT_NOREF(a);
1304 RT_NOREF(iFirst);
1305 RT_NOREF(pCommonOpts);
1306 return RTEXITCODE_SUCCESS;
1307}
1308
1309static RTEXITCODE deleteCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1310{
1311 HRESULT hrc = S_OK;
1312 hrc = checkAndSetCommonOptions(a, pCommonOpts);
1313 if (FAILED(hrc))
1314 return RTEXITCODE_FAILURE;
1315
1316 static const RTGETOPTDEF s_aOptions[] =
1317 {
1318 { "--id", 'i', RTGETOPT_REQ_STRING }
1319 };
1320 RTGETOPTSTATE GetState;
1321 RTGETOPTUNION ValueUnion;
1322 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1323 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1324
1325 Utf8Str strImageId;
1326
1327 int c;
1328 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1329 {
1330 switch (c)
1331 {
1332 case 'i':
1333 {
1334 if (strImageId.isNotEmpty())
1335 return errorArgument("Duplicate parameter: --id");
1336
1337 strImageId = ValueUnion.psz;
1338 if (strImageId.isEmpty())
1339 return errorArgument("Empty parameter: --id");
1340
1341 break;
1342 }
1343
1344 case VINF_GETOPT_NOT_OPTION:
1345 return errorUnknownSubcommand(ValueUnion.psz);
1346
1347 default:
1348 return errorGetOpt(c, &ValueUnion);
1349 }
1350 }
1351
1352 if (strImageId.isEmpty())
1353 return errorArgument("Missing parameter: --id");
1354
1355
1356 ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
1357
1358 ComObjPtr<ICloudClient> oCloudClient;
1359 CHECK_ERROR2_RET(hrc, pCloudProfile,
1360 CreateCloudClient(oCloudClient.asOutParam()),
1361 RTEXITCODE_FAILURE);
1362 RTPrintf("Deleting cloud image with id %s...\n", strImageId.c_str());
1363
1364 ComPtr<IProgress> progress;
1365 CHECK_ERROR2_RET(hrc, oCloudClient,
1366 DeleteImage(Bstr(strImageId).raw(), progress.asOutParam()),
1367 RTEXITCODE_FAILURE);
1368 hrc = showProgress(progress);
1369 CHECK_PROGRESS_ERROR_RET(progress, ("Deleting cloud image failed"), RTEXITCODE_FAILURE);
1370
1371 if (SUCCEEDED(hrc))
1372 RTPrintf("Cloud image with was deleted successfully\n");
1373
1374 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
1375}
1376
1377static RTEXITCODE handleCloudImage(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
1378{
1379 if (a->argc < 1)
1380 return errorNoSubcommand();
1381
1382 static const RTGETOPTDEF s_aOptions[] =
1383 {
1384 { "create", 1000, RTGETOPT_REQ_NOTHING },
1385 { "export", 1001, RTGETOPT_REQ_NOTHING },
1386 { "import", 1002, RTGETOPT_REQ_NOTHING },
1387 { "info", 1003, RTGETOPT_REQ_NOTHING },
1388 { "update", 1004, RTGETOPT_REQ_NOTHING },
1389 { "delete", 1005, RTGETOPT_REQ_NOTHING }
1390 };
1391
1392 RTGETOPTSTATE GetState;
1393 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
1394 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1395
1396 int c;
1397 RTGETOPTUNION ValueUnion;
1398 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1399 {
1400 switch (c)
1401 {
1402 /* Sub-commands: */
1403 case 1000:
1404// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_CREATE);
1405 return createCloudImage(a, GetState.iNext, pCommonOpts);
1406 case 1001:
1407// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_EXPORT);
1408 return exportCloudImage(a, GetState.iNext, pCommonOpts);
1409 case 1002:
1410// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_IMPORT);
1411 return importCloudImage(a, GetState.iNext, pCommonOpts);
1412 case 1003:
1413// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_INFO);
1414 return showCloudImageInfo(a, GetState.iNext, pCommonOpts);
1415 case 1004:
1416// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_UPDATE);
1417 return updateCloudImage(a, GetState.iNext, pCommonOpts);
1418 case 1005:
1419// setCurrentSubcommand(HELP_SCOPE_CLOUDIMAGE_DELETE);
1420 return deleteCloudImage(a, GetState.iNext, pCommonOpts);
1421 case VINF_GETOPT_NOT_OPTION:
1422 return errorUnknownSubcommand(ValueUnion.psz);
1423
1424 default:
1425 return errorGetOpt(c, &ValueUnion);
1426 }
1427 }
1428
1429 return errorNoSubcommand();
1430}
1431
1432RTEXITCODE handleCloud(HandlerArg *a)
1433{
1434 if (a->argc < 1)
1435 return errorNoSubcommand();
1436
1437 static const RTGETOPTDEF s_aOptions[] =
1438 {
1439 /* common options */
1440 { "--provider", 'v', RTGETOPT_REQ_STRING },
1441 { "--profile", 'f', RTGETOPT_REQ_STRING },
1442 { "list", 1000, RTGETOPT_REQ_NOTHING },
1443 { "image", 1001, RTGETOPT_REQ_NOTHING },
1444 { "instance", 1002, RTGETOPT_REQ_NOTHING },
1445 { "network", 1003, RTGETOPT_REQ_NOTHING },
1446 { "volume", 1004, RTGETOPT_REQ_NOTHING },
1447 { "object", 1005, RTGETOPT_REQ_NOTHING }
1448 };
1449
1450 RTGETOPTSTATE GetState;
1451 int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
1452 AssertRCReturn(vrc, RTEXITCODE_FAILURE);
1453
1454 CLOUDCOMMONOPT commonOpts = { {NULL, NULL}, {NULL, NULL} };
1455 int c;
1456 RTGETOPTUNION ValueUnion;
1457 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
1458 {
1459 switch (c)
1460 {
1461 case 'v': // --provider
1462 commonOpts.provider.pszProviderName = ValueUnion.psz;
1463 break;
1464 case 'f': // --profile
1465 commonOpts.profile.pszProfileName = ValueUnion.psz;
1466 break;
1467 /* Sub-commands: */
1468 case 1000:
1469 return handleCloudLists(a, GetState.iNext, &commonOpts);
1470 case 1001:
1471 return handleCloudImage(a, GetState.iNext, &commonOpts);
1472 case 1002:
1473 return handleCloudInstance(a, GetState.iNext, &commonOpts);
1474 case VINF_GETOPT_NOT_OPTION:
1475 return errorUnknownSubcommand(ValueUnion.psz);
1476
1477 default:
1478 return errorGetOpt(c, &ValueUnion);
1479 }
1480 }
1481
1482 return errorNoSubcommand();
1483}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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