started working on better versions and index persistence

This commit is contained in:
Cyryl Płotnicki 2019-09-01 22:16:00 +01:00
parent 0c715852d6
commit 1464cd26c8
7 changed files with 156 additions and 13 deletions

76
Cargo.lock generated
View file

@ -28,10 +28,35 @@ dependencies = [
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_cbor 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-padding"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.2"
@ -56,6 +81,14 @@ name = "cfg-if"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure"
version = "0.1.5"
@ -76,6 +109,11 @@ dependencies = [
"synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -86,6 +124,14 @@ name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.11"
@ -111,6 +157,11 @@ name = "libc"
version = "0.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.5"
@ -298,6 +349,17 @@ dependencies = [
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.44"
@ -352,6 +414,11 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
@ -407,18 +474,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872"
"checksum half 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9353c2a89d550b58fa0061d8ed8d002a7d8cdf2494eb0e432859bd3a9e543836"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
@ -442,11 +516,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
"checksum serde_cbor 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "318690c4f04ae6553665f3846c0614c9995bb1ea51a2f1c5c4b4ed338c248b49"
"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"

View file

@ -12,3 +12,4 @@ serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.10"
tempfile = "3.1"
walkdir = "2.2"
sha2 = "0.8"

View file

@ -8,6 +8,7 @@ use crate::repository_item::RepositoryItem;
pub struct IndexItem {
relative_path: String,
original_source_path: String,
version: Box<[u8]>,
}
#[derive(Serialize, Deserialize)]
@ -56,7 +57,7 @@ impl Index {
let original_source_path = Path::new(index_item.original_source_path.as_str());
let absolute_path = repository_path.join(relative_path);
let absolute_path = absolute_path.as_path();
RepositoryItem::from(original_source_path, absolute_path, relative_path)
RepositoryItem::from(original_source_path, absolute_path, relative_path, index_item.version)
}
}
@ -65,6 +66,7 @@ impl From<RepositoryItem> for IndexItem {
IndexItem {
relative_path: i.relative_path().to_string_lossy().to_string(),
original_source_path: i.original_source_path().to_string_lossy().to_string(),
version: i.version(),
}
}
}

View file

@ -1,8 +1,8 @@
pub mod backup;
pub mod error;
pub mod repository;
pub mod restore;
pub mod source;
mod index;
pub mod repository;
mod repository_item;

View file

@ -4,7 +4,10 @@ use std::path::Path;
use crate::error::BakareError;
use crate::index::{Index, IndexIterator};
use crate::repository_item::RepositoryItem;
use sha2::Digest;
use sha2::Sha512;
use std::fs::File;
use std::io::{BufReader, Read};
/// represents a place where backup is stored an can be restored from.
/// right now only on-disk directory storage is supported
@ -66,20 +69,41 @@ impl<'a> Repository<'a> {
if source_path.is_dir() {
fs::create_dir(destination_path)?;
}
if source_path.is_file() {
println!("storing {} as {}", source_path.display(), destination_path.display());
fs::create_dir_all(destination_path.parent().unwrap())?;
let version = Repository::calculate_initial_version(source_path)?;
fs::copy(source_path, destination_path)?;
self.index.remember(RepositoryItem::from(
source_path,
destination_path,
destination_path.strip_prefix(self.path)?,
Box::from(version),
));
}
Ok(())
}
fn calculate_initial_version(source_path: &Path) -> Result<Box<[u8]>, BakareError> {
let source_file = File::open(source_path)?;
let mut reader = BufReader::new(source_file);
let mut buffer = Vec::with_capacity(1024);
let mut hasher = Sha512::new();
loop {
let count = reader.read(&mut buffer)?;
if count == 0 {
break;
}
hasher.input(&buffer);
}
let version = hasher.result();
Ok(Box::from(version.as_slice()))
}
pub fn item_by_source_path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> {
println!(
"trying to find {} in a repo [{}] of {} items",

View file

@ -1,4 +1,6 @@
use crate::error::BakareError;
use sha2::digest::DynDigest;
use sha2::{Digest, Sha512};
use std::fs;
use std::path::Path;
@ -7,14 +9,16 @@ pub struct RepositoryItem {
relative_path: Box<Path>,
absolute_path: Box<Path>,
original_source_path: Box<Path>,
version: Box<[u8]>,
}
impl RepositoryItem {
pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path) -> Self {
pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: Box<[u8]>) -> Self {
RepositoryItem {
relative_path: Box::from(relative_path),
absolute_path: Box::from(absolute_path),
original_source_path: Box::from(original_source_path),
version,
}
}
pub fn save(&self, save_to: &Path) -> Result<(), BakareError> {
@ -44,4 +48,8 @@ impl RepositoryItem {
pub fn original_source_path(&self) -> &Path {
&self.original_source_path
}
pub fn version(&self) -> Box<[u8]> {
self.version.clone()
}
}

View file

@ -5,6 +5,7 @@ use bakare::source::TempSource;
use bakare::error::BakareError;
use bakare::repository::Repository;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::path::Path;
@ -12,7 +13,7 @@ use tempfile::tempdir;
use walkdir::WalkDir;
#[test]
fn restore_backed_up_files() -> Result<(), BakareError> {
fn restore_multiple_files() -> Result<(), BakareError> {
let source = TempSource::new()?;
source.write_text_to_file("first", "some contents")?;
@ -22,17 +23,44 @@ fn restore_backed_up_files() -> Result<(), BakareError> {
assert_same_after_restore(source.path())
}
#[test]
fn restore_files_after_reopening_repository() -> Result<(), BakareError> {
let source = TempSource::new()?;
let repository_path = tempdir()?.into_path();
let restore_target = tempdir()?.into_path();
Repository::init(repository_path.as_path())?;
let relative_path_text = "some file path";
let original_contents = "some old contents";
{
let mut backup_repository = Repository::open(repository_path.as_path())?;
let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository);
source.write_text_to_file(relative_path_text, original_contents)?;
backup_engine.backup()?;
}
{
let restore_repository = Repository::open(repository_path.as_path())?;
let restore_engine = restore::Engine::new(&restore_repository, &restore_target)?;
restore_engine.restore_all()?;
}
let restored_file_path = restore_target.join(relative_path_text);
let contents = fs::read_to_string(restored_file_path)?;
assert_eq!(contents, original_contents);
Ok(())
}
#[test]
fn restore_older_version_of_file() -> Result<(), BakareError> {
let source = TempSource::new()?;
let repository_path = tempdir()?.into_path();
//let restore_repository = Repository::open(repository_path.as_path())?;
Repository::init(repository_path.as_path())?;
let relative_path_text = "some path";
let file_path = source.file_path(relative_path_text);
let new_contents = "totally new contents";
let restore_target = tempdir()?;
//let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?;
let old_contents = "some old contents";
{
@ -43,19 +71,23 @@ fn restore_older_version_of_file() -> Result<(), BakareError> {
}
let reading_repository = Repository::open(repository_path.as_path())?;
let file_id = reading_repository.item_by_source_path(&file_path)?;
assert!(file_id.is_some());
//let file_id = file_id.unwrap();
//let old_version = file_id.version();
let item = reading_repository.item_by_source_path(&file_path)?;
assert!(item.is_some());
let item = item.unwrap();
let old_version = item.version();
{
let new_contents = "totally new contents";
let mut backup_repository = Repository::open(repository_path.as_path())?;
let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository);
source.write_text_to_file(relative_path_text, new_contents)?;
backup_engine.backup()?;
}
//restore_engine.restore_as_of_version(&file_id, old_version)?;
let restore_repository = Repository::open(repository_path.as_path())?;
let restore_target = tempdir()?;
let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?;
//restore_engine.restore_as_of_version(&item, old_version)?;
assert_target_file_contents(restore_target.path(), relative_path_text, old_contents)
}