init project
This commit is contained in:
+242
@@ -0,0 +1,242 @@
|
||||
var protobuf = require("protobufjs");
|
||||
var path = require("path");
|
||||
|
||||
// Constants
|
||||
var BUILDKIT_TRACE_ID = "moby.buildkit.trace";
|
||||
var BUILDKIT_IMAGE_ID = "moby.image.id";
|
||||
var PROTO_TYPE = "moby.buildkit.v1.StatusResponse";
|
||||
var ENCODING_UTF8 = "utf8";
|
||||
var ENCODING_BASE64 = "base64";
|
||||
|
||||
var StatusResponse;
|
||||
|
||||
// Load the protobuf schema
|
||||
function loadProto() {
|
||||
if (StatusResponse) return StatusResponse;
|
||||
|
||||
var root = protobuf.loadSync(
|
||||
path.resolve(__dirname, "proto", "buildkit_status.proto")
|
||||
);
|
||||
StatusResponse = root.lookupType(PROTO_TYPE);
|
||||
return StatusResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a BuildKit trace message
|
||||
* @param {string} base64Data - Base64-encoded protobuf data from aux field
|
||||
* @returns {Object} Decoded status response with vertexes, logs, etc.
|
||||
*/
|
||||
function decodeBuildKitStatus(base64Data) {
|
||||
var StatusResponse = loadProto();
|
||||
|
||||
// Handle empty messages
|
||||
if (!base64Data || base64Data.length === 0) {
|
||||
return {
|
||||
vertexes: [],
|
||||
statuses: [],
|
||||
logs: [],
|
||||
warnings: []
|
||||
};
|
||||
}
|
||||
|
||||
var buffer = Buffer.from(base64Data, ENCODING_BASE64);
|
||||
var message = StatusResponse.decode(buffer);
|
||||
return StatusResponse.toObject(message, {
|
||||
longs: String,
|
||||
enums: String,
|
||||
bytes: String,
|
||||
defaults: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats BuildKit status into human-readable text
|
||||
* @param {Object} status - Decoded status response
|
||||
* @returns {string[]} Array of human-readable log lines
|
||||
*/
|
||||
function formatBuildKitStatus(status) {
|
||||
var lines = [];
|
||||
|
||||
// Process vertexes (build steps)
|
||||
if (status.vertexes && status.vertexes.length > 0) {
|
||||
status.vertexes.forEach(function(vertex) {
|
||||
if (vertex.name && vertex.started && !vertex.completed) {
|
||||
lines.push("[" + vertex.digest.substring(0, 12) + "] " + vertex.name);
|
||||
}
|
||||
if (vertex.error) {
|
||||
lines.push("ERROR: " + vertex.error);
|
||||
}
|
||||
if (vertex.completed && vertex.cached) {
|
||||
lines.push("CACHED: " + vertex.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process logs (command output)
|
||||
if (status.logs && status.logs.length > 0) {
|
||||
status.logs.forEach(function(log) {
|
||||
var msg = Buffer.from(log.msg).toString(ENCODING_UTF8);
|
||||
if (msg.trim()) {
|
||||
lines.push(msg.trimEnd());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process status updates (progress)
|
||||
if (status.statuses && status.statuses.length > 0) {
|
||||
status.statuses.forEach(function(s) {
|
||||
if (s.name && s.total > 0) {
|
||||
var percent = Math.floor((s.current / s.total) * 100);
|
||||
lines.push(s.name + ": " + percent + "% (" + s.current + "/" + s.total + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process warnings
|
||||
if (status.warnings && status.warnings.length > 0) {
|
||||
status.warnings.forEach(function(warning) {
|
||||
var msg = Buffer.from(warning.short).toString(ENCODING_UTF8);
|
||||
lines.push("WARNING: " + msg);
|
||||
});
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a BuildKit stream line and extract human-readable logs
|
||||
* @param {string} line - JSON line from build stream
|
||||
* @returns {Object} { isBuildKit: boolean, logs: string[], raw: Object }
|
||||
*/
|
||||
function parseBuildKitLine(line) {
|
||||
try {
|
||||
var json = JSON.parse(line);
|
||||
|
||||
// Check if it's a BuildKit trace message
|
||||
if (json.id === BUILDKIT_TRACE_ID && json.aux !== undefined) {
|
||||
var status = decodeBuildKitStatus(json.aux);
|
||||
var logs = formatBuildKitStatus(status);
|
||||
|
||||
return {
|
||||
isBuildKit: true,
|
||||
logs: logs,
|
||||
raw: status
|
||||
};
|
||||
}
|
||||
|
||||
// Check if it's the final image ID
|
||||
if (json.id === BUILDKIT_IMAGE_ID && json.aux && json.aux.ID) {
|
||||
return {
|
||||
isBuildKit: true,
|
||||
logs: ["Built image: " + json.aux.ID],
|
||||
raw: json.aux
|
||||
};
|
||||
}
|
||||
|
||||
// Not a BuildKit message
|
||||
return {
|
||||
isBuildKit: false,
|
||||
logs: [],
|
||||
raw: json
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
isBuildKit: false,
|
||||
logs: [],
|
||||
raw: null,
|
||||
error: e.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow progress of a stream, automatically handling both BuildKit and regular output.
|
||||
* This provides the same ergonomics as modem.followProgress but decodes BuildKit logs.
|
||||
*
|
||||
* @param {Stream} stream - Stream from buildImage(), pull(), push(), etc.
|
||||
* @param {Function} onFinished - Called when stream ends: (err, output) => void
|
||||
* @param {Function} onProgress - Called for each log event: (event) => void
|
||||
* @returns {void}
|
||||
*/
|
||||
function followProgress(stream, onFinished, onProgress) {
|
||||
var buffer = '';
|
||||
var output = [];
|
||||
var finished = false;
|
||||
|
||||
stream.on('data', onStreamEvent);
|
||||
stream.on('error', onStreamError);
|
||||
stream.on('end', onStreamEnd);
|
||||
stream.on('close', onStreamEnd);
|
||||
|
||||
function onStreamEvent(data) {
|
||||
buffer += data.toString();
|
||||
|
||||
// Process complete lines
|
||||
var lines = buffer.split('\n');
|
||||
buffer = lines.pop(); // Save incomplete line
|
||||
|
||||
lines.forEach(function(line) {
|
||||
if (!line.trim()) return;
|
||||
|
||||
processLine(line);
|
||||
});
|
||||
}
|
||||
|
||||
function processLine(line) {
|
||||
try {
|
||||
// Try to parse as BuildKit or regular Docker output
|
||||
var result = parseBuildKitLine(line);
|
||||
|
||||
if (result.isBuildKit) {
|
||||
// BuildKit message - create events from decoded logs
|
||||
result.logs.forEach(function(log) {
|
||||
var event = { stream: log + '\n' };
|
||||
output.push(event);
|
||||
if (onProgress) onProgress(event);
|
||||
});
|
||||
} else if (result.raw) {
|
||||
// Regular Docker message
|
||||
output.push(result.raw);
|
||||
if (onProgress) onProgress(result.raw);
|
||||
}
|
||||
} catch (e) {
|
||||
// If parsing fails, try plain JSON
|
||||
try {
|
||||
var json = JSON.parse(line);
|
||||
output.push(json);
|
||||
if (onProgress) onProgress(json);
|
||||
} catch (e2) {
|
||||
// Ignore parse errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onStreamError(err) {
|
||||
finished = true;
|
||||
stream.removeListener('data', onStreamEvent);
|
||||
stream.removeListener('error', onStreamError);
|
||||
stream.removeListener('end', onStreamEnd);
|
||||
stream.removeListener('close', onStreamEnd);
|
||||
if (onFinished) onFinished(err, output);
|
||||
}
|
||||
|
||||
function onStreamEnd() {
|
||||
if (finished) return;
|
||||
finished = true;
|
||||
|
||||
// Process any remaining data in buffer
|
||||
if (buffer.trim()) {
|
||||
processLine(buffer);
|
||||
}
|
||||
|
||||
stream.removeListener('data', onStreamEvent);
|
||||
stream.removeListener('error', onStreamError);
|
||||
stream.removeListener('end', onStreamEnd);
|
||||
stream.removeListener('close', onStreamEnd);
|
||||
if (onFinished) onFinished(null, output);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
followProgress: followProgress
|
||||
};
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents a config
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Config's id
|
||||
*/
|
||||
var Config = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
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(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',
|
||||
500: 'server error',
|
||||
503: 'node is not part of a swarm'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a config.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Config.prototype.update = function(opts, callback) {
|
||||
var self = this;
|
||||
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: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the config
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Config.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/configs/' + this.id,
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'config not found',
|
||||
500: 'server error',
|
||||
503: 'node is not part of a swarm'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Config;
|
||||
+1085
File diff suppressed because it is too large
Load Diff
+1903
File diff suppressed because it is too large
Load Diff
+139
@@ -0,0 +1,139 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an Exec
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Exec's ID
|
||||
*/
|
||||
var Exec = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
Exec.prototype[require('util').inspect.custom] = function() { return this; };
|
||||
|
||||
/**
|
||||
* Start the exec call that was setup.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Exec.prototype.start = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/exec/' + this.id + '/start',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
isStream: true,
|
||||
allowEmpty: true,
|
||||
hijack: args.opts.hijack,
|
||||
openStdin: args.opts.stdin,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'no such exec',
|
||||
409: 'container stopped/paused',
|
||||
500: 'container not running'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the exec call that was setup.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Exec.prototype.resize = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/exec/' + this.id + '/resize?',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such exec',
|
||||
500: 'container not running'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get low-level information about the exec call.
|
||||
*
|
||||
* @param {Object} opts Options (optional)
|
||||
* @param {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',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = Exec;
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an image
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} name Image's name
|
||||
*/
|
||||
var Image = function(modem, name) {
|
||||
this.modem = modem;
|
||||
this.name = name;
|
||||
};
|
||||
|
||||
Image.prototype[require('util').inspect.custom] = function() { return this; };
|
||||
|
||||
/**
|
||||
* Inspect
|
||||
* @param {Object} opts Inspect options, only 'manifests' (optional)
|
||||
* @param {Function} callback Callback, if specified Docker will be queried.
|
||||
* @return {Object} Name only if callback isn't specified.
|
||||
*/
|
||||
Image.prototype.inspect = function(opts, callback) {
|
||||
var args = util.processArgs(opts, callback);
|
||||
var self = this;
|
||||
|
||||
var opts = {
|
||||
path: '/images/' + this.name + '/json',
|
||||
method: 'GET',
|
||||
options: args.opts,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such image',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(opts, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(opts, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Distribution
|
||||
* @param {Object} opts
|
||||
* @param {Function} callback Callback, if specified Docker will be queried.
|
||||
* @return {Object} Name only if callback isn't specified.
|
||||
*/
|
||||
Image.prototype.distribution = function(opts, callback) {
|
||||
var args = util.processArgs(opts, callback);
|
||||
var self = this;
|
||||
|
||||
var fopts = {
|
||||
path: '/distribution/' + this.name + '/json',
|
||||
method: 'GET',
|
||||
statusCodes: {
|
||||
200: true,
|
||||
401: 'no such image',
|
||||
500: 'server error'
|
||||
},
|
||||
authconfig: (args.opts) ? args.opts.authconfig : undefined
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(fopts, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(fopts, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* History
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Image.prototype.history = function(callback) {
|
||||
var self = this;
|
||||
var opts = {
|
||||
path: '/images/' + this.name + '/history',
|
||||
method: 'GET',
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such image',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(opts, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(opts, function(err, data) {
|
||||
if (err) return callback(err, data);
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get
|
||||
* @param {Function} callback Callback with data stream.
|
||||
*/
|
||||
Image.prototype.get = function(callback) {
|
||||
var self = this;
|
||||
var opts = {
|
||||
path: '/images/' + this.name + '/get',
|
||||
method: 'GET',
|
||||
isStream: true,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(opts, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(opts, function(err, data) {
|
||||
if (err) return callback(err, data);
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Push
|
||||
* @param {Object} opts Push options, like 'registry' (optional)
|
||||
* @param {Function} callback Callback with stream.
|
||||
* @param {Object} auth Registry authentication
|
||||
*/
|
||||
Image.prototype.push = function(opts, callback, auth) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
var isStream = true;
|
||||
if (args.opts.stream === false) {
|
||||
isStream = false;
|
||||
}
|
||||
var optsf = {
|
||||
path: '/images/' + this.name + '/push?',
|
||||
method: 'POST',
|
||||
options: args.opts,
|
||||
authconfig: args.opts.authconfig || auth,
|
||||
abortSignal: args.opts.abortSignal,
|
||||
isStream: isStream,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such image',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
delete optsf.options.authconfig;
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tag
|
||||
* @param {Object} opts Tag options, like 'repo' (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Image.prototype.tag = function(opts, callback) {
|
||||
var self = this;
|
||||
var optsf = {
|
||||
path: '/images/' + this.name + '/tag?',
|
||||
method: 'POST',
|
||||
options: opts,
|
||||
abortSignal: opts && opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true, // unofficial, but proxies may return it
|
||||
201: true,
|
||||
400: 'bad parameter',
|
||||
404: 'no such image',
|
||||
409: 'conflict',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the image
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
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',
|
||||
409: 'conflict',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Image;
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an network
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Network's id
|
||||
*/
|
||||
var Network = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
Network.prototype[require('util').inspect.custom] = function() { return this; };
|
||||
|
||||
/**
|
||||
* Inspect
|
||||
* @param {Function} callback Callback, if specified Docker will be queried.
|
||||
* @return {Object} Id only if callback isn't specified.
|
||||
*/
|
||||
Network.prototype.inspect = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var opts = {
|
||||
path: '/networks/' + this.id + '?',
|
||||
method: 'GET',
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such network',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(opts, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(opts, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the network
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Network.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/networks/' + this.id,
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'no such network',
|
||||
409: 'conflict',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects a container to a network
|
||||
* @param {[Object]} opts Connect options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Network.prototype.connect = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/networks/' + this.id + '/connect',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
201: true,
|
||||
404: 'network or container is not found',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Disconnects a container from a network
|
||||
* @param {[Object]} opts Disconnect options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Network.prototype.disconnect = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/networks/' + this.id + '/disconnect',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
201: true,
|
||||
404: 'network or container is not found',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = Network;
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an Node
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Node's ID
|
||||
*/
|
||||
var Node = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
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(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/nodes/' + this.id,
|
||||
method: 'GET',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such node',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update a node.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Node.prototype.update = function(opts, callback) {
|
||||
var self = this;
|
||||
if (!callback && typeof opts === 'function') {
|
||||
callback = opts;
|
||||
}
|
||||
|
||||
var optsf = {
|
||||
path: '/nodes/' + this.id + '/update?',
|
||||
method: 'POST',
|
||||
abortSignal: opts && opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such node',
|
||||
406: 'node is not part of a swarm',
|
||||
500: 'server error'
|
||||
},
|
||||
options: opts
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove a Node.
|
||||
* Warning: This method is not documented in the API.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Node.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/nodes/' + this.id + '?',
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such node',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = Node;
|
||||
+372
@@ -0,0 +1,372 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents a plugin
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} name Plugin's name
|
||||
*/
|
||||
var Plugin = function(modem, name, remote) {
|
||||
this.modem = modem;
|
||||
this.name = name;
|
||||
this.remote = remote || name;
|
||||
};
|
||||
|
||||
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(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/json',
|
||||
method: 'GET',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'plugin is not installed',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the plugin
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '?',
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'plugin is not installed',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
if (err) return args.callback(err, data);
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* get privileges
|
||||
* @param {Object} opts Options (optional)
|
||||
* @param {Function} callback Callback
|
||||
* @return {Object} Name only if callback isn't specified.
|
||||
*/
|
||||
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(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Installs a new plugin
|
||||
* @param {Object} opts Create options
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.pull = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
if(args.opts._query && !args.opts._query.name) {
|
||||
args.opts._query.name = this.name;
|
||||
}
|
||||
if(args.opts._query && !args.opts._query.remote) {
|
||||
args.opts._query.remote = this.remote;
|
||||
}
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/pull?',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
isStream: true,
|
||||
options: args.opts,
|
||||
statusCodes: {
|
||||
200: true, // unofficial, but proxies may return it
|
||||
204: true,
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enable
|
||||
* @param {Object} opts Plugin enable options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.enable = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/enable?',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable
|
||||
* @param {Object} opts Plugin disable options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.disable = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/disable',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Push
|
||||
* @param {Object} opts Plugin push options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.push = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/push',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'plugin not installed',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* COnfigure
|
||||
* @param {Object} opts Plugin configure options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Plugin.prototype.configure = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/set',
|
||||
method: 'POST',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'plugin not installed',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Upgrade plugin
|
||||
*
|
||||
* @param {object} auth
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Plugin.prototype.upgrade = function(auth, opts, callback) {
|
||||
var self = this;
|
||||
if (!callback && typeof opts === 'function') {
|
||||
callback = opts;
|
||||
opts = auth;
|
||||
auth = opts.authconfig || undefined;
|
||||
}
|
||||
|
||||
var optsf = {
|
||||
path: '/plugins/' + this.name + '/upgrade?',
|
||||
method: 'POST',
|
||||
abortSignal: opts && opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'plugin not installed',
|
||||
500: 'server error'
|
||||
},
|
||||
authconfig: auth,
|
||||
options: opts
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = Plugin;
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package moby.filesync.v1;
|
||||
|
||||
option go_package = "auth";
|
||||
|
||||
service Auth{
|
||||
rpc Credentials(CredentialsRequest) returns (CredentialsResponse);
|
||||
rpc FetchToken(FetchTokenRequest) returns (FetchTokenResponse);
|
||||
rpc GetTokenAuthority(GetTokenAuthorityRequest) returns (GetTokenAuthorityResponse);
|
||||
rpc VerifyTokenAuthority(VerifyTokenAuthorityRequest) returns (VerifyTokenAuthorityResponse);
|
||||
}
|
||||
|
||||
message CredentialsRequest {
|
||||
string Host = 1;
|
||||
}
|
||||
|
||||
message CredentialsResponse {
|
||||
string Username = 1;
|
||||
string Secret = 2;
|
||||
}
|
||||
|
||||
message FetchTokenRequest {
|
||||
string ClientID = 1;
|
||||
string Host = 2;
|
||||
string Realm = 3;
|
||||
string Service = 4;
|
||||
repeated string Scopes = 5;
|
||||
}
|
||||
|
||||
message FetchTokenResponse {
|
||||
string Token = 1;
|
||||
int64 ExpiresIn = 2; // seconds
|
||||
int64 IssuedAt = 3; // timestamp
|
||||
}
|
||||
|
||||
message GetTokenAuthorityRequest {
|
||||
string Host = 1;
|
||||
bytes Salt = 2;
|
||||
}
|
||||
|
||||
message GetTokenAuthorityResponse {
|
||||
bytes PublicKey = 1;
|
||||
}
|
||||
|
||||
message VerifyTokenAuthorityRequest {
|
||||
string Host = 1;
|
||||
bytes Payload = 2;
|
||||
bytes Salt = 3;
|
||||
}
|
||||
|
||||
message VerifyTokenAuthorityResponse {
|
||||
bytes Signed = 1;
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package moby.buildkit.v1;
|
||||
|
||||
// Minimal definitions for decoding BuildKit status messages
|
||||
// Based on https://github.com/moby/buildkit/blob/master/api/services/control/control.proto
|
||||
// Related to https://github.com/moby/buildkit/blob/master/solver/pb/ops.proto (vertices map to the solver op DAG)
|
||||
|
||||
message StatusResponse {
|
||||
repeated Vertex vertexes = 1;
|
||||
repeated VertexStatus statuses = 2;
|
||||
repeated VertexLog logs = 3;
|
||||
repeated VertexWarning warnings = 4;
|
||||
}
|
||||
|
||||
message Vertex {
|
||||
string digest = 1;
|
||||
repeated string inputs = 2;
|
||||
string name = 3;
|
||||
bool cached = 4;
|
||||
Timestamp started = 5;
|
||||
Timestamp completed = 6;
|
||||
string error = 7;
|
||||
ProgressGroup progressGroup = 8;
|
||||
}
|
||||
|
||||
message VertexStatus {
|
||||
string ID = 1;
|
||||
string vertex = 2;
|
||||
string name = 3;
|
||||
int64 current = 4;
|
||||
int64 total = 5;
|
||||
Timestamp timestamp = 6;
|
||||
Timestamp started = 7;
|
||||
Timestamp completed = 8;
|
||||
}
|
||||
|
||||
message VertexLog {
|
||||
string vertex = 1;
|
||||
Timestamp timestamp = 2;
|
||||
int64 stream = 3;
|
||||
bytes msg = 4;
|
||||
}
|
||||
|
||||
message VertexWarning {
|
||||
string vertex = 1;
|
||||
int64 level = 2;
|
||||
bytes short = 3;
|
||||
repeated bytes detail = 4;
|
||||
string url = 5;
|
||||
SourceInfo info = 6;
|
||||
repeated Range ranges = 7;
|
||||
}
|
||||
|
||||
message ProgressGroup {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
bool weak = 3;
|
||||
}
|
||||
|
||||
// Simplified Timestamp to match google.protobuf.Timestamp wire format
|
||||
message Timestamp {
|
||||
int64 seconds = 1;
|
||||
int32 nanos = 2;
|
||||
}
|
||||
|
||||
message SourceInfo {
|
||||
string filename = 1;
|
||||
bytes data = 2;
|
||||
// definition and language fields omitted - not needed for log decoding
|
||||
}
|
||||
|
||||
message Range {
|
||||
Position start = 1;
|
||||
Position end = 2;
|
||||
}
|
||||
|
||||
message Position {
|
||||
int32 line = 1;
|
||||
int32 character = 2;
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents a secret
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Secret's id
|
||||
*/
|
||||
var Secret = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
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(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',
|
||||
406: 'node is not part of a swarm',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a secret.
|
||||
*
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Secret.prototype.update = function(opts, callback) {
|
||||
var self = this;
|
||||
if (!callback && typeof opts === 'function') {
|
||||
callback = opts;
|
||||
}
|
||||
|
||||
var optsf = {
|
||||
path: '/secrets/' + this.id + '/update?',
|
||||
method: 'POST',
|
||||
abortSignal: opts && opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'secret not found',
|
||||
500: 'server error'
|
||||
},
|
||||
options: opts
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the secret
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Secret.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/secrets/' + this.id,
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
204: true,
|
||||
404: 'secret not found',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Secret;
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an Service
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Service's ID
|
||||
*/
|
||||
var Service = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
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(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',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete Service
|
||||
*
|
||||
* @param {Object} opts Options (optional)
|
||||
* @param {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,
|
||||
404: 'no such service',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update service
|
||||
*
|
||||
* @param {object} auth
|
||||
* @param {object} opts
|
||||
* @param {function} callback
|
||||
*/
|
||||
Service.prototype.update = function(auth, opts, callback) {
|
||||
var self = this;
|
||||
if (!callback) {
|
||||
var t = typeof opts;
|
||||
if(t === 'function'){
|
||||
callback = opts;
|
||||
opts = auth;
|
||||
auth = opts.authconfig || undefined;
|
||||
} else if (t === 'undefined'){
|
||||
opts = auth;
|
||||
auth = opts.authconfig || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var optsf = {
|
||||
path: '/services/' + this.id + '/update?',
|
||||
method: 'POST',
|
||||
abortSignal: opts && opts.abortSignal,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such service',
|
||||
500: 'server error'
|
||||
},
|
||||
authconfig: auth,
|
||||
options: opts
|
||||
};
|
||||
|
||||
if(callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Service logs
|
||||
* @param {Object} opts Logs options. (optional)
|
||||
* @param {Function} callback Callback with data
|
||||
*/
|
||||
Service.prototype.logs = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback, {});
|
||||
|
||||
var optsf = {
|
||||
path: '/services/' + this.id + '/logs?',
|
||||
method: 'GET',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
isStream: args.opts.follow || false,
|
||||
statusCodes: {
|
||||
200: true,
|
||||
404: 'no such service',
|
||||
500: 'server error',
|
||||
503: 'node is not part of a swarm'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Service;
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
var grpc = require("@grpc/grpc-js"),
|
||||
protoLoader = require("@grpc/proto-loader"),
|
||||
path = require("path"),
|
||||
uuid = require("uuid").v4;
|
||||
|
||||
function withSession(docker, auth, handler) {
|
||||
const sessionId = uuid();
|
||||
|
||||
const opts = {
|
||||
method: "POST",
|
||||
path: "/session",
|
||||
hijack: true,
|
||||
headers: {
|
||||
Upgrade: "h2c",
|
||||
"X-Docker-Expose-Session-Uuid": sessionId,
|
||||
"X-Docker-Expose-Session-Name": "testcontainers",
|
||||
},
|
||||
statusCodes: {
|
||||
200: true,
|
||||
500: "server error",
|
||||
},
|
||||
};
|
||||
|
||||
docker.modem.dial(opts, function (err, socket) {
|
||||
if (err) {
|
||||
return handler(err, null, () => undefined);
|
||||
}
|
||||
|
||||
const server = new grpc.Server();
|
||||
const creds = grpc.ServerCredentials.createInsecure();
|
||||
const injector = server.createConnectionInjector(creds);
|
||||
injector.injectConnection(socket);
|
||||
|
||||
const pkg = protoLoader.loadSync(
|
||||
path.resolve(__dirname, "proto", "auth.proto")
|
||||
);
|
||||
const service = grpc.loadPackageDefinition(pkg);
|
||||
|
||||
server.addService(service.moby.filesync.v1.Auth.service, {
|
||||
Credentials({ request }, callback) {
|
||||
// We probably want to have the possibility to pass credentials per
|
||||
// hots. The correct one could be returned based on `request.Host`
|
||||
if (auth) {
|
||||
callback(null, {
|
||||
Username: auth.username,
|
||||
Secret: auth.password,
|
||||
});
|
||||
} else {
|
||||
callback(null, {});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function done() {
|
||||
server.forceShutdown();
|
||||
socket.end();
|
||||
}
|
||||
|
||||
handler(null, sessionId, done);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = withSession;
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents an Task
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} id Task's ID
|
||||
*/
|
||||
var Task = function(modem, id) {
|
||||
this.modem = modem;
|
||||
this.id = id;
|
||||
|
||||
this.defaultOptions = {
|
||||
log: {}
|
||||
};
|
||||
};
|
||||
|
||||
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(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',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Task logs
|
||||
* @param {Object} opts Logs options. (optional)
|
||||
* @param {Function} callback Callback with data
|
||||
*/
|
||||
Task.prototype.logs = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback, this.defaultOptions.log);
|
||||
|
||||
var optsf = {
|
||||
path: '/tasks/' + this.id + '/logs?',
|
||||
method: 'GET',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
isStream: args.opts.follow || false,
|
||||
statusCodes: {
|
||||
101: true,
|
||||
200: true,
|
||||
404: 'no such container',
|
||||
500: 'server error',
|
||||
503: 'node is not part of a swarm'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = Task;
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
var DockerIgnore = require('@balena/dockerignore');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var tar = require('tar-fs');
|
||||
var zlib = require('zlib');
|
||||
|
||||
// https://github.com/HenrikJoreteg/extend-object/blob/v0.1.0/extend-object.js
|
||||
|
||||
var arr = [];
|
||||
var each = arr.forEach;
|
||||
var slice = arr.slice;
|
||||
|
||||
module.exports.extend = function(obj) {
|
||||
each.call(slice.call(arguments, 1), function(source) {
|
||||
if (source) {
|
||||
for (var prop in source) {
|
||||
obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
module.exports.processArgs = function(opts, callback, defaultOpts) {
|
||||
if (!callback && typeof opts === 'function') {
|
||||
callback = opts;
|
||||
opts = null;
|
||||
}
|
||||
return {
|
||||
callback: callback,
|
||||
opts: module.exports.extend({}, defaultOpts, opts)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse the given repo tag name (as a string) and break it out into repo/tag pair.
|
||||
* // if given the input http://localhost:8080/woot:latest
|
||||
* {
|
||||
* repository: 'http://localhost:8080/woot',
|
||||
* tag: 'latest'
|
||||
* }
|
||||
* @param {String} input Input e.g: 'repo/foo', 'ubuntu', 'ubuntu:latest'
|
||||
* @return {Object} input parsed into the repo and tag.
|
||||
*/
|
||||
module.exports.parseRepositoryTag = function(input) {
|
||||
var separatorPos;
|
||||
var digestPos = input.indexOf('@');
|
||||
var colonPos = input.lastIndexOf(':');
|
||||
// @ symbol is more important
|
||||
if (digestPos >= 0) {
|
||||
separatorPos = digestPos;
|
||||
} else if (colonPos >= 0) {
|
||||
separatorPos = colonPos;
|
||||
} else {
|
||||
// no colon nor @
|
||||
return {
|
||||
repository: input
|
||||
};
|
||||
}
|
||||
|
||||
// last colon is either the tag (or part of a port designation)
|
||||
var tag = input.slice(separatorPos + 1);
|
||||
|
||||
// if it contains a / its not a tag and is part of the url
|
||||
if (tag.indexOf('/') === -1) {
|
||||
return {
|
||||
repository: input.slice(0, separatorPos),
|
||||
tag: tag
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
repository: input
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.prepareBuildContext = function(file, next) {
|
||||
if (file && file.context) {
|
||||
fs.readFile(path.join(file.context, '.dockerignore'), (err, data) => {
|
||||
let ignoreFn;
|
||||
let filterFn;
|
||||
|
||||
if (!err) {
|
||||
const dockerIgnore = DockerIgnore({ ignorecase: false }).add(data.toString());
|
||||
|
||||
filterFn = dockerIgnore.createFilter();
|
||||
ignoreFn = (path) => {
|
||||
return !filterFn(path);
|
||||
}
|
||||
}
|
||||
|
||||
const entries = file.src.slice() || []
|
||||
|
||||
const pack = tar.pack(file.context, {
|
||||
entries: filterFn ? entries.filter(filterFn) : entries,
|
||||
ignore: ignoreFn // Only works on directories
|
||||
});
|
||||
|
||||
next(pack.pipe(zlib.createGzip()));
|
||||
})
|
||||
} else {
|
||||
next(file);
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* Represents a volume
|
||||
* @param {Object} modem docker-modem
|
||||
* @param {String} name Volume's name
|
||||
*/
|
||||
var Volume = function(modem, name) {
|
||||
this.modem = modem;
|
||||
this.name = name;
|
||||
};
|
||||
|
||||
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(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',
|
||||
500: 'server error'
|
||||
}
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the volume
|
||||
* @param {[Object]} opts Remove options (optional)
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
Volume.prototype.remove = function(opts, callback) {
|
||||
var self = this;
|
||||
var args = util.processArgs(opts, callback);
|
||||
|
||||
var optsf = {
|
||||
path: '/volumes/' + this.name,
|
||||
method: 'DELETE',
|
||||
abortSignal: args.opts.abortSignal,
|
||||
statusCodes: {
|
||||
204: true,
|
||||
404: 'no such volume',
|
||||
409: 'conflict',
|
||||
500: 'server error'
|
||||
},
|
||||
options: args.opts
|
||||
};
|
||||
|
||||
if(args.callback === undefined) {
|
||||
return new this.modem.Promise(function(resolve, reject) {
|
||||
self.modem.dial(optsf, function(err, data) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.modem.dial(optsf, function(err, data) {
|
||||
args.callback(err, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Volume;
|
||||
Reference in New Issue
Block a user