From b431dbe252bcc573f4037dae4ba979d4ff2065b8 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Fri, 6 Oct 2017 23:51:11 +0400 Subject: The first working beta version --- README.md | 40 ++++++----- package.json | 3 +- src/lib/index.js | 215 ++++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 199 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 583551a..1745d2c 100644 --- a/README.md +++ b/README.md @@ -7,26 +7,32 @@ Simple and fast work with the Docker container. +It uses the library +[dockerode](https://github.com/apocas/dockerode). + ## Installation ```bash npm install --save simple-container ``` ## Using -A simple example: +A simple example that creates and starts a container: ```JavaScript -import Container from 'simple-container'; - -var container = new Container(); +import Containers from 'simple-container'; -/* Create the container */ -container.create('hello-world:latest'); +var containers = new Containers(); -/* Start the container */ -container.start(); +containers.create('postgres:alpine').then(container => { + console.info(`The ${container.id} container was created.`); + start(container); +}); -/* Stop and destroy the container */ -container.destroy(); +/* Run the created container */ +function start(container) { + container.start().then(() => { + console.info(`The ${container.id} container is running.`); + }); +} ``` ### Remote connection @@ -34,7 +40,7 @@ By default, the local service is used. For example, if you want to use connection settings: ```JavaScript -var container = new Container({ +var containers = new Containers({ host: '127.0.0.1', port: 3000 }); @@ -48,12 +54,12 @@ You can create a container in two ways. A simple way - to specify the name of the image: ```JavaScript -container.create('hello-world:latest'); +containers.create('hello-world:latest'); ``` Another way - to provide an object with parameters: ```JavaScript -container.create({ +containers.create({ Image: 'postgres:alpine', Env: ['POSTGRES_PASSWORD = password'], Ports: [{ @@ -77,7 +83,7 @@ var auth = { serveraddress: 'https://index.docker.io/v1' }; -container.create({ +containers.create({ Image: 'project:latest', authconfig: auth }); @@ -87,11 +93,11 @@ Details in [the documentation](https://github.com/apocas/dockerode#pull-from-private-repos). ## Debugging -Use the `DEBUG` variable with the `container` option. +Use the `DEBUG` variable with the `containers` option. Result of output: ```bash -$ DEBUG="container" node ./example.js +$ DEBUG="containers" node ./example.js container { status: 'Pulling from library/postgres', id: 'alpine' } +0ms container { status: 'Already exists', container progressDetail: {}, @@ -104,7 +110,7 @@ $ DEBUG="container" node ./example.js Or redefine the function to your own: ```JavaScript -container.debug = function() { +containers.debug = function() { var args = Array.prototype.slice.call(arguments); /* Debugger code */ } diff --git a/package.json b/package.json index c95c1e2..a8d454b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "simple-container", - "version": "0.0.0-alpha.1", + "version": "0.0.0-beta.1", "description": "Simple and fast work with the Docker container", "homepage": "https://github.com/valentineus/simple-container", "license": "MIT", @@ -26,7 +26,6 @@ "mocha": "^4.0.0" }, "dependencies": { - "ancient-funicular": "^3.0.0", "debug": "^3.1.0", "dockerode": "^2.5.1" }, diff --git a/src/lib/index.js b/src/lib/index.js index 7196ec6..9e86cc7 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -1,4 +1,3 @@ -import { Item } from 'ancient-funicular'; import createDebug from 'debug'; import Docker from 'dockerode'; import { statSync } from 'fs'; @@ -6,14 +5,12 @@ import { statSync } from 'fs'; /** * @class Container */ -export default class Container extends Item { +export default class Containers { /** * @constructs Container * @param {Object=} [options] - Service connection settings */ constructor(options) { - super(); - /** * @protected * @type {Object} @@ -26,11 +23,11 @@ export default class Container extends Item { this._docker = new Docker(options); } else { - var socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock'; + var socket = this._getSocket(); var stats = statSync(socket); if (!stats.isSocket()) { - throw new Error('Local service is not found.'); + throw new Error(''); } this._docker = new Docker({ @@ -41,14 +38,15 @@ export default class Container extends Item { /** * @protected - * @param {Object|String} options - Container parameters - * @description Creates and registers a container in the system. + * @param {String|Object} options - The name of the image or options + * @returns {Promise} Returns the container object + * @description Creates a container by options or name, returning the management interface. */ create(options) { var self = this; if (!self._isString(options) && !self._isObject(options)) { - throw new Error('The variable \'options\' is not correct.'); + throw new Error(''); } if (self._isString(options)) { @@ -56,42 +54,190 @@ export default class Container extends Item { options = { Image }; } - self._pullImage(options.Image, (error) => { - self._handlerError(error); - self._createContainer(options); + return new Promise((resolve, reject) => { + self._getImage(options.Image, (error) => { + if (error) { + reject(error); + } + + self._createContainer(options, (error, container) => { + if (error) { + reject(error); + } + + resolve(container); + }); + }); }); } /** * @protected - * @description Stops and destroys the container. + * @param {String=} [id] - Container ID + * @returns {Promise} Returns the container or container object + * @description Returns the container management interface. */ - destroy() {} + get(id) { + var self = this; + + if (id && !self._isString(id)) { + throw new Error(''); + } + + return new Promise((resolve, reject) => { + self._getContainers((error, list) => { + if (error) { + reject(error); + } + + if (self._isString(id)) { + self._findContainer(list, id, (result) => { + resolve(self._getContainer(result.Id)); + }); + } + else { + self._createListContainers(list, (result) => { + resolve(result); + }); + } + }); + }); + } /** * @protected - * @param {String} image - Name of the image - * @param {Function} callback - Called function - * @description Pulls out the image of the container. + * @param {String=} [id] - Container ID + * @returns {Promise} Returns the container or container object + * @description Searches in existing containers. */ - _pullImage(image, callback) { + info(id) { var self = this; - self._docker.pull(image).then(stream => { - self._docker.modem.followProgress(stream, callback, self.debug); - }).catch(error => self._handlerError(error)); + + if (id && !self._isString(id)) { + throw new Error(''); + } + + return new Promise((resolve, reject) => { + self._getContainers((error, list) => { + if (error) { + reject(error); + } + + if (self._isString(id)) { + self._findContainer(list, id, (result) => { + resolve(result); + }); + } + else { + self._createInformationList(list, (result) => { + resolve(result); + }); + } + }); + }); + } + + /** + * @protected + * @param {Object} options - Settings created by the container + * @param {Function} callback - Callback after creation + * @description Creates a container and returns its interface. + */ + _createContainer(options, callback) { + this._docker.createContainer(options, (error, container) => { + callback(error, container); + }); + } + + /** + * @protected + * @param {Array} list - List of containers + * @param {Function} callback - Callback after building the list + * @description Creates a list of containers for the user. + */ + _createInformationList(list, callback) { + callback(list.reduce((result, item) => { + result[item.Id] = item; + return result; + }, {})); } /** * @protected - * @param {Object} options - Container settings - * @description Creating a container and registering management. + * @param {Array} list - List of containers + * @param {Function} callback - Callback after building the list + * @description Creates a list of container interfaces. */ - _createContainer(options) { + _createListContainers(list, callback) { var self = this; - self._docker.createContainer(options).then(container => { - /* @todo Class registration */ - self.debug(container); - }).catch(error => self._handlerError(error)); + + callback(list.reduce((result, item) => { + result[item.Id] = self._getContainer(item.Id); + return result; + }, {})); + } + + /** + * @protected + * @returns {String} Socket + * @description Getting the system socket. + */ + _getSocket() { + return process.env.DOCKER_SOCKET || '/var/run/docker.sock'; + } + + /** + * @protected + * @param {Function} callback - Callback after receiving the list + * @description Getting a list of all available containers in the system. + */ + _getContainers(callback) { + this._docker.listContainers({ all: true }, (error, list) => { + callback(error, list); + }); + } + + /** + * @protected + * @param {String} id - Container ID + * @returns {Object} Container interface + * @description Getting the interface of the container. + */ + _getContainer(id) { + return this._docker.getContainer(id); + } + + /** + * @protected + * @param {String} image - The name of the image + * @param {Function} callback - Callback after download + * @description Load the image needed for the container. + */ + _getImage(image, callback) { + var self = this; + + self._docker.pull(image, (error, stream) => { + if (error) { + callback(error); + } + + self._docker.modem.followProgress(stream, callback, self.debug); + }); + } + + /** + * @protected + * @param {Array} list - List of containers + * @param {String} id - Container ID + * @param {Function} callback - Callback with the search result + * @description Search for a specific container from the general list of containers. + */ + _findContainer(list, id, callback) { + list.find(item => { + if (item.Id == id) { + callback(item); + } + }); } /** @@ -114,24 +260,13 @@ export default class Container extends Item { return typeof value === 'object'; } - /** - * @protected - * @param {*} error - A string with an error - * @description Handles the error if present. - */ - _handlerError(error) { - if (error) { - throw new Error(error); - } - } - /** * @param {*} Any variables * @description A simple debugger. */ debug() { var args = Array.prototype.slice.call(arguments); - var debug = createDebug('container'); + var debug = createDebug('containers'); debug.apply(null, args); } } \ No newline at end of file -- cgit v1.2.3