UNPKG

draig-car

Version:

Database REST API interactive generator CLI and REPL OpenAPI3 based JS generator with interactive ORM/ODM REPL

159 lines (151 loc) 4.49 kB
const chalk = require('chalk') const { Readable } = require('stream') const { Docker } = require('node-docker-api') const docker = new Docker() const u = require('../../util') const ccfg = require('../../cfg/container')(u.loadConfig()) async function findImage(client) { const images = await docker.image.list() return images.find(i => i.data.RepoTags.find(n => n === ccfg[client].img)) } async function findContainer(cont) { const conts = await docker.container.list({ all: true }) return conts.find(c => c.data.Names[0].endsWith(cont)) } module.exports = { async runContainer(ctx) { const client = ctx.argv.dbclient let dbc = 'draigdb-' + client let mycont = await findContainer(dbc) if (mycont) { console.warn( chalk`Container {green ${dbc}} already exists - ` + "Existing user's schema/DB will be discarded" ) return mycont } console.info( chalk`Creating container {green ${dbc}} with image` + chalk` {green ${ccfg[client].img}}` ) mycont = await docker.container.create({ name: dbc, env: ccfg[client].env, Image: ccfg[client].img, HostConfig: { NetworkMode: 'default', PortBindings: { [`${ccfg[client].port}/tcp`]: [ { HostPort: `${ccfg[client].port}` } ] } }, Ulimits: [{ Name: 'core', Hard: 0, Soft: 0 }] }) await mycont.start() const state = (await mycont.status()).data.State.Status if (state !== 'running') { console.error( chalk`{red ERROR}: Container {green ${dbc}} did not started - ` + chalk`State: {green ${state}}` ) } else { console.log( chalk`Waiting {green ${ccfg[client].t}} seconds for the DB to start up` ) await new Promise(r => setTimeout(r, 1000 * ccfg[client].t)) return mycont } }, async execInContainer(mycont, ctx) { const client = ctx.argv.dbclient const ex = await mycont.exec.create({ Tty: false, AttachStdin: true, AttachStdout: true, AttachStderr: true, Cmd: ccfg[client].cmd }) console.log(chalk`(Re)creating {green client} schema/db...`) const stream = await ex.start({ hijack: true, stdin: true }) const readable = Readable.from(ccfg[client].lines.map(l => l + '\n')) docker.modem.demuxStream(stream, process.stdout, process.stderr) readable.pipe(stream) return new Promise((resolve, reject) => { stream.on('end', () => { if (!ctx.argv._.includes('run')) { require('../../init').initCtx(ctx, ctx.argv) console.log( chalk`{yellow WARN}: Now you will need to run ` + chalk`{green generate, migrate} and {green seed} to ` + 'restore your schema/tables and data !' ) } resolve() }) }) }, async contAction(ctx, reqState, actionLabel) { let dbc = 'draigdb-' + ctx.argv.dbclient try { const mycont = await findContainer(dbc) if (mycont) { const state = mycont.data.State if (state !== reqState) { console.info( chalk`${actionLabel} ${state} container {green ${dbc}}` ) const result = reqState === 'running' ? await mycont.start().then(c => c.status()) : await mycont.stop().then(c => c.status()) console.log(chalk`New status: {green ${result.data.State.Status}}`) } else { console.warn(chalk`Container {green ${dbc}} yet in state ${state}`) } } else { console.error( chalk`{red ERROR}: Container {green ${dbc}} does not exist - ` + chalk`Try {green resetdb} command` ) } } catch (e) { console.error( chalk`{red ERROR}: ${e.message} - ` + 'Please, make sure that docker service is running' ) } }, async pullImage(client) { if (await findImage(client)) return console.warn( chalk`Image {green ${ccfg[client].img}} for {green ${client}} not found -` + ' Please, wait while the image is downloaded' ) let stream = await docker.image.create( {}, { fromImage: ccfg[client].img } ) await new Promise((resolve, reject) => { docker.modem.followProgress( stream, err => { process.stdout.write('\n') if (err) { console.error( chalk`{red ERROR}: ${ccfg[client].img} failed - ${err}` ) reject(false) } else { console.log(chalk`Image {green ${ccfg[client].img}} pulled OK`) resolve(true) } }, event => { var outputMessage = event.status if (event.id) outputMessage += ': ' + event.id if (event.progress) outputMessage += ' ' + event.progress process.stdout.write(outputMessage + ' \r') } ) }) } }