UNPKG

firmament-docker

Version:

Typescript classes for performing Docker operations

248 lines 10.7 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 }); const inversify_1 = require("inversify"); const __1 = require(".."); const docker_util_options_impl_1 = require("./util/docker-util-options-impl"); const firmament_yargs_1 = require("firmament-yargs"); const fs = require("fs"); const path = require("path"); const async = require("async"); const sanitize = require("sanitize-filename"); let DockerImageManagementImpl = class DockerImageManagementImpl extends firmament_yargs_1.ForceErrorImpl { constructor(DM, spawn, safeJson, commandUtil) { super(); this.DM = DM; this.spawn = spawn; this.safeJson = safeJson; this.commandUtil = commandUtil; } loadImages(imageRegEx, inputFolder, cb) { const me = this; async.waterfall([ (cb) => { fs.readdir(inputFolder, cb); }, (files, cb) => { const regExp = new RegExp(imageRegEx); cb(null, files .filter((file) => regExp.test(file)) .map((file) => `${path.resolve(inputFolder, file)}`)); }, (pathsToLoad, cb) => { me.commandUtil.stdoutWrite(`Queueing the following image files for load:\n\n`); pathsToLoad.forEach((pathToLoad) => { me.commandUtil.stdoutWrite(`${pathToLoad}\n`); }); me.commandUtil.stdoutWrite(`\n`); async.eachSeries(pathsToLoad, (pathToLoad, cb) => { me.commandUtil.stdoutWrite(`Loading image: '${pathToLoad}' -- `); me.spawn.spawnShellCommandAsync([ 'bash', '-c', `docker load -i ${pathToLoad}` ], {}, (err, result) => { me.commandUtil.stdoutWrite(result); }, cb); }, cb); } ], cb); } saveImages(imageRegEx, outputFolder, cb) { const me = this; async.waterfall([ (cb) => { me.spawn.spawnShellCommandAsync([ 'bash', '-c', `docker images -a | awk '{print \$1":"\$2}'` ], { cacheStdOut: true }, () => { }, (err, listImagesResult) => { me.safeJson.safeParse(listImagesResult, (err, obj) => { cb(err, obj.stdoutText.toString().split('\n')); }); }); }, (allImages, cb) => { allImages.shift(); allImages.pop(); const regExp = new RegExp(imageRegEx); cb(null, allImages.filter((image) => regExp.test(image))); }, (matchingImages, cb) => { const imageOutputFiles = []; me.commandUtil.stdoutWrite(`Queueing the following images for save:\n\n`); matchingImages.forEach((matchingImage) => { me.commandUtil.stdoutWrite(`${matchingImage}\n`); }); me.commandUtil.stdoutWrite(`\n`); async.each(matchingImages, (image, cb) => { const outputPath = `${path.resolve(outputFolder, sanitize(image, { replacement: '_' }))}.tar.gz`; me.spawn.spawnShellCommandAsync([ 'bash', '-c', `docker save ${image} -o ${outputPath}` ], { cacheStdOut: true, cacheStdErr: true }, () => { }, (err) => { me.commandUtil.stdoutWrite(`Saving: '${outputPath}'\n`); imageOutputFiles.push(outputPath); cb(err); }); }, (err) => { cb(err, imageOutputFiles); }); } ], (err) => { cb(err); }); } listImages(listAllImages, cb) { let dockerUtilOptions = new docker_util_options_impl_1.DockerUtilOptionsImpl(__1.ImageOrContainer.Image, listAllImages); this.DM.dockerUtil.forceError = this.forceError; this.DM.dockerUtil.listImagesOrContainers(dockerUtilOptions, cb); } getImages(ids, cb) { let dockerUtilOptions = new docker_util_options_impl_1.DockerUtilOptionsImpl(__1.ImageOrContainer.Image); this.DM.dockerUtil.forceError = this.forceError; this.DM.dockerUtil.getImagesOrContainers(ids, dockerUtilOptions, cb); } getImage(id, cb) { let dockerUtilOptions = new docker_util_options_impl_1.DockerUtilOptionsImpl(__1.ImageOrContainer.Image); this.DM.dockerUtil.forceError = this.forceError; this.DM.dockerUtil.getImageOrContainer(id, dockerUtilOptions, cb); } removeImages(ids, cb) { let dockerUtilOptions = new docker_util_options_impl_1.DockerUtilOptionsImpl(__1.ImageOrContainer.Image); this.DM.dockerUtil.forceError = this.forceError; this.DM.dockerUtil.removeImagesOrContainers(ids, dockerUtilOptions, cb); } pullImage(imageName, progressCb, cb) { this.DM.dockerode.forceError = this.forceError; let me = this; me.DM.dockerode.pull(imageName, (err, outputStream) => { if (me.DM.commandUtil.callbackIfError(cb, err)) { return; } outputStream.on('data', (chunk) => { try { let data = JSON.parse(chunk); if (data.error) { throw new Error(data.error); } if (data.status === 'Downloading' || data.status === 'Extracting') { progressCb(data.id, data.status, data.progressDetail.current, data.progressDetail.total); } } catch (err) { progressCb('**error**', err.message, 0, 10); if (cb) { cb(err); cb = null; } } }); outputStream.on('end', () => { if (cb) { cb(null); cb = null; } }); outputStream.on('error', function (err) { let msg = `Encountered error '${err.message}' while pulling image: '${imageName}'`; let newError = new Error(msg); me.DM.commandUtil.logError(newError, true); if (cb) { cb(newError); cb = null; } }); }); } buildDockerFile(dockerFilePath, dockerImageName, progressCb, cb) { this.DM.dockerode.forceError = this.forceError; let me = this; try { require('fs').statSync(dockerFilePath); } catch (err) { if (me.DM.commandUtil.callbackIfError(cb, err)) { return; } } try { let tar = require('tar-fs'); let tarStream = tar.pack(dockerFilePath); tarStream.on('error', (err) => { cb(err); }); me.DM.dockerode.buildImage(tarStream, { t: dockerImageName }, function (err, outputStream) { if (me.DM.commandUtil.callbackIfError(cb, err)) { return; } let error = null; outputStream.on('data', function (chunk) { try { let data = JSON.parse(chunk); if (data.stream) { me.commandUtil.stdoutWrite(data.stream); } else { if (data.error) { error = data.error; return; } if (data.status == 'Downloading' || data.status == 'Extracting') { progressCb(data.id, data.status, data.progressDetail.current, data.progressDetail.total); } } } catch (err) { error = err; } }); outputStream.on('end', function () { cb(error && error.message && error.message.indexOf('not found in repository') === -1 ? error : null); }); outputStream.on('error', function (err) { let msg = `Encountered error '${err.message}' while building: '${dockerImageName}'`; me.DM.commandUtil.logError(new Error(msg), true); }); }); } catch (err) { me.DM.commandUtil.callbackIfError(cb, err); } } }; DockerImageManagementImpl = __decorate([ inversify_1.injectable(), __param(0, inversify_1.inject('DockerManagement')), __param(1, inversify_1.inject('Spawn')), __param(2, inversify_1.inject('SafeJson')), __param(3, inversify_1.inject('CommandUtil')), __metadata("design:paramtypes", [Object, Object, Object, Object]) ], DockerImageManagementImpl); exports.DockerImageManagementImpl = DockerImageManagementImpl; //# sourceMappingURL=docker-image-management-impl.js.map