diff --git a/lib/config.js b/lib/config.js index f1db599..7ca1f89 100644 --- a/lib/config.js +++ b/lib/config.js @@ -14,15 +14,19 @@ Config.prototype[require('util').inspect.custom] = function() { return this; }; /** * Inspect + * + * @param {Object} opts Options (optional) * @param {Function} callback Callback, if specified Docker will be queried. * @return {Object} Name only if callback isn't specified. */ -Config.prototype.inspect = function(callback) { +Config.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/configs/' + this.id, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'config not found', @@ -31,7 +35,7 @@ Config.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -42,7 +46,7 @@ Config.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -55,23 +59,22 @@ Config.prototype.inspect = function(callback) { */ Config.prototype.update = function(opts, callback) { var self = this; - if (!callback && typeof opts === 'function') { - callback = opts; - } + var args = util.processArgs(opts, callback); var optsf = { path: '/configs/' + this.id + '/update?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'config not found', 500: 'server error', 503: 'node is not part of a swarm' }, - options: opts + options: args.opts }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -82,7 +85,7 @@ Config.prototype.update = function(opts, callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -100,6 +103,7 @@ Config.prototype.remove = function(opts, callback) { var optsf = { path: '/configs/' + this.id, method: 'DELETE', + abortSignal: opts.abortSignal, statusCodes: { 200: true, 204: true, diff --git a/lib/container.js b/lib/container.js index d1b2466..e25dd58 100644 --- a/lib/container.js +++ b/lib/container.js @@ -52,6 +52,7 @@ Container.prototype.inspect = function(opts, callback) { path: '/containers/' + this.id + '/json?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such container', @@ -87,6 +88,7 @@ Container.prototype.rename = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/rename?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 204: true, @@ -124,6 +126,7 @@ Container.prototype.update = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/update', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 204: true, @@ -162,6 +165,7 @@ Container.prototype.top = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/top?', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such container', @@ -188,13 +192,17 @@ Container.prototype.top = function(opts, callback) { /** * Containers changes + * @param {Object} Options * @param {Function} callback Callback */ -Container.prototype.changes = function(callback) { +Container.prototype.changes = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/containers/' + this.id + '/changes', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such container', @@ -202,7 +210,7 @@ Container.prototype.changes = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -213,7 +221,7 @@ Container.prototype.changes = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -230,6 +238,7 @@ Container.prototype.listCheckpoint = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/checkpoints?', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such container', @@ -267,6 +276,7 @@ Container.prototype.deleteCheckpoint = function(checkpoint, opts, callback) { var optsf = { path: '/containers/' + this.id + '/checkpoints/' + checkpoint + '?', method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -304,6 +314,7 @@ Container.prototype.createCheckpoint = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/checkpoints', method: 'POST', + abortSignal: args.opts.abortSignal, allowEmpty: true, statusCodes: { 200: true, //unofficial, but proxies may return it @@ -333,13 +344,17 @@ Container.prototype.createCheckpoint = function(opts, callback) { /** * Export + * @param {Object} opts Options (optional) * @param {Function} callback Callback with the octet-stream. */ -Container.prototype.export = function(callback) { +Container.prototype.export = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/containers/' + this.id + '/export', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -348,7 +363,7 @@ Container.prototype.export = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -359,7 +374,7 @@ Container.prototype.export = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -376,6 +391,7 @@ Container.prototype.start = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/start?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -414,6 +430,7 @@ Container.prototype.pause = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/pause', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -450,6 +467,7 @@ Container.prototype.unpause = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/unpause', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -488,6 +506,7 @@ Container.prototype.exec = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/exec', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -530,6 +549,7 @@ Container.prototype.commit = function(opts, callback) { var optsf = { path: '/commit?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -567,6 +587,7 @@ Container.prototype.stop = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/stop?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -605,6 +626,7 @@ Container.prototype.restart = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/restart?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -642,6 +664,7 @@ Container.prototype.kill = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/kill?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -679,6 +702,7 @@ Container.prototype.resize = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/resize?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -716,6 +740,7 @@ Container.prototype.attach = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/attach?', method: 'POST', + abortSignal: args.opts.abortSignal, isStream: true, hijack: args.opts.hijack, openStdin: args.opts.stdin, @@ -755,6 +780,7 @@ Container.prototype.wait = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/wait?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -792,6 +818,7 @@ Container.prototype.remove = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '?', method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -831,6 +858,7 @@ Container.prototype.copy = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/copy', method: 'POST', + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -868,6 +896,7 @@ Container.prototype.getArchive = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/archive?', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -906,6 +935,7 @@ Container.prototype.infoArchive = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/archive?', method: 'HEAD', + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -945,6 +975,7 @@ Container.prototype.putArchive = function(file, opts, callback) { path: '/containers/' + this.id + '/archive?', method: 'PUT', file: file, + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -984,6 +1015,7 @@ Container.prototype.logs = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/logs?', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: args.opts.follow || false, statusCodes: { 200: true, @@ -1024,6 +1056,7 @@ Container.prototype.stats = function(opts, callback) { var optsf = { path: '/containers/' + this.id + '/stats?', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: isStream, statusCodes: { 200: true, diff --git a/lib/docker.js b/lib/docker.js index 6de6567..fc605ef 100644 --- a/lib/docker.js +++ b/lib/docker.js @@ -45,6 +45,7 @@ Docker.prototype.createContainer = function(opts, callback) { method: 'POST', options: opts, authconfig: opts.authconfig, + abortSignal: opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -95,6 +96,7 @@ Docker.prototype.createImage = function(auth, opts, callback) { method: 'POST', options: opts, authconfig: auth, + abortSignal: opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -136,6 +138,7 @@ Docker.prototype.loadImage = function(file, opts, callback) { method: 'POST', options: opts, file: file, + abortSignal: opts && opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -171,7 +174,7 @@ Docker.prototype.importImage = function(file, opts, callback) { callback = opts; opts = undefined; } - + if (!opts) opts = {}; @@ -182,6 +185,7 @@ Docker.prototype.importImage = function(file, opts, callback) { method: 'POST', options: opts, file: file, + abortSignal: opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -216,6 +220,7 @@ Docker.prototype.checkAuth = function(opts, callback) { path: '/auth', method: 'POST', options: opts, + abortSignal: opts.abortSignal, statusCodes: { 200: true, 204: true, @@ -247,7 +252,6 @@ Docker.prototype.checkAuth = function(opts, callback) { */ Docker.prototype.buildImage = function(file, opts, callback) { var self = this; - var content; if (!callback && typeof opts === 'function') { callback = opts; @@ -260,6 +264,7 @@ Docker.prototype.buildImage = function(file, opts, callback) { method: 'POST', file: file, options: opts, + abortSignal: opts && opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -407,6 +412,7 @@ Docker.prototype.listContainers = function(opts, callback) { path: '/containers/json?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -443,6 +449,7 @@ Docker.prototype.listImages = function(opts, callback) { path: '/images/json?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -479,6 +486,7 @@ Docker.prototype.getImages = function(opts, callback) { path: '/images/get?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -516,6 +524,7 @@ Docker.prototype.listServices = function(opts, callback) { path: '/services?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -551,6 +560,7 @@ Docker.prototype.listNodes = function(opts, callback) { path: '/nodes?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -589,6 +599,7 @@ Docker.prototype.listTasks = function(opts, callback) { path: '/tasks?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -623,6 +634,7 @@ Docker.prototype.createSecret = function(opts, callback) { path: '/secrets/create?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -663,6 +675,7 @@ Docker.prototype.createConfig = function(opts, callback) { path: '/configs/create?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -704,6 +717,7 @@ Docker.prototype.listSecrets = function(opts, callback) { path: '/secrets?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -739,6 +753,7 @@ Docker.prototype.listConfigs = function(opts, callback) { path: '/configs?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -773,6 +788,7 @@ Docker.prototype.createPlugin = function(opts, callback) { path: '/plugins/create?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 204: true, @@ -812,6 +828,7 @@ Docker.prototype.listPlugins = function(opts, callback) { path: '/plugins?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -847,6 +864,7 @@ Docker.prototype.pruneImages = function(opts, callback) { path: '/images/prune?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -871,21 +889,24 @@ Docker.prototype.pruneImages = function(opts, callback) { /** * Prune builder + * @param {Object} opts Options (optional) * @param {Function} callback Callback */ -Docker.prototype.pruneBuilder = function(callback) { +Docker.prototype.pruneBuilder = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/build/prune', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' } }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -896,7 +917,7 @@ Docker.prototype.pruneBuilder = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -914,6 +935,7 @@ Docker.prototype.pruneContainers = function(opts, callback) { path: '/containers/prune?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -949,6 +971,7 @@ Docker.prototype.pruneVolumes = function(opts, callback) { path: '/volumes/prune?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -984,6 +1007,7 @@ Docker.prototype.pruneNetworks = function(opts, callback) { path: '/networks/prune?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -1020,6 +1044,7 @@ Docker.prototype.createVolume = function(opts, callback) { method: 'POST', allowEmpty: true, options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -1067,6 +1092,7 @@ Docker.prototype.createService = function(auth, opts, callback) { method: 'POST', options: opts, authconfig: auth, + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, 201: true, @@ -1105,6 +1131,7 @@ Docker.prototype.listVolumes = function(opts, callback) { path: '/volumes?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -1140,6 +1167,7 @@ Docker.prototype.createNetwork = function(opts, callback) { path: '/networks/create?', method: 'POST', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -1179,6 +1207,7 @@ Docker.prototype.listNetworks = function(opts, callback) { path: '/networks?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -1214,6 +1243,7 @@ Docker.prototype.searchImages = function(opts, callback) { method: 'GET', options: opts, authconfig: opts.authconfig, + abortSignal: opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -1238,13 +1268,17 @@ Docker.prototype.searchImages = function(opts, callback) { /** * Info - * @param {Function} callback Callback with info + * @param {Object} opts Options (optional) + * @param {Function} callback Callback with info */ -Docker.prototype.info = function(callback) { +Docker.prototype.info = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var opts = { path: '/info', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -1252,7 +1286,7 @@ Docker.prototype.info = function(callback) { }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(opts, function(err, data) { if (err) { @@ -1263,27 +1297,31 @@ Docker.prototype.info = function(callback) { }); } else { this.modem.dial(opts, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; /** * Version - * @param {Function} callback Callback + * @param {Object} opts Options (optional) + * @param {Function} callback Callback */ -Docker.prototype.version = function(callback) { +Docker.prototype.version = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var opts = { path: '/version', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' } }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(opts, function(err, data) { if (err) { @@ -1294,27 +1332,31 @@ Docker.prototype.version = function(callback) { }); } else { this.modem.dial(opts, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; /** * Ping - * @param {Function} callback Callback + * @param {Object} opts Options (optional) + * @param {Function} callback Callback */ -Docker.prototype.ping = function(callback) { +Docker.prototype.ping = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/_ping', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' } }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -1325,7 +1367,7 @@ Docker.prototype.ping = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -1333,20 +1375,24 @@ Docker.prototype.ping = function(callback) { /** * SystemDf equivalent to system/df API Engine * get usage data information - * @param {Function} callback Callback + * @param {Object} opts Options (optional) + * @param {Function} callback Callback */ -Docker.prototype.df = function(callback) { +Docker.prototype.df = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/system/df', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' } }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -1357,7 +1403,7 @@ Docker.prototype.df = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -1375,6 +1421,7 @@ Docker.prototype.getEvents = function(opts, callback) { path: '/events?', method: 'GET', options: args.opts, + abortSignal: args.opts.abortSignal, isStream: true, statusCodes: { 200: true, @@ -1596,6 +1643,7 @@ Docker.prototype.swarmInit = function(opts, callback) { var optsf = { path: '/swarm/init', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -1633,6 +1681,7 @@ Docker.prototype.swarmJoin = function(opts, callback) { var optsf = { path: '/swarm/join', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -1670,6 +1719,7 @@ Docker.prototype.swarmLeave = function(opts, callback) { var optsf = { path: '/swarm/leave?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 406: 'node is not part of a Swarm' @@ -1706,6 +1756,7 @@ Docker.prototype.swarmUpdate = function(opts, callback) { var optsf = { path: '/swarm/update?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 400: 'bad parameter', @@ -1735,13 +1786,17 @@ Docker.prototype.swarmUpdate = function(opts, callback) { * Inspect a Swarm. * Warning: This method is not documented in the API * - * @param {Function} callback Callback + * @param {Object} opts Options (optional) + * @param {Function} callback Callback */ -Docker.prototype.swarmInspect = function(callback) { +Docker.prototype.swarmInspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/swarm', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 406: 'This node is not a swarm manager', @@ -1749,7 +1804,7 @@ Docker.prototype.swarmInspect = function(callback) { } }; - if (callback === undefined) { + if (args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -1760,7 +1815,7 @@ Docker.prototype.swarmInspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; diff --git a/lib/exec.js b/lib/exec.js index fe42ddb..e2714af 100644 --- a/lib/exec.js +++ b/lib/exec.js @@ -25,6 +25,7 @@ Exec.prototype.start = function(opts, callback) { var optsf = { path: '/exec/' + this.id + '/start', method: 'POST', + abortSignal: args.opts.abortSignal, isStream: true, allowEmpty: true, hijack: args.opts.hijack, @@ -70,6 +71,7 @@ Exec.prototype.resize = function(opts, callback) { var optsf = { path: '/exec/' + this.id + '/resize?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such exec', @@ -98,14 +100,17 @@ Exec.prototype.resize = function(opts, callback) { /** * Get low-level information about the exec call. * + * @param {Object} opts Options (optional) * @param {function} callback */ -Exec.prototype.inspect = function(callback) { +Exec.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/exec/' + this.id + '/json', method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such exec', @@ -113,7 +118,7 @@ Exec.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -125,7 +130,7 @@ Exec.prototype.inspect = function(callback) { } else { this.modem.dial(optsf, function(err, data) { if (err) return callback(err, data); - callback(err, data); + args.callback(err, data); }); } }; diff --git a/lib/image.js b/lib/image.js index 668b1e9..1a81413 100644 --- a/lib/image.js +++ b/lib/image.js @@ -169,6 +169,7 @@ Image.prototype.push = function(opts, callback, auth) { method: 'POST', options: args.opts, authconfig: args.opts.authconfig || auth, + abortSignal: args.opts.abortSignal, isStream: isStream, statusCodes: { 200: true, @@ -206,6 +207,7 @@ Image.prototype.tag = function(opts, callback) { path: '/images/' + this.name + '/tag?', method: 'POST', options: opts, + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, // unofficial, but proxies may return it 201: true, @@ -241,10 +243,10 @@ Image.prototype.remove = function(opts, callback) { var self = this; var args = util.processArgs(opts, callback); - var optsf = { path: '/images/' + this.name + '?', method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such image', diff --git a/lib/network.js b/lib/network.js index 3a651b4..f80c7f3 100644 --- a/lib/network.js +++ b/lib/network.js @@ -60,6 +60,7 @@ Network.prototype.remove = function(opts, callback) { var optsf = { path: '/networks/' + this.id, method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 204: true, @@ -99,6 +100,7 @@ Network.prototype.connect = function(opts, callback) { var optsf = { path: '/networks/' + this.id + '/connect', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 201: true, @@ -137,6 +139,7 @@ Network.prototype.disconnect = function(opts, callback) { var optsf = { path: '/networks/' + this.id + '/disconnect', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 201: true, diff --git a/lib/node.js b/lib/node.js index 0c46281..c290577 100644 --- a/lib/node.js +++ b/lib/node.js @@ -15,14 +15,17 @@ Node.prototype[require('util').inspect.custom] = function() { return this; }; /** * Query Docker for Node details. * + * @param {Object} opts Options (optional) * @param {function} callback */ -Node.prototype.inspect = function(callback) { +Node.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/nodes/' + this.id, method: 'GET', + abortSignal: args.abortSignal, statusCodes: { 200: true, 404: 'no such node', @@ -30,7 +33,7 @@ Node.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -41,7 +44,7 @@ Node.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -62,6 +65,7 @@ Node.prototype.update = function(opts, callback) { var optsf = { path: '/nodes/' + this.id + '/update?', method: 'POST', + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, 404: 'no such node', @@ -102,6 +106,7 @@ Node.prototype.remove = function(opts, callback) { var optsf = { path: '/nodes/' + this.id + '?', method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such node', diff --git a/lib/plugin.js b/lib/plugin.js index da1b008..e119257 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -15,15 +15,19 @@ Plugin.prototype[require('util').inspect.custom] = function() { return this; }; /** * Inspect + * + * @param {Object} opts Options (optional) * @param {Function} callback Callback, if specified Docker will be queried. * @return {Object} Name only if callback isn't specified. */ -Plugin.prototype.inspect = function(callback) { +Plugin.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/plugins/' + this.name, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'plugin is not installed', @@ -31,7 +35,7 @@ Plugin.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -42,7 +46,7 @@ Plugin.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -59,6 +63,7 @@ Plugin.prototype.remove = function(opts, callback) { var optsf = { path: '/plugins/' + this.name + '?', method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'plugin is not installed', @@ -86,24 +91,28 @@ Plugin.prototype.remove = function(opts, callback) { /** * get privileges + * @param {Object} opts Options (optional) * @param {Function} callback Callback * @return {Object} Name only if callback isn't specified. */ -Plugin.prototype.privileges = function(callback) { +Plugin.prototype.privileges = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); + var optsf = { path: '/plugins/privileges?', method: 'GET', options: { 'remote': this.remote }, + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -114,7 +123,7 @@ Plugin.prototype.privileges = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -139,6 +148,7 @@ Plugin.prototype.pull = function(opts, callback) { var optsf = { path: '/plugins/pull?', method: 'POST', + abortSignal: args.opts.abortSignal, isStream: true, options: args.opts, statusCodes: { @@ -177,6 +187,7 @@ Plugin.prototype.enable = function(opts, callback) { var optsf = { path: '/plugins/' + this.name + '/enable?', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -212,6 +223,7 @@ Plugin.prototype.disable = function(opts, callback) { var optsf = { path: '/plugins/' + this.name + '/disable', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 500: 'server error' @@ -247,6 +259,7 @@ Plugin.prototype.push = function(opts, callback) { var optsf = { path: '/plugins/' + this.name + '/push', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'plugin not installed', @@ -283,6 +296,7 @@ Plugin.prototype.configure = function(opts, callback) { var optsf = { path: '/plugins/' + this.name + '/set', method: 'POST', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'plugin not installed', @@ -326,6 +340,7 @@ Plugin.prototype.upgrade = function(auth, opts, callback) { var optsf = { path: '/plugins/' + this.name + '/upgrade?', method: 'POST', + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, 204: true, diff --git a/lib/secret.js b/lib/secret.js index 925a1ed..43fbd75 100644 --- a/lib/secret.js +++ b/lib/secret.js @@ -14,15 +14,18 @@ Secret.prototype[require('util').inspect.custom] = function() { return this; }; /** * Inspect + * @param {Object} opts Options (optional) * @param {Function} callback Callback, if specified Docker will be queried. * @return {Object} Name only if callback isn't specified. */ -Secret.prototype.inspect = function(callback) { +Secret.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/secrets/' + this.id, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'secret not found', @@ -31,7 +34,7 @@ Secret.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -42,7 +45,7 @@ Secret.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -62,6 +65,7 @@ Secret.prototype.update = function(opts, callback) { var optsf = { path: '/secrets/' + this.id + '/update?', method: 'POST', + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, 404: 'secret not found', @@ -99,6 +103,7 @@ Secret.prototype.remove = function(opts, callback) { var optsf = { path: '/secrets/' + this.id, method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 204: true, diff --git a/lib/service.js b/lib/service.js index 6528605..db444bb 100644 --- a/lib/service.js +++ b/lib/service.js @@ -15,14 +15,17 @@ Service.prototype[require('util').inspect.custom] = function() { return this; }; /** * Query Docker for service details. * + * @param {Object} opts Options (optional) * @param {function} callback */ -Service.prototype.inspect = function(callback) { +Service.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/services/' + this.id, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such service', @@ -30,7 +33,7 @@ Service.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -41,7 +44,7 @@ Service.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -49,14 +52,17 @@ Service.prototype.inspect = function(callback) { /** * Delete Service * + * @param {Object} opts Options (optional) * @param {function} callback */ -Service.prototype.remove = function(callback) { +Service.prototype.remove = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/services/' + this.id, method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 204: true, @@ -65,7 +71,7 @@ Service.prototype.remove = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -76,7 +82,7 @@ Service.prototype.remove = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -105,6 +111,7 @@ Service.prototype.update = function(auth, opts, callback) { var optsf = { path: '/services/' + this.id + '/update?', method: 'POST', + abortSignal: opts && opts.abortSignal, statusCodes: { 200: true, 404: 'no such service', @@ -144,6 +151,7 @@ Service.prototype.logs = function(opts, callback) { var optsf = { path: '/services/' + this.id + '/logs?', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: args.opts.follow || false, statusCodes: { 200: true, diff --git a/lib/task.js b/lib/task.js index 4e2f5fd..7adf968 100644 --- a/lib/task.js +++ b/lib/task.js @@ -19,14 +19,17 @@ Task.prototype[require('util').inspect.custom] = function() { return this; }; /** * Query Docker for Task details. * + * @param {Object} opts Options (optional) * @param {function} callback */ -Task.prototype.inspect = function(callback) { +Task.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/tasks/' + this.id, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'unknown task', @@ -34,7 +37,7 @@ Task.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -45,7 +48,7 @@ Task.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -62,6 +65,7 @@ Task.prototype.logs = function(opts, callback) { var optsf = { path: '/tasks/' + this.id + '/logs?', method: 'GET', + abortSignal: args.opts.abortSignal, isStream: args.opts.follow || false, statusCodes: { 101: true, diff --git a/lib/volume.js b/lib/volume.js index 6e5b32d..1284e35 100644 --- a/lib/volume.js +++ b/lib/volume.js @@ -14,15 +14,18 @@ Volume.prototype[require('util').inspect.custom] = function() { return this; }; /** * Inspect + * @param {Object} opts Options (optional) * @param {Function} callback Callback, if specified Docker will be queried. * @return {Object} Name only if callback isn't specified. */ -Volume.prototype.inspect = function(callback) { +Volume.prototype.inspect = function(opts, callback) { var self = this; + var args = util.processArgs(opts, callback); var optsf = { path: '/volumes/' + this.name, method: 'GET', + abortSignal: args.opts.abortSignal, statusCodes: { 200: true, 404: 'no such volume', @@ -30,7 +33,7 @@ Volume.prototype.inspect = function(callback) { } }; - if(callback === undefined) { + if(args.callback === undefined) { return new this.modem.Promise(function(resolve, reject) { self.modem.dial(optsf, function(err, data) { if (err) { @@ -41,7 +44,7 @@ Volume.prototype.inspect = function(callback) { }); } else { this.modem.dial(optsf, function(err, data) { - callback(err, data); + args.callback(err, data); }); } }; @@ -58,6 +61,7 @@ Volume.prototype.remove = function(opts, callback) { var optsf = { path: '/volumes/' + this.name, method: 'DELETE', + abortSignal: args.opts.abortSignal, statusCodes: { 204: true, 404: 'no such volume', diff --git a/test/container.js b/test/container.js index c22cc73..6dc3e72 100644 --- a/test/container.js +++ b/test/container.js @@ -704,7 +704,7 @@ describe("#container", function() { describe("#wait", function() { var testWaitContainer - before(function(done) { + beforeEach(function(done) { docker.createContainer({ Image: 'ubuntu', AttachStdin: false, @@ -732,14 +732,38 @@ describe("#container", function() { expect(info.State.Running).to.be.false; console.log(info.State.Running) done(); - }) - }) + }) + }) container.start((err) => { expect(err).to.be.null; }) }); - after(function(done) { + it("should allow aborting pending waits", function(done) { + // Only supported on recent Node versions: + if (!global.AbortController) this.skip(); + this.timeout(5000); + var container = docker.getContainer(testWaitContainer); + + var abortController = new AbortController(); + + container.wait({ + condition: 'next-exit', + abortSignal: abortController.signal + }, (err, data) => { + expect(err.code).to.equal('ABORT_ERR'); + expect(data).to.be.null; + container.inspect((err, info) => { + expect(err).to.be.null; + expect(info.State.Running).to.be.false; + console.log(info.State.Running) + done(); + }) + }); + + abortController.abort(); + }); + afterEach(function(done) { docker.getContainer(testWaitContainer).remove(function() { done(); });