mimir/source/main.ts
Fenris Wolf 6e0ff08234 [int]
2025-02-20 09:12:08 +01:00

424 lines
9.2 KiB
TypeScript

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<void>
{
// 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<string> = [];
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<void>(undefined);
}
main();