From 0577a068f094c9e250f1bd1f99cb4fce3e2ef50b Mon Sep 17 00:00:00 2001 From: Juanra GM Date: Thu, 25 Jan 2024 17:24:54 +0100 Subject: [PATCH] feat(cli): add `mongo-dump` task --- .changeset/tame-pots-promise.md | 5 ++ Dockerfile | 1 + packages/cli/src/tasks/MongoDumpTask.ts | 71 +++++++++++++++++++ .../src/utils/datatruck/config-task-type.ts | 10 +++ packages/cli/src/utils/datatruck/task.ts | 3 + 5 files changed, 90 insertions(+) create mode 100644 .changeset/tame-pots-promise.md create mode 100644 packages/cli/src/tasks/MongoDumpTask.ts diff --git a/.changeset/tame-pots-promise.md b/.changeset/tame-pots-promise.md new file mode 100644 index 0000000..5e5c9a2 --- /dev/null +++ b/.changeset/tame-pots-promise.md @@ -0,0 +1,5 @@ +--- +"@datatruck/cli": minor +--- + +Add `mongo-dump` task (only backup) diff --git a/Dockerfile b/Dockerfile index b5afa02..2ec7bb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ RUN apk add --no-cache \ mariadb-client \ mariadb-backup \ postgresql-client \ + mongodb-tools \ python3 \ tar \ pigz diff --git a/packages/cli/src/tasks/MongoDumpTask.ts b/packages/cli/src/tasks/MongoDumpTask.ts new file mode 100644 index 0000000..9ff37a3 --- /dev/null +++ b/packages/cli/src/tasks/MongoDumpTask.ts @@ -0,0 +1,71 @@ +import { AsyncProcess } from "../utils/async-process"; +import { ensureEmptyDir, fetchData, mkdirIfNotExists } from "../utils/fs"; +import { mkTmpDir } from "../utils/temp"; +import { TaskBackupData, TaskRestoreData, TaskAbstract } from "./TaskAbstract"; + +export type MongoDumpTaskConfig = { + command?: string; + hostname?: string; + port?: number; + username?: string; + password?: string | { path: string }; + compress?: boolean; + concurrency?: number; +}; + +export const mongodumpTaskName = "mongo-dump"; + +export class MongoDumpTask extends TaskAbstract { + protected verbose?: boolean; + private get command() { + return this.config.command ?? "mongodump"; + } + + override async backup(data: TaskBackupData) { + this.verbose = data.options.verbose; + + const snapshotPath = + data.package.path ?? + (await mkTmpDir(mongodumpTaskName, "task", "backup", "snapshot")); + + await mkdirIfNotExists(snapshotPath); + await ensureEmptyDir(snapshotPath); + + const p = new AsyncProcess( + this.command, + [ + ...(this.config.hostname ? ["/h", this.config.hostname] : []), + ...(this.config.port ? ["/p", this.config.port] : []), + ...(this.config.username ? ["/u", this.config.username] : []), + ...(this.config.compress ? ["/gzip"] : []), + ...(this.config.concurrency ? ["/j", this.config.concurrency] : []), + "/o", + snapshotPath, + ], + { + $log: this.verbose, + }, + ); + + const password = + this.config.password !== undefined + ? (await fetchData(this.config.password, (p) => p.path)) ?? "" + : ""; + + p.stdin.writable.write(`${password}\n`); + + await p.stderr.parseLines((line) => { + data.onProgress({ + absolute: { + description: line.slice(0, 255), + }, + }); + }); + + return { snapshotPath }; + } + + override async restore(data: TaskRestoreData) { + throw new Error("Not implemented"); + } +} diff --git a/packages/cli/src/utils/datatruck/config-task-type.ts b/packages/cli/src/utils/datatruck/config-task-type.ts index 4f0c45d..bbe38a2 100644 --- a/packages/cli/src/utils/datatruck/config-task-type.ts +++ b/packages/cli/src/utils/datatruck/config-task-type.ts @@ -3,6 +3,10 @@ import type { MariadbTaskConfig, mariadbTaskName, } from "../../tasks/MariadbTask"; +import { + MongoDumpTaskConfig, + mongodumpTaskName, +} from "../../tasks/MongoDumpTask"; import type { MssqlTaskConfig, mssqlTaskName } from "../../tasks/MssqlTask"; import type { MysqlDumpTaskConfig, @@ -39,6 +43,11 @@ export type PostgresqlDumpTaskConfigItem = { config: PostgresqlDumpTaskConfig; }; +export type MongodumpTaskConfigItem = { + name: typeof mongodumpTaskName; + config: MongoDumpTaskConfig; +}; + export type ScriptTaskConfigItem = { name: typeof scriptTaskName; config: ScriptTaskConfig; @@ -50,4 +59,5 @@ export type TaskConfig = | MssqlTaskConfigItem | MysqlDumpTaskConfigItem | PostgresqlDumpTaskConfigItem + | MongodumpTaskConfigItem | ScriptTaskConfigItem; diff --git a/packages/cli/src/utils/datatruck/task.ts b/packages/cli/src/utils/datatruck/task.ts index 388eb33..eeb5d88 100644 --- a/packages/cli/src/utils/datatruck/task.ts +++ b/packages/cli/src/utils/datatruck/task.ts @@ -1,5 +1,6 @@ import { GitTask, gitTaskName } from "../../tasks/GitTask"; import { MariadbTask, mariadbTaskName } from "../../tasks/MariadbTask"; +import { MongoDumpTask, mongodumpTaskName } from "../../tasks/MongoDumpTask"; import { MssqlTask, mssqlTaskName } from "../../tasks/MssqlTask"; import { MysqlDumpTask, mysqlDumpTaskName } from "../../tasks/MysqlDumpTask"; import { @@ -22,6 +23,8 @@ export function createTask(task: TaskConfig): TaskAbstract { return new PostgresqlDumpTask(task.config ?? {}); } else if (task.name === mssqlTaskName) { return new MssqlTask(task.config ?? {}); + } else if (task.name === mongodumpTaskName) { + return new MongoDumpTask(task.config ?? {}); } else if (task.name === scriptTaskName) { return new ScriptTask(task.config ?? {}); } else {