UNPKG

3.33 kBJavaScriptView Raw
1const Container = require('./container')
2const Docker = require('dockerode')
3const tarstream = require('tar-stream')
4const tarfs = require('tar-fs')
5const chalk = require('chalk')
6const async = require('async')
7const jsonpath = require('jsonpath')
8
9const docker = new Docker({
10 socketPath: '/var/run/docker.sock'
11})
12
13class ContainerBuildError extends Error {
14 constructor (...args) {
15 super(...args)
16 this.name = 'ContainerBuildError'
17 }
18}
19
20class ComponentContainer extends Container {
21 constructor (component, devServer) {
22 super(devServer, component.name, 'component')
23 this.component = component
24 this.buildOutput = []
25 this.dynamicParams = {resources: {}}
26 }
27
28 getImage() {
29 return `noop/${this.component.app.id}/component/${this.component.name}`.toLowerCase()
30 }
31
32 getEnv() {
33 const env = {}
34 Object.keys(this.component.env).forEach((key) => {
35 env[key] = this.component.env[key].default
36 })
37 Object.keys(this.devServer.envOverrides['_all']).forEach((key) => {
38 env[key] = this.devServer.envOverrides['_all'][key]
39 })
40 if (this.devServer.envOverrides[this.component.name]) {
41 Object.keys(this.devServer.envOverrides[this.component.name]).forEach((key) => {
42 env[key] = this.devServer.envOverrides[this.component.name][key]
43 })
44 }
45 Object.keys(env).filter((key) => {
46 return /^\$\..+$/.test(env[key])
47 }).forEach((key) => {
48 let dynamicValue
49 try {
50 dynamicValue = jsonpath.query(this.dynamicParams, env[key])
51 } catch (err) {
52 console.log(chalk.yellow(`Unable to resolve dynamic value '${env[key]}'`), err)
53 }
54 if (dynamicValue) env[key] = dynamicValue
55 })
56 return env
57 }
58
59 build (done) {
60 this.buildStart = new Date()
61 console.log(`Building '${this.component.name}' component container...`)
62 const pack = tarstream.pack()
63 pack.entry({name: 'Dockerfile'}, this.component.dockerfile, (err) => {
64 if (err) return done(err)
65 tarfs.pack(this.component.rootPath, {pack: pack})
66 const buildOpts = {t: this.getImage()}
67 docker.buildImage(pack, buildOpts, (err, output) => {
68 if (err) return done(err)
69 const complete = (err) => {
70 this.buildEnd = new Date()
71 if (err) {
72 console.log(chalk.red(`Build failed for '${this.component.name}' component container`))
73 console.log(' ', err)
74 done(new ContainerBuildError(err))
75 } else {
76 const duration = (this.buildEnd.getTime() - this.buildStart.getTime()) / 1000
77 console.log(`Build completed for '${this.component.name}' in ${duration}s`)
78 done()
79 }
80 }
81 docker.modem.followProgress(output, complete, (event) => {
82 if (event.stream && /\w/.test(event.stream)) {
83 let line = event.stream.trim()
84 this.buildOutput.push(line)
85 if (/^Step \d+\/\d+ :/.test(line)) line = chalk.cyan(line)
86 console.log(' ', line.replace(/(\r\n|\r|\n)/g, '\n '))
87 }
88 })
89 })
90 })
91 }
92
93 reload (done) {
94 async.auto({
95 build: (done) => this.build(done),
96 stop: ['build', (results, done) => this.stop(done)],
97 start: ['stop', (results, done) => this.start(done)]
98 }, done)
99 }
100}
101
102module.exports = ComponentContainer