Skip to main content

tuwunel_service/storage/provider/
local.rs

1//! Local-filesystem storage-provider construction.
2//!
3//! A configured directory is wrapped by the common provider interface. Empty
4//! base paths disable the provider, while optional directory creation happens
5//! before the backend is initialized.
6
7use std::{fs, sync::Arc};
8
9use object_store::local::LocalFileSystem;
10use tuwunel_core::{
11	Result,
12	config::{StorageProvider, StorageProviderLocal},
13	debug, debug_info, error, trace,
14};
15
16use super::Provider;
17
18/// Builds an enabled local-filesystem provider.
19///
20/// An empty base path returns `None`. When requested, the directory is created
21/// before the backend is configured with its cleanup policy.
22#[tracing::instrument(name = "new", level = "info", skip_all, err)]
23pub(in super::super) fn new(
24	args: &crate::Args<'_>,
25	name: &str,
26	config: &StorageProviderLocal,
27) -> Result<Option<(String, Arc<Provider>)>> {
28	// Fail successfully if this provider is disabled by the configuration..
29	if config.base_path.is_empty() {
30		debug!(?name, "'base_path' is not set. This configuration will be skipped");
31		return Ok(None);
32	}
33
34	if config.create_if_missing {
35		trace!(
36			%name,
37			path = ?config.base_path,
38			"Creating directory on local filesystem if missing...",
39		);
40
41		fs::create_dir_all(&config.base_path)?;
42	}
43
44	trace!(?name, ?config, "Initializing LocalFS...");
45
46	let provider = LocalFileSystem::new_with_prefix(config.base_path.clone())
47		.inspect_err(|e| error!("Failed to configure LocalFS storage client: {e}"))?
48		.with_automatic_cleanup(config.delete_empty_directories);
49
50	debug_info!(
51		name = %name,
52		path = ?config.base_path,
53		"Started Local FS storage client.",
54	);
55
56	let provider = Provider {
57		name: name.to_owned(),
58		base_path: None, // LocalFileSystem computes base_path internally
59		config: StorageProvider::local(config.clone()),
60		startup_check: config.startup_check,
61		services: args.services.clone(),
62		provider: Box::new(provider),
63		signer: None,
64	};
65
66	Ok(Some((name.to_owned(), Arc::new(provider))))
67}