[int]
This commit is contained in:
parent
09b657ae5c
commit
6e0ff08234
9 changed files with 4637 additions and 1980 deletions
1555
lib/plankton/plankton.d.ts
vendored
1555
lib/plankton/plankton.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
218
misc/backup.js
Normal file
218
misc/backup.js
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
#!/usr/bin/env nodejs
|
||||||
|
|
||||||
|
|
||||||
|
function string_coin(
|
||||||
|
template,
|
||||||
|
arguments_
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let result = template;
|
||||||
|
Object.entries(arguments_).forEach(
|
||||||
|
([key, value]) => {
|
||||||
|
result = result.replace(new RegExp("{{" + key + "}}", "g"), value);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function borg_init(
|
||||||
|
repository_directory,
|
||||||
|
{
|
||||||
|
"encryption": encryption = "none",
|
||||||
|
} = {
|
||||||
|
}
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return string_coin(
|
||||||
|
"borg init --encryption={{encryption}} {{repository_directory}}\n",
|
||||||
|
{
|
||||||
|
"repository_directory": repository_directory,
|
||||||
|
"encryption": encryption,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function borg_create(
|
||||||
|
repository_directory,
|
||||||
|
archive_name,
|
||||||
|
directories,
|
||||||
|
{
|
||||||
|
"compression": compression = "none",
|
||||||
|
} = {
|
||||||
|
}
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return string_coin(
|
||||||
|
"borg create --compression={{compression}} {{repository_directory}}::{{archive_name}} {{directories}}\n",
|
||||||
|
{
|
||||||
|
"repository_directory": repository_directory,
|
||||||
|
"archive_name": archive_name,
|
||||||
|
"compression": compression,
|
||||||
|
"directories": directories.join(" "),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function borg_prune(
|
||||||
|
repository_directory,
|
||||||
|
age,
|
||||||
|
{
|
||||||
|
"keep_weekly": keep_weekly = null,
|
||||||
|
"keep_yearly": keep_yearly = null,
|
||||||
|
} = {
|
||||||
|
}
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return string_coin(
|
||||||
|
"borg prune --keep-within=2w{{macro_keep_weekly}}{{macro_keep_yearly}} {{repository_directory}}\n",
|
||||||
|
{
|
||||||
|
"repository_directory": repository_directory,
|
||||||
|
"keep_within": age,
|
||||||
|
"macro_keep_weekly": ((keep_weekly === null) ? "" : string_coin(" --keep-weekly={{x}}", {"x": keep_weekly.toFixed(0)})),
|
||||||
|
"macro_keep_yearly": ((keep_yearly === null) ? "" : string_coin(" --keep-yearly={{x}}", {"x": keep_yearly.toFixed(0)})),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_conf(
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const _fs = require("fs");
|
||||||
|
const conf = JSON.parse(_fs.readFileSync("conf.json"));
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_stamp(
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const date = (new Date(Date.now()));
|
||||||
|
return string_coin(
|
||||||
|
"{{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"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_repository_directory(
|
||||||
|
conf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return conf.target.data.repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function init(
|
||||||
|
conf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const repository_directory = get_repository_directory(conf);
|
||||||
|
if (false) {
|
||||||
|
process.stdout.write(
|
||||||
|
string_coin(
|
||||||
|
"mkdir --parents {{repository_directory}}\n",
|
||||||
|
{
|
||||||
|
"repository_directory": repository_directory,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
process.stdout.write(
|
||||||
|
borg_init(
|
||||||
|
repository_directory,
|
||||||
|
{
|
||||||
|
"encryption": "none",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function run(
|
||||||
|
conf,
|
||||||
|
stamp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const repository_directory = get_repository_directory(conf);
|
||||||
|
conf.concerns.forEach(
|
||||||
|
concern => {
|
||||||
|
process.stdout.write(
|
||||||
|
string_coin(
|
||||||
|
"## {{name}}\n",
|
||||||
|
{
|
||||||
|
"name": concern.name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
process.stdout.write(
|
||||||
|
borg_create(
|
||||||
|
repository_directory,
|
||||||
|
string_coin(
|
||||||
|
"{{concern_name}}-{{stamp}}",
|
||||||
|
{
|
||||||
|
"concern_name": concern.name,
|
||||||
|
"stamp": stamp,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
[concern.source_directory],
|
||||||
|
{
|
||||||
|
"compression": conf.target.data.compression,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
process.stdout.write(
|
||||||
|
borg_prune(
|
||||||
|
repository_directory,
|
||||||
|
"2w",
|
||||||
|
{
|
||||||
|
"keep_weekly": 7,
|
||||||
|
"keep_yearly": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
process.stdout.write(
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function main(
|
||||||
|
args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// args
|
||||||
|
const action = (args.shift() ?? "run");
|
||||||
|
|
||||||
|
// exec
|
||||||
|
switch (action) {
|
||||||
|
case "init": {
|
||||||
|
const conf = get_conf();
|
||||||
|
init(conf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "run": {
|
||||||
|
const conf = get_conf();
|
||||||
|
const stamp = get_stamp();
|
||||||
|
run(conf, stamp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw (new Error("unhandled action: " + action));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main(process.argv.slice(2));
|
||||||
|
|
34
misc/conf-example.mmr.json
Normal file
34
misc/conf-example.mmr.json
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"version": "1",
|
||||||
|
"target": {
|
||||||
|
"kind": "plain",
|
||||||
|
"parameters": {
|
||||||
|
"directory": "/tmp/backup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concerns": [
|
||||||
|
{
|
||||||
|
"active": true,
|
||||||
|
"name": "fehuz",
|
||||||
|
"kind": "files",
|
||||||
|
"parameters": {
|
||||||
|
"path": "/var/fehuz",
|
||||||
|
"name": "fehuz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"active": true,
|
||||||
|
"name": "uruz",
|
||||||
|
"kind": "postgresql_dump",
|
||||||
|
"parameters": {
|
||||||
|
"credentials": {
|
||||||
|
"host": "postgresql.example.org",
|
||||||
|
"username": "username",
|
||||||
|
"password": "password",
|
||||||
|
"schema": "example"
|
||||||
|
},
|
||||||
|
"name": "uruz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
48
misc/conf.json
Normal file
48
misc/conf.json
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"kind": "borg",
|
||||||
|
"data": {
|
||||||
|
"repository": "ssh://pv-fensalir-kvasir///home/kvasir/repos/ramsch.sx",
|
||||||
|
"compression": "lz4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concerns": [
|
||||||
|
{
|
||||||
|
"name": "espe-database",
|
||||||
|
"source_directory": "/tmp/backup/espe-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forgejo-database",
|
||||||
|
"source_directory": "/tmp/backup/forgejo-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forgejo-files",
|
||||||
|
"source_directory": "/tmp/backup/forgejo-files"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hedgedoc-database",
|
||||||
|
"source_directory": "/tmp/backup/hedgedoc-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "owncloud-files",
|
||||||
|
"source_directory": "/tmp/backup/owncloud-files"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "synapse-database",
|
||||||
|
"source_directory": "/tmp/backup/synapse-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vikunja-database",
|
||||||
|
"source_directory": "/tmp/backup/vikunja-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wiki_js-database",
|
||||||
|
"source_directory": "/tmp/backup/wiki_js-database"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zeitbild-files",
|
||||||
|
"source_directory": "/tmp/backup/zeitbild-files"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
9
misc/setup-client.sh
Normal file
9
misc/setup-client.sh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
mkdir --parents ~/.ssh/keypairs
|
||||||
|
ssh-keygen -t ed25519 -f ~/.ssh/keypairs/fensalir-kvasir
|
||||||
|
|
||||||
|
# todo: add entry to ~/.ssh/config
|
||||||
|
|
17
misc/setup-server.sh
Normal file
17
misc/setup-server.sh
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
## const
|
||||||
|
|
||||||
|
username=kvasir
|
||||||
|
repodir=repos
|
||||||
|
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
apt update && apt install borgbackup
|
||||||
|
|
||||||
|
useradd ${username} --create-home --home-dir=/home/${username}/${repodir} --groups sudo
|
||||||
|
# todo: add ssh key to ~/.ssh/authorized_keys
|
||||||
|
|
||||||
|
sudo --other-user=${username} mkdir --parents /home/${username}/${repodir}
|
||||||
|
|
497
source/main.ts
497
source/main.ts
|
@ -1,3 +1,228 @@
|
||||||
|
|
||||||
|
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
|
function get_stamp(): string
|
||||||
|
@ -22,134 +247,176 @@ function get_stamp(): string
|
||||||
*/
|
*/
|
||||||
async function main(): Promise<void>
|
async function main(): Promise<void>
|
||||||
{
|
{
|
||||||
const conf = lib_plankton.json.decode(await lib_plankton.file.read("conf.json"));
|
// 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();
|
const stamp: string = get_stamp();
|
||||||
const target_directory = (conf.target.directory + "/" + stamp);
|
|
||||||
|
|
||||||
let commands: Array<string> = [];
|
switch (conf.target.kind) {
|
||||||
const commands_add : (command: string) => void = (command) => {
|
case "plain": {
|
||||||
commands.push(command);
|
const target_directory = (conf.target.parameters.directory/* + "/" + stamp*/);
|
||||||
};
|
|
||||||
const commands_apply : () => void = () => {
|
let commands: Array<string> = [];
|
||||||
// TODO
|
const commands_add : (command: string) => void = (command) => {
|
||||||
process.stdout.write(commands.join("\n") + "\n");
|
commands.push(command);
|
||||||
};
|
};
|
||||||
|
const commands_apply : () => void = () => {
|
||||||
commands_add(
|
// TODO
|
||||||
lib_plankton.string.coin(
|
process.stdout.write(commands.join("\n") + "\n");
|
||||||
"mkdir --parents {{directory}}",
|
};
|
||||||
{
|
|
||||||
"directory": target_directory,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
commands_add(
|
|
||||||
""
|
|
||||||
);
|
|
||||||
for await (const concern of conf.concerns) {
|
|
||||||
if (! concern.active) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commands_add(
|
commands_add(
|
||||||
lib_plankton.string.coin(
|
lib_plankton.string.coin(
|
||||||
"# {{name}}",
|
"mkdir --parents {{directory}}",
|
||||||
{
|
{
|
||||||
"name": concern.name,
|
"directory": target_directory,
|
||||||
"kind": concern.kind,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
commands_add(
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"echo '-- {{name}}' > /dev/stderr",
|
|
||||||
{
|
|
||||||
"name": concern.name,
|
|
||||||
"kind": concern.kind,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
switch (concern.kind) {
|
|
||||||
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(
|
|
||||||
"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}}.sql",
|
|
||||||
{
|
|
||||||
"directory": target_directory,
|
|
||||||
"name": concern.parameters.name,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
commands_add(
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"rm {{path}}",
|
|
||||||
{
|
|
||||||
"path": password_file_path,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "files": {
|
|
||||||
commands_add(
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"tar --create --directory={{path}} . > {{target_path}}",
|
|
||||||
{
|
|
||||||
"path": concern.parameters.path,
|
|
||||||
"target_path": lib_plankton.string.coin(
|
|
||||||
"{{directory}}/{{name}}.tar",
|
|
||||||
{
|
|
||||||
"directory": target_directory,
|
|
||||||
"name": concern.parameters.name,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw (new Error("unhandled kind: " + concern.kind));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commands_add(
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands_add(
|
|
||||||
lib_plankton.string.coin(
|
|
||||||
"echo '{{directory}}'",
|
|
||||||
{
|
|
||||||
"directory": target_directory,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
commands_apply();
|
|
||||||
|
|
||||||
return Promise.resolve<void>(undefined);
|
return Promise.resolve<void>(undefined);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ dir=lib/plankton
|
||||||
|
|
||||||
modules=""
|
modules=""
|
||||||
modules="${modules} base"
|
modules="${modules} base"
|
||||||
|
modules="${modules} conf"
|
||||||
modules="${modules} file"
|
modules="${modules} file"
|
||||||
modules="${modules} call"
|
modules="${modules} call"
|
||||||
modules="${modules} json"
|
modules="${modules} json"
|
||||||
|
|
Loading…
Add table
Reference in a new issue