core/misc/backup.js

219 lines
3.5 KiB
JavaScript
Raw Normal View History

2025-02-20 09:12:08 +01:00
#!/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));