Skip to content

Commit

Permalink
fix(tooling): Run wait-for-user before tooling to make sure the permi…
Browse files Browse the repository at this point in the history
…ssion setup is finished

Refs: lando/lando#3373
  • Loading branch information
florianPat committed Jul 23, 2024
1 parent 8786c4e commit 090837d
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 9 deletions.
22 changes: 21 additions & 1 deletion lib/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ const composeFlags = {
outputFilePath: '-o',
};

const composeFlagOptionMapping = {
build: ['noCache', 'pull', 'q'],
down: ['removeOrphans', 'volumes'],
exec: ['background', 'detach', 'noTTY'],
kill: ['removeOrphans'],
logs: ['follow', 'timestamps'],
ps: ['q'],
pull: ['q'],
rm: ['force', 'volumes'],
up: ['background', 'detach', 'noRecreate', 'noDeps', 'pull', 'q', 'recreate', 'removeOrphans', 'timestamps'],
config: ['outputFilePath', 'q'],
};

// Default options nad things
const defaultOptions = {
build: {noCache: false, pull: true},
Expand All @@ -40,7 +53,14 @@ const defaultOptions = {
/*
* Helper to merge options with default
*/
const mergeOpts = (run, opts = {}) => _.merge({}, defaultOptions[run], opts);
const mergeOpts = (run, opts = {}) => _.merge(
{},
defaultOptions[run],
_.pickBy(
opts,
(value, index) => (!_.includes(_.keys(composeFlags), index)) || _.includes(composeFlagOptionMapping[run], index),
),
);

/*
* Parse docker-compose options
Expand Down
2 changes: 2 additions & 0 deletions lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ exports.run = (data, compose, docker, started = true) => Promise.mapSeries(norma
// if this is a prestart build step and its not the last one make sure we set started = true
// this prevents us from having to stop and then restart the container during builds
started = _.get(datum, 'opts.prestart', false) && !_.get(datum, 'opts.last', false);

return compose('run', _.merge({}, datum, {opts: {cmd: '/helpers/wait-for-user.sh', id: datum.id}}));
});
}
})
Expand Down
3 changes: 2 additions & 1 deletion scripts/wait-for-user.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set -e
# user info
user="${1:-$LANDO_WEBROOT_USER}"
id="${2:-$LANDO_HOST_UID}"
gid="${3:-$LANDO_HOST_GID}"

# retry settings
attempt=0
Expand All @@ -13,7 +14,7 @@ retry=25

until [ "$attempt" -ge "$retry" ]
do
id "$user"| grep uid | grep "$id" &>/dev/null && break
id -u "$user" | grep "$id" &>/dev/null && id -g "$user" | grep "$gid" &>/dev/null && su "$user" -c "whoami" &>/dev/null && break
attempt=$((attempt+1))
sleep "$delay"
done
1 change: 1 addition & 0 deletions tasks/ssh.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = (lando, app) => {
const api = _.get(_.find(app.info, {service}), 'api', 3);
// set additional opt defaults if possible
const opts = [undefined, api === 4 ? undefined : '/app'];
opts[2] = !app._config.command.deps ?? false;
// mix any v4 service info on top of app.config.services
const services = _(_.get(app, 'config.services', {}))
.map((service, id) => _.merge({}, {id}, service))
Expand Down
3 changes: 2 additions & 1 deletion utils/build-tooling-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const getContainerPath = (appRoot, appMount = undefined) => {
return dir.join('/');
};

module.exports = (app, command, service, user, env = {}, dir = undefined, appMount = undefined) => ({
module.exports = (app, command, service, user, env = {}, dir = undefined, appMount = undefined, noDeps = false) => ({
id: app.containers[service],
compose: app.compose,
project: app.project,
Expand All @@ -32,5 +32,6 @@ module.exports = (app, command, service, user, env = {}, dir = undefined, appMou
services: _.compact([service]),
hijack: false,
autoRemove: true,
noDeps,
}, _.identity),
});
6 changes: 4 additions & 2 deletions utils/build-tooling-task.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ module.exports = (config, injected) => {
// Kick off the pre event wrappers
.then(() => app.events.emit(`pre-${eventName}`, config, answers))
// Get an interable of our commandz
.then(() => _.map(require('./parse-tooling-config')(cmd, service, options, answers)))
.then(() => _.map(require('./parse-tooling-config')(cmd, service, name, options, answers)))
// Build run objects
.map(({command, service}) => require('./build-tooling-runner')(app, command, service, user, env, dir, appMount))
.map(
({command, service}) =>
require('./build-tooling-runner')(app, command, service, user, env, dir, appMount, !answers.deps ?? false))
// Try to run the task quickly first and then fallback to compose launch
.each(runner => require('./build-docker-exec')(injected, stdio, runner).catch(execError => {
return injected.engine.isRunning(runner.id).then(isRunning => {
Expand Down
8 changes: 4 additions & 4 deletions utils/parse-tooling-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ const handleDynamic = (config, options = {}, answers = {}) => {
* the first three assuming they are [node, lando.js, options.name]'
* Check to see if we have global lando opts and remove them if we do
*/
const handleOpts = (config, argopts = []) => {
const handleOpts = (config, name, argopts = []) => {
// Append any user specificed opts
argopts = argopts.concat(process.argv.slice(3));
argopts = argopts.concat(process.argv.slice(process.argv.findIndex(value => value === name) + 1));
// If we have no args then just return right away
if (_.isEmpty(argopts)) return config;
// Return
Expand All @@ -65,13 +65,13 @@ const parseCommand = (cmd, service) => ({
});

// adds required methods to ensure the lando v3 debugger can be injected into v4 things
module.exports = (cmd, service, options = {}, answers = {}) => _(cmd)
module.exports = (cmd, service, name, options = {}, answers = {}) => _(cmd)
// Put into an object so we can handle "multi-service" tooling
.map(cmd => parseCommand(cmd, service))
// Handle dynamic services
.map(config => handleDynamic(config, options, answers))
// Add in any argv extras if they've been passed in
.map(config => handleOpts(config, handlePassthruOpts(options, answers)))
.map(config => handleOpts(config, name, handlePassthruOpts(options, answers)))
// Wrap the command in /bin/sh if that makes sense
.map(config => _.merge({}, config, {command: require('./shell-escape')(config.command, true, config.args)}))
// Add any args to the command and compact to remove undefined
Expand Down

0 comments on commit 090837d

Please sign in to comment.