UNPKG

firmament-docker

Version:

Typescript classes for performing Docker operations

274 lines 12.3 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); var DockerUtilImpl_1; const inversify_1 = require("inversify"); const _ = require("lodash"); const __1 = require("../.."); const firmament_yargs_1 = require("firmament-yargs"); const firmament_yargs_2 = require("firmament-yargs"); const deepExtend = require('deep-extend'); const async = require("async"); let DockerUtilImpl = DockerUtilImpl_1 = class DockerUtilImpl extends firmament_yargs_2.ForceErrorImpl { constructor(dockerode, positive, safeJson, spawn, commandUtil) { super(); this.dockerode = dockerode; this.positive = positive; this.safeJson = safeJson; this.spawn = spawn; this.commandUtil = commandUtil; } writeJsonTemplateFile(objectToWrite, fullOutputPath) { const me = this; me.commandUtil.log("Writing JSON template file '" + fullOutputPath + "' ..."); me.safeJson.writeFileSync(fullOutputPath, { spaces: 2 }, objectToWrite); } listImagesOrContainers(options, cb) { this.dockerode.forceError = this.forceError; let me = this; let listFn; deepExtend(options, { all: true }); listFn = (options.IorC === __1.ImageOrContainer.Image) ? me.dockerode.listImages : me.dockerode.listContainers; listFn.call(me.dockerode, { all: true }, (err, imagesOrContainers) => { if (me.commandUtil.callbackIfError(cb, err)) { return; } _.remove(imagesOrContainers, (iOrC) => { if (options.IorC === __1.ImageOrContainer.Container) { return !iOrC.Names; } else if (options.IorC === __1.ImageOrContainer.Image) { return !iOrC.RepoTags; } }); imagesOrContainers.sort(function (a, b) { if (options.IorC === __1.ImageOrContainer.Container) { return a.Names[0].localeCompare(b.Names[0]); } else if (options.IorC === __1.ImageOrContainer.Image) { let ref = a.RepoTags[0] + a.Id; let cmp = b.RepoTags[0] + b.Id; return ref.localeCompare(cmp); } }); let firmamentId = 0; imagesOrContainers = imagesOrContainers.map(imageOrContainer => { imageOrContainer.firmamentId = (++firmamentId).toString(); if (options.IorC === __1.ImageOrContainer.Container) { return (options.listAll || (imageOrContainer.Status.substring(0, 2) === 'Up')) ? imageOrContainer : null; } else { return (options.listAll || (imageOrContainer.RepoTags[0] !== '<none>:<none>')) ? imageOrContainer : null; } }).filter(imageOrContainer => { return imageOrContainer !== null; }); cb(null, imagesOrContainers); }); } getImagesOrContainers(ids, options, cb) { this.dockerode.forceError = this.forceError; let me = this; if (!ids) { options.listAll = true; me.listImagesOrContainers(options, (err, imagesOrContainers) => { if (me.commandUtil.callbackIfError(cb, err)) { return; } ids = []; imagesOrContainers.forEach(imageOrContainer => { ids.push(imageOrContainer.firmamentId); }); me.getImagesOrContainers(ids, options, cb); }); return; } let fnArray = ids.map(id => { return async.apply(me.getImageOrContainer.bind(me), id.toString(), options); }); async.series(fnArray, (err, results) => { if (!me.commandUtil.callbackIfError(cb, err)) { cb(err, results.filter(result => !!result)); } }); } getImageOrContainer(id, options, cb) { this.dockerode.forceError = this.forceError; let me = this; async.waterfall([ (cb) => { options.listAll = true; me.listImagesOrContainers(options, cb); }, (imagesOrContainers, cb) => { let foundImagesOrContainers = imagesOrContainers.filter(imageOrContainer => { if (imageOrContainer.firmamentId === id) { return true; } else { if (options.IorC === __1.ImageOrContainer.Container) { for (let i = 0; i < imageOrContainer.Names.length; ++i) { if (imageOrContainer.Names[i] === (id[0] === '/' ? id : '/' + id)) { return true; } } } else if (options.IorC === __1.ImageOrContainer.Image) { for (let i = 0; i < imageOrContainer.RepoTags.length; ++i) { if (imageOrContainer.RepoTags[i] === '<none>:<none>') { continue; } if (imageOrContainer.RepoTags[i] === id) { return true; } } } let charCount = id.length; if (charCount < 3) { return false; } return DockerUtilImpl_1.compareIds(id, imageOrContainer.Id); } }); if (foundImagesOrContainers.length > 0) { let imageOrContainer; if (options.IorC === __1.ImageOrContainer.Container) { imageOrContainer = me.dockerode.getContainer(foundImagesOrContainers[0].Id, options); imageOrContainer.Name = foundImagesOrContainers[0].Names[0]; } else if (options.IorC === __1.ImageOrContainer.Image) { imageOrContainer = me.dockerode.getImage(foundImagesOrContainers[0].Id, options); imageOrContainer.Name = foundImagesOrContainers[0].RepoTags[0]; } imageOrContainer.Id = DockerUtilImpl_1.stripSha256(foundImagesOrContainers[0].Id); cb(null, imageOrContainer); } else { cb(null, `Unable to find: ${id}`); } } ], cb); } removeImagesOrContainers(ids, options, cb) { this.dockerode.forceError = this.forceError; let me = this; ids = ids || []; let thingsToRemove = options.IorC === __1.ImageOrContainer.Container ? 'containers' : 'images'; let thingToRemove = options.IorC === __1.ImageOrContainer.Container ? 'container' : 'image'; if (!ids.length) { throw new Error(`Specify ${thingsToRemove} to remove by FirmamentId, Docker ID or Name. Or 'all' to remove all.`); } if (_.indexOf(ids, 'all') !== -1) { if (!this.positive.areYouSure(`You're sure you want to remove all ${thingsToRemove}? [y/N] `, `Operation canceled.`, false, firmament_yargs_1.FailureRetVal.TRUE)) { return cb(null, null); } ids = null; } if (!ids && thingsToRemove === 'images') { return async.waterfall([ (cb) => { me.spawn.spawnShellCommandAsync([ 'bash', '-c', `docker images -a | awk '{print \$3}'` ], { cacheStdOut: true }, me.logErrAndResult.bind(me), cb); }, (listImagesResult, cb) => { me.safeJson.safeParse(listImagesResult, (err, obj) => { const imagesToDelete = obj.stdoutText.toString().split('\n'); if (imagesToDelete.shift() !== 'IMAGE') { return cb(new Error('Remove docker images FAILED')); } cb(err, imagesToDelete); }); }, (imagesToDelete, cb) => { async.eachSeries(imagesToDelete, (imageToDelete, cb) => { me.spawn.spawnShellCommandAsync([ 'docker', 'rmi', '-f', `${imageToDelete}` ], { cacheStdOut: true }, me.logErrAndResult.bind(me), () => { cb(null); }); }, cb); } ], cb); } me.getImagesOrContainers(ids, options, (err, dockerImagesOrContainers) => { if (me.commandUtil.callbackIfError(cb, err)) { return; } async.map(dockerImagesOrContainers, (imageOrContainer, cb) => { if (typeof imageOrContainer === 'string') { me.commandUtil.logAndCallback(imageOrContainer, cb, null, { msg: imageOrContainer }); } else { imageOrContainer.remove({ force: 1 }, (err) => { let msg = `Removing ${thingToRemove} '${imageOrContainer.Name}' with id: '${imageOrContainer.Id.substr(0, 8)}'`; me.commandUtil.logAndCallback(msg, cb, err, { msg }); }); } }, cb); }); } static compareIds(id0, id1) { let str0 = DockerUtilImpl_1.stripSha256(id0).toLowerCase(); let str1 = DockerUtilImpl_1.stripSha256(id1).toLowerCase(); let len = str0.length < str1.length ? str0.length : str1.length; str0 = str0.substr(0, len); str1 = str1.substr(0, len); return str0 === str1; } static stripSha256(id) { const testPrefix = 'sha256:'; let startIdx = (testPrefix === id.substr(0, testPrefix.length)) ? testPrefix.length : 0; return id.substr(startIdx); } logErrAndResult(err, result) { const me = this; if (err) { return me.commandUtil.log(err.message); } me.commandUtil.log((result || '').toString()); } }; DockerUtilImpl = DockerUtilImpl_1 = __decorate([ inversify_1.injectable(), __param(0, inversify_1.inject('DockerOde')), __param(1, inversify_1.inject('Positive')), __param(2, inversify_1.inject('SafeJson')), __param(3, inversify_1.inject('Spawn')), __param(4, inversify_1.inject('CommandUtil')), __metadata("design:paramtypes", [Object, Object, Object, Object, Object]) ], DockerUtilImpl); exports.DockerUtilImpl = DockerUtilImpl; //# sourceMappingURL=docker-util-impl.js.map