Skip to content

Commit

Permalink
add webdav command
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Jan 10, 2024
1 parent 7f00f6e commit 187c8d6
Show file tree
Hide file tree
Showing 4 changed files with 421 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ mimalloc = { version = "0.1.39", default_features = false, optional = true }
rhai = { workspace = true }
simplelog = { workspace = true }
runtime-format = "0.1.3"
webdav-handler = {version = "0.2.0", features = ["warp-compat"]}
bytes = "1.5.0"
futures = "0.3.30"
tokio = "1.35.1"
warp = "0.3.6"

[dev-dependencies]
aho-corasick = { workspace = true }
Expand Down
6 changes: 5 additions & 1 deletion src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub(crate) mod self_update;
pub(crate) mod show_config;
pub(crate) mod snapshots;
pub(crate) mod tag;
pub(crate) mod webdav;

use std::fs::File;
use std::path::PathBuf;
Expand All @@ -36,7 +37,7 @@ use crate::{
init::InitCmd, key::KeyCmd, list::ListCmd, ls::LsCmd, merge::MergeCmd, mount::MountCmd,
prune::PruneCmd, repair::RepairCmd, repoinfo::RepoInfoCmd, restore::RestoreCmd,
self_update::SelfUpdateCmd, show_config::ShowConfigCmd, snapshots::SnapshotCmd,
tag::TagCmd,
tag::TagCmd, webdav::WebDavCmd,
},
config::{progress_options::ProgressOptions, RusticConfig},
{Application, RUSTIC_APP},
Expand Down Expand Up @@ -129,6 +130,9 @@ enum RusticCmd {

/// Change tags of snapshots
Tag(TagCmd),

/// Mount repository
WebDav(WebDavCmd),
}

/// Entry point for the application. It needs to be a struct to allow using subcommands!
Expand Down
84 changes: 84 additions & 0 deletions src/commands/webdav.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! `mount` subcommand
mod webdavfs;

use std::net::SocketAddr;

use crate::{commands::open_repository, status_err, Application, RUSTIC_APP};
use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::Result;
use webdav_handler::{warp::dav_handler, DavHandler};
use webdavfs::RusticWebDavFS;

#[derive(clap::Parser, Command, Debug)]
pub(crate) struct WebDavCmd {
/// 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>,

/// Use symlinks. Note this may not be supported by all WebDAV clients
#[clap(long)]
symlinks: bool,

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

impl Runnable for WebDavCmd {
fn run(&self) {
if let Err(err) = self.inner_run() {
status_err!("{}", err);
RUSTIC_APP.shutdown(Shutdown::Crash);
};
}
}

impl WebDavCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();

let repo = open_repository(&config)?.to_indexed()?;

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)?;
RusticWebDavFS::from_node(repo, node)
} else {
let snapshots = repo.get_matching_snapshots(sn_filter)?;
RusticWebDavFS::from_snapshots(
repo,
snapshots,
path_template,
time_template,
self.symlinks,
)?
};

tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async {
let addr: SocketAddr = ([127, 0, 0, 1], 4918).into();

let dav_server = DavHandler::builder().filesystem(target_fs).build_handler();

warp::serve(dav_handler(dav_server)).run(addr).await;
});

Ok(())
}
}
Loading

0 comments on commit 187c8d6

Please sign in to comment.