function Parser(config) { assert.object(config, 'config'); assert.arrayOfObject(config.options, 'config.options'); assert.optionalBool(config.interspersed, 'config.interspersed'); var self = this; this.interspersed = (config.interspersed !== undefined ? config.interspersed : true); this.allowUnknown = (config.allowUnknown !== undefined ? config.allowUnknown : false); this.options = config.options.map(function(o) { return shallowCopy(o); }); this.optionFromName = {}; this.optionFromEnv = {}; for (var i = 0; i < this.options.length; i++) { var o = this.options[i]; if (o.group !== undefined && o.group !== null) { assert.optionalString(o.group, format('config.options.%d.group', i)); continue; } assert.ok(optionTypes[o.type], format('invalid config.options.%d.type: "%s" in %j', i, o.type, o)); assert.optionalString(o.name, format('config.options.%d.name', i)); assert.optionalArrayOfString(o.names, format('config.options.%d.names', i)); assert.ok((o.name || o.names) && !(o.name && o.names), format('exactly one of "name" or "names" required: %j', o)); assert.optionalString(o.help, format('config.options.%d.help', i)); var env = o.env || []; if (typeof(env) === 'string') { env = [env]; } assert.optionalArrayOfString(env, format('config.options.%d.env', i)); assert.optionalString(o.helpGroup, format('config.options.%d.helpGroup', i)); assert.optionalBool(o.helpWrap, format('config.options.%d.helpWrap', i)); assert.optionalBool(o.hidden, format('config.options.%d.hidden', i)); if (o.name) { o.names = [o.name]; } else { assert.string(o.names[0], format('config.options.%d.names is empty', i)); } o.key = optionKeyFromName(o.names[0]); o.names.forEach(function(n) { if (self.optionFromName[n]) { throw new Error(format('option name collision: "%s" used in %j and %j', n, self.optionFromName[n], o)); } self.optionFromName[n] = o; }); env.forEach(function(n) { if (self.optionFromEnv[n]) { throw new Error(format('option env collision: "%s" used in %j and %j', n, self.optionFromEnv[n], o)); } self.optionFromEnv[n] = o; }); } }
function Writer(host, port, useIPv6) { assert.string(host, "host"); assert.number(port, "port"); assert.optionalBool(useIPv6, "useIPv6"); // == private functions and declarations var self = this; var sock; // == overridden methods self._write = function(chunk, encoding, cb) { var buf = new Buffer(chunk.join(" "), "ascii"); sock.send(buf, 0, buf.length, port, host, function(err /* , bytes */) { cb(err); }); }; // == and finally, initialization stream.Writable.call(self, { objectMode: true }); sock = dgram.createSocket(useIPv6 ? "udp6" : "udp4"); }
function env_to_boolean(varname, value_if_missing) { mod_assert.string(varname, 'varname'); mod_assert.optionalBool(value_if_missing, 'value_if_missing'); if (!process.env.hasOwnProperty(varname) || process.env[varname] === '') { /* * The variable was not set in the environment, or was set * to the empty string. */ if (value_if_missing === true || value_if_missing === false) { return (value_if_missing); } throw (new VError('environment variable %s was not set', varname)); } var v = process.env[varname].trim().toLowerCase(); if (NAMES_TRUE.indexOf(v) !== -1) { return (true); } else if (NAMES_FALSE.indexOf(v) !== -1) { return (false); } else { throw (new VError('value "%s" is not valid for environment ' + 'variable %s', v, varname)); } }
BuildSpec.prototype.get = function get(name, optional) { mod_assert.string(name, 'name'); mod_assert.optionalBool(optional, 'optional'); var self = this; /* * Files are added to the list with "unshift", i.e. most recent * addition is at index 0. */ for (var i = 0; i < self.bs_specs.length; i++) { var spec = self.bs_specs[i]; var val = pluck(spec.spec_object, name); if (val !== undefined) { return (val); } } if (optional !== true) { throw (new VError('could not find value "%s" in build specs', name)); } return (undefined); };
// --- special v1-related, but not RegistryClientV1-tied functionality /** * Ping a given Docker *index* URL (as opposed to a registry that requires * a repo name). */ function pingIndex(opts, cb) { assert.object(opts, 'opts'); assert.string(opts.indexName, 'opts.indexName'); assert.optionalBool(opts.insecure, 'opts.insecure'); assert.optionalObject(opts.log, 'opts.log'); assert.optionalString(opts.userAgent, 'opts.userAgent'); assert.func(cb, 'cb'); var index = common.parseIndex(opts.indexName); var client = restify.createJsonClient({ url: common.urlFromIndex(index), log: opts.log, userAgent: opts.userAgent || common.DEFAULT_USERAGENT, rejectUnauthorized: !opts.insecure }); client.get({ path: '/v1/_ping' }, function _afterPing(err, req, res, obj) { client.close(); if (err) { return cb(err); } return cb(null, obj, res); }); }
self.helpSubcmds.forEach(function (sc) { if (typeof (sc) === 'object') { assert.string(sc.group, 'helpSubcmds.*.group'); assert.optionalBool(sc.unmatched, 'helpSubcmds.*.unmatched'); self._subcmdOrder.push(sc); if (sc.unmatched) { if (++unmatchCount > 1) { throw (new Error(format('"unmatched" directive used ' + 'more than once in "helpSubcmds" option: %j', sc))); } /* * Include all of the unmatched names here: */ while (unmatchedNames.length > 0) { self._subcmdOrder.push(unmatchedNames.shift()); } } return; } /* * If this is not a group heading object, it must be the name * of a handler to include in the output: */ assert.string(sc); if (matchedNames.indexOf(sc) === -1) { throw (new Error('command handler included in help order ' + 'but not found: ' + sc)); } self._subcmdOrder.push(sc); });
SMRT.prototype.createOrUpdateProfile = function createOrUpdateProfile( profile, options, callback) { assert.object(profile, 'profile'); if (typeof(options) === 'function') { callback = options; options = {}; } assert.object(options, 'options') assert.optionalBool(options.setDefault, 'options.setDefault') assert.func(callback, 'callback') var found = false; for (var i = 0; i < this.profiles.length; i++) { if (this.profiles[i].name === profile.name) { this.profiles[i] = profile; found = true; } } if (!found) { this.profiles.push(profile); } if (options.setDefault) { this.defaultProfileName = this.config.defaultProfile = profile.name; } common.saveConfigSync(this.config); callback(); };
function MantaStorage(options) { assert.object(options.log, 'options.log'); assert.object(options.config, 'options.config'); var config = options.config; assert.string(config.url, 'options.config.url'); assert.string(config.user, 'options.config.user'); assert.string(config.key, 'options.config.key'); assert.string(config.keyId, 'options.config.keyId'); assert.optionalBool(config.insecure, 'options.config.insecure'); assert.string(config.baseDir, 'options.config.baseDir'); this.type = 'manta'; this.log = options.log.child({stor: this.type}, true); // Manta variables this.url = config.url; this.user = config.user; this.baseDir = config.baseDir; this.dir = path.join(this.baseDir, 'images'); this.archiveDir = path.join(this.baseDir, 'archive'); var insecure = config.hasOwnProperty('insecure') ? config.insecure : false; this.client = manta.createClient({ log: this.log, sign: { key: config.key, keyId: config.keyId, user: this.user }, user: this.user, url: this.url, // manta.createClient doesn't take 'insecure' currently // (manta.createBinClient *does*). rejectUnauthorized: !insecure }); }
// ---- convenience main function for a script /** * Mainline for a Cmdln-using tool. E.g., * * function MyTool() { * // ... * } * util.inherits(MyTool, Cmdln); * * ... * if (require.main === module) { * cmdln.main(MyTool); * } * * This does not have a callback because it calls `process.exit` (with an * appropriate exit status). * * @param cmdClass {Function} The Cmdln subclass ctor. * @param argv {Array} The argv to process. Optional. Default is `process.argv`. * @param options {Object} * - `showCode` {Boolean} Default false. Whether to show the error `code` * in the stderr output, if available on the error objects returned * by subcommands. E.g.: * fash: error: no command given # showCode=false * fash: error (NoCommand): no command given # showCode=true * See the doc on the `CmdlnError` class above for details on the `code`. */ function main(cmdClass, argv, options) { assert.func(cmdClass, 'cmdClass'); assert.optionalArrayOfString(argv, 'argv'); assert.optionalObject(options, 'options'); if (!options) { options = {}; } assert.optionalBool(options.showCode, 'options.showCode'); if (!argv) { argv = process.argv; } // TODO: Should prefer passing in the cmdClass *instance* here, then can // set it up. var cli = new cmdClass(); cli.main(argv, function (err, subcmd) { if (err) { // If the `err` has no "message" field, then this probably isn't // and Error instance. Let's just not print an error message. This // can happen if the subcmd passes back `true` or similar to // indicate "yes there was an error". if (err.message !== undefined) { var code = (err.body ? err.body.code : err.code); console.error('%s%s: error%s: %s', cli.name, (subcmd ? ' ' + subcmd : ''), ((options.showCode && code) ? format(' (%s)', code) : ''), (process.env.DEBUG ? err.stack : err.message)); } process.exit(err.exitStatus || 1); } process.exit(0); }); }
function StringClient(options) { assert.object(options, 'options'); assert.optionalObject(options.gzip, 'options.gzip'); assert.optionalObject(options.contentMd5, 'options.contentMd5'); if (options.contentMd5) { assert.optionalArrayOfString(options.contentMd5.encodings, 'options.contentMd5.encodings'); assert.optionalBool(options.contentMd5.ignore, 'options.contentMd5.ignore'); if (Array.isArray(options.contentMd5.encodings)) { options.contentMd5.encodings.forEach(function _checkMd5Enc(enc) { assert.ok(Buffer.isEncoding(enc), 'encoding "' + enc + '" is an invalid encoding'); }); } } options.accept = options.accept || 'text/plain'; options.name = options.name || 'StringClient'; options.contentType = options.contentType || 'application/x-www-form-urlencoded'; HttpClient.call(this, options); this.contentMd5 = options.contentMd5 || {}; this.gzip = options.gzip; if (!this.contentMd5.encodings) { // The undefined value here is used to make node use the default // encoding when computing the response content md5 hash. this.contentMd5.encodings = [undefined]; } }
function _showUser(opts, cb) { assert.object(opts.cli, 'opts.cli'); assert.string(opts.id, 'opts.id'); assert.optionalBool(opts.roles, 'opts.roles'); assert.optionalBool(opts.keys, 'opts.keys'); assert.func(cb, 'cb'); var cli = opts.cli; cli.tritonapi.getUser({ id: opts.id, roles: opts.roles, keys: opts.keys }, function onUser(err, user) { if (err) { return cb(err); } if (opts.json) { console.log(JSON.stringify(user)); } else { var skip = {keys: true, roles: true, default_roles: true}; Object.keys(user).forEach(function (field) { if (skip[field]) { return; } console.log('%s: %s', field, user[field]); }); if (opts.roles) { console.log('roles:'); user.roles.forEach( function (r) { console.log(' ' + r); }); console.log('default_roles:'); user.default_roles.forEach( function (r) { console.log(' ' + r); }); } if (opts.keys) { console.log('keys:'); user.keys.forEach(function (key) { console.log(' %s%s', key.fingerprint, key.name ? format(' (%s)', key.name) : ''); }); } } cb(); }); }
MountDumpReply.prototype.addMapping = function addMapping(opts, noClone) { assert.object(opts); assert.string(opts.name, 'options.name'); assert.string(opts.dirpath, 'options.dirpath'); assert.optionalBool(noClone, 'noClone'); this.mappings.push(noClone ? opts : clone(opts)); };
// --- Exports /** * Creates the dhcpd server */ function createServer(opts) { assert.object(opts, 'opts'); assert.optionalObject(opts.config, 'opts.config'); assert.optionalString(opts.configFile, 'opts.configFile'); assert.object(opts.log, 'opts.log'); assert.object(opts.adminPoolCache, 'opts.adminPoolCache'); var config; var log = opts.log; if (opts.config) { config = opts.config; } else { assert.string(opts.configFile, 'opts.configFile'); log.info('Loading config from "%s"', opts.configFile); config = JSON.parse(fs.readFileSync(opts.configFile, 'utf-8')); } var requiredStrings = [ 'adminUuid', 'listenIp', 'tftpRoot', 'defaultGateway', 'serverIp', 'netmask']; for (var r in requiredStrings) { var req = requiredStrings[r]; assert.string(config[req], 'config.' + req); } assert.number(config.leaseTime, 'config.leaseTime'); assert.number(config.port, 'config.port'); assert.optionalArrayOfString(config.resolvers); assert.optionalBool(config.disableBootTimeFiles, 'config.disableBootTimeFiles'); assert.optionalBool(config.disableHash, 'config.disableHash'); assert.optionalBool(config.ipxeHTTP, 'config.ipxeHTTP'); assert.optionalBool(config.chainloadGrub, 'config.chainloadGrub'); log.info({ config: config }, 'server config loaded'); return new DHCPD({ log: log, config: config, adminPoolCache: opts.adminPoolCache, napi: opts.napi }); }
function findObjectsForShards(opts, cb) { assert.object(opts, 'opts'); assert.arrayOfString(opts.shards, 'opts.shards'); assert.object(opts.client, 'opts.client'); assert.object(opts.log, 'opts.log'); assert.arrayOfString(opts.tablePrefixes, 'opts.tablePrefixes'); assert.optionalNumber(opts.timestamp, 'opts.timestamp'); assert.optionalBool(opts.returnObjects, 'opts.returnObjects'); var shards = opts.shards; if (shards.length === 0) { cb(new Error('No shards specified.')); return; } vasync.forEachParallel({ func: findShardObjects, inputs: shards.map(function (s) { return ({ 'shard': s, 'client': opts.client, 'tablePrefixes': opts.tablePrefixes, 'timestamp': opts.timestamp }); }) }, function (err, results) { if (err) { return (cb(err)); } if (results.successes.length !== shards.length) { return (cb(new Error('Couldnt find latest backups ' + 'for all shards.'))); } var objects = []; var earliestMorayDump = null; for (var i = 0; i < shards.length; ++i) { var res = results.successes[i]; res.forEach(function (o) { var mtime = new Date(o.mtime); if (!earliestMorayDump || mtime < earliestMorayDump) { earliestMorayDump = mtime; } if (opts.returnObjects) { objects.push(o); } else { objects.push(o.path); } }); opts.earliestMorayDump = earliestMorayDump; } opts.log.info(objects, 'found objects for shard'); cb(null, objects); }); }
function addOptionType(optionType) { assert.object(optionType, 'optionType'); assert.string(optionType.name, 'optionType.name'); assert.bool(optionType.takesArg, 'optionType.takesArg'); if (optionType.takesArg) { assert.string(optionType.helpArg, 'optionType.helpArg'); } assert.func(optionType.parseArg, 'optionType.parseArg'); assert.optionalBool(optionType.array, 'optionType.array'); assert.optionalBool(optionType.arrayFlatten, 'optionType.arrayFlatten'); optionTypes[optionType.name] = { takesArg: optionType.takesArg, helpArg: optionType.helpArg, parseArg: optionType.parseArg, array: optionType.array, arrayFlatten: optionType.arrayFlatten, default: optionType.default }; }
function _deleteUsers(opts, cb) { assert.object(opts.cli, 'opts.cli'); assert.arrayOfString(opts.ids, 'opts.ids'); assert.optionalBool(opts.yes, 'opts.yes'); assert.func(cb, 'cb'); var cli = opts.cli; if (opts.ids.length === 0) { cb(); return; } vasync.pipeline({funcs: [ function confirm(_, next) { if (opts.yes) { return next(); } var msg; if (opts.ids.length === 1) { msg = 'Delete user "' + opts.ids[0] + '"? [y/n] '; } else { msg = format('Delete %d users (%s)? [y/n] ', opts.ids.length, opts.ids.join(', ')); } common.promptYesNo({msg: msg}, function (answer) { if (answer !== 'y') { console.error('Aborting'); next(true); // early abort signal } else { next(); } }); }, function deleteThem(_, next) { vasync.forEachPipeline({ inputs: opts.ids, func: function deleteOne(id, nextId) { cli.tritonapi.cloudapi.deleteUser({id: id}, function (err) { if (err) { nextId(err); return; } console.log('Deleted user "%s"', id); nextId(); }); } }, next); } ]}, function (err) { if (err === true) { err = null; } cb(err); }); }
/** * Sort an array of objects (in-place). * * @param items {Array} The array of objects to sort. * @param fields {Array} Array of field names (lookups) on which to sort -- * higher priority to fields earlier in the array. The comparison may * be reversed by prefixing the field with '-'. E.g.: * ['-age', 'lastname', 'firstname'] * @param options {Object} Optional. * - dottedLookup {Boolean} * * From node-tabula. */ function sortArrayOfObjects(items, fields, options) { assert.optionalObject(options, 'options'); if (!options) { options = {}; } assert.optionalBool(options.dottedLookup, 'options.dottedLookup'); var dottedLookup = options.dottedLookup; function cmp(a, b) { for (var i = 0; i < fields.length; i++) { var field = fields[i]; var invert = false; if (field[0] === '-') { invert = true; field = field.slice(1); } assert.ok(field.length, 'zero-length sort field: ' + fields); var a_field, b_field; if (dottedLookup) { // This could be sped up by bring some processing out of `cmp`. var lookup = new Function('return this.' + field); try { a_field = lookup.call(a); } catch (e) {} try { b_field = lookup.call(b); } catch (e) {} } else { a_field = a[field]; b_field = b[field]; } var a_cmp = Number(a_field); var b_cmp = Number(b_field); if (isNaN(a_cmp) || isNaN(b_cmp)) { a_cmp = a_field; b_cmp = b_field; } // Comparing < or > to `undefined` with any value always // returns false. if (a_cmp === undefined && b_cmp === undefined) { /* jsl:pass */ } else if (a_cmp === undefined) { return (invert ? 1 : -1); } else if (b_cmp === undefined) { return (invert ? -1 : 1); } else if (a_cmp < b_cmp) { return (invert ? 1 : -1); } else if (a_cmp > b_cmp) { return (invert ? -1 : 1); } } return 0; } items.sort(cmp); }
function bashCompletionSpecFromOptions(args) { assert.object(args, 'args'); assert.object(args.options, 'args.options'); assert.optionalString(args.context, 'args.context'); assert.optionalBool(args.includeHidden, 'args.includeHidden'); assert.optionalArrayOfString(args.argtypes, 'args.argtypes'); var context = args.context || ''; var includeHidden = (args.includeHidden === undefined ? false : args.includeHidden); var spec = []; var shortopts = []; var longopts = []; var optargs = []; (args.options || []).forEach(function(o) { if (o.group) { return; } var optNames = o.names || [o.name]; var optType = getOptionType(o.type); if (optType.takesArg) { var completionType = o.completionType || optType.completionType || o.type; optNames.forEach(function(optName) { if (optName.length === 1) { if (includeHidden || !o.hidden) { shortopts.push('-' + optName); } optargs.push('-' + optName + '=' + completionType); } else { if (includeHidden || !o.hidden) { longopts.push('--' + optName); } optargs.push('--' + optName + '=' + completionType); } }); } else { optNames.forEach(function(optName) { if (includeHidden || !o.hidden) { if (optName.length === 1) { shortopts.push('-' + optName); } else { longopts.push('--' + optName); } } }); } }); spec.push(format('local cmd%s_shortopts="%s"', context, shortopts.sort().join(' '))); spec.push(format('local cmd%s_longopts="%s"', context, longopts.sort().join(' '))); spec.push(format('local cmd%s_optargs="%s"', context, optargs.sort().join(' '))); if (args.argtypes) { spec.push(format('local cmd%s_argtypes="%s"', context, args.argtypes.join(' '))); } return spec.join('\n'); }
PAPI.prototype.list = function list(filter, options, cb) { var self = this; assert.object(options, 'options'); assert.optionalBool(options.escape, 'options.escape'); assert.optionalObject(options.headers, 'options.headers'); assert.func(cb, 'cb'); var escape = (options.escape === undefined ? true : options.escape); var headers = options.headers; delete options.escape; delete options.headers; var query = {}; if (typeof (filter) === 'string') { query.filter = filter; } else { Object.keys(filter).forEach(function (k) { var val = filter[k]; if (escape && typeof (val) === 'string') { /* JSSTYLED */ query[k] = val.replace(/\*/g, '{\\2a}'); } else { query[k] = val; } }); } Object.keys(options).forEach(function (k) { query[k] = options[k]; }); var opts = { path: '/packages', query: query }; if (headers) { opts.headers = headers; } return self.client.get(opts, function (err, req, res, pkgs) { if (err) { return cb(err); } var count = Number(res.headers['x-resource-count']); return cb(null, pkgs, count); }); };
/** * Filter `servers` according to `constraints.vm.locality` rules. */ function filterLocality(log, state, servers, constraints) { assert.object(log, 'log'); assert.object(state, 'state'); assert.arrayOfObject(servers, 'servers'); assert.object(constraints, 'constraints'); assert.uuid(constraints.vm.owner_uuid, 'constraints.vm.owner_uuid'); var ownerUuid = constraints.vm.owner_uuid; if (servers.length === 0) { return ([servers]); } // Parse "locality". See format notes in top-comment. assert.optionalObject(constraints.vm.locality, 'constraints.vm.locality'); var locality = constraints.vm.locality || {}; assert.optionalBool(locality.strict, 'locality.strict'); var strict = Boolean(locality.strict); var far = normNearFar(locality.far, 'locality.far'); var near = normNearFar(locality.near, 'locality.near'); var reasons = {}; if (near.length === 0 && far.length === 0) { // Default behaviour: basic attempt to spread out the // customer's VMs. servers = softSpreadByOwner(servers, reasons, ownerUuid); } else { // Process `far` first (far wins over near, see notes above). if (far.length > 0) { servers = filterFar(servers, reasons, far, strict, ownerUuid); } if (servers.length > 0 && near.length > 0) { if (strict) { servers = filterNearStrict(servers, reasons, near, ownerUuid); } else { servers = filterNearNonStrict(servers, reasons, near, ownerUuid); } } } if (Object.keys(reasons).length === 0) { reasons = undefined; } return ([servers, reasons]); }
function CreateInstanceProcedure(opts) { assert.string(opts.svcName, 'opts.svcName'); assert.arrayOfString(opts.serverNames, 'opts.serverNames'); assert.ok(opts.serverNames.length > 0, 'at least one server name'); assert.optionalUuid(opts.imageUuid, 'opts.imageUuid'); assert.optionalString(opts.imageChannel, 'opts.imageChannel'); assert.optionalBool(opts.skipHACheck, 'opts.skipHACheck'); this.svcName = opts.svcName; this.serverNames = opts.serverNames; this.imageUuid = opts.imageUuid; this.imageChannel = opts.imageChannel; this.skipHACheck = Boolean(opts.skipHACheck); }
/** * Return a restify handler to redirect to the given location. * * @param location {String} Path to with to redirect. * @param permanent {Boolean} Optional. If true, then uses "301" (Moved * Permanently), else uses "302" (Found). Default is false. */ function redir(location, permanent) { assert.string(location, 'location'); assert.optionalBool(permanent, permanent); var code = (permanent ? 301 : 302); return function redirect(req, res, next) { res.set('Content-Length', 0); res.set('Connection', 'keep-alive'); res.set('Date', new Date()); res.set('Location', location); res.send(code); next(); }; }
function Control(options) { assert.optionalObject(options); options = options || {}; assert.optionalString(options.type); assert.optionalBool(options.criticality); if (options.value) { console.log(assert.buffer.toString()); assert.buffer(options.value); } this.type = options.type || ''; this.criticality = options.critical || options.criticality || false; this.value = options.value || null; }
/* * ProgressBar -- the main class. */ function ProgressBar(options) { var self = this; mod_assert.object(options, 'options'); mod_assert.string(options.filename, 'options.filename'); mod_assert.optionalBool(options.hidecursor, 'options.hidecursor'); mod_assert.optionalNumber(options.maxdrawfreq, 'options.maxdrawfreq'); if (options.nosize) { mod_assert.bool(options.nosize); mod_assert.ok(typeof (options.size) === 'undefined', 'nosize and size are mutually exclusive'); } else { mod_assert.number(options.size, 'options.size'); mod_assert.ok(options.size >= 0, 'options.size 0 or more'); } self.pb_hide_cursor = options.hidecursor ? true : false; self.pb_filename = options.filename; if (options.nosize) { self.pb_nosize = true; self.pb_size = 0; } else { self.pb_nosize = false; self.pb_size = options.size; } self.pb_progress = 0; self.pb_done = false; self.pb_tty = process.stderr; self.pb_rlif = null; if (USE_READLINE || !ECMA48_TERMINAL) { self.pb_rlif = init_readline(self.pb_tty); } if (options.maxdrawfreq !== undefined) { mod_assert.ok(options.maxdrawfreq > 0, 'options.maxdrawfreq > 0'); self.pb_drawperiod = Math.floor((1 / options.maxdrawfreq) * 1000); } else { self.pb_drawperiod = 500; /* 2 Hz */ } self.pb_lastdrawtime = 0; self.pb_startat = +Date.now(); self.pb_readings = 0; }
function sql(rpcctx, statement, values, options) { var opts, log, req, res; assert.object(rpcctx, 'rpcctx'); assert.string(statement, 'statement'); assert.ok(Array.isArray(values)); assert.object(options, 'options'); assert.optionalNumber(options.timeout, 'options.timeout'); assert.optionalBool(options.readOnlyOverride, 'options.readOnlyOverride'); opts = { req_id: options.req_id || libuuid.create(), timeout: options.timeout, readOnlyOverride: options.readOnlyOverride || false }; log = rpc.childLogger(rpcctx, opts); res = new events.EventEmitter(); /* * We specify ignoreNullValues because electric-moray sends spurious * trailing null values from successful sql() commands. These are not * generally allowed, but we have to maintain compatibility with broken * servers. */ req = rpc.rpcCommon({ 'rpcctx': rpcctx, 'rpcmethod': 'sql', 'rpcargs': [ statement, values, opts ], 'ignoreNullValues': true, 'log': log }, function (err) { if (err) { res.emit('error', err); } else { res.emit('end'); } res.emit('_moray_internal_rpc_done'); }); req.on('data', function (msg) { if (msg !== null) { log.debug('sql: msg: %j', msg); res.emit('record', msg); } }); return (res); }
///--- Helpers /** * appends streams * @private * @function appendStream * @param {Stream} streams the stream to append to * @param {Stream} s the stream to append * @returns {undefined} */ function appendStream(streams, s) { assert.arrayOfObject(streams, 'streams'); assert.object(s, 'stream'); if (s instanceof Stream) { streams.push({ raw: false, stream: s }); } else { assert.optionalBool(s.raw, 'stream.raw'); assert.object(s.stream, 'stream.stream'); streams.push(s); } }
/** * Return a name (suitable for some of the 'Image' fields in inspect * responses) for the given image (of the format returned from `imageFromUuid`). */ function nameFromImage(image, excludeLatest) { assert.optionalBool(excludeLatest, 'excludeLatest'); var name; if (!image) { name = '<unknown>'; } else if (image.RepoTags && image.RepoTags.length) { name = image.RepoTags[0]; var idx = name.lastIndexOf(':'); if (idx !== -1 && name.slice(idx) === ':latest') { name = name.slice(0, idx); } } else { name = image.Id.slice(0, 12); } return name; }
/** * Filter `servers` according to `opts.vm.locality` rules. */ function filterSoftLocality(servers, opts, cb) { assert.arrayOfObject(servers, 'servers'); assert.object(opts, 'opts'); assert.object(opts.vm, 'opts.vm'); assert.func(cb, 'cb'); var ownerUuid = opts.vm.owner_uuid; assert.uuid(ownerUuid, 'opts.vm.owner_uuid'); var reasons = {}; if (servers.length === 0) { return (cb(null, servers, reasons)); } // Parse "locality". See format notes in top-comment. assert.optionalObject(opts.vm.locality, 'opts.vm.locality'); var locality = opts.vm.locality || {}; assert.optionalBool(locality.strict, 'locality.strict'); var strict = Boolean(locality.strict); var far = shared.normNearFar(locality.far, 'locality.far'); var near = shared.normNearFar(locality.near, 'locality.near'); if (near.length === 0 && far.length === 0) { // Default behaviour: basic attempt to spread out the // customer's VMs. servers = softSpreadByOwner(servers, reasons, ownerUuid); } else if (strict) { reasons.skip = 'Strict locality requested and no spreading ' + 'needed'; return (cb(null, servers, reasons)); } else { // Process `far` first (far wins over near, see notes above). if (far.length > 0) { servers = shared.filterFar(servers, reasons, far, strict, ownerUuid); } if (servers.length > 0 && near.length > 0) { servers = filterNearNonStrict(servers, reasons, near, ownerUuid); } } return (cb(null, servers, reasons)); }
// --- Exports /** * Get a VM's firewall status from firewaller on a CN */ function getFwStatus(t, opts, callback) { assert.object(t, 't'); assert.object(opts, 'opts'); assert.object(opts.vm, 'opts.vm'); assert.string(opts.vm.uuid, 'opts.vm.uuid'); assert.string(opts.vm.server_uuid, 'opts.vm.server_uuid'); assert.optionalBool(opts.exp, 'opts.exp'); assert.optionalObject(opts.expErr, 'opts.expErr'); var desc = fmt(' (server %s, rule uuid=%s)', opts.vm.server_uuid, opts.vm.uuid); var checkOpts = { desc: desc, errCode: 'ResourceNotFound', server_uuid: opts.vm.server_uuid, url: '/vms/' + opts.vm.uuid + '/status' }; checkUrl(t, checkOpts, function (err, req, res, obj) { if (err && err.client) { // Couldn't get the client - no sense in going further return done(err, null, t, callback); } if (opts.expErr) { t.ok(err, 'expected error'); if (err) { var code = opts.expCode || 422; t.equal(err.statusCode, code, 'status code'); t.deepEqual(err.body, opts.expErr, 'error body'); } return done(err, null, t, callback); } if (common.ifErr(t, err, 'getting VM status' + desc)) { return done(err, null, t, callback); } if (opts.exp) { t.equal(obj.running, opts.exp, 'status' + desc); } return done(null, obj, t, callback); }); }
/** * Call `vmadm start UUID`. * * @param uuid {String} The current snapshot name. * @param options {Object} * - log {Bunyan Logger} * @param callback {Function} `function (err)` */ function vmStart(uuid, options, callback) { assert.string(uuid, 'uuid'); assert.object(options, 'options'); assert.optionalBool(options.force, 'options.force'); assert.object(options.log, 'options.log'); assert.func(callback); var optStr = ''; if (options.force) { optStr += ' -F'; } var cmd = format('/usr/sbin/vmadm start%s %s', optStr, uuid); options.log.trace({cmd: cmd}, 'start vmStart'); exec(cmd, function (err, stdout, stderr) { options.log.trace({cmd: cmd, err: err, stdout: stdout, stderr: stderr}, 'finish vmStart'); callback(err); }); }