@nikitajs/docker
Advanced tools
Comparing version 0.9.7 to 1.0.0-alpha.0
485
lib/build.js
@@ -5,3 +5,3 @@ // Generated by CoffeeScript 2.5.1 | ||
// Build docker repository from Dockerfile, from content or from current working | ||
// directory (exclusive options). | ||
// directory. | ||
@@ -16,31 +16,4 @@ // The user can choose whether the build is local or on the remote. | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `image` (string) | ||
// Name of the image, required. | ||
// * `tag` (string) | ||
// Tag of the image. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `file` | ||
// Path to Dockerfile. | ||
// * `content` (string | [string]) | ||
// Use this text to build the repository. | ||
// * `quiet` (boolean) | ||
// Suppress the verbose output generated by the containers. Default to false | ||
// * `rm` (boolean) | ||
// Remove intermediate containers after build, default to true. | ||
// * `force_rm` (boolean) | ||
// Always remove intermediate containers during build, default to false. | ||
// * `no_cache` (boolean) | ||
// Do not use cache when building the repository, default to false. | ||
// * `build_arg` ("k=v" | []) | ||
// Send arguments to the build (Must match an ARG command). | ||
// * `cwd` (string) | ||
// change the working directory for the build. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -57,17 +30,13 @@ // Error object if any. | ||
// ## Examples | ||
// ## Builds a repository from dockerfile without any resourcess | ||
// ### Builds a repository from dockerfile without any resourcess | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.build({ | ||
// ```js | ||
// const {status} = await nikita.docker.build({ | ||
// image: 'ryba/targe-build', | ||
// source: '/home/ryba/Dockerfile' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container built: ' + status); | ||
// }); | ||
// }) | ||
// console.info(`Container was built: ${status}`) | ||
// ``` | ||
// ### Builds an repository from dockerfile with external resources | ||
// ## Builds a repository from dockerfile with external resources | ||
@@ -92,243 +61,271 @@ // In this case nikita download all the external files into a resources directory in the same location | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.build({ | ||
// ```js | ||
// const {status} = await nikita.docker.build({ | ||
// tag: 'ryba/target-build', | ||
// source: '/home/ryba/Dockerfile', | ||
// resources: ['http://url.com/package.tar.gz/','/home/configuration.sh'] | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container built: ' + status); | ||
// }); | ||
// }) | ||
// console.info(`Container was built: ${status}`) | ||
// ``` | ||
// ### Builds an repository from stdin | ||
// ## Builds a repository from stdin | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.build({ | ||
// ```js | ||
// const {status} = await nikita.docker.build({ | ||
// ssh: ssh, | ||
// tag: 'ryba/target-build' | ||
// content: "FROM ubuntu\nRUN echo 'helloworld'" | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container built: ' + status); | ||
// }); | ||
// }) | ||
// console.info(`Container was built: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, path, string, util, | ||
// ## Hooks | ||
var errors, handler, on_action, path, schema, utils, | ||
indexOf = [].indexOf; | ||
module.exports = function({options}, callback) { | ||
var cmd, dockerfile_cmds, i, j, k, l, len, len1, len2, number_of_step, opt, ref, ref1, ref2, ref3, source, ssh, userargs, v; | ||
this.log({ | ||
message: "Entering Docker build", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/build' | ||
}); | ||
// SSH connection | ||
ssh = this.ssh(options.ssh); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
on_action = function({config}) { | ||
if ((config.content != null) && (config.file != null)) { | ||
throw errors.NIKITA_DOCKER_BUILD_CONTENT_FILE_REQUIRED(); | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
}; | ||
// ## Schema | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'build_arg': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'object', | ||
patternProperties: { | ||
'.*': { | ||
typeof: 'string' | ||
} | ||
} | ||
} | ||
], | ||
description: `Send arguments to the build, match the Docker native ARG command.` | ||
}, | ||
'content': { | ||
type: 'string', | ||
description: `Content of the Docker file, required unless \`file\` is provided.` | ||
}, | ||
'cwd': { | ||
type: 'string', | ||
description: `Change the build working directory.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'file': { | ||
type: 'string', | ||
description: `Path to Dockerfile, required unless \`content\` is provided.` | ||
}, | ||
'force_rm': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Always remove intermediate containers during build.` | ||
}, | ||
'image': { | ||
type: 'string', | ||
description: `Name of the Docker image present in the registry.` | ||
}, | ||
'quiet': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Suppress the verbose output generated by the containers.` | ||
}, | ||
'rm': { | ||
type: 'boolean', | ||
default: true, | ||
description: `Remove intermediate containers after a successful build.` | ||
}, | ||
'no_cache': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Do not use cache when building the repository.` | ||
}, | ||
'tag': { | ||
type: 'string', | ||
description: `Tag of the Docker image, default to latest.` | ||
} | ||
} | ||
if (options.image == null) { | ||
// Validation | ||
return callback(Error('Required option "image"')); | ||
} | ||
if ((options.content != null) && (options.file != null)) { | ||
return callback(Error('Can not build from Dockerfile and content')); | ||
} | ||
if (options.rm == null) { | ||
options.rm = true; | ||
} | ||
cmd = 'build'; | ||
}, | ||
required: ['image'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var dockerfile_commands, i, image_id, k, len, line, lines, number_of_cache, number_of_step, ref, ref1, ref2, source, stderr, stdout, userargs; | ||
number_of_step = 0; | ||
userargs = []; | ||
// status unmodified if final tag already exists | ||
dockerfile_cmds = ['CMD', 'LABEL', 'EXPOSE', 'ENV', 'ADD', 'COPY', 'ENTRYPOINT', 'VOLUME', 'USER', 'WORKDIR', 'ARG', 'ONBUILD', 'RUN', 'STOPSIGNAL', 'MAINTAINER']; | ||
source = null; | ||
if (options.file) { | ||
source = options.file; | ||
} else if (options.cwd) { | ||
source = `${options.cwd}/Dockerfile`; | ||
dockerfile_commands = ['CMD', 'LABEL', 'EXPOSE', 'ENV', 'ADD', 'COPY', 'ENTRYPOINT', 'VOLUME', 'USER', 'WORKDIR', 'ARG', 'ONBUILD', 'RUN', 'STOPSIGNAL', 'MAINTAINER']; | ||
source = void 0; | ||
if (config.file) { | ||
source = config.file; | ||
} else if (config.cwd) { | ||
source = `${config.cwd}/Dockerfile`; | ||
} | ||
if (options.file) { | ||
if (options.cwd == null) { | ||
options.cwd = path.dirname(options.file); | ||
if (config.file) { | ||
if (config.cwd == null) { | ||
config.cwd = path.dirname(config.file); | ||
} | ||
} | ||
ref1 = ['force_rm', 'quiet', 'no_cache']; | ||
// Apply search and replace to content | ||
// options.write ?= [] | ||
// if options.from? or options.to? or options.match? or options.replace? or options.before? | ||
// options.write.push | ||
// from: options.from | ||
// to: options.to | ||
// match: options.match | ||
// replace: options.replace | ||
// append: options.append | ||
// before: options.before | ||
// options.append = false | ||
// Build cmd | ||
for (i = 0, len = ref1.length; i < len; i++) { | ||
opt = ref1[i]; | ||
if (options[opt]) { | ||
cmd += ` --${opt.replace('_', '-')}`; | ||
if (config.cwd) { | ||
if (config.file == null) { | ||
config.file = path.resolve(config.cwd, 'Dockerfile'); | ||
} | ||
} | ||
ref2 = ['build_arg']; | ||
for (j = 0, len1 = ref2.length; j < len1; j++) { | ||
opt = ref2[j]; | ||
if (options[opt] != null) { | ||
if (Array.isArray(options[opt])) { | ||
ref3 = options[opt]; | ||
for (l = 0, len2 = ref3.length; l < len2; l++) { | ||
k = ref3[l]; | ||
cmd += ` --${opt.replace('_', '-')} ${k}`; | ||
// Make sure the Dockerfile exists | ||
if (!config.content) { | ||
await this.fs.assert(config.file); | ||
} | ||
// Build the image | ||
({stdout, stderr} = (await this.docker.tools.execute({ | ||
command: [ | ||
'build', | ||
...(['force_rm', | ||
'quiet', | ||
'no_cache'].filter(function(opt) { | ||
return config[opt]; | ||
}).map(function(opt) { | ||
return `--${opt.replace('_', | ||
'-')}`; | ||
})), | ||
...(utils.array.flatten(['build_arg']).filter(function(opt) { | ||
return config[opt]; | ||
}).map(function(opt) { | ||
var i, | ||
k, | ||
len, | ||
ref, | ||
results; | ||
if (Array.isArray(config[opt])) { | ||
ref = config[opt]; | ||
results = []; | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
k = ref[i]; | ||
results.push(`--${opt.replace('_', | ||
'-')} ${k}`); | ||
} | ||
return results; | ||
} else { | ||
return `--${opt.replace('_', | ||
'-')} ${config[opt]}`; | ||
} | ||
} else { | ||
cmd += ` --${opt.replace('_', '-')} ${options[opt]}`; | ||
} | ||
} | ||
} | ||
cmd += ` --rm=${options.rm ? 'true' : 'false'}`; | ||
cmd += ` -t \"${options.image}${options.tag ? `:${options.tag}` : ''}\"`; | ||
if (options.cwd) { | ||
// custom command for content option0 | ||
if (options.file == null) { | ||
options.file = path.resolve(options.cwd, 'Dockerfile'); | ||
} | ||
} | ||
if (options.content != null) { | ||
this.log({ | ||
message: "Building from text: Docker won't have a context. ADD/COPY not working", | ||
level: 'WARN', | ||
module: 'nikita/docker/build' | ||
})), | ||
'--rm=' + (config.rm ? 'true' : 'false'), | ||
'-t ' + utils.string.escapeshellarg(config.image + (config.tag ? `:${config.tag}` : '')), | ||
(config.content != null ? (log({ | ||
message: "Building from text: Docker won't have a context. ADD/COPY not working", | ||
level: 'WARN' | ||
}), | ||
config.content != null ? `- <<DOCKERFILE\n${config.content}\nDOCKERFILE` : void 0) : config.file != null ? (log({ | ||
message: `Building from Dockerfile: \"${config.file}\"`, | ||
level: 'INFO' | ||
}), | ||
`-f ${config.file} ${config.cwd}`) : (log({ | ||
message: "Building from CWD", | ||
level: 'INFO' | ||
}), | ||
'.')) | ||
].join(' '), | ||
cwd: config.cwd | ||
}))); | ||
// Get the content of the Dockerfile | ||
if (config.content) { | ||
await this.file({ | ||
content: config.content, | ||
source: source, | ||
target: function({content}) { | ||
return config.content = content; | ||
}, | ||
from: config.from, | ||
to: config.to, | ||
match: config.match, | ||
replace: config.replace, | ||
append: config.append, | ||
before: config.before, | ||
write: config.write | ||
}); | ||
if (options.content != null) { | ||
cmd += ` - <<DOCKERFILE\n${options.content}\nDOCKERFILE`; | ||
} | ||
} else if (options.file != null) { | ||
this.log({ | ||
message: `Building from Dockerfile: \"${options.file}\"`, | ||
level: 'INFO', | ||
module: 'nikita/docker/build' | ||
}); | ||
cmd += ` -f ${options.file} ${options.cwd}`; | ||
} else { | ||
this.log({ | ||
message: "Building from CWD", | ||
level: 'INFO', | ||
module: 'nikita/docker/build' | ||
// Read Dockerfile if necessary to count steps | ||
log({ | ||
message: `Reading Dockerfile from : ${config.file}`, | ||
level: 'INFO' | ||
}); | ||
cmd += ' .'; | ||
({ | ||
data: config.content | ||
} = (await this.fs.base.readFile({ | ||
target: config.file, | ||
encoding: 'utf8' | ||
}))); | ||
} | ||
this.file({ | ||
if: options.content, | ||
content: options.content, | ||
source: source, | ||
target: function(content) { | ||
return options.content = content; | ||
}, | ||
from: options.from, | ||
to: options.to, | ||
match: options.match, | ||
replace: options.replace, | ||
append: options.append, | ||
before: options.before, | ||
write: options.write | ||
}); | ||
this.call({ // Read Dockerfile if necessary to count steps | ||
unless: options.content | ||
}, function(_, callback) { | ||
this.log({ | ||
message: `Reading Dockerfile from : ${options.file}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/build' | ||
}); | ||
return this.fs.readFile({ | ||
ssh: options.ssh, | ||
target: options.file, | ||
encoding: 'utf8' | ||
}, function(err, {data}) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
options.content = data; | ||
return callback(); | ||
}); | ||
}); | ||
this.call(function() { // Count steps | ||
var len3, line, m, ref4, ref5, ref6, results; | ||
ref4 = string.lines(options.content); | ||
results = []; | ||
for (m = 0, len3 = ref4.length; m < len3; m++) { | ||
line = ref4[m]; | ||
if (ref5 = (ref6 = /^(.*?)\s/.exec(line)) != null ? ref6[1] : void 0, indexOf.call(dockerfile_cmds, ref5) >= 0) { | ||
results.push(number_of_step++); | ||
} else { | ||
results.push(void 0); | ||
} | ||
ref = utils.string.lines(config.content); | ||
// Count steps | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
line = ref[i]; | ||
if (ref1 = (ref2 = /^(.*?)\s/.exec(line)) != null ? ref2[1] : void 0, indexOf.call(dockerfile_commands, ref1) >= 0) { | ||
number_of_step++; | ||
} | ||
return results; | ||
}); | ||
this.system.execute({ | ||
cmd: docker.wrap(options, cmd), | ||
cwd: options.cwd | ||
}, function(err, {stdout, stderr}) { | ||
var image_id, line, lines, number_of_cache; | ||
if (err) { | ||
throw err; | ||
} | ||
image_id = null; | ||
// Count cache | ||
lines = utils.string.lines(stdout); | ||
number_of_cache = 0; | ||
for (k in lines) { | ||
line = lines[k]; | ||
if (line.indexOf('Using cache') !== -1) { | ||
number_of_cache = number_of_cache + 1; | ||
} | ||
image_id = null; | ||
// lines = string.lines stderr | ||
lines = string.lines(stdout); | ||
number_of_cache = 0; | ||
for (k in lines) { | ||
line = lines[k]; | ||
if (line.indexOf('Using cache') !== -1) { | ||
number_of_cache = number_of_cache + 1; | ||
} | ||
if (line.indexOf('Successfully built') !== -1) { | ||
image_id = line.split(' ').pop().toString(); | ||
} | ||
if (line.indexOf('Successfully built') !== -1) { | ||
image_id = line.split(' ').pop().toString(); | ||
} | ||
return userargs = { | ||
status: number_of_step !== number_of_cache, | ||
image: image_id, | ||
stdout: stdout, | ||
stderr: stderr | ||
}; | ||
} | ||
userargs = { | ||
status: number_of_step !== number_of_cache, | ||
image: image_id, | ||
stdout: stdout, | ||
stderr: stderr | ||
}; | ||
log(userargs.status ? { | ||
message: `New image id ${userargs[1]}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/build' | ||
} : { | ||
message: `Identical image id ${userargs[1]}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/build' | ||
}); | ||
return this.next(function(err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
this.log(userargs.status ? { | ||
message: `New image id ${userargs[1]}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/build' | ||
} : { | ||
message: `Identical image id ${userargs[1]}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/build' | ||
}); | ||
return callback(null, userargs); | ||
}); | ||
return userargs; | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
}, | ||
hooks: { | ||
on_action: on_action | ||
} | ||
}; | ||
string = require('@nikitajs/core/lib/misc/string'); | ||
// ## Errors | ||
errors = { | ||
NIKITA_DOCKER_BUILD_CONTENT_FILE_REQUIRED: function() { | ||
return utils.error('NIKITA_DOCKER_BUILD_CONTENT_FILE_REQUIRED', ['could not build the container,', 'one of the `content` or `file` config property must be provided']); | ||
} | ||
}; | ||
// ## Dependencies | ||
utils = require('./utils'); | ||
path = require('path'); | ||
util = require('util'); |
@@ -7,34 +7,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `content` (string) | ||
// The content of the docker-compose.yml to write if not exist. | ||
// * `eof` (string) | ||
// Inherited from nikita.file use when writing docker-compose.yml file. | ||
// * `backup` (string|boolean) | ||
// Create a backup, append a provided string to the filename extension or a | ||
// timestamp if value is not a string, only apply if the target file exists and | ||
// is modified. | ||
// * `detached` (boolean) | ||
// Run Containers in detached mode. Default to true. | ||
// * `force` (boolean) | ||
// Force to re-create the containers if the config and image have not changed | ||
// Default to false | ||
// * `services` (string|array) | ||
// Specify specific services to create. | ||
// * `target` (string) | ||
// The docker-compose.yml absolute's file's path, required if no content is | ||
// specified. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -49,121 +19,159 @@ // Error object if any. | ||
// ## Source Code | ||
var docker, path; | ||
// ## Schema | ||
var handler, path, schema, utils; | ||
module.exports = function({options}) { | ||
var clean_target, cmd, cmd_ps, cmd_up, k, ref, services, source_dir, v; | ||
this.log({ | ||
message: "Entering Docker Compose", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/compose/up' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'content': { | ||
type: 'object', | ||
description: `The content of the docker-compose.yml to write if not exist.` | ||
}, | ||
'eof': { | ||
type: 'boolean', | ||
default: true, | ||
description: `Inherited from nikita.file use when writing docker-compose.yml file.` | ||
}, | ||
'backup': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'boolean' | ||
} | ||
], | ||
default: false, | ||
description: `Create a backup, append a provided string to the filename extension or | ||
a timestamp if value is not a string, only apply if the target file | ||
exists and is modified.` | ||
}, | ||
'detached': { | ||
type: 'boolean', | ||
default: true, | ||
description: `Run containers in detached mode.` | ||
}, | ||
'force': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Force to re-create the containers if the config and image have not | ||
changed.` | ||
}, | ||
'services': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Specify specific services to create.` | ||
}, | ||
'target': { | ||
type: 'string', | ||
description: `The docker-compose.yml absolute's file's path, required if no content | ||
is specified.` | ||
} | ||
} | ||
ref = options.docker; | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {find, log} | ||
}) { | ||
var clean_target, containers, k, ref, status, stdout, v; | ||
// Global config | ||
config.docker = (await find(function({ | ||
config: {docker} | ||
}) { | ||
return docker; | ||
})); | ||
ref = config.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
if (config[k] == null) { | ||
config[k] = v; | ||
} | ||
} | ||
if ((options.target == null) && (options.content == null)) { | ||
if ((config.target == null) && (config.content == null)) { | ||
// Validate parameters | ||
throw Error('Missing docker-compose content or target'); | ||
} | ||
if (options.content && (options.target == null)) { | ||
if (options.target == null) { | ||
options.target = `/tmp/nikita_docker_compose_${Date.now()}/docker-compose.yml`; | ||
if (config.content && (config.target == null)) { | ||
if (config.target == null) { | ||
config.target = `/tmp/nikita_docker_compose_${Date.now()}/docker-compose.yml`; | ||
} | ||
clean_target = true; | ||
} | ||
if (options.detached == null) { | ||
options.detached = true; | ||
if (config.recreate == null) { | ||
config.recreate = false; // TODO: move to schema | ||
} | ||
if (options.force == null) { | ||
options.force = false; | ||
if (config.services == null) { | ||
config.services = []; | ||
} | ||
if (options.recreate == null) { | ||
options.recreate = false; | ||
if (!Array.isArray(config.services)) { | ||
config.services = [config.services]; | ||
} | ||
if (options.services == null) { | ||
options.services = []; | ||
// services = config.services.join ' ' | ||
await this.file.yaml({ | ||
if: config.content != null, | ||
eof: config.eof, | ||
backup: config.backup, | ||
target: config.target, | ||
content: config.content | ||
}); | ||
({status, stdout} = (await this.docker.tools.execute({ | ||
command: `--file ${config.target} ps -q | xargs docker ${utils.opts(config)} inspect`, | ||
compose: true, | ||
cwd: config.cwd, | ||
uid: config.uid, | ||
code_skipped: 123, | ||
stdout_log: false, | ||
metadata: { | ||
shy: true | ||
} | ||
}))); | ||
if (!status) { | ||
status = true; | ||
} else { | ||
containers = JSON.parse(stdout); | ||
status = containers.some(function(container) { | ||
return !container.State.Running; | ||
}); | ||
if (status) { | ||
log("Docker created, need start"); | ||
} | ||
} | ||
if (!Array.isArray(options.services)) { | ||
options.services = [options.services]; | ||
try { | ||
return (await this.docker.tools.execute({ | ||
if: config.force || status, | ||
command: [`--file ${config.target} up`, config.detached ? '-d' : void 0, config.force ? '--force-recreate' : void 0, ...config.services].join(' '), | ||
compose: true, | ||
cwd: path.dirname(config.target), | ||
uid: config.uid | ||
})); | ||
} finally { | ||
await this.fs.remove({ | ||
if: clean_target, | ||
target: config.target | ||
}); | ||
} | ||
services = options.services.join(' '); | ||
// Construct exec command | ||
cmd = ` --file ${options.target}`; | ||
cmd_ps = `${cmd} ps -q | xargs docker ${docker.opts(options)} inspect`; | ||
cmd_up = `${cmd} up`; | ||
if (options.detached) { | ||
cmd_up += ' -d '; | ||
}; | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
schema: schema | ||
} | ||
if (options.force) { | ||
cmd_up += ' --force-recreate '; | ||
} | ||
cmd_up += ` ${services}`; | ||
source_dir = `${path.dirname(options.target)}`; | ||
if (options.eof == null) { | ||
options.eof = true; | ||
} | ||
if (options.backup == null) { | ||
options.backup = false; | ||
} | ||
options.compose = true; | ||
this.call(function() { | ||
return this.file.yaml({ | ||
if: options.content != null, | ||
eof: options.eof, | ||
backup: options.backup, | ||
target: options.target, | ||
content: options.content | ||
}); | ||
}); | ||
this.call(function(_, callback) { | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd_ps), | ||
cwd: options.cwd, | ||
uid: options.uid, | ||
code_skipped: 123, | ||
stdout_log: false | ||
}, function(err, {status, stdout}) { | ||
var containers; | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (!status) { | ||
return callback(null, true); | ||
} | ||
containers = JSON.parse(stdout); | ||
status = containers.some(function(container) { | ||
return !container.State.Running; | ||
}); | ||
if (status) { | ||
this.log("Docker created, need start"); | ||
} | ||
return callback(null, status); | ||
}); | ||
}); | ||
this.system.execute({ | ||
if: function() { | ||
return options.force || this.status(); | ||
}, | ||
cwd: source_dir, | ||
uid: options.uid, | ||
cmd: docker.wrap(options, cmd_up) | ||
}, docker.callback); | ||
return this.system.remove({ | ||
if: clean_target, | ||
target: options.target, | ||
always: true // Not yet implemented | ||
}); | ||
}; | ||
// ## Dependencies | ||
utils = require('../utils'); | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
path = require('path'); |
191
lib/cp.js
@@ -16,23 +16,10 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine or boot2docker. | ||
// * `source` (string) | ||
// The path to upload or the container followed by the path to download. | ||
// * `target` (string) | ||
// The path to download or the container followed by the path to upload. | ||
// ## Uploading a file | ||
// ```javascript | ||
// require('nikita') | ||
// .docker({ | ||
// ```js | ||
// const {status} = await nikita.docker.cp({ | ||
// source: readable_stream or '/path/to/source' | ||
// target: 'my_container:/path/to/target' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container copied' + status) | ||
// ) | ||
// }) | ||
// console.info(`Container was copied: ${status}`) | ||
// ``` | ||
@@ -42,49 +29,41 @@ | ||
// ```javascript | ||
// require('nikita') | ||
// .docker({ | ||
// ```js | ||
// const {status} = await nikita.docker.cp({ | ||
// source: 'my_container:/path/to/source', | ||
// target: writable_stream or '/path/to/target' | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Container copied: ' + status); | ||
// }); | ||
// }) | ||
// console.info(`Container was copied: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, misc, path; | ||
// ## Schema | ||
var handler, path, schema, utils; | ||
module.exports = function({options}) { | ||
var _, k, ref, source_container, source_mkdir, source_path, ssh, target_container, target_mkdir, target_path, v; | ||
this.log({ | ||
message: "Entering Docker cp", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/cp' | ||
}); | ||
// SSH connection | ||
ssh = this.ssh(options.ssh); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'source': { | ||
type: 'string', | ||
description: `The path to upload or the container followed by the path to download.` | ||
}, | ||
'target': { | ||
type: 'string', | ||
description: `The path to download or the container followed by the path to upload.` | ||
} | ||
} | ||
if (!options.source) { | ||
// Validate parameters | ||
throw Error('Missing option "source"'); | ||
} | ||
if (!options.target) { | ||
throw Error('Missing option "target"'); | ||
} | ||
[_, source_container, source_path] = /(.*:)?(.*)/.exec(options.source); | ||
[_, target_container, target_path] = /(.*:)?(.*)/.exec(options.target); | ||
}, | ||
required: ['source', 'target'] | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var _, err, source_container, source_mkdir, source_path, stats, target_container, target_mkdir, target_path; | ||
[_, source_container, source_path] = /(.*:)?(.*)/.exec(config.source); | ||
[_, target_container, target_path] = /(.*:)?(.*)/.exec(config.target); | ||
if (source_container && target_container) { | ||
throw Error('Incompatible source and target options'); | ||
throw Error('Incompatible source and target config'); | ||
} | ||
if (!source_container && !target_container) { | ||
throw Error('Incompatible source and target options'); | ||
throw Error('Incompatible source and target config'); | ||
} | ||
@@ -94,74 +73,68 @@ source_mkdir = false; | ||
// Source is on the host, normalize path | ||
this.call(function({}, callback) { | ||
if (source_container) { | ||
return callback(); | ||
} | ||
if (!source_container) { | ||
if (/\/$/.test(source_path)) { | ||
source_path = `${source_path}/${path.basename(target_path)}`; | ||
return callback(); | ||
} | ||
return this.fs.stat({ | ||
ssh: options.ssh, | ||
target: source_path | ||
}, function(err, {stats}) { | ||
if (err && err.code !== 'ENOENT') { | ||
return callback(err); | ||
try { | ||
({stats} = (await this.fs.base.stat({ | ||
ssh: config.ssh, | ||
target: source_path | ||
}))); | ||
if (utils.stats.isDirectory(stats.mode)) { | ||
source_path = `${source_path}/${path.basename(target_path)}`; | ||
} | ||
if ((err != null ? err.code : void 0) === 'ENOENT') { | ||
// TODO wdavidw: seems like a mistake to me, we shall have source_mkdir instead | ||
return target_mkdir = true && callback(); | ||
} catch (error) { | ||
err = error; | ||
if (err.code !== 'NIKITA_FS_STAT_TARGET_ENOENT') { | ||
throw err; | ||
} | ||
if (misc.stats.isDirectory(stats.mode)) { | ||
source_path = `${source_path}/${path.basename(target_path)}`; | ||
} | ||
return callback(); | ||
}); | ||
}); | ||
this.system.mkdir({ | ||
// TODO wdavidw: seems like a mistake to me, we shall have source_mkdir instead | ||
target_mkdir = true; | ||
} | ||
} | ||
await this.fs.mkdir({ | ||
target: source_path, | ||
if: function() { | ||
return source_mkdir; | ||
} | ||
if: source_mkdir | ||
}); | ||
// Destination is on the host | ||
this.call(function({}, callback) { | ||
if (target_container) { | ||
return callback(); | ||
} | ||
if (!target_container) { | ||
if (/\/$/.test(target_path)) { | ||
target_path = `${target_path}/${path.basename(target_path)}`; | ||
return callback(); | ||
} | ||
return this.fs.stat({ | ||
ssh: options.ssh, | ||
target: target_path | ||
}, function(err, {stats}) { | ||
if (err && err.code !== 'ENOENT') { | ||
return callback(err); | ||
try { | ||
({stats} = (await this.fs.base.stat({ | ||
target: target_path | ||
}))); | ||
if (utils.stats.isDirectory(stats.mode)) { | ||
target_path = `${target_path}/${path.basename(target_path)}`; | ||
} | ||
if ((err != null ? err.code : void 0) === 'ENOENT') { | ||
return target_mkdir = true && callback(); | ||
} catch (error) { | ||
err = error; | ||
if (err.code !== 'NIKITA_FS_STAT_TARGET_ENOENT') { | ||
throw err; | ||
} | ||
if (misc.stats.isDirectory(stats.mode)) { | ||
target_path = `${target_path}/${path.basename(target_path)}`; | ||
} | ||
return callback(); | ||
}); | ||
}); | ||
this.system.mkdir({ | ||
target_mkdir = true; | ||
} | ||
} | ||
await this.fs.base.mkdir({ | ||
target: target_path, | ||
if: function() { | ||
return target_mkdir; | ||
} | ||
if: target_mkdir | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, `cp ${options.source} ${options.target}`) | ||
}, docker.callback); | ||
return (await this.docker.tools.execute({ | ||
command: `cp ${config.source} ${config.target}` | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; | ||
// ## Dependencies | ||
path = require('path'); | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
misc = require('@nikitajs/core/lib/misc'); | ||
utils = require('./utils'); |
175
lib/exec.js
@@ -6,21 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `code_skipped` (int | array) | ||
// The exit code(s) to skip. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required using docker-machine. | ||
// * `service` (boolean) | ||
// if true, run container as a service, else run as a command, true by default. | ||
// * `uid` (name | uid) | ||
// Username or uid. | ||
// * `gid` (name | gid) | ||
// Groupname or gid. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -37,76 +20,106 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.exec({ | ||
// ```js | ||
// const {status} = await nikita.docker.exec({ | ||
// container: 'myContainer', | ||
// cmd: '/bin/bash -c "echo toto"' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Command executed: ' + status); | ||
// }); | ||
// command: '/bin/bash -c "echo toto"' | ||
// }) | ||
// console.info(`Command was executed: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker exec", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/exec' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container` | ||
}, | ||
'code_skipped': { | ||
oneOf: [ | ||
{ | ||
type: 'integer' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'integer' | ||
} | ||
} | ||
], | ||
description: `The exit code(s) to skip.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'service': { | ||
type: 'boolean', | ||
default: false, | ||
description: `If true, run container as a service, else run as a command, true by | ||
default.` | ||
}, | ||
'uid': { | ||
oneOf: [ | ||
{ | ||
type: 'integer' | ||
}, | ||
{ | ||
type: 'string' | ||
} | ||
], | ||
description: `Username or uid.` | ||
}, | ||
'gid': { | ||
oneOf: [ | ||
{ | ||
type: 'integer' | ||
}, | ||
{ | ||
type: 'string' | ||
} | ||
], | ||
description: `Groupname or gid.` | ||
} | ||
}, | ||
required: ['container', 'command'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var command; | ||
if (config.service == null) { | ||
config.service = false; | ||
} | ||
if (options.container == null) { | ||
// Validate parameters | ||
throw Error('Missing container'); | ||
} | ||
if (options.cmd == null) { | ||
throw Error('Missing cmd'); | ||
} | ||
if (options.service == null) { | ||
options.service = false; | ||
} | ||
// Construct exec command | ||
cmd = 'exec'; | ||
if (options.uid != null) { | ||
cmd += ` -u ${options.uid}`; | ||
if (options.gid != null) { | ||
cmd += `:${options.gid}`; | ||
command = 'exec'; | ||
if (config.uid != null) { | ||
command += ` -u ${config.uid}`; | ||
if (config.gid != null) { | ||
command += `:${config.gid}`; | ||
} | ||
} else if (options.gid != null) { | ||
this.log({ | ||
message: 'options.gid ignored unless options.uid is provided', | ||
level: 'WARN', | ||
module: 'nikita/lib/docker/exec' | ||
} else if (config.gid != null) { | ||
log({ | ||
message: 'config.gid ignored unless config.uid is provided', | ||
level: 'WARN' | ||
}); | ||
} | ||
cmd += ` ${options.container} ${options.cmd}`; | ||
delete options.cmd; | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd), | ||
code_skipped: options.code_skipped | ||
}, function() { // Note: There is no way to pass additionnal arguments in sync mode without | ||
// a callback, or we would have ', docker.callback' as next line | ||
var e; | ||
try { | ||
docker.callback.call(null, ...arguments); | ||
} catch (error) { | ||
e = error; | ||
arguments[0] = e; | ||
} | ||
return callback(...arguments); | ||
}); | ||
command += ` ${config.container} ${config.command}`; | ||
// delete config.command | ||
return (await this.docker.tools.execute({ | ||
command: command, | ||
code_skipped: config.code_skipped | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
102
lib/kill.js
@@ -9,15 +9,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `signal` (int|string) | ||
// Use a specified signal. SIGKILL by default. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -30,55 +19,60 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.kill({ | ||
// ```js | ||
// const {status} = await nikita.docker.kill({ | ||
// container: 'toto', | ||
// signal: 9 | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Container killed: ' + status); | ||
// }) | ||
// console.info(`Container was killed: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker kill", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/kill' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'signal': { | ||
oneOf: [ | ||
{ | ||
type: 'integer' | ||
}, | ||
{ | ||
type: 'string' | ||
} | ||
], | ||
description: `Use a specified signal. SIGKILL by default.` | ||
} | ||
} | ||
if (options.container == null) { | ||
// Validate parameters | ||
return callback(Error('Missing container parameter')); | ||
} | ||
cmd = 'kill'; | ||
if (options.signal != null) { | ||
cmd += ` -s ${options.signal}`; | ||
} | ||
cmd += ` ${options.container}`; | ||
this.system.execute({ | ||
cmd: docker.wrap(options, `ps | grep '${options.container}' | grep 'Up'`), | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var status; | ||
({status} = (await this.docker.tools.execute({ | ||
command: `ps | egrep ' ${config.container}$' | grep 'Up'`, | ||
code_skipped: 1 | ||
}, docker.callback); | ||
return this.system.execute({ | ||
}))); | ||
return (await this.docker.tools.execute({ | ||
if: function() { | ||
return this.status(-1); | ||
return status; | ||
}, | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
command: ['kill', config.signal != null ? `-s ${config.signal}` : void 0, `${config.container}`].join(' ') | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
271
lib/load.js
@@ -6,18 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `input` (string) | ||
// TAR archive file to read from. | ||
// * `source` (string) | ||
// Alias for the "input" option. | ||
// * `checksum` (string) | ||
// If provided, will check if attached input archive to checksum already exist, | ||
// not native to docker but implemented to get better performance. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -34,42 +20,50 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.load({ | ||
// ```js | ||
// const {status} = await nikita.docker.load({ | ||
// image: 'nikita/load_test:latest', | ||
// machine: machine, | ||
// source: source + "/nikita_load.tar" | ||
// }, function(err, {status}) { | ||
// console.log( err ? err.message : 'Container loaded: ' + status); | ||
// }) | ||
// console.info(`Image was loaded: ${status}`); | ||
// ``` | ||
// ## Source Code | ||
var docker, string, util; | ||
// ## Schema | ||
var handler, schema, utils; | ||
module.exports = function({options}, callback) { | ||
var cmd, images, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker load", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/load' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'checksum': { | ||
type: 'string', | ||
description: `If provided, will check if attached input archive to checksum already | ||
exist, not native to docker but implemented to get better performance.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'input': { | ||
type: 'string', | ||
description: `TAR archive file to read from.` | ||
}, | ||
'source': { | ||
type: 'string', | ||
description: `Alias for the "input" option.` | ||
} | ||
} | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var command, i, image, images, infos, j, k, len, len1, new_image, new_images, new_k, ref, ref1, status, stderr, stdout; | ||
// Validate parameters | ||
if (options.input == null) { | ||
options.input = options.source; | ||
if (config.input == null) { | ||
config.input = config.source; | ||
} | ||
if (options.input == null) { | ||
return callback(Error('Missing input parameter')); | ||
if (config.input == null) { | ||
throw Error('Missing input parameter'); | ||
} | ||
cmd = `load -i ${options.input}`; | ||
command = `load -i ${config.input}`; | ||
// need to records the list of image to see if status is modified or not after load | ||
@@ -79,122 +73,111 @@ // for this we print the existing images as REPOSITORY:TAG:IMAGE | ||
images = {}; | ||
delete options.cmd; | ||
this.log({ | ||
delete config.command; | ||
log({ | ||
message: 'Storing previous state of image', | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
level: 'INFO' | ||
}); | ||
if (options.checksum == null) { | ||
this.log({ | ||
if (config.checksum == null) { | ||
log({ | ||
message: 'No checksum provided', | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
level: 'INFO' | ||
}); | ||
} | ||
if (options.checksum) { | ||
this.log({ | ||
message: `Checksum provided :${options.checksum}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
if (config.checksum) { | ||
log({ | ||
message: `Checksum provided :${config.checksum}`, | ||
level: 'INFO' | ||
}); | ||
} | ||
if (options.checksum == null) { | ||
options.checksum = ''; | ||
if (config.checksum == null) { | ||
config.checksum = ''; | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, " images | grep -v '<none>' | awk '{ print $1\":\"$2\":\"$3 }'") | ||
}, (err, {stdout}) => { | ||
var i, image, infos, len, ref1; | ||
if (err) { | ||
return callback(err); | ||
} | ||
// skip header line, wi skip it here instead of in the grep to have | ||
// an array with at least one not empty line | ||
if (string.lines(stdout).length > 1) { | ||
ref1 = string.lines(stdout); | ||
for (i = 0, len = ref1.length; i < len; i++) { | ||
image = ref1[i]; | ||
image = image.trim(); | ||
if (image !== '') { | ||
infos = image.split(':'); | ||
if (infos[2] === options.checksum) { | ||
// if image is here we skip | ||
this.log({ | ||
message: `Image already exist checksum :${options.checksum}, repo:tag ${`${infos[0]}:${infos[1]}`}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
}); | ||
} | ||
if (infos[2] === options.checksum) { | ||
return callback(null, false); | ||
} | ||
images[`${infos[0]}:${infos[1]}`] = `${infos[2]}`; | ||
({stdout} = (await this.docker.tools.execute({ | ||
command: "images | grep -v '<none>' | awk '{ print $1\":\"$2\":\"$3 }'" | ||
}))); | ||
// skip header line, wi skip it here instead of in the grep to have | ||
// an array with at least one not empty line | ||
if (utils.string.lines(stdout).length > 1) { | ||
ref = utils.string.lines(stdout); | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
image = ref[i]; | ||
image = image.trim(); | ||
if (image !== '') { | ||
infos = image.split(':'); | ||
if (infos[2] === config.checksum) { | ||
// if image is here we skip | ||
log({ | ||
message: `Image already exist checksum :${config.checksum}, repo:tag \"${infos[0]}:${infos[1]}\"`, | ||
level: 'INFO' | ||
}); | ||
} | ||
if (infos[2] === config.checksum) { | ||
return false; | ||
} | ||
images[`${infos[0]}:${infos[1]}`] = `${infos[2]}`; | ||
} | ||
} | ||
this.log({ | ||
message: `Start Loading ${options.input} `, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
}); | ||
this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, 'images | grep -v \'<none>\' | awk \'{ print $1":"$2":"$3 }\'') | ||
}, function(err, {stdout, stderr}) { | ||
var j, len1, new_image, new_images, new_k, ref2, status; | ||
if (err) { | ||
return callback(err); | ||
} | ||
log({ | ||
message: `Start Loading ${config.input} `, | ||
level: 'INFO' | ||
}); | ||
await this.docker.tools.execute({ | ||
command: command | ||
}); | ||
({stdout, stderr} = (await this.docker.tools.execute({ | ||
command: 'images | grep -v \'<none>\' | awk \'{ print $1":"$2":"$3 }\'' | ||
}))); | ||
new_images = {}; | ||
status = false; | ||
log({ | ||
message: 'Comparing new images', | ||
level: 'INFO' | ||
}); | ||
if (utils.string.lines(stdout).length > 1) { | ||
ref1 = utils.string.lines(stdout.toString()); | ||
for (j = 0, len1 = ref1.length; j < len1; j++) { | ||
image = ref1[j]; | ||
if (image !== '') { | ||
infos = image.split(':'); | ||
new_images[`${infos[0]}:${infos[1]}`] = `${infos[2]}`; | ||
} | ||
new_images = {}; | ||
status = false; | ||
this.log({ | ||
message: 'Comparing new images', | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
}); | ||
if (string.lines(stdout).length > 1) { | ||
ref2 = string.lines(stdout.toString()); | ||
for (j = 0, len1 = ref2.length; j < len1; j++) { | ||
image = ref2[j]; | ||
if (image !== '') { | ||
infos = image.split(':'); | ||
new_images[`${infos[0]}:${infos[1]}`] = `${infos[2]}`; | ||
} | ||
} | ||
} | ||
for (new_k in new_images) { | ||
new_image = new_images[new_k]; | ||
if (images[new_k] == null) { | ||
} | ||
} | ||
for (new_k in new_images) { | ||
new_image = new_images[new_k]; | ||
if (images[new_k] == null) { | ||
status = true; | ||
break; | ||
} else { | ||
for (k in images) { | ||
image = images[k]; | ||
if (image !== new_image && new_k === k) { | ||
status = true; | ||
log({ | ||
message: 'Identical images', | ||
level: 'INFO' | ||
}); | ||
break; | ||
} else { | ||
for (k in images) { | ||
image = images[k]; | ||
if (image !== new_image && new_k === k) { | ||
status = true; | ||
this.log({ | ||
message: 'Identical images', | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/load' | ||
}); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return callback(err, { | ||
status: status, | ||
stdout: stdout, | ||
stderr: stderr | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
return { | ||
status: status, | ||
stdout: stdout, | ||
stderr: stderr | ||
}; | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
string = require('@nikitajs/core/lib/misc/string'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; | ||
util = require('util'); | ||
// ## Dependencies | ||
utils = require('./utils'); |
113
lib/login.js
@@ -6,79 +6,64 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `registry` (string) | ||
// Address of the registry server. "https://index.docker.io/v1/" by default | ||
// * `machine` (string) | ||
// Name of the docker-machine, require if using docker-machine | ||
// * `email` (string) | ||
// * `user` (string) | ||
// Username | ||
// * `password` (string) | ||
// Remove intermediate containers after build. Default to false | ||
// * `cwd` (string) | ||
// change the working directory for the build. | ||
// ## Callback parameters | ||
// * `err` | ||
// Error object if any. | ||
// * `status` | ||
// True when the command was executed successfully. | ||
// True when the command was executed successfully. | ||
// * `stdout` | ||
// Stdout value(s) unless `stdout` option is provided. | ||
// Stdout value(s) unless `stdout` option is provided. | ||
// * `stderr` | ||
// Stderr value(s) unless `stderr` option is provided. | ||
// Stderr value(s) unless `stderr` option is provided. | ||
// ## Source Code | ||
var docker, path, util; | ||
// ## Schema | ||
var handler, schema, utils; | ||
module.exports = function({options}, callback) { | ||
var cmd, i, k, len, opt, ref, ref1, v; | ||
this.log({ | ||
message: "Entering Docker login", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/login' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'email': { | ||
type: 'string', | ||
description: `User email.` | ||
}, | ||
'password': { | ||
type: 'string', | ||
description: `User password.` | ||
}, | ||
'user': { | ||
type: 'string', | ||
description: `Username of the user.` | ||
} | ||
} | ||
if (options.image == null) { | ||
// Validate parameters and madatory conditions | ||
return callback(Error('Missing image parameter')); | ||
} | ||
if ((options.content != null) && (options.dockerfile != null)) { | ||
return callback(Error('Can not build from Dockerfile and content')); | ||
} | ||
cmd = 'login'; | ||
ref1 = ['email', 'user', 'password']; | ||
for (i = 0, len = ref1.length; i < len; i++) { | ||
opt = ref1[i]; | ||
if (options[opt] != null) { | ||
cmd += ` -${opt.charAt(0)} ${options[opt]}`; | ||
} | ||
} | ||
if (options.registry != null) { | ||
cmd += ` \"${options.registry}\"`; | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Handler | ||
handler = async function({config}) { | ||
return (await this.docker.tools.execute({ | ||
command: [ | ||
'login', | ||
...(['email', | ||
'user', | ||
'password'].filter(function(opt) { | ||
return config[opt] != null; | ||
}).map(function(opt) { | ||
return `-${opt.charAt(0)} ${config[opt]}`; | ||
})), | ||
config.registry != null ? `${utils.string.escapeshellarg(config.registry)}` : void 0 | ||
].join(' ') | ||
})); | ||
}; | ||
path = require('path'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; | ||
util = require('util'); | ||
// ## Dependencies | ||
utils = require('./utils'); |
@@ -6,18 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `registry` (string) | ||
// Address of the registry server, default to "https://index.docker.io/v1/". | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -28,40 +14,45 @@ // Error object if any. | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema, utils; | ||
module.exports = function({options}, callback) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker logout", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/logout' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'registry': { | ||
type: 'string', | ||
description: `Address of the registry server, default to "https://index.docker.io/v1/".` | ||
} | ||
} | ||
if (options.container == null) { | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var command; | ||
if (config.container == null) { | ||
// Validate parameters | ||
return callback(Error('Missing container parameter')); | ||
} | ||
// rm is false by default only if options.service is true | ||
cmd = 'logout'; | ||
if (options.registry != null) { | ||
cmd += ` \"${options.registry}\"`; | ||
// rm is false by default only if config.service is true | ||
command = 'logout'; | ||
if (config.registry != null) { | ||
command += ` \"${config.registry}\"`; | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
return (await this.execute({ | ||
command: utils.wrap(config, command) | ||
}, docker.callback)); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; | ||
util = require('util'); | ||
// ## Dependencies | ||
utils = require('./utils'); |
@@ -6,18 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -30,44 +16,40 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.pause({ | ||
// ```js | ||
// const {status} = await nikita.docker.pause({ | ||
// container: 'toto' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container paused: ' + status); | ||
// }) | ||
// console.info(`Container was paused: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var k, ref, v; | ||
this.log({ | ||
message: "Entering Docker pause", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/pause' | ||
}); | ||
// Global parameters | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
} | ||
} | ||
if (options.container == null) { | ||
// Validate parameters | ||
return callback(Error('Missing container parameter')); | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, `pause ${options.container}`) | ||
}, docker.callback); | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Handler | ||
handler = async function({config}) { | ||
return (await this.docker.tools.execute({ | ||
command: `pause ${config.container}` | ||
})); | ||
}; | ||
util = require('util'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
127
lib/pull.js
// Generated by CoffeeScript 2.5.1 | ||
// # `nikita.docker.pull` | ||
// Pull a container | ||
// Pull an image or a repository from a registry. | ||
// ## Options | ||
// ## Output | ||
// * `tag` (string) | ||
// Name of the tag to pull. | ||
// * `version` (string) | ||
// Version of the tag to control. Default to `latest`. | ||
// * `code_skipped` (string) | ||
// The exit code to skip if different from 0. | ||
// * `all` (Boolean) | ||
// Download all tagged images in the repository. Default to false. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -30,67 +19,69 @@ // Error object if any. | ||
// 1- builds an image from dockerfile without any resourcess | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.pull({ | ||
// tag: 'postgresql' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container pulled: ' + status); | ||
// ```js | ||
// const {status} = await nikita.docker.pull({ | ||
// image: 'postgresql' | ||
// }) | ||
// console.info(`Image was pulled: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var cmd, cmd_images, k, ref, v, version; | ||
this.log({ | ||
message: "Entering Docker pull", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/pull' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'all': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Pull all tagged images in the repository.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'image': { | ||
type: 'string', | ||
description: `Name of an image or a repository to pull. It can contain \`tag\`.` | ||
}, | ||
'tag': { | ||
type: 'string', | ||
description: `Specific image tag within a repository to pull. Default to \`latest\`.` | ||
} | ||
} | ||
// Validate parameters | ||
version = options.version || options.tag.split(':')[1] || 'latest'; | ||
delete options.version; // present in misc.docker.options, will probably disappear at some point | ||
if (options.all == null) { | ||
options.all = false; | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var name, status, tag; | ||
// Validate | ||
[name, tag] = config.image.split(':'); | ||
config.image = name; | ||
if (tag && config.tag) { | ||
// it can be later changed to give a preference instead of error | ||
throw Error('Tag must be specified either in the image or in the tag config'); | ||
} | ||
cmd_images = 'images'; | ||
cmd_images += ` | grep '${options.tag}'`; | ||
if (!options.all) { | ||
cmd_images += ` | grep '${version}'`; | ||
if (config.tag == null) { | ||
config.tag = tag || 'latest'; | ||
} | ||
if (options.tag == null) { | ||
throw Error('Missing Tag Name'); | ||
} | ||
// rm is false by default only if options.service is true | ||
cmd = 'pull'; | ||
cmd += options.all ? ` -a ${options.tag}` : ` ${options.tag}:${version}`; | ||
this.system.execute({ | ||
cmd: docker.wrap(options, cmd_images), | ||
// Check if exist | ||
({status} = (await this.docker.tools.execute({ | ||
// avoid checking when all config is true, | ||
// because there is no native way to list all existing tags on the registry | ||
unless: config.all, | ||
command: ['images', `| grep '${config.image}'`, `| grep '${config.tag}'`].join(' '), | ||
code_skipped: 1 | ||
}); | ||
return this.system.execute({ | ||
unless: function() { | ||
return this.status(-1); | ||
}, | ||
cmd: docker.wrap(options, cmd), | ||
code_skipped: options.code_skipped | ||
}, callback); | ||
}))); | ||
// Pull image | ||
return (await this.docker.tools.execute({ | ||
unless: status, | ||
command: ['pull', config.all ? `-a ${config.image}` : `${config.image}:${config.tag}`].join(' ') | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
util = require('util'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
// Generated by CoffeeScript 2.5.1 | ||
// Registration of `nikita.docker` actions | ||
var registry; | ||
//# Dependency | ||
var register; | ||
require('@nikitajs/file/lib/register'); | ||
({register} = require('@nikitajs/core/lib/registry')); | ||
// require '@nikitajs/network/lib/register' | ||
registry = require('@nikitajs/core/lib/registry'); | ||
//# Action registration | ||
register(module.exports = { | ||
module.exports = { | ||
docker: { | ||
build: '@nikitajs/docker/lib/build', | ||
checksum: '@nikitajs/docker/lib/checksum', | ||
compose: { | ||
@@ -20,2 +19,3 @@ '': '@nikitajs/docker/lib/compose', | ||
exec: '@nikitajs/docker/lib/exec', | ||
inspect: '@nikitajs/docker/lib/inspect', | ||
kill: '@nikitajs/docker/lib/kill', | ||
@@ -30,7 +30,12 @@ load: '@nikitajs/docker/lib/load', | ||
save: '@nikitajs/docker/lib/save', | ||
service: '@nikitajs/docker/lib/service', | ||
// service: '@nikitajs/docker/lib/service' | ||
start: '@nikitajs/docker/lib/start', | ||
status: '@nikitajs/docker/lib/status', | ||
stop: '@nikitajs/docker/lib/stop', | ||
unpause: '@nikitajs/docker/lib/unpause', | ||
tools: { | ||
checksum: '@nikitajs/docker/lib/tools/checksum', | ||
execute: '@nikitajs/docker/lib/tools/execute', | ||
service: '@nikitajs/docker/lib/tools/service', | ||
status: '@nikitajs/docker/lib/tools/status' | ||
}, | ||
// unpause: '@nikitajs/docker/lib/unpause' | ||
volume_create: '@nikitajs/docker/lib/volume_create', | ||
@@ -40,2 +45,13 @@ volume_rm: '@nikitajs/docker/lib/volume_rm', | ||
} | ||
}); | ||
}; | ||
(async function() { | ||
var err; | ||
try { | ||
return (await registry.register(module.exports)); | ||
} catch (error) { | ||
err = error; | ||
console.error(err.stack); | ||
return process.exit(1); | ||
} | ||
})(); |
// Generated by CoffeeScript 2.5.1 | ||
// # `nikita.docker.start` | ||
// # `nikita.docker.restart` | ||
// Start stopped containers or restart (stop + starts) a started container. | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine | ||
// * `timeout` (int) | ||
// Seconds to wait for stop before killing it | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -31,49 +15,44 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.restart({ | ||
// ```js | ||
// const {status} = await nikita.docker.restart({ | ||
// container: 'toto' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container restarted: ' + status); | ||
// }) | ||
// console.info(`Container was started or restarted: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker restart", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/restart' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'timeout': { | ||
type: 'integer', | ||
description: `Seconds to wait for stop before killing it.` | ||
} | ||
} | ||
if (options.container == null) { | ||
// Validate parameters | ||
return callback(Error('Missing container parameter')); | ||
} | ||
cmd = 'restart'; | ||
if (options.timeout != null) { | ||
cmd += ` -t ${options.timeout}`; | ||
} | ||
cmd += ` ${options.container}`; | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Handler | ||
handler = async function({config}) { | ||
return (await this.docker.tools.execute({ | ||
command: ['restart', config.timeout != null ? `-t ${config.timeout}` : void 0, `${config.container}`].join(' ') | ||
})); | ||
}; | ||
util = require('util'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
147
lib/rm.js
@@ -7,19 +7,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if docker-machine installed. | ||
// * `link` (boolean) | ||
// Remove the specified link. | ||
// * `volumes` (boolean) | ||
// Remove the volumes associated with the container. | ||
// * `force` (boolean) | ||
// Force the removal of a running container (uses SIGKILL). | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -32,72 +17,80 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.rm({ | ||
// ```js | ||
// const {status} = await nikita.docker.rm({ | ||
// container: 'toto' | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Container removed: ' + status); | ||
// }) | ||
// console.info(`Container was removed: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, opt, ref, v; | ||
this.log({ | ||
message: "Entering Docker rm", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/rm' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'link': { | ||
type: 'boolean', | ||
description: `Remove the specified link.` | ||
}, | ||
'volumes': { | ||
type: 'boolean', | ||
description: `Remove the volumes associated with the container.` | ||
}, | ||
'force': { | ||
type: 'boolean', | ||
description: `Force the removal of a running container (uses SIGKILL).` | ||
} | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var exists, running; | ||
({ | ||
status: exists, | ||
data: running | ||
} = (await this.docker.tools.execute({ | ||
metadata: { | ||
templated: false | ||
}, | ||
command: `inspect ${config.container} --format '{{ json .State.Running }}'`, | ||
code_skipped: 1, | ||
format: 'json' | ||
}))); | ||
if (!exists) { | ||
return false; | ||
} | ||
if (options.container == null) { | ||
// Validate parameters and madatory conditions | ||
return callback(Error('Missing container parameter')); | ||
if (running && !config.force) { | ||
throw Error('Container must be stopped to be removed without force'); | ||
} | ||
cmd = (function() { | ||
var i, len, ref1, results; | ||
ref1 = ['link', 'volumes', 'force']; | ||
results = []; | ||
for (i = 0, len = ref1.length; i < len; i++) { | ||
opt = ref1[i]; | ||
if (options[opt]) { | ||
results.push(`-${opt.charAt(0)}`); | ||
} else { | ||
results.push(void 0); | ||
} | ||
} | ||
return results; | ||
})(); | ||
cmd = `rm ${cmd.join(' ')} ${options.container}`; | ||
this.system.execute({ | ||
cmd: docker.wrap(options, `ps | grep '${options.container}'`), | ||
code_skipped: 1 | ||
}, (err, {status}) => { | ||
if (status && !options.force) { | ||
throw Error('Container must be stopped to be removed without force', null); | ||
} | ||
}); | ||
this.system.execute({ | ||
cmd: docker.wrap(options, `ps -a | grep '${options.container}'`), | ||
code_skipped: 1 | ||
}, docker.callback); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd), | ||
if: function() { | ||
return this.status(-1); | ||
} | ||
}, docker.callback); | ||
return (await this.docker.tools.execute({ | ||
command: [ | ||
'rm', | ||
...(['link', | ||
'volumes', | ||
'force'].filter(function(opt) { | ||
return config[opt]; | ||
}).map(function(opt) { | ||
return `-${opt.charAt(0)}`; | ||
})), | ||
config.container | ||
].join(' ') | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
132
lib/rmi.js
@@ -7,15 +7,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `image` (string) | ||
// Name of the image, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if docker-machine installed. | ||
// * `no_prune` (boolean) | ||
// Do not delete untagged parents. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -26,59 +15,74 @@ // Error object if any. | ||
// ## Source Code | ||
var docker, util; | ||
// ## Hook | ||
var handler, on_action, schema; | ||
module.exports = function({options}) { | ||
var cmd_images, cmd_rmi, i, k, len, opt, ref, ref1, v; | ||
this.log({ | ||
message: "Entering Docker rmi", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/rmi' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
on_action = function({config, metadata}) { | ||
if (metadata.argument != null) { | ||
return config.image = metadata.argument; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
}; | ||
// ## Schema | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
// ...docker.wrap_schema | ||
'cwd': { | ||
type: 'string', | ||
description: `Change the build working directory.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'image': { | ||
type: 'string', | ||
description: `Name of the Docker image present in the registry.` | ||
}, | ||
'no_prune': { | ||
type: 'boolean', | ||
description: `Do not delete untagged parents.` | ||
}, | ||
'tag': { | ||
type: 'string', | ||
description: `Tag of the Docker image, default to latest.` | ||
} | ||
} | ||
if (options.image == null) { | ||
// Validate parameters and madatory conditions | ||
throw Error('Missing image parameter'); | ||
} | ||
cmd_images = 'images'; | ||
cmd_images += ` | grep '${options.image} '`; | ||
if (options.tag != null) { | ||
cmd_images += ` | grep ' ${options.tag} '`; | ||
} | ||
cmd_rmi = 'rmi'; | ||
ref1 = ['force', 'no_prune']; | ||
for (i = 0, len = ref1.length; i < len; i++) { | ||
opt = ref1[i]; | ||
if (options[opt] != null) { | ||
cmd_rmi += ` --${opt.replace('_', '-')}`; | ||
}, | ||
required: ['image'] | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
await this.docker.tools.execute({ | ||
command: ['images', `| grep '${config.image} '`, config.tag != null ? `| grep ' ${config.tag} '` : void 0].join(' '), | ||
code_skipped: [1] | ||
}); | ||
return (await this.docker.tools.execute({ | ||
command: [ | ||
'rmi', | ||
['force', | ||
'no_prune'].filter(function(opt) { | ||
return config[opt] != null; | ||
}).map(function(opt) { | ||
return ` --${opt.replace('_', | ||
'-')}`; | ||
}), | ||
` ${config.image}`, | ||
config.tag != null ? `:${config.tag}` : void 0 | ||
].join(''), | ||
if: function({parent}) { | ||
return parent.parent.tools.status(-1); | ||
} | ||
})); | ||
}; | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
hooks: { | ||
on_action: on_action | ||
}, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
cmd_rmi += ` ${options.image}`; | ||
if (options.tag != null) { | ||
cmd_rmi += `:${options.tag}`; | ||
} | ||
this.system.execute({ | ||
cmd: docker.wrap(options, cmd_images), | ||
code_skipped: 1 | ||
}, docker.callback); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd_rmi), | ||
if: function() { | ||
return this.status(-1); | ||
} | ||
}, docker.callback); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
util = require('util'); |
571
lib/run.js
@@ -6,83 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Alias of name. | ||
// * `name` (string) | ||
// Assign a name to the container to run. | ||
// * `image` (string) | ||
// Name/ID of base image, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `cmd` (string) | ||
// Overwrite the default ENTRYPOINT of the image, equivalent to | ||
// `--entrypoint docker parameter` | ||
// * `hostname` (string) | ||
// Hostname in the docker container. | ||
// * `port` ( 'int:int' | [] ) | ||
// Port mapping. | ||
// * `volume` ( 'path:path' | [] ) | ||
// Path mapping. | ||
// * `device` ('path' | [] ) | ||
// Send host device(s) to container. | ||
// * `dns` (ip-address | [] ) | ||
// Set custom DNS server(s). | ||
// * `dns_search` (ip-address | [] ) | ||
// Set custom DNS search domain(s). | ||
// * `expose` ( int | string | [] ) | ||
// Export port(s). | ||
// * `link` ( containerName | containerID | [] ) | ||
// Link to other container(s). | ||
// * `label` (string | [] ) | ||
// Set meta data on a container. | ||
// * `label_file` (path) | ||
// Read in a line delimited file of labels. | ||
// * `add_host` ('host:ip' | [] ) | ||
// Add a custom host-to-IP mapping (host:ip). | ||
// * `cap_add` ( | [] ) | ||
// Add Linux Capabilities. | ||
// * `cap_drop` ( | [] ) | ||
// Drop Linux Capabilities. | ||
// * `blkio_weight` (int) | ||
// Block IO (relative weight), between 10 and 1000. | ||
// * `cgroup_parent` | ||
// Optional parent cgroup for the container. | ||
// * `cid_file` ( path ) | ||
// Write the container ID to the file. | ||
// * `cpuset_cpus` (string) | ||
// CPUs in which to allow execution (ex: 0-3 0,1 ...). | ||
// * `entrypoint` () | ||
// Overwrite the default ENTRYPOINT of the image. | ||
// * `ipc` () | ||
// IPC namespace to use. | ||
// * `ulimit` ( | [] ) | ||
// Ulimit options. | ||
// * `volumes_from` (containerName | containerID | [] ) | ||
// Mount volumes from the specified container(s). | ||
// * `detach` (boolean) | ||
// if true, run container in background. | ||
// * `env` ('VAR=value' | [] ) | ||
// Environment variables for the container.. | ||
// * `env_file` ( path | [] ) | ||
// Read in a file of environment variables. | ||
// * `rm` (boolean) | ||
// Delete the container when it ends. True by default. | ||
// * `cwd` (path) | ||
// Working directory of container. | ||
// * `net` (string) | ||
// Set the Network mode for the container. | ||
// * `pid` (string) | ||
// PID namespace to use. | ||
// * `publish_all` (boolean) | ||
// Publish all exposed ports to random ports. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0.. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -99,5 +20,4 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker({ | ||
// ```js | ||
// const {status} = await nikita.docker.run({ | ||
// ssh: ssh | ||
@@ -108,48 +28,338 @@ // name: 'myContainer' | ||
// entrypoint: '/bin/true' | ||
// }, function(err, status, stdout, stderr){ | ||
// console.log( err ? err.message : 'Container state changed to running: ' + status); | ||
// }) | ||
// console.info(`Container was run: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Hooks | ||
var handler, on_action, schema; | ||
module.exports = function({options}, callback) { | ||
var cmd, flag, i, k, len, opt, p, ref, ref1, ref2, ref3, ref4, ref5, v; | ||
this.log({ | ||
message: "Entering Docker run", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/run' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
on_action = function({config}) { | ||
// throw Error 'Property "container" no longer exists' if config.container | ||
// config.name = config.container if not config.name? and config.container? | ||
if (config.name == null) { | ||
config.name = config.container; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
if (typeof config.expose === 'string') { | ||
return config.expose = parseInt(config.expose); | ||
} | ||
}; | ||
// ## Schema | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'add_host': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Add a custom host-to-IP mapping (host:ip) in the form of \`host:ip\`.` | ||
}, | ||
'blkio_weight': { | ||
type: 'integer', | ||
description: `Block IO (relative weight), between 10 and 1000.` | ||
}, | ||
'cap_add': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Add Linux Capabilities.` | ||
}, | ||
'cap_drop': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Drop Linux Capabilities.` | ||
}, | ||
'cgroup_parent': { | ||
type: 'string', | ||
description: `Optional parent cgroup for the container.` | ||
}, | ||
'cid_file': { | ||
type: 'string', | ||
description: `Write the container ID to the file.` | ||
}, | ||
'container': { | ||
type: 'string', | ||
description: `Alias of name.` | ||
}, | ||
'cpuset_cpus': { | ||
type: 'string', | ||
description: `CPUs in which to allow execution (ex: 0-3 0,1 ...).` | ||
}, | ||
'cwd': { | ||
type: 'string', | ||
description: `Working directory of container.` | ||
}, | ||
'detach': { | ||
type: 'boolean', | ||
description: `if true, run container in background.` | ||
}, | ||
'device': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Send host device(s) to container.` | ||
}, | ||
'dns': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Set custom DNS server(s).` | ||
}, | ||
'dns_search': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Set custom DNS search domain(s).` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'entrypoint': { | ||
type: 'string', | ||
description: `Overwrite the default ENTRYPOINT of the image, equivalent to | ||
\`--entrypoint docker parameter\`` | ||
}, | ||
'env': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Environment variables for the container in the form of \`VAR=value\`.` | ||
}, | ||
'env_file': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Read in a file of environment variables.` | ||
}, | ||
'expose': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Export port(s).` | ||
}, | ||
'hostname': { | ||
type: 'string', | ||
description: `Hostname in the docker container.` | ||
}, | ||
'image': { | ||
type: 'string', | ||
description: `Name/ID of base image.` | ||
}, | ||
'ipc': { | ||
type: 'string', | ||
description: `IPC namespace to use.` | ||
}, | ||
'label': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Set meta data on a container.` | ||
}, | ||
'label_file': { | ||
type: 'string', | ||
description: `Path to read in a line delimited file of labels.` | ||
}, | ||
'link': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Link to other container(s) in the form of a container name or a | ||
container ID.` | ||
}, | ||
'name': { | ||
type: 'string', | ||
description: `Assign a name to the container to run.` | ||
}, | ||
'net': { | ||
type: 'string', | ||
description: `Set the Network mode for the container.` | ||
}, | ||
'port': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Port mapping in the form of \`int:int\`.` | ||
}, | ||
'pid': { | ||
type: 'string', | ||
description: `PID namespace to use.` | ||
}, | ||
'publish_all': { | ||
type: 'boolean', | ||
description: `Publish all exposed ports to random ports.` | ||
}, | ||
'rm': { | ||
type: 'boolean', | ||
default: true, | ||
description: `Delete the container when it ends. True by default.` | ||
}, | ||
'ulimit': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'integer' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'integer' | ||
} | ||
] | ||
} | ||
} | ||
], | ||
description: `Ulimit options.` | ||
}, | ||
'volume': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Volume mapping, in the form of \`path:path\`.` | ||
}, | ||
'volumes_from': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Mount volumes from the specified container(s).` | ||
} | ||
} | ||
if (options.image == null) { | ||
}, | ||
required: ['image'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var command, flag, i, len, opt, p, ref, ref1, ref2, ref3, ref4, result, status; | ||
if (!((config.name != null) || config.rm)) { | ||
// Validate parameters | ||
return callback(Error('Missing image')); | ||
} | ||
if (options.rm == null) { | ||
options.rm = true; | ||
} | ||
if (options.name == null) { | ||
options.name = options.container; | ||
} | ||
if (!((options.name != null) || options.rm)) { | ||
this.log({ | ||
log({ | ||
message: "Should specify a container name if rm is false", | ||
level: 'WARN', | ||
module: 'nikita/docker/run' | ||
level: 'WARN' | ||
}); | ||
} | ||
// Construct exec command | ||
cmd = 'run'; | ||
ref1 = { | ||
command = 'run'; | ||
ref = { | ||
name: '--name', | ||
@@ -172,13 +382,13 @@ hostname: '-h', | ||
}; | ||
// Classic options | ||
for (opt in ref1) { | ||
flag = ref1[opt]; | ||
if (options[opt] != null) { | ||
cmd += ` ${flag} ${options[opt]}`; | ||
// Classic config | ||
for (opt in ref) { | ||
flag = ref[opt]; | ||
if (config[opt] != null) { | ||
command += ` ${flag} ${config[opt]}`; | ||
} | ||
} | ||
if (options.detach) { // else ' -t' | ||
cmd += ' -d'; | ||
if (config.detach) { // else ' -t' | ||
command += ' -d'; | ||
} | ||
ref2 = { | ||
ref1 = { | ||
rm: '--rm', | ||
@@ -189,10 +399,10 @@ publish_all: '-P', | ||
}; | ||
// Flag options | ||
for (opt in ref2) { | ||
flag = ref2[opt]; | ||
if (options[opt]) { | ||
cmd += ` ${flag}`; | ||
// Flag config | ||
for (opt in ref1) { | ||
flag = ref1[opt]; | ||
if (config[opt]) { | ||
command += ` ${flag}`; | ||
} | ||
} | ||
ref3 = { | ||
ref2 = { | ||
port: '-p', | ||
@@ -214,14 +424,14 @@ volume: '-v', | ||
}; | ||
// Arrays Options | ||
for (opt in ref3) { | ||
flag = ref3[opt]; | ||
if (options[opt] != null) { | ||
if (typeof options[opt] === 'string' || typeof options[opt] === 'number') { | ||
cmd += ` ${flag} ${options[opt]}`; | ||
} else if (Array.isArray(options[opt])) { | ||
ref4 = options[opt]; | ||
for (i = 0, len = ref4.length; i < len; i++) { | ||
p = ref4[i]; | ||
if ((ref5 = typeof p) === 'string' || ref5 === 'number') { | ||
cmd += ` ${flag} ${p}`; | ||
// Arrays config | ||
for (opt in ref2) { | ||
flag = ref2[opt]; | ||
if (config[opt] != null) { | ||
if (typeof config[opt] === 'string' || typeof config[opt] === 'number') { | ||
command += ` ${flag} ${config[opt]}`; | ||
} else if (Array.isArray(config[opt])) { | ||
ref3 = config[opt]; | ||
for (i = 0, len = ref3.length; i < len; i++) { | ||
p = ref3[i]; | ||
if ((ref4 = typeof p) === 'string' || ref4 === 'number') { | ||
command += ` ${flag} ${p}`; | ||
} else { | ||
@@ -236,42 +446,47 @@ callback(Error(`Invalid parameter, '${opt}' array should only contains string or number`)); | ||
} | ||
cmd += ` ${options.image}`; | ||
if (options.cmd) { | ||
cmd += ` ${options.cmd}`; | ||
command += ` ${config.image}`; | ||
if (config.command) { | ||
command += ` ${config.command}`; | ||
} | ||
// need to delete the cmd options or it will be used in docker.exec | ||
delete options.cmd; | ||
this.system.execute({ | ||
if: options.name != null, | ||
cmd: docker.wrap(options, `ps -a | grep '${options.name}'`), | ||
// need to delete the command config or it will be used in docker.exec | ||
// delete config.command | ||
({status} = (await this.docker.tools.execute({ | ||
if: config.name != null, | ||
command: `ps -a | egrep ' ${config.name}$'`, | ||
code_skipped: 1, | ||
shy: true | ||
}, function(err, {status}) { | ||
docker.callback(...arguments); | ||
if (status) { | ||
return this.log({ | ||
message: "Container already running. Skipping", | ||
level: 'INFO', | ||
module: 'nikita/docker/run' | ||
}); | ||
metadata: { | ||
shy: true | ||
} | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd), | ||
}))); | ||
if (status) { | ||
log({ | ||
message: "Container already running. Skipping", | ||
level: 'INFO' | ||
}); | ||
} | ||
result = (await this.docker.tools.execute({ | ||
command: command, | ||
if: function() { | ||
return (options.name == null) || this.status(-1) === false; | ||
return (config.name == null) || status === false; | ||
} | ||
}, function(err, {status}) { | ||
docker.callback(...arguments); | ||
if (status) { | ||
this.log({ | ||
message: "Container now running", | ||
level: 'WARN', | ||
module: 'nikita/docker/run' | ||
}); | ||
} | ||
return callback(...arguments); | ||
}); | ||
})); | ||
if (result.status) { | ||
log({ | ||
message: "Container now running", | ||
level: 'WARN' | ||
}); | ||
} | ||
return result; | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
hooks: { | ||
on_action: on_action | ||
}, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
134
lib/save.js
@@ -6,24 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `image` (string) | ||
// Name/ID of base image, required. | ||
// * `tag` (string) | ||
// Tag of the image. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `output` (string). | ||
// TAR archive output path, required. | ||
// * `target` (string). | ||
// Shortcut for "output" option, required. | ||
// * `code` (int | array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -40,63 +20,69 @@ // Error object if any. | ||
// ```javascript | ||
// nikita.docker({ | ||
// ssh: ssh | ||
// output: 'test-image.tar' | ||
// image: 'test-image' | ||
// compression: 'gzip' | ||
// entrypoint: '/bin/true' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container saved: ' + status); | ||
// ```js | ||
// const {status} = await nikita.docker.save({ | ||
// image: 'nikita/load_test:latest', | ||
// output: `${scratch}/nikita_saved.tar`, | ||
// }) | ||
// console.info(`Container was saved: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Hooks | ||
var handler, on_action, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker save", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/save' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
on_action = function({config}) { | ||
return config.output != null ? config.output : config.output = config.target; | ||
}; | ||
// ## Schema | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'image': { | ||
type: 'string', | ||
description: `Name/ID of base image.` | ||
}, | ||
'tag': { | ||
type: 'string', | ||
description: `Tag of the image.` | ||
}, | ||
'output': { | ||
type: 'string', | ||
description: `TAR archive output path.` | ||
}, | ||
'target': { | ||
type: 'string', | ||
description: `Shortcut for "output" option, required.` | ||
} | ||
} | ||
if (options.image == null) { | ||
// Validate parameters | ||
throw Error('Missing image parameter'); | ||
} | ||
if (options.output == null) { | ||
options.output = options.target; | ||
} | ||
if (options.output == null) { | ||
throw Error('Missing output parameter'); | ||
} | ||
}, | ||
required: ['image', 'output'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
// Saves image to local tmp path, than copy it | ||
cmd = `save -o ${options.output} ${options.image}`; | ||
if (options.tag != null) { | ||
cmd += `:${options.tag}`; | ||
} | ||
this.log({ | ||
message: `Extracting image ${options.output} to file:${options.image}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/save' | ||
log({ | ||
message: `Extracting image ${config.output} to file:${config.image}`, | ||
level: 'INFO' | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
return (await this.docker.tools.execute({ | ||
command: [`save -o ${config.output} ${config.image}`, config.tag != null ? `:${config.tag}` : void 0].join('') | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
util = require('util'); | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
hooks: { | ||
on_action: on_action | ||
}, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
143
lib/start.js
// Generated by CoffeeScript 2.5.1 | ||
// # `nikita.docker.restart` | ||
// # `nikita.docker.start` | ||
// Start a container. | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `attach` (boolean) | ||
// attach STDOUT/STDERR, default to false. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -35,76 +19,69 @@ // Error object if any. | ||
// 1- builds an image from dockerfile without any resourcess | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.start({ | ||
// ```js | ||
// const {status} = await nikita.docker.start({ | ||
// container: 'toto', | ||
// attach: true | ||
// }, function(err, is_true, stdout, stderr){ | ||
// console.log( err ? err.message : 'Container state changed to started: ' + status); | ||
// }) | ||
// console.info(`Container was started: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker start", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/start' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'attach': { | ||
type: 'boolean', | ||
default: false, | ||
description: `Attach STDOUT/STDERR.` | ||
}, | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container, required.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
} | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var status; | ||
({status} = (await this.docker.tools.status(config, { | ||
metadata: { | ||
shy: true | ||
} | ||
}))); | ||
if (status) { | ||
log({ | ||
message: `Container already started ${config.container} (Skipping)`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/start' | ||
}); | ||
} else { | ||
log({ | ||
message: `Starting container ${config.container}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/start' | ||
}); | ||
} | ||
if (options.container == null) { | ||
// Validation | ||
throw Error('Missing container parameter'); | ||
return (await this.docker.tools.execute({ | ||
unless: status, | ||
command: ['start', config.attach ? '-a' : void 0, `${config.container}`].join(' ') | ||
})); | ||
}; | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
// rm is false by default only if options.service is true | ||
cmd = 'start'; | ||
if (options.attach) { | ||
cmd += ' -a'; | ||
} | ||
cmd += ` ${options.container}`; | ||
this.docker.status({ | ||
shy: true | ||
}, options, function(err, {status}) { | ||
if (err) { | ||
throw err; | ||
} | ||
if (status) { | ||
this.log({ | ||
message: `Container already started ${options.container} (Skipping)`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/start' | ||
}); | ||
} else { | ||
this.log({ | ||
message: `Starting container ${options.container}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/start' | ||
}); | ||
} | ||
if (status) { | ||
return this.end(); | ||
} | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
util = require('util'); |
135
lib/stop.js
@@ -6,15 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `timeout` (int) | ||
// Seconds to wait for stop before killing it | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -27,73 +16,69 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.stop({ | ||
// ```js | ||
// const {status} = await nikita.docker.stop({ | ||
// container: 'toto' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container state changed to stopped: ' + status); | ||
// }) | ||
// console.info(`Container was stopped: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker stop", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/stop' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'timeout': { | ||
type: 'integer', | ||
description: `Seconds to wait for stop before killing the container (Docker default | ||
is 10).` | ||
} | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
var status; | ||
// rm is false by default only if config.service is true | ||
({status} = (await this.docker.tools.status(config, { | ||
metadata: { | ||
shy: true | ||
} | ||
}))); | ||
if (status) { | ||
log({ | ||
message: `Stopping container ${config.container}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/stop' | ||
}); | ||
} else { | ||
log({ | ||
message: `Container already stopped ${config.container} (Skipping)`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/stop' | ||
}); | ||
} | ||
if (options.container == null) { | ||
// Validate parameters | ||
throw Error('Missing container parameter'); | ||
return (await this.docker.tools.execute({ | ||
if: status, | ||
command: ['stop', config.timeout != null ? `-t ${config.timeout}` : void 0, `${config.container}`].join(' ') | ||
})); | ||
}; | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
// rm is false by default only if options.service is true | ||
cmd = 'stop'; | ||
if (options.timeout != null) { | ||
cmd += ` -t ${options.timeout}`; | ||
} | ||
cmd += ` ${options.container}`; | ||
this.docker.status({ | ||
shy: true | ||
}, options, function(err, {status}) { | ||
if (err) { | ||
throw err; | ||
} | ||
if (status) { | ||
this.log({ | ||
message: `Stopping container ${options.container}`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/stop' | ||
}); | ||
} else { | ||
this.log({ | ||
message: `Container already stopped ${options.container} (Skipping)`, | ||
level: 'INFO', | ||
module: 'nikita/lib/docker/stop' | ||
}); | ||
} | ||
if (!status) { | ||
return this.end(); | ||
} | ||
}); | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
util = require('util'); |
@@ -6,13 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -25,46 +16,50 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.pause({ | ||
// ```js | ||
// const {status} = await nikita.docker.unpause({ | ||
// container: 'toto' | ||
// }, function(err, {status}){ | ||
// console.log( err ? err.message : 'Container was unpaused: ' + status); | ||
// }) | ||
// console.info(`Container was unpaused: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var k, ref, v; | ||
this.log({ | ||
message: "Entering Docker unpause", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/unpause' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'boot2docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/boot2docker' | ||
}, | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
} | ||
} | ||
if (options.container == null) { | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Handler | ||
handler = async function({ | ||
config, | ||
tools: {log} | ||
}) { | ||
if (config.container == null) { | ||
// Validation | ||
throw Error('Missing container parameter'); | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, `unpause ${options.container}`) | ||
}, function() { | ||
return docker.callback(callback, ...arguments); | ||
}); | ||
return (await this.docker.tools.execute({ | ||
command: `unpause ${config.container}` | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
util = require('util'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
// Generated by CoffeeScript 2.5.1 | ||
// # `nikita.volume_create` | ||
// # `nikita.docker.volume_create` | ||
// Create a volume. | ||
// Create a volume. | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `driver` (string) | ||
// Specify volume driver name. | ||
// * `label` (string|array) | ||
// Set metadata for a volume. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `name` (string) | ||
// Specify volume name. | ||
// * `opt` (string|array) | ||
// Set driver specific options. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -30,70 +15,91 @@ // Error object if any. | ||
// ```javascript | ||
// require('nikita') | ||
// .docker.pause({ | ||
// ```js | ||
// const {status} = await nikita.docker.volume_create({ | ||
// name: 'my_volume' | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Volume created: ' + status); | ||
// }) | ||
// console.info(`Volume was created: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker volume_create", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/volume_create' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'driver': { | ||
type: 'string', | ||
description: `Specify volume driver name.` | ||
}, | ||
'label': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Set metadata for a volume.` | ||
}, | ||
'name': { | ||
type: 'string', | ||
description: `Specify volume name.` | ||
}, | ||
'opt': { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
], | ||
description: `Set driver specific options.` | ||
} | ||
} | ||
if (typeof options.label === 'string') { | ||
// Normalize options | ||
options.label = [options.label]; | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
var status; | ||
if (typeof config.label === 'string') { | ||
// Normalize config | ||
config.label = [config.label]; | ||
} | ||
if (typeof options.opt === 'string') { | ||
options.opt = [options.opt]; | ||
if (typeof config.opt === 'string') { | ||
config.opt = [config.opt]; | ||
} | ||
// Build the docker command arguments | ||
cmd = ["volume create"]; | ||
if (options.driver) { | ||
cmd.push(`--driver ${options.driver}`); | ||
} | ||
if (options.label) { | ||
cmd.push(`--label ${options.label.join(',')}`); | ||
} | ||
if (options.name) { | ||
cmd.push(`--name ${options.name}`); | ||
} | ||
if (options.opt) { | ||
cmd.push(`--opt ${options.opt.join(',')}`); | ||
} | ||
cmd = cmd.join(' '); | ||
this.system.execute({ | ||
if: options.name, | ||
cmd: docker.wrap(options, `volume inspect ${options.name}`), | ||
({status} = (await this.docker.tools.execute({ | ||
if: config.name, | ||
command: `volume inspect ${config.name}`, | ||
code: 1, | ||
code_skipped: 0, | ||
shy: true | ||
}); | ||
return this.system.execute({ | ||
metadata: { | ||
shy: true | ||
} | ||
}))); | ||
return (await this.docker.tools.execute({ | ||
if: function() { | ||
return !options.name || this.status(-1); | ||
return !config.name || status; | ||
}, | ||
cmd: docker.wrap(options, cmd) | ||
}); | ||
command: ["volume create", config.driver ? `--driver ${config.driver}` : void 0, config.label ? `--label ${config.label.join(',')}` : void 0, config.name ? `--name ${config.name}` : void 0, config.opt ? `--opt ${config.opt.join(',')}` : void 0].join(' ') | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
// Generated by CoffeeScript 2.5.1 | ||
// # `nikita.volume_rm` | ||
// # `nikita.docker.volume_rm` | ||
// Remove a volume. | ||
// Remove a volume. | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string|array). | ||
// Name or Id of the container, required. | ||
// * `machine` (string) | ||
// Name of the docker-machine, required if using docker-machine. | ||
// * `name` (string) | ||
// Specify volume name. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -26,43 +15,45 @@ // Error object if any. | ||
// ```javascript | ||
// nikita.docker.volume_rm({ | ||
// ```js | ||
// const {status} = await nikita.docker.volume_rm({ | ||
// name: 'my_volume' | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Volume removed: ' + status); | ||
// }) | ||
// console.info(`Volume was removed: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}) { | ||
var k, ref, v; | ||
this.log({ | ||
message: "Entering Docker volume_rm", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/volume_rm' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
}, | ||
'name': { | ||
type: 'string', | ||
description: `Specify volume name.` | ||
} | ||
} | ||
if (!options.name) { | ||
}; | ||
// ## Handler | ||
handler = async function({config}) { | ||
if (!config.name) { | ||
// Validation | ||
throw Error("Missing required option name"); | ||
} | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, `volume rm ${options.name}`), | ||
return (await this.docker.tools.execute({ | ||
command: `volume rm ${config.name}`, | ||
code: 0, | ||
code_skipped: 1 | ||
}); | ||
})); | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
@@ -6,18 +6,4 @@ // Generated by CoffeeScript 2.5.1 | ||
// ## Options | ||
// ## Output | ||
// * `boot2docker` (boolean) | ||
// Whether to use boot2docker or not, default to false. | ||
// * `container` (string) | ||
// Name/ID of the container, optional. | ||
// * `machine` (string) | ||
// Name of the docker-machine, optional if using docker-machine. | ||
// * `code` (int|array) | ||
// Expected code(s) returned by the command, int or array of int, default to 0. | ||
// * `code_skipped` | ||
// Expected code(s) returned by the command if it has no effect, executed will | ||
// not be incremented, int or array of int. | ||
// ## Callback parameters | ||
// * `err` | ||
@@ -30,46 +16,39 @@ // Error object if any. | ||
// ```javascript | ||
// nikita.docker.wait({ | ||
// ```js | ||
// const {status} = await nikita.docker.wait({ | ||
// container: 'toto' | ||
// }, function(err, status){ | ||
// console.log( err ? err.message : 'Did we really had to wait: ' + status); | ||
// }) | ||
// console.info(`Did we really had to wait: ${status}`) | ||
// ``` | ||
// ## Source Code | ||
var docker, util; | ||
// ## Schema | ||
var handler, schema; | ||
module.exports = function({options}, callback) { | ||
var cmd, k, ref, v; | ||
this.log({ | ||
message: "Entering Docker wait", | ||
level: 'DEBUG', | ||
module: 'nikita/lib/docker/wait' | ||
}); | ||
// Global options | ||
if (options.docker == null) { | ||
options.docker = {}; | ||
} | ||
ref = options.docker; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (options[k] == null) { | ||
options[k] = v; | ||
schema = { | ||
type: 'object', | ||
properties: { | ||
'container': { | ||
type: 'string', | ||
description: `Name/ID of the container.` | ||
}, | ||
'docker': { | ||
$ref: 'module://@nikitajs/docker/lib/tools/execute#/properties/docker' | ||
} | ||
} | ||
if (options.container == null) { | ||
// Validation | ||
return callback(Error('Missing container parameter')); | ||
} | ||
// rm is false by default only if options.service is true | ||
cmd = `wait ${options.container} | read r; return $r`; | ||
// Construct other exec parameter | ||
return this.system.execute({ | ||
cmd: docker.wrap(options, cmd) | ||
}, docker.callback); | ||
}, | ||
required: ['container'] | ||
}; | ||
// ## Modules Dependencies | ||
docker = require('@nikitajs/core/lib/misc/docker'); | ||
// ## Handler | ||
handler = async function({config}) { | ||
// Old implementation was `wait {container} | read r; return $r` | ||
return (await this.docker.tools.execute(`wait ${config.container}`)); | ||
}; | ||
util = require('util'); | ||
// ## Exports | ||
module.exports = { | ||
handler: handler, | ||
metadata: { | ||
global: 'docker', | ||
schema: schema | ||
} | ||
}; |
@@ -5,2 +5,3 @@ { | ||
"keywords": [ | ||
"nikita", | ||
"build", | ||
@@ -16,3 +17,3 @@ "cli", | ||
], | ||
"version": "0.9.7", | ||
"version": "1.0.0-alpha.0", | ||
"author": "David Worms <david@adaltas.com>", | ||
@@ -41,10 +42,14 @@ "bugs": { | ||
], | ||
"dependencies": { | ||
"@nikitajs/file": "^1.0.0-alpha.0" | ||
}, | ||
"peerDependencies": { | ||
"@nikitajs/core": "^0.9.5" | ||
"@nikitajs/core": "^0.9.7" | ||
}, | ||
"devDependencies": { | ||
"@nikitajs/network": "^1.0.0-alpha.0", | ||
"coffeescript": "^2.5.1", | ||
"mocha": "7.1.1", | ||
"should": "~13.2.3", | ||
"ssh2-they": "^2.0.4" | ||
"mocha": "^8.2.1", | ||
"mocha-they": "^0.1.2", | ||
"should": "^13.2.3" | ||
}, | ||
@@ -57,2 +62,15 @@ "engines": { | ||
], | ||
"mocha": { | ||
"throw-deprecation": true, | ||
"require": [ | ||
"should", | ||
"coffeescript/register", | ||
"@nikitajs/docker/src/register", | ||
"@nikitajs/network/src/register" | ||
], | ||
"inline-diffs": true, | ||
"timeout": 40000, | ||
"reporter": "spec", | ||
"recursive": true | ||
}, | ||
"publishConfig": { | ||
@@ -69,7 +87,8 @@ "access": "public" | ||
"scripts": { | ||
"build": "coffee -b -o lib src && sed -i -e 's/src/lib/g' lib/register.js", | ||
"build": "coffee -b -o lib src && find lib -type f | xargs sed -i -e 's/@nikitajs\\/docker\\/src/@nikitajs\\/docker\\/lib/g'", | ||
"pretest": "npm run build", | ||
"test": "mocha 'test/**/*.coffee'" | ||
"test": "mocha 'test/**/*.coffee'", | ||
"testall": "mocha 'test/**/*.coffee' && env/run.sh" | ||
}, | ||
"gitHead": "60b27a97d345e810697619dabe7379984b640aee" | ||
"gitHead": "c5ee53354302fd36836e269ceac5639381efadd2" | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
78791
31
2986
2
5
1
+ Added@nikitajs/core@1.0.0-alpha.6(transitive)
+ Added@nikitajs/file@1.0.0-alpha.6(transitive)
+ Addedajv@8.16.0(transitive)
+ Addedajv-formats@3.0.1(transitive)
+ Addedajv-keywords@5.1.0(transitive)
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedbuildcheck@0.0.6(transitive)
+ Addedchalk@5.3.0(transitive)
+ Addedcoffeescript@1.12.7(transitive)
+ Addedcpu-features@0.0.10(transitive)
+ Addedcson@8.4.0(transitive)
+ Addedcson-parser@4.0.9(transitive)
+ Addeddedent@1.5.3(transitive)
+ Addeddiff@5.2.0(transitive)
+ Addedeach@2.7.0(transitive)
+ Addedeachr@7.4.0(transitive)
+ Addededitions@6.21.0(transitive)
+ Addedextract-opts@5.9.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhandlebars@4.7.8(transitive)
+ Addedini@4.1.3(transitive)
+ Addedjson-schema-traverse@1.0.0(transitive)
+ Addedminimatch@9.0.4(transitive)
+ Addedmixme@0.5.101.1.0(transitive)
+ Addednan@2.19.0(transitive)
+ Addedneo-async@2.6.2(transitive)
+ Addedplug-and-play@2.5.8(transitive)
+ Addedrequire-from-string@2.0.2(transitive)
+ Addedrequirefresh@5.13.0(transitive)
+ Addedsafefs@8.10.0(transitive)
+ Addedself-templated@0.2.3(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addedssh2@1.14.0(transitive)
+ Addedssh2-connect@3.4.2(transitive)
+ Addedssh2-exec@0.7.6(transitive)
+ Addedssh2-fs@1.1.2(transitive)
+ Addedtoposort@2.0.2(transitive)
+ Addedtypechecker@9.3.0(transitive)
+ Addeduglify-js@3.18.0(transitive)
+ Addeduuid@10.0.0(transitive)
+ Addedversion-compare@3.11.0(transitive)
+ Addedversion-range@4.14.0(transitive)
+ Addedwordwrap@1.0.0(transitive)
+ Addedxmlbuilder@15.1.1(transitive)
+ Addedxmldom@0.6.0(transitive)