#0 - Add volume restoration functionality #2

Merged
GuillaumeHemmen merged 1 commit from feat/implement-restore into master 2024-08-21 13:27:50 +02:00

View file

@ -81,7 +81,7 @@ const listAndSelectDockerVolumes = async (toolbox: Toolbox): Promise<string[]> =
const {selectedVolumes} = await prompt.ask({ const {selectedVolumes} = await prompt.ask({
type: 'multiselect', type: 'multiselect',
name: 'selectedVolumes', name: 'selectedVolumes',
message: 'Select the volumes you want to backup:', message: 'Select the volumes you want to treat:',
choices: volumeList, choices: volumeList,
}) as { selectedVolumes: string[] }; }) as { selectedVolumes: string[] };
@ -116,6 +116,62 @@ const runVolumeBackup = async (toolbox: Toolbox, workingDir: string, volumes: st
} }
} }
const listAndSelectArchives = async (toolbox: Toolbox, workingDir: string, volumes: string[]): Promise<string[]> =>{
const {print, filesystem} = toolbox
print.divider();
print.warning('To avoid problem with docker compose, we list only the archive to restore if');
print.warning('there is an EXISTING volume of the same name. Please, ensure that the volumes');
print.warning('are created prior to run this tool.');
const spinner = print.spin('running docker volume ls');
// test if an archive for the name of the volume exist if yes add it to the list
try {
const archives: string[] = [];
for (const volume of volumes) {
// check if file exist
if (filesystem.exists(`${workingDir}/${volume}.tar`)) {
spinner.succeed(`Archive found for ${volume}.`);
archives.push(`${volume}`);
} else {
spinner.fail(`No archive found for ${volume}.`);
}
}
return archives;
} catch (listAndSelectArchivesError) {
spinner.fail('Failed to list docker volumes or to access backups!')
process.exit(4)
}
}
const runVolumeRestore = async (toolbox: Toolbox, workingDir: string, archives: string[]) => {
const {print, system} = toolbox;
print.divider();
print.info('starting restore process');
print.newline();
const spinner = print.spin();
for (const archive of archives) {
try {
spinner.start(`restore volume ${archive}...`)
await system.run(`docker run -v "${archive}":/volume -v "${workingDir}":/tmp alpine sh -c "rm -rf /volume/* && tar -p -xf /tmp/${archive}.tar -C /volume"`);
spinner.succeed(`volume ${archive} restored!`)
} catch (error) {
spinner.fail(`volume ${archive} restore failed!`)
print.error(error);
print.newline();
}
}
}
const command: GluegunCommand = { const command: GluegunCommand = {
name: 'docker-volume-manager', name: 'docker-volume-manager',
run: async (toolbox) => { run: async (toolbox) => {
@ -133,7 +189,6 @@ const command: GluegunCommand = {
if (choice === 'Backup volume') { if (choice === 'Backup volume') {
// select the backup location folder // select the backup location folder
// @ts-ignore
const workingFolder = await getAndValidateBackupFolder(toolbox); const workingFolder = await getAndValidateBackupFolder(toolbox);
// list and select the volumes // list and select the volumes
@ -145,10 +200,14 @@ const command: GluegunCommand = {
print.success('Your volume have been backed up!') print.success('Your volume have been backed up!')
} else if (choice === 'Restore volumes') { } else if (choice === 'Restore volumes') {
// select the backup location folder // select the backup location folder
const workingFolder = await getAndValidateBackupFolder(toolbox);
// list and select the archives to restore // list and select the archives to restore
const volumes = await listAndSelectDockerVolumes(toolbox);
const archives = await listAndSelectArchives(toolbox, workingFolder, volumes);
// run the restore // run the restore
await runVolumeRestore(toolbox, workingFolder, archives);
print.success('your backup have been restored!'); print.success('your backup have been restored!');
} else if (choice === 'exit') { } else if (choice === 'exit') {