VirtualBox

Ignore:
Timestamp:
Nov 15, 2023 10:21:46 AM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160214
Message:

Jira:VBP-402. Added OCI telemetry API support in VBoxManage. 2 new commands - 'VBoxManage cloud instance metriclist' and 'VBoxManage cloud instance metricdata' Added help documentation for these commands.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageCloud.cpp

    r100809 r102095  
    4949
    5050#include <list>
     51#include <vector>
    5152
    5253using namespace com;//at least for Bstr
    5354
    5455DECLARE_TRANSLATION_CONTEXT(Cloud);
    55 
     56DECLARE_TRANSLATION_CONTEXT(CloudMachine);
    5657
    5758/**
     
    11471148}
    11481149
     1150
     1151static RTEXITCODE cloudInstanceMetricList(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
     1152{
     1153    HRESULT hrc = S_OK;
     1154
     1155    static const RTGETOPTDEF s_aOptions[] =
     1156    {
     1157        { "--id",           'i', RTGETOPT_REQ_STRING },
     1158        { "help",           'h', RTGETOPT_REQ_NOTHING },
     1159        { "--help",         'h', RTGETOPT_REQ_NOTHING }
     1160    };
     1161    RTGETOPTSTATE GetState;
     1162    RTGETOPTUNION ValueUnion;
     1163    int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
     1164    AssertRCReturn(vrc, RTEXITCODE_FAILURE);
     1165    if (a->argc == iFirst)
     1166    {
     1167        RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
     1168        printHelp(g_pStdOut);
     1169        return RTEXITCODE_SUCCESS;
     1170    }
     1171
     1172    Utf8Str strInstanceId;
     1173
     1174    int c;
     1175    while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
     1176    {
     1177        switch (c)
     1178        {
     1179            case 'i':
     1180            {
     1181                if (strInstanceId.isNotEmpty())
     1182                    return errorArgument(Cloud::tr("Duplicate parameter: --id"));
     1183
     1184                strInstanceId = ValueUnion.psz;
     1185                if (strInstanceId.isEmpty())
     1186                    return errorArgument(Cloud::tr("Empty parameter: --id"));
     1187
     1188                break;
     1189            }
     1190            case 'h':
     1191                printHelp(g_pStdOut);
     1192                return RTEXITCODE_SUCCESS;
     1193            case VINF_GETOPT_NOT_OPTION:
     1194                return errorUnknownSubcommand(ValueUnion.psz);
     1195
     1196            default:
     1197                return errorGetOpt(c, &ValueUnion);
     1198        }
     1199    }
     1200
     1201    /* Delayed check. It allows us to print help information.*/
     1202    hrc = checkAndSetCommonOptions(a, pCommonOpts);
     1203    if (FAILED(hrc))
     1204        return RTEXITCODE_FAILURE;
     1205
     1206    if (strInstanceId.isEmpty())
     1207        return errorArgument(Cloud::tr("Missing parameter: --id"));
     1208
     1209    ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
     1210
     1211    ComObjPtr<ICloudClient> oCloudClient;
     1212    CHECK_ERROR2_RET(hrc, pCloudProfile,
     1213                     CreateCloudClient(oCloudClient.asOutParam()),
     1214                     RTEXITCODE_FAILURE);
     1215    RTPrintf(Cloud::tr("Getting list of metric names for the cloud instance with id %s\n"), strInstanceId.c_str());
     1216    RTPrintf(Cloud::tr("Reply is the list, each metric name is placed on a separate line as \' - <metric name>\'\n"));
     1217
     1218    ComPtr<IProgress> progress;
     1219
     1220    CHECK_ERROR2_RET(hrc, oCloudClient, ReadCloudMachineList(progress.asOutParam()), RTEXITCODE_FAILURE);
     1221
     1222    /* First step*/
     1223    RTPrintf(Cloud::tr("First, reading the cloud machines list...\n"));
     1224    hrc = showProgress(progress);
     1225    CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Reading the cloud machines list failed")), RTEXITCODE_FAILURE);
     1226
     1227    com::SafeIfaceArray<ICloudMachine> aMachines;
     1228    CHECK_ERROR2_RET(hrc, oCloudClient,
     1229                     COMGETTER(CloudMachineList)(ComSafeArrayAsOutParam(aMachines)),
     1230                     RTEXITCODE_FAILURE);
     1231
     1232    const size_t cMachines = aMachines.size();
     1233    if (cMachines == 0)
     1234        return RTEXITCODE_SUCCESS;
     1235
     1236    std::vector<ComPtr<ICloudMachine> > vMachines(cMachines);
     1237    std::vector<com::Bstr> vBstrCloudIds(cMachines);
     1238    std::vector<com::Bstr> vBstrIds(cMachines);
     1239
     1240    com::Bstr bstrFoundMachineVBoxId;
     1241
     1242    for (size_t i = 0; i < cMachines; ++i)
     1243    {
     1244        vMachines[i] = aMachines[i];
     1245
     1246        CHECK_ERROR2_RET(hrc, vMachines[i],
     1247                         COMGETTER(CloudId)(vBstrCloudIds[i].asOutParam()),
     1248                         RTEXITCODE_FAILURE);
     1249
     1250        Utf8Str strCurrMachineCloudId(vBstrCloudIds[i]);
     1251        if (strCurrMachineCloudId.equals(strInstanceId))
     1252        {
     1253            CHECK_ERROR2_RET(hrc, vMachines[i],
     1254                             COMGETTER(Id)(vBstrIds[i].asOutParam()),
     1255                             RTEXITCODE_FAILURE);
     1256            bstrFoundMachineVBoxId = vBstrIds[i];
     1257            break;
     1258        }
     1259    }
     1260
     1261    if (bstrFoundMachineVBoxId.isEmpty())
     1262    {
     1263        RTPrintf("The passed cloud instance Id \'%s\' WASN'T found among the cloud machines "
     1264                 "of user \'%s\' registered with VirtualBox\n",
     1265                 strInstanceId.c_str(), pCommonOpts->profile.pszProfileName);
     1266        return RTEXITCODE_FAILURE;
     1267    }
     1268
     1269    /* Second step*/
     1270    RTPrintf(Cloud::tr("Second, refresh information about cloud instance ...\n"));
     1271    ComPtr<ICloudMachine> pMachine;
     1272    CHECK_ERROR2_RET(hrc, oCloudClient,
     1273        GetCloudMachine(bstrFoundMachineVBoxId.raw(), pMachine.asOutParam()), RTEXITCODE_FAILURE);
     1274
     1275    ComPtr<IProgress> pRefreshProgress;
     1276    CHECK_ERROR2_RET(hrc, pMachine, Refresh(pRefreshProgress.asOutParam()), RTEXITCODE_FAILURE);
     1277
     1278    hrc = showProgress(pRefreshProgress);
     1279    CHECK_PROGRESS_ERROR_RET(pRefreshProgress, (Cloud::tr("Refreshing information about cloud instance failed")), RTEXITCODE_FAILURE);
     1280
     1281    /* Third step*/
     1282    RTPrintf(Cloud::tr("Third, getting information about cloud instance metric names...\n"));
     1283    ComPtr<IProgress> progress2;
     1284    ComPtr<IStringArray> returnMetricNames;
     1285    CHECK_ERROR2_RET(hrc, pMachine, ListMetricNames(returnMetricNames.asOutParam(), progress2.asOutParam()),  RTEXITCODE_FAILURE);
     1286
     1287    hrc = showProgress(progress2);
     1288    CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Getting information about cloud instance metrics failed")), RTEXITCODE_FAILURE);
     1289
     1290    com::SafeArray<BSTR> metricNamesArray;
     1291    CHECK_ERROR2_RET(hrc,
     1292                     returnMetricNames, COMGETTER(Values)(ComSafeArrayAsOutParam(metricNamesArray)),
     1293                     RTEXITCODE_FAILURE);
     1294
     1295    RTPrintf(Cloud::tr("Available metric names:\n"));
     1296    uint32_t cMetricNamesArraySize = metricNamesArray.size();
     1297
     1298    if (cMetricNamesArraySize == 0)
     1299    {
     1300        RTPrintf(Cloud::tr("\tThe list of metric names is empty. It may mean that an appropriate service wasn't run on the instance.\n"));
     1301        return RTEXITCODE_FAILURE;
     1302    }
     1303    else
     1304    {
     1305        Bstr value;
     1306        for (uint32_t k = 0; k < cMetricNamesArraySize; ++k)
     1307        {
     1308            value = metricNamesArray[k];
     1309            MetricType_T aMetricType;
     1310            CHECK_ERROR2_RET(hrc, oCloudClient, GetMetricTypeByName(value.raw(), &aMetricType), RTEXITCODE_FAILURE);
     1311
     1312            if (SUCCEEDED(hrc))
     1313            {
     1314                switch (aMetricType)
     1315                {
     1316                    case MetricType_CpuUtilization:
     1317                    case MetricType_MemoryUtilization:
     1318                    case MetricType_DiskBytesRead:
     1319                    case MetricType_DiskBytesWritten:
     1320                    case MetricType_NetworksBytesIn:
     1321                    case MetricType_NetworksBytesOut:
     1322                        RTPrintf(Cloud::tr(" - %ls\n"), value.raw());
     1323                        break;
     1324                    case MetricType_Invalid:
     1325                    default:
     1326                        break;
     1327                }
     1328            }
     1329        }
     1330    }
     1331
     1332    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     1333}
     1334
     1335
     1336static RTEXITCODE cloudInstanceMetricData(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
     1337{
     1338    HRESULT hrc = S_OK;
     1339
     1340    static const RTGETOPTDEF s_aOptions[] =
     1341    {
     1342        { "--id",           'i', RTGETOPT_REQ_STRING },
     1343        { "--metric-name",  'n', RTGETOPT_REQ_STRING },
     1344        { "--metric-points",'p', RTGETOPT_REQ_STRING },
     1345        { "help",           'h', RTGETOPT_REQ_NOTHING },
     1346        { "--help",         'h', RTGETOPT_REQ_NOTHING }
     1347    };
     1348    RTGETOPTSTATE GetState;
     1349    RTGETOPTUNION ValueUnion;
     1350    int vrc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
     1351    AssertRCReturn(vrc, RTEXITCODE_FAILURE);
     1352    if (a->argc == iFirst)
     1353    {
     1354        RTPrintf(Cloud::tr("Empty command parameter list, show help.\n"));
     1355        printHelp(g_pStdOut);
     1356        return RTEXITCODE_SUCCESS;
     1357    }
     1358
     1359    Utf8Str strInstanceId;
     1360    Utf8Str strMetricName;
     1361    Utf8Str strMetricPoints;
     1362
     1363    int c;
     1364    while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
     1365    {
     1366        switch (c)
     1367        {
     1368            case 'i':
     1369            {
     1370                if (strInstanceId.isNotEmpty())
     1371                    return errorArgument(Cloud::tr("Duplicate parameter: --id"));
     1372
     1373                strInstanceId = ValueUnion.psz;
     1374                if (strInstanceId.isEmpty())
     1375                    return errorArgument(Cloud::tr("Empty parameter: --id"));
     1376
     1377                break;
     1378            }
     1379            case 'n':
     1380            {
     1381                if (strMetricName.isNotEmpty())
     1382                    return errorArgument(Cloud::tr("Duplicate parameter: --metric-name"));
     1383
     1384                strMetricName = ValueUnion.psz;
     1385                if (strMetricName.isEmpty())
     1386                    return errorArgument(Cloud::tr("Empty parameter: --metric-name"));
     1387
     1388                break;
     1389            }
     1390            case 'p':
     1391            {
     1392                if (strMetricPoints.isNotEmpty())
     1393                    return errorArgument(Cloud::tr("Duplicate parameter: --metric-points"));
     1394
     1395                strMetricPoints = ValueUnion.psz;
     1396                if (strMetricPoints.isEmpty())
     1397                    return errorArgument(Cloud::tr("Empty parameter: --metric-points"));
     1398
     1399                break;
     1400            }
     1401            case 'h':
     1402                printHelp(g_pStdOut);
     1403                return RTEXITCODE_SUCCESS;
     1404            case VINF_GETOPT_NOT_OPTION:
     1405                return errorUnknownSubcommand(ValueUnion.psz);
     1406
     1407            default:
     1408                return errorGetOpt(c, &ValueUnion);
     1409        }
     1410    }
     1411
     1412    /* Delayed check. It allows us to print help information.*/
     1413    hrc = checkAndSetCommonOptions(a, pCommonOpts);
     1414    if (FAILED(hrc))
     1415        return RTEXITCODE_FAILURE;
     1416
     1417    if (strInstanceId.isEmpty())
     1418        return errorArgument(Cloud::tr("Missing parameter: --id"));
     1419    if (strMetricName.isEmpty())
     1420        return errorArgument(Cloud::tr("Missing parameter: --metric-name"));
     1421
     1422    unsigned long metricPoins;
     1423    strMetricPoints.isEmpty() ? metricPoins = 1 : metricPoins = RTStrToUInt32(strMetricPoints.c_str());
     1424
     1425    ComPtr<ICloudProfile> pCloudProfile = pCommonOpts->profile.pCloudProfile;
     1426
     1427    ComObjPtr<ICloudClient> oCloudClient;
     1428    CHECK_ERROR2_RET(hrc, pCloudProfile,
     1429                     CreateCloudClient(oCloudClient.asOutParam()),
     1430                     RTEXITCODE_FAILURE);
     1431    RTPrintf(Cloud::tr("Getting %s metric for the cloud instance with id %s...\n"), strMetricName.c_str(), strInstanceId.c_str());
     1432    RTPrintf(Cloud::tr("Reply is in the form \'%s[Rfc2822 time format]\' = \'value\'\n"), strMetricName.c_str());
     1433
     1434    /* Check the requested metric type */
     1435    MetricType_T aMetricType;
     1436    CHECK_ERROR2_RET(hrc, oCloudClient, GetMetricTypeByName(com::Bstr(strMetricName.c_str()).raw(), &aMetricType), RTEXITCODE_FAILURE);
     1437
     1438    /* First step*/
     1439    RTPrintf(Cloud::tr("First, reading the cloud machines list...\n"));
     1440    ComPtr<IProgress> progress;
     1441    CHECK_ERROR2_RET(hrc, oCloudClient, ReadCloudMachineList(progress.asOutParam()), RTEXITCODE_FAILURE);
     1442
     1443    hrc = showProgress(progress);
     1444    CHECK_PROGRESS_ERROR_RET(progress, (Cloud::tr("Reading the cloud machines list failed")), RTEXITCODE_FAILURE);
     1445
     1446    com::SafeIfaceArray<ICloudMachine> aMachines;
     1447    CHECK_ERROR2_RET(hrc, oCloudClient,
     1448                     COMGETTER(CloudMachineList)(ComSafeArrayAsOutParam(aMachines)),
     1449                     RTEXITCODE_FAILURE);
     1450
     1451    const size_t cMachines = aMachines.size();
     1452    if (cMachines == 0)
     1453        return RTEXITCODE_SUCCESS;
     1454
     1455    std::vector<ComPtr<ICloudMachine> > vMachines(cMachines);
     1456    std::vector<com::Bstr> vBstrCloudIds(cMachines);
     1457    std::vector<com::Bstr> vBstrIds(cMachines);
     1458
     1459    com::Bstr bstrFoundMachineVBoxId;
     1460
     1461    for (size_t i = 0; i < cMachines; ++i)
     1462    {
     1463        vMachines[i] = aMachines[i];
     1464
     1465        CHECK_ERROR2_RET(hrc, vMachines[i],
     1466                         COMGETTER(CloudId)(vBstrCloudIds[i].asOutParam()),
     1467                         RTEXITCODE_FAILURE);
     1468
     1469        Utf8Str strCurrMachineCloudId(vBstrCloudIds[i]);
     1470        if (strCurrMachineCloudId.equals(strInstanceId))
     1471        {
     1472            CHECK_ERROR2_RET(hrc, vMachines[i],
     1473                             COMGETTER(Id)(vBstrIds[i].asOutParam()),
     1474                             RTEXITCODE_FAILURE);
     1475            bstrFoundMachineVBoxId = vBstrIds[i];
     1476            break;
     1477        }
     1478    }
     1479
     1480    if (bstrFoundMachineVBoxId.isEmpty())
     1481    {
     1482        RTPrintf("The passed cloud instance Id \'%s\' WASN'T found among the cloud machines "
     1483                 "of user \'%s\' registered with VirtualBox\n",
     1484                 strInstanceId.c_str(), pCommonOpts->profile.pszProfileName);
     1485        return RTEXITCODE_FAILURE;
     1486    }
     1487
     1488    /* Second step*/
     1489    RTPrintf(Cloud::tr("Second, refresh information about cloud instance ...\n"));
     1490    ComPtr<ICloudMachine> pMachine;
     1491    CHECK_ERROR2_RET(hrc, oCloudClient,
     1492        GetCloudMachine(bstrFoundMachineVBoxId.raw(), pMachine.asOutParam()), RTEXITCODE_FAILURE);
     1493
     1494    ComPtr<IProgress> pRefreshProgress;
     1495    CHECK_ERROR2_RET(hrc, pMachine, Refresh(pRefreshProgress.asOutParam()), RTEXITCODE_FAILURE);
     1496
     1497    hrc = showProgress(pRefreshProgress);
     1498    CHECK_PROGRESS_ERROR_RET(pRefreshProgress, (Cloud::tr("Refreshing information about cloud instance failed")), RTEXITCODE_FAILURE);
     1499
     1500    /* Third step*/
     1501    RTPrintf(Cloud::tr("Third, request metric data from cloud instance ...\n"));
     1502    ComPtr<IProgress> progress2;
     1503    ComPtr<IStringArray> returnDataValues;
     1504    ComPtr<IStringArray> returnDataTimestamps;
     1505    ComPtr<IStringArray> returnMeasureUnits;
     1506
     1507    CHECK_ERROR2_RET(hrc, pMachine, EnumerateMetricData(aMetricType,
     1508                                                        metricPoins,
     1509                                                        returnDataValues.asOutParam(),
     1510                                                        returnDataTimestamps.asOutParam(),
     1511                                                        returnMeasureUnits.asOutParam(),
     1512                                                        progress2.asOutParam()),  RTEXITCODE_FAILURE);
     1513
     1514    hrc = showProgress(progress2);
     1515    CHECK_PROGRESS_ERROR_RET(progress2, (Cloud::tr("Getting metric data failed")), RTEXITCODE_FAILURE);
     1516
     1517    com::SafeArray<BSTR> dataValueArray;
     1518    CHECK_ERROR2_RET(hrc,
     1519                     returnDataValues, COMGETTER(Values)(ComSafeArrayAsOutParam(dataValueArray)),
     1520                     RTEXITCODE_FAILURE);
     1521
     1522    com::SafeArray<BSTR> dataTimestampArray;
     1523    CHECK_ERROR2_RET(hrc,
     1524                     returnDataTimestamps, COMGETTER(Values)(ComSafeArrayAsOutParam(dataTimestampArray)),
     1525                     RTEXITCODE_FAILURE);
     1526
     1527    com::SafeArray<BSTR> measureUnitArray;
     1528    CHECK_ERROR2_RET(hrc,
     1529                     returnMeasureUnits, COMGETTER(Values)(ComSafeArrayAsOutParam(measureUnitArray)),
     1530                     RTEXITCODE_FAILURE);
     1531
     1532    size_t cDataValueArraySize = dataValueArray.size();
     1533    Bstr unit = cDataValueArraySize == 0 ? Bstr("unknown units") : measureUnitArray[0];
     1534    RTPrintf(Cloud::tr("The %s metric values (in %ls):\n"), strMetricName.c_str(), unit.raw());
     1535
     1536    if (cDataValueArraySize == 0)
     1537        RTPrintf(Cloud::tr("\tThe list of metric data is empty. It may mean that an appropriate service wasn't run on the instance.\n"));
     1538    else
     1539    {
     1540        Bstr value;
     1541        for (size_t k = 0; k < cDataValueArraySize; ++k)
     1542        {
     1543            value = dataValueArray[k];
     1544            Utf8Str strTimestamp(dataTimestampArray[k]);
     1545            RTPrintf(Cloud::tr("%d: %s[%s] = %ls\n"), k, strMetricName.c_str(), strTimestamp.c_str(), value.raw());
     1546        }
     1547    }
     1548
     1549    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     1550}
     1551
     1552
    11491553static RTEXITCODE startCloudInstance(HandlerArg *a, int iFirst, PCLOUDCOMMONOPT pCommonOpts)
    11501554{
     
    14891893        kCloudInstance_Reset,
    14901894        kCloudInstance_Clone,
     1895        kCloudInstance_MetricList,
     1896        kCloudInstance_MetricData,
    14911897    };
    14921898
     
    15011907        { "reset",          kCloudInstance_Reset,     RTGETOPT_REQ_NOTHING },
    15021908        { "clone",          kCloudInstance_Clone,     RTGETOPT_REQ_NOTHING },
     1909        { "metriclist",     kCloudInstance_MetricList,RTGETOPT_REQ_NOTHING },
     1910        { "metricdata",     kCloudInstance_MetricData,RTGETOPT_REQ_NOTHING },
    15031911
    15041912        { "help",           'h',                      RTGETOPT_REQ_NOTHING },
     
    15571965                setCurrentSubcommand(HELP_SCOPE_CLOUD_INSTANCE_CLONE);
    15581966                return cloneCloudInstance(a, GetState.iNext, pCommonOpts);
     1967
     1968            case kCloudInstance_MetricData:
     1969                setCurrentSubcommand(HELP_SCOPE_CLOUD_INSTANCE_METRICDATA);
     1970                return cloudInstanceMetricData(a, GetState.iNext, pCommonOpts);
     1971
     1972            case kCloudInstance_MetricList:
     1973                setCurrentSubcommand(HELP_SCOPE_CLOUD_INSTANCE_METRICLIST);
     1974                return cloudInstanceMetricList(a, GetState.iNext, pCommonOpts);
    15591975
    15601976            case 'h':
Note: See TracChangeset for help on using the changeset viewer.

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