mirror of
https://github.com/edu4rdshl/rusnapshot.git
synced 2026-07-17 23:24:55 +00:00
Introduce read-write snapshots with the --rw/-w flag.
This commit is contained in:
parent
244551085d
commit
1cef63bacf
6 changed files with 40 additions and 20 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
17
src/cli.yml
17
src/cli.yml
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue