[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/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": {
"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 : {
@ -258,26 +284,9 @@ namespace _mimir.conf
/**
* @todo split from conf
*/
export type type_conf = {
target : (
{
kind : "keep";
parameters : type_target_parameters_keep;
}
|
{
kind : "borg";
parameters : type_target_parameters_borg;
}
);
concerns : Array<
{
active ?: boolean;
name : string;
}
&
(
export type type_concern = (
{
kind : "files";
parameters : type_concern_parameters_files;
@ -287,7 +296,20 @@ namespace _mimir.conf
kind : "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(
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",
"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,38 +106,61 @@ 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<string> = [];
const commands_add : ((command : string) => void) = (command) => {
commands.push(command);
};
const commands_apply : (() => void) = () => {
// TODO
process.stdout.write(commands.join("\n") + "\n");
};
if (! concern.active) {
// do nothing
}
else {
const directory : string = (base_directory + "/" + stamp + "/" + concern.name);
// prepare
{
commands_add(
lib_plankton.string.coin(
"## {{name}}\n",
@ -144,13 +171,31 @@ namespace _mimir
);
commands_add(
lib_plankton.string.coin(
"echo '-- {{name}}' > /dev/stderr",
"echo '-- {{name}}'",
{
"name": concern.name,
"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(
lib_plankton.string.coin(
"mkdir --parents {{directory}}",
@ -161,71 +206,42 @@ namespace _mimir
);
}
// serialize
// serialization
{
switch (concern.kind) {
case "files": {
const serialization_logic : _mimir.serialization.type_logic = _mimir.serialization.get_logic(concern);
commands = commands.concat(
_mimir.serialization.files.execute(
concern.parameters,
serialization_logic.execute(
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
{
switch (conf.target.kind) {
case "keep": {
const target_logic : _mimir.transfer.type_logic = _mimir.transfer.get_logic(conf.target);
commands = commands.concat(
_mimir.transfer.keep.execute(
conf.target.parameters,
target_logic.execute(
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;
}
}
}
// clean
// cleaning
{
/**
* @todo
* @todo use shred?
*/
commands_add(
lib_plankton.string.coin(
"rm --recursive {{path}}/*",
{
"path": base_directory,
}
)
);
}
}
commands_add(
@ -236,13 +252,6 @@ namespace _mimir
);
commands_apply();
}
}
return Promise.resolve<void>(undefined);
break;
}
default: {
throw (new Error("invalid action: " + args["action"]));
return Promise.resolve<void>(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);
}
)
);

View file

@ -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 $@)

View file

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