161 lines
4.5 KiB
JavaScript
161 lines
4.5 KiB
JavaScript
|
|
const MyVC = require('./myvc');
|
|
const Command = require('./lib/command');
|
|
const Push = require('./myvc-push');
|
|
const docker = require('./lib/docker');
|
|
const fs = require('fs-extra');
|
|
const path = require('path');
|
|
const Server = require('./lib/server');
|
|
|
|
/**
|
|
* Builds the database image and runs a container. It only rebuilds the
|
|
* image when fixtures have been modified or when the day on which the
|
|
* image was built is different to today. Some workarounds have been used
|
|
* to avoid a bug with OverlayFS driver on MacOS.
|
|
*/
|
|
class Run extends Command {
|
|
static usage = {
|
|
description: 'Build and start local database server container',
|
|
params: {
|
|
ci: 'Workaround for continuous integration system',
|
|
random: 'Whether to use a random container name or port'
|
|
}
|
|
};
|
|
|
|
static localOpts = {
|
|
alias: {
|
|
ci: 'c',
|
|
random: 'r'
|
|
},
|
|
boolean: [
|
|
'ci',
|
|
'random'
|
|
]
|
|
};
|
|
|
|
async run(myvc, opts) {
|
|
const dumpDir = opts.dumpDir;
|
|
const serverDir = path.join(__dirname, 'server');
|
|
|
|
if (!await fs.pathExists(`${dumpDir}/.dump.sql`))
|
|
throw new Error('To run local database you have to create a dump first');
|
|
|
|
// Build base server image
|
|
|
|
let serverDockerfile = path.join(dumpDir, 'Dockerfile');
|
|
if (!await fs.pathExists(serverDockerfile))
|
|
serverDockerfile = path.join(serverDir, 'Dockerfile.base');
|
|
|
|
await docker.build(__dirname, {
|
|
tag: 'myvc/base',
|
|
file: serverDockerfile
|
|
}, opts.debug);
|
|
|
|
// Build myvc server image
|
|
|
|
await docker.build(__dirname, {
|
|
tag: 'myvc/server',
|
|
file: path.join(serverDir, 'Dockerfile.server')
|
|
}, opts.debug);
|
|
|
|
// Build dump image
|
|
|
|
const today = new Date();
|
|
const pad = v => v < 10 ? '0' + v : v;
|
|
const year = today.getFullYear();
|
|
const month = pad(today.getMonth() + 1);
|
|
const day = pad(today.getDate());
|
|
const stamp = `${year}-${month}-${day}`;
|
|
|
|
await docker.build(opts.myvcDir, {
|
|
tag: opts.code,
|
|
file: path.join(serverDir, 'Dockerfile.dump'),
|
|
buildArg: `STAMP=${stamp}`
|
|
}, opts.debug);
|
|
|
|
// Run container
|
|
|
|
const isRandom = opts.random;
|
|
const dbConfig = Object.assign({}, opts.dbConfig);
|
|
|
|
let runOptions;
|
|
|
|
if (isRandom)
|
|
runOptions = {publish: '3306'};
|
|
else {
|
|
runOptions = {
|
|
name: opts.code,
|
|
publish: `3306:${dbConfig.port}`
|
|
};
|
|
try {
|
|
const server = new Server(new docker.Container(opts.code));
|
|
await server.rm();
|
|
} catch (e) {}
|
|
}
|
|
|
|
const runChown = process.platform != 'linux';
|
|
|
|
Object.assign(runOptions, null, {
|
|
env: `RUN_CHOWN=${runChown}`,
|
|
detach: true,
|
|
volume: `${path.join(dumpDir, 'fixtures.sql')}:/fixtures.sql:ro`
|
|
});
|
|
const ct = await docker.run(opts.code, null, runOptions);
|
|
const server = new Server(ct, dbConfig);
|
|
|
|
if (isRandom) {
|
|
try {
|
|
const netSettings = await ct.inspect({
|
|
format: '{{json .NetworkSettings}}'
|
|
});
|
|
|
|
if (opts.ci)
|
|
dbConfig.host = netSettings.Gateway;
|
|
|
|
dbConfig.port = netSettings.Ports['3306/tcp'][0].HostPort;
|
|
} catch (err) {
|
|
await server.rm();
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
await server.wait();
|
|
|
|
// Apply changes
|
|
|
|
Object.assign(opts, {
|
|
commit: true,
|
|
dbConfig
|
|
});
|
|
await myvc.runCommand(Push, opts);
|
|
|
|
// Apply fixtures
|
|
|
|
console.log('Applying fixtures.');
|
|
await ct.exec(null,
|
|
'docker-import.sh', ['/fixtures'], 'spawn', opts.debug);
|
|
|
|
// Create triggers
|
|
|
|
console.log('Creating triggers.');
|
|
const conn = await myvc.createConnection();
|
|
|
|
for (const schema of opts.schemas) {
|
|
const triggersPath = `${opts.routinesDir}/${schema}/triggers`;
|
|
if (!await fs.pathExists(triggersPath))
|
|
continue;
|
|
|
|
const triggersDir = await fs.readdir(triggersPath);
|
|
for (const triggerFile of triggersDir)
|
|
await myvc.queryFromFile(conn, `${triggersPath}/${triggerFile}`);
|
|
}
|
|
|
|
return server;
|
|
}
|
|
}
|
|
|
|
module.exports = Run;
|
|
|
|
if (require.main === module)
|
|
new MyVC().run(Run);
|