const _conf_schema : lib_plankton.conf.type_schema = { "nullable": false, "type": "object", "properties": { "version": { "nullable": false, "type": "string" }, "target": { "anyOf": [ { "nullable": false, "type": "object", "properties": { "kind": { "nullable": false, "type": "string", "enum": ["plain"] }, "parameters": { "nullable": false, "type": "object", "properties": { "directory": { "nullable": false, "type": "string" }, }, "additionalProperties": false, "required": [ "directory", ] }, }, "additionalProperties": false, "required": [ "kind", "parameters", ] }, { "nullable": false, "type": "object", "properties": { "kind": { "nullable": false, "type": "string", "enum": ["borg"] }, "parameters": { "nullable": false, "type": "object", "properties": { "repository": { "nullable": false, "type": "string" }, "compression": { "nullable": false, "type": "string", "enum": [ "none", "lz4", "zlib", "lzma", ], "default": "lz4" }, }, "required": [ "repository", ] }, }, "additionalProperties": false, "required": [ "kind", "parameters", ] } ] }, /* "defaults": { }, */ "concerns": { "nullable": false, "type": "array", "items": { "anyOf": [ { "nullable": false, "type": "object", "properties": { "active": { "nullable": false, "type": "boolean", "default": true }, "name": { "nullable": false, "type": "string" }, "kind": { "nullable": false, "type": "string", "enum": ["files"] }, "parameters": { "nullable": false, "type": "object", "properties": { "path": { "nullable": false, "type": "string", }, "name": { "nullable": false, "type": "string", }, }, "additionalProperties": false, "required": [ "path", "name", ] } }, "additionalProperties": false, "required": [ "name", "kind", "parameters", ] }, { "nullable": false, "type": "object", "properties": { "active": { "nullable": false, "type": "boolean", "default": true }, "name": { "nullable": false, "type": "string" }, "kind": { "nullable": false, "type": "string", "enum": ["postgresql_dump"] }, "parameters": { "nullable": false, "type": "object", "properties": { "credentials": { "nullable": false, "type": "object", "properties": { "host": { "nullable": false, "type": "string", }, "port": { "nullable": false, "type": "integer", "default": 5432 }, "username": { "nullable": false, "type": "string", }, "password": { "nullable": false, "type": "string", }, "schema": { "nullable": false, "type": "string", }, }, "additionalProperties": false, "required": [ "host", "username", "password", "schema", ] }, "name": { "nullable": false, "type": "string", }, }, "additionalProperties": false, "required": [ "credentials", "name", ] } }, "additionalProperties": false, "required": [ "name", "kind", "parameters", ] }, ] } }, }, "additionalProperties": false, "required": [ "version", "target", "concerns", ] }; /** */ function get_stamp(): string { let date: Date = (new Date(Date.now())); return lib_plankton.string.coin( // "{{year}}{{month}}{{day}}T{{hour}}{{minute}}{{second}}", "{{year}}-{{month}}-{{day}}", { "year": date.getFullYear().toFixed(0).padStart(4, "0"), "month": (date.getMonth() + 1).toFixed(0).padStart(2, "0"), "day": date.getDate().toFixed(0).padStart(2, "0"), "hour": date.getHours().toFixed(0).padStart(2, "0"), "minute": date.getMinutes().toFixed(0).padStart(2, "0"), "second": date.getSeconds().toFixed(0).padStart(2, "0"), } ); } /** */ async function main(): Promise { // const conf = lib_plankton.json.decode(await lib_plankton.file.read("conf.json")); const conf : any = await lib_plankton.conf.load( _conf_schema, "conf.json" ); const stamp: string = get_stamp(); switch (conf.target.kind) { case "plain": { const target_directory = (conf.target.parameters.directory/* + "/" + stamp*/); let commands: Array = []; const commands_add : (command: string) => void = (command) => { commands.push(command); }; const commands_apply : () => void = () => { // TODO process.stdout.write(commands.join("\n") + "\n"); }; commands_add( lib_plankton.string.coin( "mkdir --parents {{directory}}", { "directory": target_directory, } ) ); commands_add( "" ); for await (const concern of conf.concerns) { if (! concern.active) { // do nothing } else { commands_add( lib_plankton.string.coin( "# {{name}}", { "name": concern.name, "kind": concern.kind, } ) ); commands_add( lib_plankton.string.coin( "echo '-- {{name}}' > /dev/stderr", { "name": concern.name, "kind": concern.kind, } ) ); switch (concern.kind) { case "files": { commands_add( lib_plankton.string.coin( "mkdir --parents {{directory}}", { "directory": lib_plankton.string.coin( "{{directory}}/{{name}}", { "directory": target_directory, "name": concern.parameters.name, } ), } ) ); commands_add( lib_plankton.string.coin( "tar --create --directory={{path}} . > {{target_path}}", { "path": concern.parameters.path, "target_path": lib_plankton.string.coin( "{{directory}}/{{name}}/data.tar", { "directory": target_directory, "name": concern.parameters.name, } ), } ) ); break; } case "postgresql_dump": { const password_file_path: string = "${HOME}/.pgpass"; commands_add( lib_plankton.string.coin( "echo '{{host}}:{{port}}:{{schema}}:{{username}}:{{password}}' > {{path}} && chmod 0600 {{path}}", { "path": password_file_path, "host": concern.parameters.credentials.host, "port": concern.parameters.credentials.port.toFixed(0), "username": concern.parameters.credentials.username, "password": concern.parameters.credentials.password, "schema": concern.parameters.credentials.schema, } ) ); commands_add( lib_plankton.string.coin( "mkdir --parents {{directory}}", { "directory": lib_plankton.string.coin( "{{directory}}/{{name}}", { "directory": target_directory, "name": concern.parameters.name, } ), } ) ); commands_add( lib_plankton.string.coin( "pg_dump --host={{host}} --port={{port}} --username={{username}} {{schema}} > {{target_path}}", { "host": concern.parameters.credentials.host, "port": concern.parameters.credentials.port.toFixed(0), "username": concern.parameters.credentials.username, "schema": concern.parameters.credentials.schema, "target_path": lib_plankton.string.coin( "{{directory}}/{{name}}/data.sql", { "directory": target_directory, "name": concern.parameters.name, } ), } ) ); commands_add( lib_plankton.string.coin( "rm {{path}}", { "path": password_file_path, } ) ); break; } default: { throw (new Error("unhandled kind: " + concern.kind)); break; } } commands_add( "" ); } } commands_add( lib_plankton.string.coin( "echo '{{directory}}'", { "directory": target_directory, } ) ); commands_apply(); break; } default: { throw (new Error("unhandled target kind: " + conf.target.kind)); break; } } return Promise.resolve(undefined); } main();