Esempio n. 1
0
function addTestVms(nbVms, concurrency, data) {
    assert.finite(nbVms, 'nbVms must be a number');
    assert.ok(nbVms > 0, 'nbVms must be a positive number');

    assert.finite(concurrency, 'concurrency must be a number');
    assert.ok(concurrency > 0, 'concurrency must be a positive number');

    assert.optionalObject(data, 'data must be an optional object');
    var morayConfig = jsprim.deepCopy(config.moray);

    morayConfig.reconnect = true;

    data = data || {};

    var morayClient;
    var moray;
    var morayBucketsInitializer;
    var moraySetup = morayInit.startMorayInit({
        morayConfig: morayConfig,
        maxBucketsReindexAttempts: 1,
        maxBucketsSetupAttempts: 1,
        changefeedPublisher: changefeedUtils.createNoopCfPublisher()
    });

    morayClient = moraySetup.morayClient;
    moray = moraySetup.moray;
    morayBucketsInitializer = moraySetup.morayBucketsInitializer;

    morayBucketsInitializer.on('done',
        function onMorayBucketsSetup() {
            log.debug('Number of test VMs to create:', nbVms);
            assert.number(nbVms);

            log.debug('concurrency:', concurrency);
            assert.number(concurrency);

            testVm.createTestVMs(nbVms, moray, {
                concurrency: concurrency,
                log: log
            }, data, function allVmsCreated(err) {
                if (err) {
                    log.error({err: err}, 'Error when creating test VMs');
                } else {
                    log.info('All VMs created successfully');
                }

                log.debug('Closing moray connection');
                morayClient.close();
            });
        });
}
Esempio n. 2
0
/*
 * Returns true if the response object "res" represents a response indicating a
 * successful HTTP request.
 */
function responseIndicatesSuccess(res) {
    assert.object(res, 'res');
    assert.finite(res.statusCode, 'res.statusCode');

    // Any 20X HTTP status code is considered to represent a successful request.
    return Math.floor(res.statusCode / 100) === 2;
}
Esempio n. 3
0
function createSocket (opts) {
  assert.object(opts, 'options');
  assert.string(opts.host, 'options.host');
  assert.finite(opts.port, 'options.port');
  assert.object(opts.proxy, 'options.proxy');
  assert.optionalBool(opts.tls, 'options.tls');

  var transport = opts.tls ? tls : net;
  var socket = transport.connect({
    host: opts.host,
    port: opts.port
  });

  PROXY_EVENTS.forEach(function (event) {
    socket.on(event, opts.proxy.emit.bind(opts.proxy, event));
  });

  return (socket);
}
Esempio n. 4
0
/*
 * Import the given set of image objects (`args.imgs`) with the given
 * concurrency.
 *
 * @param {Object} args
 *      - {Array} args.imgs - The array of image objects to import.
 *      - {String} args.source - The source IMGAPI URL.
 *      - {Number} args.concurrency - An integer number of images to import at
 *        the same time.
 *      - {Object} args.sdcadm - SdcAdm object.
 *      - {Function} args.progress - Progress output function.
 * @param {Function} cb - called as `cb(err)` where `err` is null or
 *      a single error, or a `verror.MultiError` if multiple concurrent imports
 *      failed.
 *
 * Dev Note: If there are multiple errors, then `err` will be a
 * `verror.MultiError` -- which is different from a `errors.MultiError`.
 * This is an unfortunate middle ground, until sdcadm transitions from
 * its "errors.js" wrappers to raw VError instances using facilities
 * in verror v1.7.0 (see RFD 41).
 */
