first commit
This commit is contained in:
commit
0458a4f4e8
4 changed files with 1202 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1136
Cargo.lock
generated
Normal file
1136
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "pg-backup-exec"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.16", features = ["derive"] }
|
||||||
|
color-eyre = "0.6.3"
|
||||||
|
postgres = "0.19.8"
|
||||||
|
shell-quote = { version = "0.7.1", default-features = false, features = ["sh"] }
|
55
src/main.rs
Normal file
55
src/main.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#![feature(exit_status_error)]
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
use clap::Parser;
|
||||||
|
use color_eyre::eyre;
|
||||||
|
use postgres::{Client, NoTls};
|
||||||
|
use shell_quote::{QuoteExt, Sh};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(help = "Database connection string")]
|
||||||
|
connection_string: String,
|
||||||
|
#[arg(help = "Label of the backup")]
|
||||||
|
backup_label: String,
|
||||||
|
#[arg(
|
||||||
|
last = true,
|
||||||
|
allow_hyphen_values = true,
|
||||||
|
help = "Command to run",
|
||||||
|
long_help = "Command to run in between the pg_backup_start and pg_backup_stop calls. Ran in a shell.",
|
||||||
|
required = true
|
||||||
|
)]
|
||||||
|
command: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> eyre::Result<()> {
|
||||||
|
let args = Args::parse();
|
||||||
|
color_eyre::install()?;
|
||||||
|
|
||||||
|
let mut client = Client::connect(&args.connection_string, NoTls)?;
|
||||||
|
|
||||||
|
client.execute("select pg_backup_start($1)", &[&args.backup_label])?;
|
||||||
|
|
||||||
|
let mut iter = args.command.into_iter();
|
||||||
|
|
||||||
|
let cmd = iter.next().expect("first element is required");
|
||||||
|
let mut sh_args = Sh::quote_vec(cmd.as_bytes());
|
||||||
|
|
||||||
|
for arg in iter {
|
||||||
|
sh_args.push(b' ');
|
||||||
|
sh_args.push_quoted(Sh, &arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sh_args = String::from_utf8(sh_args).expect("should be valid utf-8");
|
||||||
|
|
||||||
|
let mut child = Command::new("/bin/sh").arg("-c").arg(sh_args).spawn()?;
|
||||||
|
let exit = child.wait()?;
|
||||||
|
|
||||||
|
client.execute("select pg_backup_stop", &[])?;
|
||||||
|
drop(client);
|
||||||
|
|
||||||
|
exit.exit_ok()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue