Introduce read-write snapshots with the --rw/-w flag.

This commit is contained in:
Edu4rdSHL 2021-04-16 12:42:02 -05:00
parent 244551085d
commit 1cef63bacf
No known key found for this signature in database
GPG key ID: 3A574A4009F553E5
6 changed files with 40 additions and 20 deletions

View file

@ -17,6 +17,7 @@ pub fn get_args() -> Args {
list_snapshots: matches.is_present("list-snapshots"),
clean_snapshots: matches.is_present("clean-snapshots") || matches.is_present("keep-only"),
restore_snapshot: matches.is_present("restore-snapshot"),
rw_snapshots: matches.is_present("read-write"),
dest_dir: if matches.is_present("dest-dir") {
value_t!(matches, "dest-dir", String).unwrap_or_else(|_| String::new())
} else {
@ -46,6 +47,11 @@ pub fn get_args() -> Args {
} else {
return_value_or_default(&settings, "snapshot_kind", String::from("rusnapshot"))
},
snapshot_ro_rw: if matches.is_present("read-write") {
"read-write".to_string()
} else {
"read-only".to_string()
},
keep_only: if matches.is_present("keep-only") {
value_t!(matches, "keep-only", usize).unwrap_or_else(|_| 0)
} else {

View file

@ -50,6 +50,13 @@ args:
takes_value: true
multiple: false
- keep-only:
help: Keep only the last X items.
short: k
long: keep
takes_value: true
multiple: false
- create-snapshot:
help: Create an snapshot.
long: cr
@ -86,9 +93,9 @@ args:
takes_value: false
multiple: false
- keep-only:
help: Keep only the last X items.
short: k
long: keep
takes_value: true
- read-write:
help: Create read-write/rw snapshots.
short: w
long: rw
takes_value: false
multiple: false

View file

@ -80,6 +80,7 @@ pub fn manage_listing(args: &mut Args) -> Result<()> {
"KIND",
"SOURCE DIR",
"DESTINATION DIR",
"RO/RW",
"DATE"
]);
@ -90,6 +91,7 @@ pub fn manage_listing(args: &mut Args) -> Result<()> {
data.kind,
data.source,
data.destination,
data.ro_rw,
data.date,
]);
}

View file

