use std::{
fs::{create_dir_all, rename},
os::unix::fs::symlink,
path::PathBuf,
process::{Command, ExitCode},
};
use log::{debug, info, warn};
use crate::{clean::ls_snapshot, cli::sh_run, config::ConfigEnv};
mod t;
pub use t::{DIR_PMBS, SYMLINK_LATEST, format_t, format_t_local, get_t, get_year};
pub fn make_snapshot(config: &ConfigEnv, subvol: &str) -> Result<(), ExitCode> {
let t = get_t();
let year = get_year(t);
let now = format_t(t);
debug!("snapshot t = {} {}", t, now);
let mut p = PathBuf::from(subvol);
p.push(DIR_PMBS);
let mut y = p.clone();
y.push(format!("{}", year));
let mut to = y.clone();
to.push(format!("{}", t));
info!("snapshot {} -> {}", subvol, to.to_string_lossy());
create_dir_all(y).unwrap();
let mut c = Command::new(config.bin_btrfs.clone());
c.arg("subvol")
.arg("snapshot")
.arg("-r")
.arg(subvol)
.arg(to);
let code = sh_run(c);
if 0 != code {
return Err(ExitCode::from(1));
}
let mut latest = p.clone();
latest.push(SYMLINK_LATEST);
let mut latest_tmp = p.clone();
latest_tmp.push(format!("{}.{}", SYMLINK_LATEST, t));
let mut link_to = PathBuf::new();
link_to.push(format!("{}", year));
link_to.push(format!("{}", t));
info!(
"symlink {} -> {}",
latest.to_string_lossy(),
link_to.to_string_lossy()
);
symlink(link_to, &latest_tmp).unwrap();
rename(&latest_tmp, latest).unwrap();
let list = ls_snapshot(subvol);
let max_t = list.iter().map(|x| x.t).max().unwrap();
if max_t > t {
warn!("time error ! {} > {} ({})", max_t, t, max_t - t);
}
Ok(())
}