function importSetOfImages(args, cb) {
    assert.arrayOfObject(args.imgs, 'args.imgs');
    assert.string(args.source, 'args.source');
    assert.object(args.sdcadm, 'args.sdcadm');
    assert.func(args.progress, 'args.progress');
    assert.finite(args.concurrency, 'args.concurrency');
    assert.func(cb, 'cb');

    var errs = [];
    var progress = args.progress;
    var sdcadm = args.sdcadm;

    var q = vasync.queuev({
        concurrency: args.concurrency,
        worker: function importAnImage(image, nextImg) {
            /*
             * Need to be verified here b/c there are callers other than
             * procedures/index.js calling DownloadImages.
             */
            function checkIfImageIsUnactivated(_, nextStep) {
                if (image.state === 'unactivated') {
                    nextStep();
                    return;
                }
                sdcadm.imgapi.getImage(image.uuid, function (err, local) {
                    if (err && err.body.code === 'ResourceNotFound') {
                        nextStep();
                    } else if (err) {
                        nextStep(new errors.SDCClientError(err, 'imgapi'));
                    } else {
                        if (local.state === 'unactivated') {
                            // Let DownloadImages know that it has to
                            // remove the image first:
                            image.state = 'unactivated';
                        }
                        nextStep();
                    }
                });
            }

            function deleteImage(_, nextStep) {
                if (image.state !== 'unactivated') {
                    nextStep();
                    return;
                }

                progress('Removing unactivated image %s\n(%s@%s)',
                    image.uuid, image.name, image.version);

                sdcadm.imgapi.deleteImage(image.uuid, function (err) {
                    if (err) {
                        progress('Error removing unactivated image %s\n(%s@%s)',
                            image.uuid, image.name, image.version);

                        var e = new errors.SDCClientError(err, 'imgapi');
                        e.image = image.uuid;
                        sdcadm.log.error({err: e}, 'Error removing image');
                        nextStep(e);
                    } else {
                        nextStep();
                    }
                });
            }

            function getImage(_, nextStep) {
                progress('Downloading image %s\n    (%s@%s)',
                    image.uuid, image.name, image.version);
                sdcadm.imgapi.adminImportRemoteImageAndWait(
                    image.uuid,
                    args.source,
                    {
                        // TODO: Once IMGAPI-408 is sufficient deployed,
                        // then drop this `skipOwnerCheck`.
                        skipOwnerCheck: true,
                        // Retry image import 5 times by default:
                        retries: 5
                    },
                    function (err, _img, res) {
                        if (err) {
                            progress('Error importing image %s\n    (%s@%s)',
                                image.uuid, image.name, image.version);
                            var e = new errors.SDCClientError(err,
                                'imgapi');
                            e.image = image.uuid;
                            nextStep(e);
                        } else {
                            progress('Imported image %s\n    (%s@%s)',
                                image.uuid, image.name, image.version);
                            nextStep();
                        }
                    });
            }

            vasync.pipeline({funcs: [
                checkIfImageIsUnactivated,
                deleteImage,
                getImage
            ]}, nextImg);
        }
    });

    function onTaskComplete(err) {
        if (err) {
            errs.push(err);
            /*
             * Don't start more tasks. After a single image import failure
             * we want to fail reasonably fast, i.e. *not* wait for another
             * N image imports to be started from the queue.
             */
            q.kill();
        }
    }

    q.on('end', function done() {
        cb(VError.errorFromList(errs));
    });

    q.push(args.imgs, onTaskComplete);
    q.close();
}
Esempio n. 5
0
/*
 * This function creates a large number of "test" VMs
 * (VMs with alias='test--'), and then sends GET requests to /vms to retrieve
 * them by passing a specific "limit" value.
 * It then makes sure that the correct number of VMs are included in the
 * results, that is the number of VMs created, unless it's greater than the
 * maximum value for "limit".
 */
function testValidLimit(limit, t, callback) {
    assert.finite(limit, 'options');

    assert.object(t, 't');
    assert.func(callback, 'callback');

    var NB_TEST_VMS_TO_CREATE = limit + 1;
    var EXPECTED_NB_VMS_RETURNED = Math.min(limit, MAX_LIMIT);

    // limit === 0 means "unlimited"
    if (limit === 0) {
        EXPECTED_NB_VMS_RETURNED = NB_TEST_VMS_TO_CREATE;
    }

    async.series([
        // Delete test VMs leftover from previous tests run
        function deleteTestVms(next) {
            vmTest.deleteTestVMs(moray, {},
                function vmsDeleted(err) {
                    t.ifError(err, 'deleting test VMs should not error');
                    return next(err);
                });
        },
        function createFakeVms(next) {
            vmTest.createTestVMs(NB_TEST_VMS_TO_CREATE, moray,
                {concurrency: 100}, {},
                function fakeVmsCreated(err, vmUuids) {
                    t.equal(vmUuids.length,
                        NB_TEST_VMS_TO_CREATE,
                        NB_TEST_VMS_TO_CREATE
                        + ' vms should have been created');

                    t.ifError(err, NB_TEST_VMS_TO_CREATE
                        + ' vms should be created successfully');
                    return next(err);
                });
        },
        function listVmsWithLimit(next) {
            var listVmsQuery = '/vms?limit=' + limit + '&alias='
            + vmTest.TEST_VMS_ALIAS;

            client.get(listVmsQuery, function (err, req, res, body) {
                t.ifError(err);
                if (err)
                    return next(err);

                t.equal(res.headers['x-joyent-resource-count'],
                    NB_TEST_VMS_TO_CREATE,
                    'x-joyent-resource-count header should be equal to '
                    + NB_TEST_VMS_TO_CREATE);
                t.equal(body.length, EXPECTED_NB_VMS_RETURNED,
                    EXPECTED_NB_VMS_RETURNED
                    + ' vms should be returned from list vms');

                return next(null);
            });
        }
    ], function allDone(err, results) {
        t.ifError(err);
        return callback();
    });
}
Esempio n. 6
0
	config = JSON.parse(contents);
} else {
	config = {
		instances: [],
		logLevel: 'info',
		pollInterval: 120000
	};
}

if (ARGV['sapi-url']) {
	config.sapi = { url: ARGV['sapi-url'] };
}

assert.object(config, 'config');
assert.string(config.logLevel, 'config.logLevel');
assert.finite(config.pollInterval, 'config.pollInterval');
assert.optionalObject(config.sapi, 'config.sapi');

var log = bunyan.createLogger({
	name: 'config-agent',
	level: config.logLevel,
	stream: process.stdout,
	serializers: bunyan.stdSerializers
});


var agent;
var zonename;

// For now we stash `autoMetadata` onto the config object.
// TODO(refactor): pass autoMetadata as an opt to `new Agent`.