restic-wrapper/src/main.rs
Jan Christian Grünhage 572ac40a4a
initial commit
2024-02-03 14:12:14 +01:00

87 lines
2.4 KiB
Rust

use std::{
fs::File,
process::{Command, ExitCode},
};
use anyhow::{Context, Result, bail};
use clap::Parser;
mod cli;
mod config;
use cli::Cli;
use config::{Source, Repository, Config};
fn main() -> Result<ExitCode> {
let (repository, source, options) = setup()?;
let exit_status = Command::new("sh").arg("-c")
.arg("restic cat config || restic init")
.env("RESTIC_REPOSITORY", &repository.url)
.env("RESTIC_PASSWORD", &repository.password)
.spawn()?.wait()?;
if !exit_status.success() {
bail!("Couldn't ensure repository is initialized!")
}
let mut backup_command = Command::new("sh");
backup_command
.arg("-c")
.env("RESTIC_REPOSITORY", &repository.url)
.env("RESTIC_PASSWORD", &repository.password);
let command = match source {
Source::Path { path } => backup_command.arg(format!(
"restic backup {} {}",
options,
path.to_string_lossy()
)),
Source::Stdin { command, filename } => backup_command.arg(format!(
"{} | restic backup {} --stdin --stdin-filename '{}'",
command,
options,
filename.to_string_lossy(),
)),
};
if let Some(code) = command.spawn()?.wait()?.code() {
let code: u8 = code.try_into()?;
Ok(ExitCode::from(code))
} else {
Ok(ExitCode::SUCCESS)
}
}
fn setup() -> Result<(Repository, Source, String)> {
let args = Cli::parse();
let mut config: Config = serde_yaml::from_reader(File::open(&args.config)?)?;
let repository = config.repositories.remove(&args.repository).with_context(|| {
format!(
"Repository {} not contained in config file {}",
args.repository,
&args.config.to_string_lossy()
)
})?;
let source = config.sources.remove(&args.source).with_context(|| {
format!(
"Source {} not contained in config file {}",
args.source,
&args.config.to_string_lossy()
)
})?;
let options = match args.options {
Some(options) => config.options.remove(&options).with_context(|| {
format!(
"Options {} not contained in config file {}",
&options,
&args.config.to_string_lossy()
)
})?,
None => Default::default(),
};
Ok((repository, source, options))
}