Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add init and snapshot functionality #4

Merged
merged 2 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ log = "0.4"
open = "5.0.2"
serde = { version = "1.0.202", features = ["serde_derive"] }
paste = "1.0"
rustic_core = "0.2.0"
rustic_backend = "0.1.1"

[dependencies.libcosmic]
git = "https://github.com/pop-os/libcosmic.git"
Expand Down
6 changes: 3 additions & 3 deletions src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ impl CosmicBackupsConfig {
pub fn config() -> CosmicBackupsConfig {
match Self::config_handler() {
Some(config_handler) => {
let config = CosmicBackupsConfig::get_entry(&config_handler).unwrap_or_else(

CosmicBackupsConfig::get_entry(&config_handler).unwrap_or_else(
|(errs, config)| {
log::info!("errors loading config: {:?}", errs);
config
},
);
config
)
}
None => CosmicBackupsConfig::default(),
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use crate::{
};

pub fn menu_bar<'a>(key_binds: &HashMap<KeyBind, Action>) -> Element<'a, Message> {
MenuBar::new(vec![Tree::with_children(
MenuBar::new(vec![
Tree::with_children(
root(fl!("file")),
items(
key_binds,
Expand Down
3 changes: 3 additions & 0 deletions src/backup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod init;
pub mod restore;
pub mod snapshot;
36 changes: 36 additions & 0 deletions src/backup/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use rustic_backend::BackendOptions;
use rustic_core::{ConfigOptions, KeyOptions, Repository, RepositoryOptions};
use std::error::Error;

pub fn init(repository: &str, password: &str) -> Result<(), Box<dyn Error>> {
// Initialize Backends
let backends = BackendOptions::default()
.repository(repository)
.to_backends()?;

// Init repository
let repo_opts = RepositoryOptions::default().password(password);
let key_opts = KeyOptions::default();
let config_opts = ConfigOptions::default();

if Repository::new(&repo_opts, backends.clone())?
.open()
.is_err()
{
Repository::new(&repo_opts, backends)?.init(&key_opts, &config_opts)?;
}
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_init() {
let repository = "/tmp/test";
let password = "password";

assert!(init(repository, password).is_ok());
}
}
40 changes: 40 additions & 0 deletions src/backup/restore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use rustic_backend::BackendOptions;
use rustic_core::{LocalDestination, LsOptions, Repository, RepositoryOptions, RestoreOptions};
use std::error::Error;

fn restore(
repository: &str,
password: &str,
snap_path: &str,
restore_destination: &str,
) -> Result<(), Box<dyn Error>> {
// Initialize Backends
let backends = BackendOptions::default()
.repository(repository)
.to_backends()?;

// Open repository
let repo_opts = RepositoryOptions::default().password(password);
let repo = Repository::new(&repo_opts, backends)?
.open()?
.to_indexed()?;

// use latest snapshot without filtering snapshots
let node = repo.node_from_snapshot_path(snap_path, |_| true)?;

// use list of the snapshot contents using no additional filtering
let streamer_opts = LsOptions::default();
let ls = repo.ls(&node, &streamer_opts)?;

let destination = restore_destination; // restore to this destination dir
let create = true; // create destination dir, if it doesn't exist
let dest = LocalDestination::new(destination, create, !node.is_dir())?;

let opts = RestoreOptions::default();
let dry_run = false;
// create restore infos. Note: this also already creates needed dirs in the destination
let restore_infos = repo.prepare_restore(&opts, ls.clone(), &dest, dry_run)?;

repo.restore(restore_infos, &opts, ls, &dest)?;
Ok(())
}
50 changes: 50 additions & 0 deletions src/backup/snapshot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use rustic_backend::BackendOptions;
use rustic_core::{BackupOptions, PathList, Repository, RepositoryOptions, SnapshotOptions};
use std::error::Error;

pub fn snapshot(repository: &str, password: &str, paths: Vec<&str>) -> Result<(), Box<dyn Error>> {
// Initialize Backends
let backends = BackendOptions::default()
.repository(repository)
.to_backends()?;

println!("successfully initialized backends:\n{backends:#?}");

// Open repository
let repo_opts = RepositoryOptions::default().password(password);

let repo = Repository::new(&repo_opts, backends)?
.open()?
.to_indexed_ids()?;

println!("successfully opened repository:\n{repo:#?}");

let backup_opts = BackupOptions::default();
let source = PathList::from_strings(paths).sanitize()?;

println!("successfully sanitized paths:\n{source:#?}");

let snap = SnapshotOptions::default().to_snapshot()?;

println!("successfully created snapshot options:\n{snap:#?}");

// Create snapshot
let snap = repo.backup(&backup_opts, &source, snap)?;

println!("successfully created snapshot:\n{snap:#?}");
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_snapshot() {
let repository = "/tmp/test";
let password = "password";
let paths = vec!["/etc"];

assert!(snapshot(repository, password, paths).is_ok());
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cosmic::app::Settings;

/// The `app` module is used by convention to indicate the main component of our application.
mod app;
mod backup;
mod core;

/// The `cosmic::app::run()` function is the starting point of your application.
Expand Down
Loading