Skip to content

Commit

Permalink
fix(compose): Fix compose file path resolution as it is copied into the
Browse files Browse the repository at this point in the history
lando directory

Refs: lando/lando#3373
  • Loading branch information
florianPat committed Mar 13, 2024
1 parent 903abba commit 9d594c4
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 24 deletions.
49 changes: 29 additions & 20 deletions lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,27 +272,36 @@ module.exports = class App {
// We should only need to initialize once, if we have just go right to app ready
if (this.initialized) return this.events.emit('ready', this);
// Get compose data if we have any, otherwise set to []
const composeFiles = require('../utils/load-compose-files')(_.get(this, 'config.compose', []), this.root);
this.composeData = [new this.ComposeService('compose', {}, ...composeFiles)];
// Validate and set env files
this.envFiles = require('../utils/normalize-files')(_.get(this, 'config.env_file', []), this.root);
// Log some things
this.log.verbose('initiatilizing app at %s...', this.root);
this.log.silly('app has config', this.config);
return require('../utils/load-compose-files')(
_.get(this, 'config.compose', []),
this.root,
this._dir,
(composeFiles, outputFilePath) =>
this.engine.getComposeConfig({compose: composeFiles, project: this.project, outputFilePath}),
)

.then(composeFile => {
this.composeData = [new this.ComposeService('compose', {}, composeFile)];
// Validate and set env files
this.envFiles = require('../utils/normalize-files')(_.get(this, 'config.env_file', []), this.root);
// Log some things
this.log.verbose('initiatilizing app at %s...', this.root);
this.log.silly('app has config', this.config);

/**
* Event that allows altering of the app object right before it is
* initialized.
*
* Note that this is a global event so it is invoked with `lando.events.on`
* not `app.events.on` See example below:
*
* @since 3.0.0
* @alias app.events:pre-init
* @event pre_init
* @property {App} app The app instance.
*/
return loadPlugins(this, this._lando).then(() => this.events.emit('pre-init', this))
/**
* Event that allows altering of the app object right before it is
* initialized.
*
* Note that this is a global event so it is invoked with `lando.events.on`
* not `app.events.on` See example below:
*
* @since 3.0.0
* @alias app.events:pre-init
* @event pre_init
* @property {App} app The app instance.
*/
return loadPlugins(this, this._lando).then(() => this.events.emit('pre-init', this))
})

// Actually assemble this thing so its ready for that engine
.then(() => {
Expand Down
7 changes: 7 additions & 0 deletions lib/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const composeFlags = {
rm: '--rm',
timestamps: '--timestamps',
volumes: '-v',
outputFilePath: '-o',
};

// Default options nad things
Expand All @@ -33,6 +34,7 @@ const defaultOptions = {
pull: {},
rm: {force: true, volumes: true},
up: {background: true, noRecreate: true, recreate: false, removeOrphans: true},
config: {},
};

/*
Expand Down Expand Up @@ -127,3 +129,8 @@ exports.start = (compose, project, opts = {}) => buildShell('up', project, compo
* Run docker compose kill
*/
exports.stop = (compose, project, opts = {}) => buildShell('kill', project, compose, opts);

/*
* Run docker compose config
*/
exports.config = (compose, project, opts = {}) => buildShell('config', project, compose, opts);
20 changes: 20 additions & 0 deletions lib/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,5 +479,25 @@ module.exports = class Engine {
// stop
return this.engineCmd('stop', data);
};

/**
* Get dumped docker compose config for compose files from project
* using a `compose` object with `{compose: compose, project: project, opts: opts}`
*
* @since 3.0.0
* @param {Object} data Config needs a service within a compose context
* @param {Array} data.compose An Array of paths to Docker compose files
* @param {String} data.project A String of the project name (Usually this is the same as the app name)
* @param {String} [data.outputFilePath='/path/to/file.yml'] String to output path
* @param {Object} [data.opts] Options
* @return {Promise} A Promise.
* @example
* return lando.engine.stop(app);
*/
getComposeConfig(data) {
data.opts = {cmd: ['-o', data.outputFilePath]};
delete data.outputFilePath;
return this.engineCmd('config', data);
};
};

2 changes: 2 additions & 0 deletions lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,5 @@ exports.start = (data, compose) => retryEach(data, datum => compose('start', dat
exports.stop = (data, compose, docker) => retryEach(data, datum => {
return (datum.compose) ? compose('stop', datum) : docker.stop(getContainerId(datum));
});

exports.config = (data, compose) => retryEach(data, datum => compose('config', datum));
2 changes: 1 addition & 1 deletion utils/get-app-mounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = app => _(app.services)
// Objectify
.map(service => _.merge({name: service}, _.get(app, `config.services.${service}`, {})))
// Set the default
.map(config => _.merge({}, config, {app_mount: _.get(config, 'app_mount', 'cached')}))
.map(config => _.merge({}, config, {app_mount: _.get(config, 'app_mount', app.config.app_mount || 'cached')}))
// Filter out disabled mountes
.filter(config => config.app_mount !== false && config.app_mount !== 'disabled')
// Combine together
Expand Down
18 changes: 15 additions & 3 deletions utils/load-compose-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

const _ = require('lodash');
const Yaml = require('./../lib/yaml');
const path = require('path');
const yaml = new Yaml();
const fs = require('fs');

module.exports = (files, dir) => _(require('./normalize-files')(files, dir))
.map(file => yaml.load(file))
.value();
// This just runs `docker compose --project-directory ${dir} config -f ${files} --output ${outputPaths}` to
// make all paths relative to the lando config root
module.exports = async (files, dir, landoComposeConfigDir, outputConfigFunction) => {
const composeFilePaths = _(require('./normalize-files')(files, dir)).value();
const outputFile = path.join(landoComposeConfigDir, 'resolved-compose-config.yml');

fs.mkdirSync(path.dirname(outputFile), {recursive: true});
await outputConfigFunction(composeFilePaths, outputFile);
const result = yaml.load(outputFile);
fs.unlinkSync(outputFile);

return result;
};

0 comments on commit 9d594c4

Please sign in to comment.