424 lines
9.2 KiB
TypeScript
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();
|