diff --git a/readme.md b/readme.md index d012b65..979db2c 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ - `tools/update-plankton` - `tools/build` -- `/tmp/mimir/mimir -c misc/conf-ramsch.mmr.json borg-run` +- `/tmp/mimir/mimir -c misc/conf-ramsch.mmr.json run` diff --git a/source/conf.ts b/source/conf.ts index 38a6727..ebf8163 100644 --- a/source/conf.ts +++ b/source/conf.ts @@ -20,15 +20,20 @@ namespace _mimir.conf "kind": { "nullable": false, "type": "string", - "enum": ["keep"] + "enum": ["local"] }, "parameters": { "nullable": false, "type": "object", "properties": { + "directory": { + "nullable": false, + "type": "string" + }, }, "additionalProperties": false, "required": [ + "directory", ] }, }, @@ -223,12 +228,15 @@ namespace _mimir.conf /** + * @todo split from conf */ - export type type_target_parameters_keep = { + export type type_target_parameters_local = { + directory : string; }; /** + * @todo split from conf */ export type type_target_parameters_borg = { repository : string; @@ -237,6 +245,7 @@ namespace _mimir.conf /** + * @todo split from conf */ export type type_concern_parameters_files = { name : string; @@ -245,6 +254,23 @@ namespace _mimir.conf /** + * @todo split from conf + */ + export type type_target = ( + { + kind : "local"; + parameters : type_target_parameters_local; + } + | + { + kind : "borg"; + parameters : type_target_parameters_borg; + } + ); + + + /** + * @todo split from conf */ export type type_concern_parameters_postgresql_dump = { credentials : { @@ -257,37 +283,33 @@ namespace _mimir.conf }; + /** + * @todo split from conf + */ + export type type_concern = ( + { + kind : "files"; + parameters : type_concern_parameters_files; + } + | + { + kind : "postgresql_dump"; + parameters : type_concern_parameters_postgresql_dump; + } + ); + + /** */ export type type_conf = { - target : ( - { - kind : "keep"; - parameters : type_target_parameters_keep; - } - | - { - kind : "borg"; - parameters : type_target_parameters_borg; - } - ); + target : type_target; concerns : Array< { active ?: boolean; name : string; } & - ( - { - kind : "files"; - parameters : type_concern_parameters_files; - } - | - { - kind : "postgresql_dump"; - parameters : type_concern_parameters_postgresql_dump; - } - ) + type_concern >; }; diff --git a/source/logic/serialization/_abstract.ts b/source/logic/serialization/_abstract.ts new file mode 100644 index 0000000..3849056 --- /dev/null +++ b/source/logic/serialization/_abstract.ts @@ -0,0 +1,15 @@ +namespace _mimir.serialization +{ + + /** + */ + export type type_logic = { + execute : ( + (directory : string) + => + Array + ); + }; + +} + diff --git a/source/logic/serialization/_factory.ts b/source/logic/serialization/_factory.ts new file mode 100644 index 0000000..f90345f --- /dev/null +++ b/source/logic/serialization/_factory.ts @@ -0,0 +1,31 @@ +namespace _mimir.serialization +{ + + /** + */ + export function get_logic( + concern : _mimir.conf.type_concern + ) : type_logic + { + switch (concern.kind) { + default: { + throw (new Error("unhandled concern kind: " + concern["kind"])); + break; + } + case "files": { + return { + "execute": (directory) => _mimir.serialization.files.execute(concern.parameters, directory), + }; + break; + } + case "postgresql_dump": { + return { + "execute": (directory) => _mimir.serialization.postgresql_dump.execute(concern.parameters, directory), + }; + break; + } + } + } + +} + diff --git a/source/logic/transfer/_abstract.ts b/source/logic/transfer/_abstract.ts new file mode 100644 index 0000000..7674f10 --- /dev/null +++ b/source/logic/transfer/_abstract.ts @@ -0,0 +1,18 @@ +namespace _mimir.transfer +{ + + /** + */ + export type type_logic = { + execute : ( + ( + name : string, + stamp : string, + directory : string + ) + => + Array + ); + }; + +} diff --git a/source/logic/transfer/_factory.ts b/source/logic/transfer/_factory.ts new file mode 100644 index 0000000..dfcb660 --- /dev/null +++ b/source/logic/transfer/_factory.ts @@ -0,0 +1,31 @@ +namespace _mimir.transfer +{ + + /** + */ + export function get_logic( + target : _mimir.conf.type_target + ) : type_logic + { + switch (target.kind) { + default: { + throw (new Error("unhandled transfer kind: " + target["kind"])); + break; + } + case "local": { + return { + "execute": (name, stamp, directory) => _mimir.transfer.local.execute(target.parameters, name, stamp, directory), + }; + break; + } + case "borg": { + return { + "execute": (name, stamp, directory) => _mimir.transfer.borg.execute(target.parameters, name, stamp, directory), + }; + break; + } + } + } + +} + diff --git a/source/logic/transfer/borg.ts b/source/logic/transfer/borg.ts index b3c9715..e22498b 100644 --- a/source/logic/transfer/borg.ts +++ b/source/logic/transfer/borg.ts @@ -2,6 +2,7 @@ namespace _mimir.transfer.borg { /** + * @todo parametrize pruning */ export function execute( parameters : _mimir.conf.type_target_parameters_borg, diff --git a/source/logic/transfer/keep.ts b/source/logic/transfer/keep.ts deleted file mode 100644 index 5660bb0..0000000 --- a/source/logic/transfer/keep.ts +++ /dev/null @@ -1,19 +0,0 @@ -namespace _mimir.transfer.keep -{ - - /** - */ - export function execute( - parameters : _mimir.conf.type_target_parameters_keep, - name : string, - stamp : string, - directory : string - ) : Array - { - const result : Array = []; - // do noting - return result; - } - -} - diff --git a/source/logic/transfer/local.ts b/source/logic/transfer/local.ts new file mode 100644 index 0000000..1015dbd --- /dev/null +++ b/source/logic/transfer/local.ts @@ -0,0 +1,43 @@ +namespace _mimir.transfer.local +{ + + /** + */ + export function execute( + parameters : _mimir.conf.type_target_parameters_local, + name : string, + stamp : string, + directory : string + ) : Array + { + const result : Array = []; + const target_directory : string = lib_plankton.string.coin( + "{{base}}/{{stamp}}/{{name}}", + { + "base": parameters.directory, + "stamp": stamp, + "name": name, + } + ); + result.push( + lib_plankton.string.coin( + "mkdir --parents {{directory}}", + { + "directory": target_directory, + } + ) + ); + result.push( + lib_plankton.string.coin( + "mv {{directory_from}}/* {{directory_to}}/", + { + "directory_from": directory, + "directory_to": target_directory, + } + ) + ); + return result; + } + +} + diff --git a/source/main.ts b/source/main.ts index b688ea4..85507c7 100644 --- a/source/main.ts +++ b/source/main.ts @@ -40,18 +40,22 @@ namespace _mimir "description": "what to do", "options": ( [ + { + "name": "conf-schema", + "description": "conf-schema" + }, + { + "name": "conf-expose", + "description": "conf-expose" + }, + { + "name": "init", + "description": "init" + }, { "name": "run", "description": "run" }, - { - "name": "borg-init", - "description": "borg-init" - }, - { - "name": "borg-run", - "description": "borg-run" - }, ] .map( entry => lib_plankton.string.coin( @@ -102,55 +106,96 @@ namespace _mimir ); } else { - const conf : _mimir.conf.type_conf = await lib_plankton.conf.load(_mimir.conf.schema, args["conf_path"]); - // process.stdout.write(JSON.stringify(conf, undefined, "\t")); - const stamp: string = get_stamp(); - /** - * @todo get from configuration - */ - const base_directory : string = "/tmp/mimir"; - switch (args["action"]) { + default: { + lib_plankton.log.error( + "invalid_action", + { + "action": args["action"], + } + ); + return Promise.reject("invalid action"); + break; + } + case "conf-schema": { + process.stdout.write( + JSON.stringify( + _mimir.conf.schema, + undefined, + "\t" + ) + ); + return Promise.resolve(undefined); + break; + } + case "conf-expose": { + const conf : _mimir.conf.type_conf = await lib_plankton.conf.load(_mimir.conf.schema, args["conf_path"]); + process.stdout.write( + JSON.stringify( + conf, + undefined, + "\t" + ) + ); + return Promise.resolve(undefined); + break; + } case "init": { return Promise.reject(new Error("not implemented")); break; } case "run": { + const conf : _mimir.conf.type_conf = await lib_plankton.conf.load(_mimir.conf.schema, args["conf_path"]); + const stamp : string = get_stamp(); + /** + * @todo get from configuration + */ + const base_directory : string = "/tmp/mimir"; + for await (const concern of conf.concerns) { 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( + "## {{name}}\n", + { + "name": concern.name, + } + ) + ); + commands_add( + lib_plankton.string.coin( + "echo '-- {{name}}'", + { + "name": concern.name, + "kind": concern.kind, + } + ) + ); + if (! concern.active) { - // do nothing + commands_add( + "echo '-- (skipping)'" + ); } else { - const directory : string = (base_directory + "/" + stamp + "/" + concern.name); + const directory : string = lib_plankton.string.coin( + "{{base}}/{{stamp}}/{{name}}", + { + "base": base_directory, + "stamp": stamp, + "name": concern.name, + } + ); - // prepare + // preparation { - commands_add( - lib_plankton.string.coin( - "## {{name}}\n", - { - "name": concern.name, - } - ) - ); - commands_add( - lib_plankton.string.coin( - "echo '-- {{name}}' > /dev/stderr", - { - "name": concern.name, - "kind": concern.kind, - } - ) - ); commands_add( lib_plankton.string.coin( "mkdir --parents {{directory}}", @@ -161,89 +206,53 @@ namespace _mimir ); } - // serialize + // serialization { - switch (concern.kind) { - case "files": { - commands = commands.concat( - _mimir.serialization.files.execute( - concern.parameters, - directory - ) - ); - break; - } - case "postgresql_dump": { - commands = commands.concat( - _mimir.serialization.postgresql_dump.execute( - concern.parameters, - directory - ) - ); - break; - } - default: { - throw (new Error("unhandled kind: " + concern["kind"])); - break; - } - } + const serialization_logic : _mimir.serialization.type_logic = _mimir.serialization.get_logic(concern); + commands = commands.concat( + serialization_logic.execute( + directory + ) + ); } // transfer { - switch (conf.target.kind) { - case "keep": { - commands = commands.concat( - _mimir.transfer.keep.execute( - conf.target.parameters, - concern.name, - stamp, - directory - ) - ); - break; - } - case "borg": { - commands = commands.concat( - _mimir.transfer.borg.execute( - conf.target.parameters, - concern.name, - stamp, - directory - ) - ); - break; - } - default: { - throw (new Error("unhandled target kind: " + conf.target["kind"])); - break; - } - } + const target_logic : _mimir.transfer.type_logic = _mimir.transfer.get_logic(conf.target); + commands = commands.concat( + target_logic.execute( + concern.name, + stamp, + directory + ) + ); } - // clean + // cleaning { /** - * @todo + * @todo use shred? */ + commands_add( + lib_plankton.string.coin( + "rm --recursive {{path}}/*", + { + "path": base_directory, + } + ) + ); } - - commands_add( - "" - ); - commands_add( - "" - ); - commands_apply(); } + + commands_add( + "" + ); + commands_add( + "" + ); + commands_apply(); } - return Promise.resolve(undefined); - break; - } - default: { - throw (new Error("invalid action: " + args["action"])); - return Promise.resolve(undefined); break; } @@ -253,5 +262,17 @@ namespace _mimir } } -_mimir.main(process.argv.slice(2)); +( + _mimir.main(process.argv.slice(2)) + .then( + (result) => { + process.exit(0); + } + ) + .catch( + (reason) => { + process.exit(1); + } + ) +); diff --git a/tools/makefile b/tools/makefile index 516b6c0..7f2a93b 100644 --- a/tools/makefile +++ b/tools/makefile @@ -45,10 +45,14 @@ ${dir_temp}/mimir-raw.js: \ ${dir_lib}/plankton/plankton.d.ts \ ${dir_source}/helpers/borg.ts \ ${dir_source}/conf.ts \ + ${dir_source}/logic/serialization/_abstract.ts \ ${dir_source}/logic/serialization/files.ts \ ${dir_source}/logic/serialization/postgresql_dump.ts \ - ${dir_source}/logic/transfer/keep.ts \ + ${dir_source}/logic/serialization/_factory.ts \ + ${dir_source}/logic/transfer/_abstract.ts \ + ${dir_source}/logic/transfer/local.ts \ ${dir_source}/logic/transfer/borg.ts \ + ${dir_source}/logic/transfer/_factory.ts \ ${dir_source}/main.ts @ ${cmd_log} "compile …" @ ${cmd_mkdir} $(dir $@) diff --git a/tools/update-plankton b/tools/update-plankton index 04e904a..1cc35e7 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -12,6 +12,7 @@ modules="${modules} call" modules="${modules} json" modules="${modules} string" modules="${modules} args" +modules="${modules} log" ## exec