Skip to content

Commit

Permalink
feat(dashmate): a flag to keep data on reset (#2026)
Browse files Browse the repository at this point in the history
  • Loading branch information
shumkov authored Jul 31, 2024
1 parent 9ff08df commit aa4c131
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 38 deletions.
5 changes: 4 additions & 1 deletion packages/dashmate/src/commands/reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ export default class ResetCommand extends ConfigBaseCommand {

static flags = {
...ConfigBaseCommand.flags,
hard: Flags.boolean({ char: 'h', description: 'reset config as well as data', default: false }),
hard: Flags.boolean({ char: 'h', description: 'reset config as well as services and data', default: false }),
force: Flags.boolean({ char: 'f', description: 'skip running services check', default: false }),
platform: Flags.boolean({ char: 'p', description: 'reset platform services and data only', default: false }),
verbose: Flags.boolean({ char: 'v', description: 'use verbose mode for output', default: false }),
'keep-data': Flags.boolean({ description: 'keep data', default: false }),
};

/**
Expand All @@ -30,6 +31,7 @@ export default class ResetCommand extends ConfigBaseCommand {
hard: isHardReset,
force: isForce,
platform: isPlatformOnlyReset,
'keep-data': keepData,
},
config,
resetNodeTask,
Expand Down Expand Up @@ -58,6 +60,7 @@ export default class ResetCommand extends ConfigBaseCommand {
isPlatformOnlyReset,
isForce,
isVerbose,
keepData,
});
} catch (e) {
throw new MuteOneLineError(e);
Expand Down
12 changes: 10 additions & 2 deletions packages/dashmate/src/docker/DockerCompose.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,15 +414,23 @@ export default class DockerCompose {
* Down docker compose
*
* @param {Config} config
* @param {Object} [options]
* @param {Object} [options.removeVolumes=false]
* @return {Promise<void>}
*/
async down(config) {
async down(config, options = {}) {
await this.throwErrorIfNotInstalled();

const commandOptions = ['--remove-orphans'];

if (options.removeVolumes) {
commandOptions.push('-v');
}

try {
await dockerCompose.down({
...this.#createOptions(config),
commandOptions: ['-v', '--remove-orphans'],
commandOptions,
});
} catch (e) {
throw new DockerComposeError(e);
Expand Down
88 changes: 53 additions & 35 deletions packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,57 +52,75 @@ export default function resetNodeTaskFactory(
{
title: 'Remove all services and associated data',
enabled: (ctx) => !ctx.isPlatformOnlyReset,
task: async () => dockerCompose.down(config),
task: async (ctx, task) => {
if (ctx.keepData) {
// eslint-disable-next-line no-param-reassign
task.title = 'Remove all services and keep associated data';
}

const options = {
removeVolumes: !ctx.keepData,
};

return dockerCompose.down(config, options);
},
},
{
title: 'Remove platform services and associated data',
enabled: (ctx) => ctx.isPlatformOnlyReset,
task: async () => {
task: async (ctx, task) => {
if (ctx.keepData) {
// eslint-disable-next-line no-param-reassign
task.title = 'Remove platform services and keep associated data';
}

await dockerCompose.rm(config, { profiles: ['platform'] });

// Remove volumes
const { COMPOSE_PROJECT_NAME: composeProjectName } = generateEnvs(config);
if (ctx.keepData) {
const { COMPOSE_PROJECT_NAME: composeProjectName } = generateEnvs(config);

const projectVolumeNames = await dockerCompose.getVolumeNames(
config,
{ profiles: ['platform'] },
);
const projectVolumeNames = await dockerCompose.getVolumeNames(
config,
{ profiles: ['platform'] },
);

await Promise.all(
projectVolumeNames
.map((volumeName) => `${composeProjectName}_${volumeName}`)
.map(async (volumeName) => {
const volume = await docker.getVolume(volumeName);
await Promise.all(
projectVolumeNames
.map((volumeName) => `${composeProjectName}_${volumeName}`)
.map(async (volumeName) => {
const volume = await docker.getVolume(volumeName);

let isRetry;
do {
isRetry = false;
let isRetry;
do {
isRetry = false;

try {
await volume.remove({ force: true });
} catch (e) {
// volume is in use
if (e.statusCode === 409) {
await wait(1000);
try {
await volume.remove({ force: true });
} catch (e) {
// volume is in use
if (e.statusCode === 409) {
await wait(1000);

// Remove containers
await dockerCompose.rm(config, { profiles: ['platform'] });
// Remove containers
await dockerCompose.rm(config, { profiles: ['platform'] });

isRetry = true;
isRetry = true;

continue;
}
continue;
}

// volume does not exist
if (e.statusCode === 404) {
break;
}
// volume does not exist
if (e.statusCode === 404) {
break;
}

throw e;
}
} while (isRetry);
}),
);
throw e;
}
} while (isRetry);
}),
);
}
},
},
{
Expand Down

0 comments on commit aa4c131

Please sign in to comment.