Skip to content

Commit

Permalink
use virtual FS for mount
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Jan 9, 2024
1 parent 89c6c41 commit 7f00f6e
Show file tree
Hide file tree
Showing 5 changed files with 525 additions and 197 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ jemallocator-global = { version = "0.3.2", optional = true }
mimalloc = { version = "0.1.39", default_features = false, optional = true }
rhai = { workspace = true }
simplelog = { workspace = true }
runtime-format = "0.1.3"

[dev-dependencies]
aho-corasick = { workspace = true }
Expand Down
48 changes: 38 additions & 10 deletions src/commands/mount.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
//! `mount` subcommand
mod fs;
use std::{ffi::OsStr, path::PathBuf};
mod format;
pub mod fs;
mod mountfs;

use mountfs::RusticFS;

use fs::RusticFS;
use std::{ffi::OsStr, path::PathBuf};

use crate::{commands::open_repository, status_err, Application, RUSTIC_APP};

use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::Result;
use fuse_mt::{mount, FuseMT};

/// `dump` subcommand
#[derive(clap::Parser, Command, Debug)]
pub(crate) struct MountCmd {
/// file from snapshot to dump
#[clap(value_name = "SNAPSHOT[:PATH]")]
snap: String,
/// The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]
#[clap(long)]
path_template: Option<String>,

/// The time template to use to display times in the path template. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. [default: "%Y-%m-%d_%H-%M-%S"]
#[clap(long)]
time_template: Option<String>,

#[clap(value_name = "PATH")]
/// The mount point to use
mountpoint: PathBuf,

/// Specify directly which path to mount
#[clap(value_name = "SNAPSHOT[:PATH]")]
snap: Option<String>,
}

impl Runnable for MountCmd {
Expand All @@ -34,12 +46,28 @@ impl MountCmd {
let config = RUSTIC_APP.config();

let repo = open_repository(&config)?.to_indexed()?;
let node =
repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?;

let path_template = self
.path_template
.clone()
.unwrap_or("[{hostname}]/[{label}]/{time}".to_string());
let time_template = self
.time_template
.clone()
.unwrap_or("%Y-%m-%d_%H-%M-%S".to_string());

let sn_filter = |sn: &_| config.snapshot_filter.matches(sn);
let target_fs = if let Some(snap) = &self.snap {
let node = repo.node_from_snapshot_path(snap, sn_filter)?;
RusticFS::from_node(repo, node)?
} else {
let snapshots = repo.get_matching_snapshots(sn_filter)?;
RusticFS::from_snapshots(repo, snapshots, path_template, time_template)?
};

let options = [OsStr::new("-o"), OsStr::new("fsname=rusticfs")];

let fs = FuseMT::new(RusticFS::from_node(repo, node)?, 1);
let fs = FuseMT::new(target_fs, 1);
mount(fs, &self.mountpoint, &options)?;

Ok(())
Expand Down
37 changes: 37 additions & 0 deletions src/commands/mount/format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::fmt;

use runtime_format::{FormatKey, FormatKeyError};
use rustic_core::repofile::SnapshotFile;

pub struct FormattedSnapshot<'a>(pub &'a SnapshotFile, pub &'a str);

impl<'a> FormatKey for FormattedSnapshot<'a> {
fn fmt(&self, key: &str, f: &mut fmt::Formatter<'_>) -> Result<(), FormatKeyError> {
match key {
"id" => write!(f, "{}", self.0.id),
"long_id" => write!(f, "{:?}", self.0.id),
"time" => write!(f, "{}", self.0.time.format(self.1)),
"username" => write!(f, "{}", self.0.username),
"hostname" => write!(f, "{}", self.0.hostname),
"label" => write!(f, "{}", self.0.label),
"tags" => write!(f, "{}", self.0.tags),
"backup_start" => {
if let Some(summary) = &self.0.summary {
write!(f, "{}", summary.backup_start.format(self.1))
} else {
write!(f, "no_backup_start")
}
}
"backup_end" => {
if let Some(summary) = &self.0.summary {
write!(f, "{}", summary.backup_end.format(self.1))
} else {
write!(f, "no_backup_end")
}
}

_ => return Err(FormatKeyError::UnknownKey),
}
.map_err(FormatKeyError::Fmt)
}
}
Loading

0 comments on commit 7f00f6e

Please sign in to comment.