[mod] alles: schon recht brauchbar

This commit is contained in:
Fenris Wolf 2025-03-26 06:35:59 +00:00
parent 7e3a1c1df5
commit 44fd89e06d
12 changed files with 320 additions and 152 deletions

View file

@ -1,4 +1,4 @@
- `tools/update-plankton` - `tools/update-plankton`
- `tools/build` - `tools/build`
- `/tmp/mimir/mimir -c misc/conf-ramsch.mmr.json borg-run` - `/tmp/mimir/mimir -c misc/conf-ramsch.mmr.json run`

View file

@ -20,15 +20,20 @@ namespace _mimir.conf
"kind": { "kind": {
"nullable": false, "nullable": false,
"type": "string", "type": "string",
"enum": ["keep"] "enum": ["local"]
}, },
"parameters": { "parameters": {
"nullable": false, "nullable": false,
"type": "object", "type": "object",
"properties": { "properties": {
"directory": {
"nullable": false,
"type": "string"
},
}, },
"additionalProperties": false, "additionalProperties": false,
"required": [ "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 = { export type type_target_parameters_borg = {
repository : string; repository : string;
@ -237,6 +245,7 @@ namespace _mimir.conf
/** /**
* @todo split from conf
*/ */
export type type_concern_parameters_files = { export type type_concern_parameters_files = {
name : string; 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 = { export type type_concern_parameters_postgresql_dump = {
credentials : { credentials : {
@ -258,26 +284,9 @@ namespace _mimir.conf
/** /**
* @todo split from conf
*/ */
export type type_conf = { export type type_concern = (
target : (
{
kind : "keep";
parameters : type_target_parameters_keep;
}
|
{
kind : "borg";
parameters : type_target_parameters_borg;
}
);
concerns : Array<
{
active ?: boolean;
name : string;
}
&
(
{ {
kind : "files"; kind : "files";
parameters : type_concern_parameters_files; parameters : type_concern_parameters_files;
@ -287,7 +296,20 @@ namespace _mimir.conf
kind : "postgresql_dump"; kind : "postgresql_dump";
parameters : type_concern_parameters_postgresql_dump; parameters : type_concern_parameters_postgresql_dump;
} }
) );
/**
*/
export type type_conf = {
target : type_target;
concerns : Array<
{
active ?: boolean;
name : string;
}
&
type_concern
>; >;
}; };

View file

@ -0,0 +1,15 @@
namespace _mimir.serialization
{
/**
*/
export type type_logic = {
execute : (
(directory : string)
=>
Array<string>
);
};
}

View file

@ -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;
}
}
}
}

View file

@ -0,0 +1,18 @@
namespace _mimir.transfer
{
/**
*/
export type type_logic = {
execute : (
(
name : string,
stamp : string,
directory : string
)
=>
Array<string>
);
};
}

View file

@ -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;
}
}
}
}

View file

@ -2,6 +2,7 @@ namespace _mimir.transfer.borg
{ {
/** /**
* @todo parametrize pruning
*/ */
export function execute( export function execute(
parameters : _mimir.conf.type_target_parameters_borg, parameters : _mimir.conf.type_target_parameters_borg,

View file

@ -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<string>
{
const result : Array<string> = [];
// do noting
return result;
}
}

View file

@ -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<string>
{
const result : Array<string> = [];
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;
}
}

View file

@ -40,18 +40,22 @@ namespace _mimir
"description": "what to do", "description": "what to do",
"options": ( "options": (
[ [
{
"name": "conf-schema",
"description": "conf-schema"
},
{
"name": "conf-expose",
"description": "conf-expose"
},
{
"name": "init",
"description": "init"
},
{ {
"name": "run", "name": "run",
"description": "run" "description": "run"
}, },
{
"name": "borg-init",
"description": "borg-init"
},
{
"name": "borg-run",
"description": "borg-run"
},
] ]
.map( .map(
entry => lib_plankton.string.coin( entry => lib_plankton.string.coin(
@ -102,38 +106,61 @@ namespace _mimir
); );
} }
else { 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"]) { 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": { case "init": {
return Promise.reject(new Error("not implemented")); return Promise.reject(new Error("not implemented"));
break; break;
} }
case "run": { 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) { for await (const concern of conf.concerns) {
let commands : Array<string> = []; let commands : Array<string> = [];
const commands_add : ((command : string) => void) = (command) => { const commands_add : ((command : string) => void) = (command) => {
commands.push(command); commands.push(command);
}; };
const commands_apply : (() => void) = () => { const commands_apply : (() => void) = () => {
// TODO
process.stdout.write(commands.join("\n") + "\n"); process.stdout.write(commands.join("\n") + "\n");
}; };
if (! concern.active) {
// do nothing
}
else {
const directory : string = (base_directory + "/" + stamp + "/" + concern.name);
// prepare
{
commands_add( commands_add(
lib_plankton.string.coin( lib_plankton.string.coin(
"## {{name}}\n", "## {{name}}\n",
@ -144,13 +171,31 @@ namespace _mimir
); );
commands_add( commands_add(
lib_plankton.string.coin( lib_plankton.string.coin(
"echo '-- {{name}}' > /dev/stderr", "echo '-- {{name}}'",
{ {
"name": concern.name, "name": concern.name,
"kind": concern.kind, "kind": concern.kind,
} }
) )
); );
if (! concern.active) {
commands_add(
"echo '-- (skipping)'"
);
}
else {
const directory : string = lib_plankton.string.coin(
"{{base}}/{{stamp}}/{{name}}",
{
"base": base_directory,
"stamp": stamp,
"name": concern.name,
}
);
// preparation
{
commands_add( commands_add(
lib_plankton.string.coin( lib_plankton.string.coin(
"mkdir --parents {{directory}}", "mkdir --parents {{directory}}",
@ -161,71 +206,42 @@ namespace _mimir
); );
} }
// serialize // serialization
{ {
switch (concern.kind) { const serialization_logic : _mimir.serialization.type_logic = _mimir.serialization.get_logic(concern);
case "files": {
commands = commands.concat( commands = commands.concat(
_mimir.serialization.files.execute( serialization_logic.execute(
concern.parameters,
directory 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;
}
}
} }
// transfer // transfer
{ {
switch (conf.target.kind) { const target_logic : _mimir.transfer.type_logic = _mimir.transfer.get_logic(conf.target);
case "keep": {
commands = commands.concat( commands = commands.concat(
_mimir.transfer.keep.execute( target_logic.execute(
conf.target.parameters,
concern.name, concern.name,
stamp, stamp,
directory 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;
}
}
} }
// clean // cleaning
{ {
/** /**
* @todo * @todo use shred?
*/ */
commands_add(
lib_plankton.string.coin(
"rm --recursive {{path}}/*",
{
"path": base_directory,
}
)
);
}
} }
commands_add( commands_add(
@ -236,13 +252,6 @@ namespace _mimir
); );
commands_apply(); commands_apply();
} }
}
return Promise.resolve<void>(undefined);
break;
}
default: {
throw (new Error("invalid action: " + args["action"]));
return Promise.resolve<void>(undefined); return Promise.resolve<void>(undefined);
break; 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);
}
)
);

View file

@ -45,10 +45,14 @@ ${dir_temp}/mimir-raw.js: \
${dir_lib}/plankton/plankton.d.ts \ ${dir_lib}/plankton/plankton.d.ts \
${dir_source}/helpers/borg.ts \ ${dir_source}/helpers/borg.ts \
${dir_source}/conf.ts \ ${dir_source}/conf.ts \
${dir_source}/logic/serialization/_abstract.ts \
${dir_source}/logic/serialization/files.ts \ ${dir_source}/logic/serialization/files.ts \
${dir_source}/logic/serialization/postgresql_dump.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/borg.ts \
${dir_source}/logic/transfer/_factory.ts \
${dir_source}/main.ts ${dir_source}/main.ts
@ ${cmd_log} "compile …" @ ${cmd_log} "compile …"
@ ${cmd_mkdir} $(dir $@) @ ${cmd_mkdir} $(dir $@)

View file

@ -12,6 +12,7 @@ modules="${modules} call"
modules="${modules} json" modules="${modules} json"
modules="${modules} string" modules="${modules} string"
modules="${modules} args" modules="${modules} args"
modules="${modules} log"
## exec ## exec