@ -16,15 +16,14 @@ pub fn test_database(connection_str: &str) -> Result<()> {
pub fn setup_initial_database(connection: &Connection) -> Result<()> {
connection.execute("PRAGMA journal_mode=WAL")?;
connection.execute("CREATE TABLE IF NOT EXISTS snapshots (name TEXT NOT NULL, snap_id TEXT NOT NULL, kind TEXT NOT NULL, source TEXT NOT NULL, destination TEXT NOT NULL, date TEXT DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(name, snap_id))")?;
connection.execute("CREATE TABLE IF NOT EXISTS snapshots (name TEXT NOT NULL, snap_id TEXT NOT NULL, kind TEXT NOT NULL, source TEXT NOT NULL, destination TEXT NOT NULL, ro_rw TEXT NOT NULL, date TEXT DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(name, snap_id))")?;
Ok(())
}
pub fn commit_to_database(connection: &Connection, args: &Args) -> Result<()> {
let statement = format!(
"INSERT INTO snapshots (name, snap_id, kind, source, destination) VALUES ('{}', '{}', '{}', '{}', '{}')",
args.snapshot_name, args.snapshot_id, args.snapshot_kind, args.source_dir, args.dest_dir
"INSERT INTO snapshots (name, snap_id, kind, source, destination, ro_rw) VALUES ('{}', '{}', '{}', '{}', '{}', '{}')",
args.snapshot_name, args.snapshot_id, args.snapshot_kind, args.source_dir, args.dest_dir, args.snapshot_ro_rw
);
connection.execute(&statement)?;
@ -54,7 +53,8 @@ pub fn return_snapshot_data(connection: &Connection, args: &Args) -> Result<Data
snap_data.kind = statement.read::<String>(2).unwrap();
snap_data.source = statement.read::<String>(3).unwrap();
snap_data.destination = statement.read::<String>(4).unwrap();
snap_data.date = statement.read::<String>(5).unwrap();
snap_data.ro_rw = statement.read::<String>(5).unwrap();
snap_data.date = statement.read::<String>(6).unwrap();
}
Ok(snap_data)
@ -73,7 +73,8 @@ pub fn return_all_data(connection: &Connection) -> Result<Vec<Database>> {
db_struct.kind = statement.read::<String>(2).unwrap();
db_struct.source = statement.read::<String>(3).unwrap();
db_struct.destination = statement.read::<String>(4).unwrap();
db_struct.date = statement.read::<String>(5).unwrap();
db_struct.ro_rw = statement.read::<String>(5).unwrap();
db_struct.date = statement.read::<String>(6).unwrap();
snapshots_data.push(db_struct);
}
@ -84,7 +85,7 @@ pub fn return_all_data(connection: &Connection) -> Result<Vec<Database>> {
pub fn return_only_x_items(connection: &Connection, args: &Args) -> Result<Vec<Database>> {
let mut snapshots_data: Vec<Database> = Vec::new();
let mut statement = connection.prepare(&format!("SELECT name,snap_id,kind,source,destination,date FROM (SELECT row_number() over(ORDER BY date DESC) n,* from snapshots WHERE name like '{}%' AND kind = '{}') WHERE n > {}", args.snapshot_prefix, args.snapshot_kind, args.keep_only))?;
let mut statement = connection.prepare(&format!("SELECT name,snap_id,kind,source,destination,ro_rw,date FROM (SELECT row_number() over(ORDER BY date DESC) n,* from snapshots WHERE name like '{}%' AND kind = '{}' AND ro_rw = '{}') WHERE n > {}", args.snapshot_prefix, args.snapshot_kind, args.snapshot_ro_rw, args.keep_only))?;
while let State::Row = statement.next()? {
let mut db_struct = Database::default();
@ -94,7 +95,8 @@ pub fn return_only_x_items(connection: &Connection, args: &Args) -> Result<Vec<D
db_struct.kind = statement.read::<String>(2).unwrap();
db_struct.source = statement.read::<String>(3).unwrap();
db_struct.destination = statement.read::<String>(4).unwrap();
db_struct.date = statement.read::<String>(5).unwrap();
db_struct.ro_rw = statement.read::<String>(5).unwrap();
db_struct.date = statement.read::<String>(6).unwrap();
snapshots_data.push(db_struct);
}

View file

@ -4,14 +4,13 @@ use {
};
pub fn take_snapshot(args: &Args) -> bool {
let snapshot_name = format!("{}/{}", args.dest_dir, args.snapshot_name);
let mut btrfs_args = vec!["subvolume", "snapshot", &args.source_dir, &snapshot_name];
if !args.rw_snapshots {
btrfs_args.push("-r")
}
Command::new("btrfs")
.args(&[
"subvolume",
"snapshot",
"-r",
&args.source_dir,
&format!("{}/{}", args.dest_dir, args.snapshot_name),
])
.args(&btrfs_args)
.status()
.expect("Error while taking the snapshot.")
.success()

View file

@ -5,6 +5,7 @@ pub struct Args {
pub list_snapshots: bool,
pub clean_snapshots: bool,
pub restore_snapshot: bool,
pub rw_snapshots: bool,
pub dest_dir: String,
pub source_dir: String,
pub database_file: String,
@ -12,6 +13,7 @@ pub struct Args {
pub snapshot_id: String,
pub snapshot_prefix: String,
pub snapshot_kind: String,
pub snapshot_ro_rw: String,
pub keep_only: usize,
}
@ -21,6 +23,7 @@ pub struct Database {
pub kind: String,
pub source: String,
pub destination: String,
pub ro_rw: String,
pub date: String,
}
@ -32,6 +35,7 @@ impl Database {
kind: String::new(),
source: String::new(),
destination: String::new(),
ro_rw: String::new(),
date: String::new(),
}
}