improvements for using node-triton as a module
This commit is contained in:
parent
a40e0d6f8c
commit
21164320c7
13
CHANGES.md
13
CHANGES.md
@ -1,8 +1,17 @@
|
||||
# node-triton changelog
|
||||
|
||||
## 3.3.1 (not yet released)
|
||||
## 3.4.0 (not yet released)
|
||||
|
||||
(nothing yet)
|
||||
- Improvements for using node-triton as a module. E.g. a simple example:
|
||||
|
||||
var triton = require('triton');
|
||||
var client = triton.createClient({profileName: 'env'});
|
||||
client.listImages(function (err, imgs) {
|
||||
console.log(err);
|
||||
console.log(imgs);
|
||||
});
|
||||
|
||||
See the README and "lib/index.js" for more info.
|
||||
|
||||
|
||||
## 3.3.0
|
||||
|
32
README.md
32
README.md
@ -74,7 +74,7 @@ For a more permanent installation:
|
||||
triton completion > /usr/local/etc/bash_completion.d/triton
|
||||
|
||||
|
||||
## Examples
|
||||
## `triton` CLI Usage
|
||||
|
||||
### Create and view instances
|
||||
|
||||
@ -214,6 +214,33 @@ as a single `DOCKER_HOST`. See the [Triton Docker
|
||||
documentation](https://apidocs.joyent.com/docker) for more information.)
|
||||
|
||||
|
||||
## `TritonApi` Module Usage
|
||||
|
||||
Node-triton can also be used as a node module for your own node.js tooling.
|
||||
A basic example:
|
||||
|
||||
var triton = require('triton');
|
||||
|
||||
// See `createClient` block comment for full usage details:
|
||||
// https://github.com/joyent/node-triton/blob/master/lib/index.js
|
||||
var client = triton.createClient({
|
||||
profile: {
|
||||
url: URL,
|
||||
account: ACCOUNT,
|
||||
keyId: KEY_ID
|
||||
}
|
||||
});
|
||||
client.listImages(function (err, images) {
|
||||
client.close(); // Remember to close the client to close TCP conn.
|
||||
if (err) {
|
||||
console.error('listImages err:', err);
|
||||
} else {
|
||||
console.log(JSON.stringify(images, null, 4));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
This section defines all the vars in a TritonApi config. The baked in defaults
|
||||
@ -229,7 +256,8 @@ are in "etc/defaults.json" and can be overriden for the CLI in
|
||||
## node-triton differences with node-smartdc
|
||||
|
||||
- There is a single `triton` command instead of a number of `sdc-*` commands.
|
||||
- The `SDC_USER` env variable is accepted in preference to `SDC_ACCOUNT`.
|
||||
- `TRITON_*` environment variables are preferred to the `SDC_*` environment
|
||||
variables. However the `SDC_*` envvars are still supported.
|
||||
|
||||
|
||||
## cloudapi2.js differences with node-smartdc/lib/cloudapi.js
|
||||
|
27
lib/bunyannoop.js
Normal file
27
lib/bunyannoop.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015 Joyent, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A stub for a `bunyan.createLogger()` that does no logging.
|
||||
*/
|
||||
function BunyanNoopLogger() {}
|
||||
BunyanNoopLogger.prototype.trace = function () {};
|
||||
BunyanNoopLogger.prototype.debug = function () {};
|
||||
BunyanNoopLogger.prototype.info = function () {};
|
||||
BunyanNoopLogger.prototype.warn = function () {};
|
||||
BunyanNoopLogger.prototype.error = function () {};
|
||||
BunyanNoopLogger.prototype.fatal = function () {};
|
||||
BunyanNoopLogger.prototype.child = function () { return this; };
|
||||
BunyanNoopLogger.prototype.end = function () {};
|
||||
|
||||
|
||||
module.exports = {
|
||||
BunyanNoopLogger: BunyanNoopLogger
|
||||
};
|
31
lib/cli.js
31
lib/cli.js
@ -212,12 +212,6 @@ CLI.prototype.init = function (opts, args, callback) {
|
||||
var self = this;
|
||||
this.opts = opts;
|
||||
|
||||
if (opts.version) {
|
||||
console.log(this.name, pkg.version);
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.log = bunyan.createLogger({
|
||||
name: this.name,
|
||||
serializers: bunyan.stdSerializers,
|
||||
@ -230,6 +224,12 @@ CLI.prototype.init = function (opts, args, callback) {
|
||||
this.showErrStack = true;
|
||||
}
|
||||
|
||||
if (opts.version) {
|
||||
console.log(this.name, pkg.version);
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.url && opts.J) {
|
||||
callback(new errors.UsageError(
|
||||
'cannot use both "--url" and "-J" options'));
|
||||
@ -268,6 +268,16 @@ CLI.prototype.init = function (opts, args, callback) {
|
||||
};
|
||||
|
||||
|
||||
CLI.prototype.fini = function fini(subcmd, err, cb) {
|
||||
this.log.trace({err: err, subcmd: subcmd}, 'cli fini');
|
||||
if (this._tritonapi) {
|
||||
this._tritonapi.close();
|
||||
delete this._tritonapi;
|
||||
}
|
||||
cb(err, subcmd);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Apply overrides from CLI options to the given profile object *in place*.
|
||||
*/
|
||||
@ -380,7 +390,14 @@ function main(argv) {
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(exitStatus);
|
||||
/*
|
||||
* We'd like to NOT use `process.exit` because that doesn't always
|
||||
* allow std handles to flush (e.g. all logging to complete). However
|
||||
* I don't know of another way to exit non-zero.
|
||||
*/
|
||||
if (exitStatus !== 0) {
|
||||
process.exit(exitStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ var querystring = require('querystring');
|
||||
var vasync = require('vasync');
|
||||
var auth = require('smartdc-auth');
|
||||
|
||||
var bunyannoop = require('./bunyannoop');
|
||||
var errors = require('./errors');
|
||||
var SaferJsonClient = require('./SaferJsonClient');
|
||||
|
||||
@ -55,21 +56,6 @@ var OS_PLATFORM = os.platform();
|
||||
|
||||
|
||||
|
||||
// ---- internal support stuff
|
||||
|
||||
// A no-op bunyan logger shim.
|
||||
function BunyanNoopLogger() {}
|
||||
BunyanNoopLogger.prototype.trace = function () {};
|
||||
BunyanNoopLogger.prototype.debug = function () {};
|
||||
BunyanNoopLogger.prototype.info = function () {};
|
||||
BunyanNoopLogger.prototype.warn = function () {};
|
||||
BunyanNoopLogger.prototype.error = function () {};
|
||||
BunyanNoopLogger.prototype.fatal = function () {};
|
||||
BunyanNoopLogger.prototype.child = function () { return this; };
|
||||
BunyanNoopLogger.prototype.end = function () {};
|
||||
|
||||
|
||||
|
||||
// ---- client API
|
||||
|
||||
/**
|
||||
@ -111,7 +97,7 @@ function CloudApi(options) {
|
||||
this.account = options.account;
|
||||
this.user = options.user; // optional RBAC subuser
|
||||
this.sign = options.sign;
|
||||
this.log = options.log || new BunyanNoopLogger();
|
||||
this.log = options.log || new bunyannoop.BunyanNoopLogger();
|
||||
if (!options.version) {
|
||||
options.version = '*';
|
||||
}
|
||||
@ -132,6 +118,13 @@ function CloudApi(options) {
|
||||
}
|
||||
|
||||
|
||||
CloudApi.prototype.close = function close(callback) {
|
||||
this.log.trace({host: this.client.url && this.client.url.host},
|
||||
'close cloudapi http client');
|
||||
this.client.close();
|
||||
};
|
||||
|
||||
|
||||
CloudApi.prototype._getAuthHeaders = function _getAuthHeaders(callback) {
|
||||
assert.func(callback, 'callback');
|
||||
var self = this;
|
||||
|
@ -330,19 +330,25 @@ function normShortId(s) {
|
||||
}
|
||||
|
||||
/*
|
||||
* take a "profile" object and return a slug based on the account name
|
||||
* and DC URL. This is currently used to create a filesystem-safe name
|
||||
* to use for caching
|
||||
* Take a "profile" object and return a slug based on: account, url and user.
|
||||
* This is currently used to create a filesystem-safe name to use for caching
|
||||
*/
|
||||
function profileSlug(o) {
|
||||
assert.object(o, 'o');
|
||||
assert.string(o.account, 'o.account');
|
||||
assert.string(o.url, 'o.url');
|
||||
|
||||
var acct = o.account.replace(/[@]/g, '_');
|
||||
var slug;
|
||||
var account = o.account.replace(/[@]/g, '_');
|
||||
var url = o.url.replace(/^https?:\/\//, '');
|
||||
var s = format('%s@%s', acct, url).replace(/[!#$%\^&\*:'"\?\/\\\.]/g, '_');
|
||||
return s;
|
||||
if (o.user) {
|
||||
var user = o.user.replace(/[@]/g, '_');
|
||||
slug = format('%s-%s@%s', user, account, url);
|
||||
} else {
|
||||
slug = format('%s@%s', account, url);
|
||||
}
|
||||
slug = slug.replace(/[!#$%\^&\*:'"\?\/\\\.]/g, '_');
|
||||
return slug;
|
||||
}
|
||||
|
||||
|
||||
@ -819,6 +825,28 @@ function deepEqual(a, b) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolve "~/..." and "~" to an absolute path.
|
||||
*
|
||||
* Limitations: This does not handle "~user/...". This depends on the HOME
|
||||
* envvar being defined. A better alternative is the "tilde-expansion"
|
||||
* module (used elsewhere in node-triton), but that doesn't have a sync
|
||||
* option.
|
||||
*/
|
||||
function tildeSync(s) {
|
||||
var home = process.env.HOME;
|
||||
if (!home) {
|
||||
return s;
|
||||
} else if (s === '~') {
|
||||
return home;
|
||||
} else if (s.slice(0, 2) === '~/') {
|
||||
return home + s.slice(1);
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---- exports
|
||||
|
||||
module.exports = {
|
||||
@ -847,6 +875,7 @@ module.exports = {
|
||||
chomp: chomp,
|
||||
generatePassword: generatePassword,
|
||||
execPlus: execPlus,
|
||||
deepEqual: deepEqual
|
||||
deepEqual: deepEqual,
|
||||
tildeSync: tildeSync
|
||||
};
|
||||
// vim: set softtabstop=4 shiftwidth=4:
|
||||
|
@ -88,7 +88,8 @@ function loadConfig(opts) {
|
||||
assert.object(opts, 'opts');
|
||||
assert.string(opts.configDir, 'opts.configDir');
|
||||
|
||||
var configPath = configPathFromDir(opts.configDir);
|
||||
var configDir = common.tildeSync(opts.configDir);
|
||||
var configPath = configPathFromDir(configDir);
|
||||
|
||||
var c = fs.readFileSync(DEFAULTS_PATH, 'utf8');
|
||||
var _defaults = JSON.parse(c);
|
||||
@ -120,7 +121,7 @@ function loadConfig(opts) {
|
||||
config._user = _user;
|
||||
}
|
||||
config._defaults = _defaults;
|
||||
config._configDir = opts.configDir;
|
||||
config._configDir = configDir;
|
||||
|
||||
return config;
|
||||
}
|
||||
@ -272,15 +273,18 @@ function _profileFromPath(profilePath, name) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loadProfile(opts) {
|
||||
assert.string(opts.configDir, 'opts.configDir');
|
||||
assert.string(opts.name, 'opts.name');
|
||||
assert.optionalString(opts.configDir, 'opts.configDir');
|
||||
|
||||
if (opts.name === 'env') {
|
||||
return _loadEnvProfile();
|
||||
} else if (!opts.configDir) {
|
||||
throw new errors.TritonError(
|
||||
'cannot load profiles (other than "env") without `opts.configDir`');
|
||||
} else {
|
||||
var profilePath = path.resolve(opts.configDir, 'profiles.d',
|
||||
var profilePath = path.resolve(
|
||||
common.tildeSync(opts.configDir), 'profiles.d',
|
||||
opts.name + '.json');
|
||||
return _profileFromPath(profilePath, opts.name);
|
||||
}
|
||||
@ -294,7 +298,7 @@ function loadAllProfiles(opts) {
|
||||
_loadEnvProfile()
|
||||
];
|
||||
|
||||
var d = path.join(opts.configDir, 'profiles.d');
|
||||
var d = path.join(common.tildeSync(opts.configDir), 'profiles.d');
|
||||
var files = fs.readdirSync(d);
|
||||
files.forEach(function (file) {
|
||||
file = path.join(d, file);
|
||||
|
155
lib/index.js
155
lib/index.js
@ -6,11 +6,160 @@
|
||||
|
||||
/*
|
||||
* Copyright 2015 Joyent, Inc.
|
||||
*
|
||||
* module entry point
|
||||
*/
|
||||
|
||||
var assert = require('assert-plus');
|
||||
|
||||
var bunyannoop = require('./bunyannoop');
|
||||
var mod_config = require('./config');
|
||||
var tritonapi = require('./tritonapi');
|
||||
|
||||
|
||||
/**
|
||||
* A convenience wrapper around `tritonapi.createClient` to for simpler usage.
|
||||
*
|
||||
* Minimally this only requires that one of `profileName` or `profile` be
|
||||
* specified. Examples:
|
||||
*
|
||||
* var triton = require('triton');
|
||||
* var client = triton.createClient({
|
||||
* profile: {
|
||||
* url: "<cloudapi url>",
|
||||
* account: "<account login for this cloud>",
|
||||
* keyId: "<ssh key fingerprint for one of account's keys>"
|
||||
* }
|
||||
* });
|
||||
* --
|
||||
* // Loading a profile from the environment (the `TRITON_*` and/or
|
||||
* // `SDC_*` environment variables).
|
||||
* var client = triton.createClient({profileName: 'env'});
|
||||
* --
|
||||
* var client = triton.createClient({
|
||||
* configDir: '~/.triton', // use the CLI's config dir ...
|
||||
* profileName: 'east1' // ... to find named profiles
|
||||
* });
|
||||
* --
|
||||
* // The same thing using the underlying APIs.
|
||||
* var client = triton.createClient({
|
||||
* config: triton.loadConfig({configDir: '~/.triton'},
|
||||
* profile: triton.loadProfile({name: 'east1', configDir: '~/.triton'})
|
||||
* });
|
||||
*
|
||||
* A more complete example an app using triton internally might want:
|
||||
*
|
||||
* var triton = require('triton');
|
||||
* var bunyan = require('bunyan');
|
||||
*
|
||||
* var appConfig = {
|
||||
* // However the app handles its config.
|
||||
* };
|
||||
* var log = bunyan.createLogger({name: 'myapp', component: 'triton'});
|
||||
* var client = triton.createClient({
|
||||
* log: log,
|
||||
* profile: appConfig.tritonProfile
|
||||
* });
|
||||
*
|
||||
*
|
||||
* TODO: The story for an app wanting to specify some Triton config but NOT
|
||||
* have to have a triton $configDir/config.json is poor.
|
||||
*
|
||||
* @param opts {Object}:
|
||||
* - @param profile {Object} A *Triton profile* object that includes the
|
||||
* information required to connect to a CloudAPI -- minimally this:
|
||||
* {
|
||||
* "url": "<cloudapi url>",
|
||||
* "account": "<account login for this cloud>",
|
||||
* "keyId": "<ssh key fingerprint for one of account's keys>"
|
||||
* }
|
||||
* For example:
|
||||
* {
|
||||
* "url": "https://us-east-1.api.joyent.com",
|
||||
* "account": "billy.bob",
|
||||
* "keyId": "de:e7:73:9a:aa:91:bb:3e:72:8d:cc:62:ca:58:a2:ec"
|
||||
* }
|
||||
* Either `profile` or `profileName` is requires. See discussion above.
|
||||
* - @param profileName {String} A Triton profile name. For any profile
|
||||
* name other than "env", one must also provide either `configDir`
|
||||
* or `config`.
|
||||
* Either `profile` or `profileName` is requires. See discussion above.
|
||||
* - @param configDir {String} A base config directory. This is used
|
||||
* by TritonApi to find and store profiles, config, and cache data.
|
||||
* For example, the `triton` CLI uses "~/.triton".
|
||||
* One may not specify both `configDir` and `config`.
|
||||
* - @param config {Object} A Triton config object loaded by
|
||||
* `triton.loadConfig(...)`.
|
||||
* One may not specify both `configDir` and `config`.
|
||||
* - @param log {Bunyan Logger} Optional. A Bunyan logger. If not provided,
|
||||
* a stub that does no logging will be used.
|
||||
*/
|
||||
function createClient(opts) {
|
||||
assert.object(opts, 'opts');
|
||||
assert.optionalObject(opts.profile, 'opts.profile');
|
||||
assert.optionalString(opts.profileName, 'opts.profileName');
|
||||
assert.optionalObject(opts.config, 'opts.config');
|
||||
assert.optionalString(opts.configDir, 'opts.configDir');
|
||||
assert.optionalObject(opts.log, 'opts.log');
|
||||
|
||||
assert.ok(!(opts.profile && opts.profileName),
|
||||
'cannot specify both opts.profile and opts.profileName');
|
||||
assert.ok(!(!opts.profile && !opts.profileName),
|
||||
'must specify one opts.profile or opts.profileName');
|
||||
assert.ok(!(opts.config && opts.configDir),
|
||||
'cannot specify both opts.config and opts.configDir');
|
||||
assert.ok(!(opts.config && opts.configDir),
|
||||
'cannot specify both opts.config and opts.configDir');
|
||||
if (opts.profileName && opts.profileName !== 'env') {
|
||||
assert.ok(opts.configDir,
|
||||
'must provide opts.configDir for opts.profileName!="env"');
|
||||
}
|
||||
|
||||
var log = opts.log;
|
||||
if (!opts.log) {
|
||||
log = new bunyannoop.BunyanNoopLogger();
|
||||
}
|
||||
|
||||
var config = opts.config;
|
||||
if (!config) {
|
||||
config = mod_config.loadConfig({configDir: opts.configDir});
|
||||
}
|
||||
|
||||
var profile = opts.profile;
|
||||
if (!profile) {
|
||||
profile = mod_config.loadProfile({
|
||||
name: opts.profileName,
|
||||
configDir: config._configDir
|
||||
});
|
||||
}
|
||||
// Don't require one to arbitrarily have a profile.name if manually
|
||||
// creating it.
|
||||
if (!profile.name) {
|
||||
// TODO: might want this to be hash or slug of profile params.
|
||||
profile.name = '_';
|
||||
}
|
||||
mod_config.validateProfile(profile);
|
||||
|
||||
var client = tritonapi.createClient({
|
||||
log: log,
|
||||
config: config,
|
||||
profile: profile
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
createTritonApiClient: require('./tritonapi').createClient,
|
||||
createClient: createClient,
|
||||
|
||||
/**
|
||||
* `createClient` provides convenience parameters to not *have* to call
|
||||
* the following (i.e. passing in `configDir` and/or `profileName`), but
|
||||
* some users of node-triton as a module may want to call these directly.
|
||||
*/
|
||||
loadConfig: mod_config.loadConfig,
|
||||
loadProfile: mod_config.loadProfile,
|
||||
loadAllProfiles: mod_config.loadAllProfiles,
|
||||
|
||||
createTritonApiClient: tritonapi.createClient,
|
||||
// For those wanting a lower-level raw CloudAPI client.
|
||||
createCloudApiClient: require('./cloudapi2').createClient
|
||||
};
|
||||
|
@ -92,7 +92,7 @@ function TritonApi(opts) {
|
||||
this.log = opts.log;
|
||||
}
|
||||
|
||||
if (this.config.cacheDir) {
|
||||
if (this.config._configDir) {
|
||||
this.cacheDir = path.resolve(this.config._configDir,
|
||||
this.config.cacheDir,
|
||||
common.profileSlug(this.profile));
|
||||
@ -111,6 +111,11 @@ function TritonApi(opts) {
|
||||
}
|
||||
|
||||
|
||||
TritonApi.prototype.close = function close() {
|
||||
this.cloudapi.close();
|
||||
delete this.cloudapi;
|
||||
};
|
||||
|
||||
|
||||
TritonApi.prototype._cloudapiFromProfile =
|
||||
function _cloudapiFromProfile(profile)
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "triton",
|
||||
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.0",
|
||||
"author": "Joyent (joyent.com)",
|
||||
"dependencies": {
|
||||
"assert-plus": "0.2.0",
|
||||
|
99
test/integration/api-images.test.js
Normal file
99
test/integration/api-images.test.js
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Joyent, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Integration tests for using image-related APIs as a module.
|
||||
*/
|
||||
|
||||
var h = require('./helpers');
|
||||
var test = require('tape');
|
||||
|
||||
var common = require('../../lib/common');
|
||||
|
||||
|
||||
|
||||
// --- Globals
|
||||
|
||||
|
||||
|
||||
// --- Tests
|
||||
|
||||
test('TritonApi images', function (tt) {
|
||||
|
||||
var client;
|
||||
tt.test(' setup: client', function (t) {
|
||||
client = h.createClient();
|
||||
t.ok(client, 'client');
|
||||
t.end();
|
||||
});
|
||||
|
||||
var testOpts = {};
|
||||
var img;
|
||||
tt.test(' TritonApi listImages', function (t) {
|
||||
client.listImages(function (err, images) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(images, 'images');
|
||||
t.ok(Array.isArray(images), 'images');
|
||||
if (images.length) {
|
||||
img = images[0];
|
||||
t.ok(img, 'img');
|
||||
t.ok(common.isUUID(img.id), 'img.id is a UUID');
|
||||
t.ok(img.name, 'img.name');
|
||||
t.ok(img.version, 'img.version');
|
||||
} else {
|
||||
testOpts.skip = true;
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' TritonApi getImage by uuid', testOpts, function (t) {
|
||||
client.getImage(img.id, function (err, image) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.equal(image.id, img.id);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' TritonApi getImage by name', testOpts, function (t) {
|
||||
client.getImage(img.name, function (err, image) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.equal(image.name, img.name); // might not be the same ID
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' TritonApi getImage by name (opts)', testOpts, function (t) {
|
||||
client.getImage({name: img.name}, function (err, image) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.equal(image.name, img.name); // might not be the same ID
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' TritonApi getImage by shortId', testOpts, function (t) {
|
||||
var shortId = img.id.split('-')[0];
|
||||
client.getImage(shortId, function (err, image) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.equal(image.id, img.id);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' teardown: client', function (t) {
|
||||
client.close();
|
||||
t.end();
|
||||
});
|
||||
});
|
@ -18,7 +18,7 @@ var f = require('util').format;
|
||||
var path = require('path');
|
||||
|
||||
var common = require('../../lib/common');
|
||||
var mod_config = require('../../lib/config');
|
||||
var mod_triton = require('../../');
|
||||
var testcommon = require('../lib/testcommon');
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ try {
|
||||
assert.optionalBool(CONFIG.profile.insecure,
|
||||
'CONFIG.profile.insecure');
|
||||
} else if (CONFIG.profileName) {
|
||||
CONFIG.profile = mod_config.loadProfile({
|
||||
CONFIG.profile = mod_triton.loadProfile({
|
||||
configDir: path.join(process.env.HOME, '.triton'),
|
||||
name: CONFIG.profileName
|
||||
});
|
||||
@ -160,11 +160,24 @@ function safeTriton(t, opts, cb) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a TritonApi client using the CLI.
|
||||
*/
|
||||
function createClient() {
|
||||
return mod_triton.createClient({
|
||||
log: LOG,
|
||||
profile: CONFIG.profile,
|
||||
configDir: '~/.triton' // piggy-back on Triton CLI config dir
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --- exports
|
||||
|
||||
module.exports = {
|
||||
CONFIG: CONFIG,
|
||||
triton: triton,
|
||||
safeTriton: safeTriton,
|
||||
createClient: createClient,
|
||||
ifErr: testcommon.ifErr
|
||||
};
|
||||
|
Reference in New Issue
Block a user