Apply clippy fixes for code quality
Clippy Fixes Applied:
- Removed unused imports
- Fixed manual implementation of .is_multiple_of()
- Fixed unnecessary_sort_by suggestions
- Added missing Ipv4Addr imports
Files Modified:
- forward_acl.rs: Add Ipv4Addr import
- known_hosts.rs: Add Ipv4Addr import
- Various files: Remove unused imports
Build: ✅ markbase-core
Tests: 495 passed
This commit is contained in:
BIN
data/auth.sqlite
BIN
data/auth.sqlite
Binary file not shown.
@@ -162,7 +162,7 @@ pub async fn handle_webdav_command(cmd: WebdavCommand) -> anyhow::Result<()> {
|
|||||||
if folders.is_empty() {
|
if folders.is_empty() {
|
||||||
println!("No virtual folders.");
|
println!("No virtual folders.");
|
||||||
} else {
|
} else {
|
||||||
println!("{:<30} {}", "Folder", "Description");
|
println!("{:<30} Description", "Folder");
|
||||||
println!("{}", "-".repeat(60));
|
println!("{}", "-".repeat(60));
|
||||||
for (f, d) in folders {
|
for (f, d) in folders {
|
||||||
println!("{:<30} {}", f, d);
|
println!("{:<30} {}", f, d);
|
||||||
@@ -254,7 +254,7 @@ async fn run_webdav_server(
|
|||||||
|
|
||||||
let valid = match (auth, expected) {
|
let valid = match (auth, expected) {
|
||||||
(Some((u, p)), Some(exp)) => {
|
(Some((u, p)), Some(exp)) => {
|
||||||
u == exp.username && exp.password.as_ref().map_or(true, |exp_p| p == *exp_p)
|
u == exp.username && exp.password.as_ref().is_none_or(|exp_p| p == *exp_p)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -103,21 +103,21 @@ pub async fn handle_smb_server_command(cmd: SmbServerCommand) -> anyhow::Result<
|
|||||||
s3_secret_key,
|
s3_secret_key,
|
||||||
s3_region,
|
s3_region,
|
||||||
ldap,
|
ldap,
|
||||||
ldap_url,
|
ldap_url: _,
|
||||||
ldap_base_dn,
|
ldap_base_dn: _,
|
||||||
ldap_bind_dn,
|
ldap_bind_dn: _,
|
||||||
ldap_bind_password,
|
ldap_bind_password: _,
|
||||||
ldap_user_search_base,
|
ldap_user_search_base: _,
|
||||||
ldap_group_search_base,
|
ldap_group_search_base: _,
|
||||||
ldap_user_id_attr,
|
ldap_user_id_attr: _,
|
||||||
ldap_user_filter,
|
ldap_user_filter: _,
|
||||||
ldap_group_filter,
|
ldap_group_filter: _,
|
||||||
ldap_home_dir_attr,
|
ldap_home_dir_attr: _,
|
||||||
ldap_home_dir_prefix,
|
ldap_home_dir_prefix: _,
|
||||||
ldap_user_groups_attr,
|
ldap_user_groups_attr: _,
|
||||||
} => {
|
} => {
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use smb_server::{Access, Share, SmbServer};
|
use smb_server::{Access, Share, SmbServer};
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::RwLock;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
|
use std::io::{self, Read, Write};
|
||||||
use std::io::{self, Cursor, Read, Write};
|
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
pub const CTDB_MAGIC: u32 = 0x43544442;
|
pub const CTDB_MAGIC: u32 = 0x43544442;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::sync::{Arc, RwLock};
|
use std::sync::RwLock;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use super::ip_manager::IpManager;
|
use super::ip_manager::IpManager;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{self, Read, Write, Seek, SeekFrom};
|
use std::io::{self, Read, Write, Seek, SeekFrom};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Mutex, RwLock};
|
||||||
|
|
||||||
const TDB_MAGIC: u32 = 0x1BADFACE;
|
const TDB_MAGIC: u32 = 0x1BADFACE;
|
||||||
const TDB_VERSION: u32 = 1;
|
const TDB_VERSION: u32 = 1;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ CREATE INDEX IF NOT EXISTS idx_file_tags_tag ON file_tags(tag);
|
|||||||
CREATE INDEX IF NOT EXISTS idx_file_tags_filename ON file_tags(filename);
|
CREATE INDEX IF NOT EXISTS idx_file_tags_filename ON file_tags(filename);
|
||||||
";
|
";
|
||||||
|
|
||||||
fn user_db_path(state: &AppState, username: &str) -> PathBuf {
|
fn user_db_path(_state: &AppState, username: &str) -> PathBuf {
|
||||||
let root = std::env::var("MB_WEBDAV_PARENT")
|
let root = std::env::var("MB_WEBDAV_PARENT")
|
||||||
.unwrap_or_else(|_| "/Users/accusys/momentry/var/sftpgo/data".to_string());
|
.unwrap_or_else(|_| "/Users/accusys/momentry/var/sftpgo/data".to_string());
|
||||||
PathBuf::from(root)
|
PathBuf::from(root)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ pub async fn list_objects(
|
|||||||
|
|
||||||
pub async fn get_object(
|
pub async fn get_object(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
println!("S3 GET Object: bucket={}, key={}", bucket, key);
|
println!("S3 GET Object: bucket={}, key={}", bucket, key);
|
||||||
@@ -174,7 +174,7 @@ pub async fn get_object(
|
|||||||
|
|
||||||
pub async fn put_object(
|
pub async fn put_object(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
body: Body,
|
body: Body,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
@@ -378,7 +378,7 @@ pub async fn generate_s3_key(State(state): State<crate::server::AppState>) -> im
|
|||||||
|
|
||||||
pub async fn delete_object(
|
pub async fn delete_object(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
println!("S3 DELETE Object: bucket={}, key={}", bucket, key);
|
println!("S3 DELETE Object: bucket={}, key={}", bucket, key);
|
||||||
@@ -606,7 +606,7 @@ static MULTIPART_UPLOADS: once_cell::sync::Lazy<Arc<RwLock<HashMap<String, Multi
|
|||||||
|
|
||||||
pub async fn initiate_multipart_upload(
|
pub async fn initiate_multipart_upload(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// Authentication check
|
// Authentication check
|
||||||
@@ -641,7 +641,7 @@ pub async fn initiate_multipart_upload(
|
|||||||
|
|
||||||
pub async fn upload_part(
|
pub async fn upload_part(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
query: axum::extract::Query<UploadPartQuery>,
|
query: axum::extract::Query<UploadPartQuery>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
body: Body,
|
body: Body,
|
||||||
@@ -732,7 +732,7 @@ pub struct UploadPartQuery {
|
|||||||
|
|
||||||
pub async fn complete_multipart_upload(
|
pub async fn complete_multipart_upload(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
query: axum::extract::Query<CompleteMultipartQuery>,
|
query: axum::extract::Query<CompleteMultipartQuery>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
body: Body,
|
body: Body,
|
||||||
@@ -835,7 +835,7 @@ pub struct CompleteMultipartQuery {
|
|||||||
|
|
||||||
pub async fn abort_multipart_upload(
|
pub async fn abort_multipart_upload(
|
||||||
Path((bucket, key)): Path<(String, String)>,
|
Path((bucket, key)): Path<(String, String)>,
|
||||||
State(state): State<crate::server::AppState>,
|
State(_state): State<crate::server::AppState>,
|
||||||
query: axum::extract::Query<AbortMultipartQuery>,
|
query: axum::extract::Query<AbortMultipartQuery>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|||||||
@@ -2666,7 +2666,7 @@ static ADMIN_WEBDAV_HANDLER: LazyLock<Option<dav_server::DavHandler>> = LazyLock
|
|||||||
});
|
});
|
||||||
|
|
||||||
async fn handle_webdav_admin(
|
async fn handle_webdav_admin(
|
||||||
Extension(upload_hook): Extension<Arc<crate::ssh_server::upload_hook::UploadHook>>,
|
Extension(_upload_hook): Extension<Arc<crate::ssh_server::upload_hook::UploadHook>>,
|
||||||
req: axum::extract::Request,
|
req: axum::extract::Request,
|
||||||
) -> axum::response::Response {
|
) -> axum::response::Response {
|
||||||
let admin_users = std::env::var("MB_WEBDAV_ADMIN_USERS")
|
let admin_users = std::env::var("MB_WEBDAV_ADMIN_USERS")
|
||||||
@@ -2731,7 +2731,7 @@ async fn handle_webdav_admin(
|
|||||||
// Backup/Snapshot API Handlers (Phase 5-6)
|
// Backup/Snapshot API Handlers (Phase 5-6)
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
use crate::vfs::{VfsBackend, local_fs::LocalFs, backup_scheduler::{BackupScheduler, BackupScheduleConfig, BackupStats}};
|
use crate::vfs::{VfsBackend, local_fs::LocalFs, backup_scheduler::{BackupScheduler, BackupScheduleConfig}};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@@ -2841,7 +2841,7 @@ async fn run_backup_handler() -> Json<serde_json::Value> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn list_snapshots_handler(Query(params): Query<std::collections::HashMap<String, String>>) -> Json<Vec<String>> {
|
async fn list_snapshots_handler(Query(params): Query<std::collections::HashMap<String, String>>) -> Json<Vec<String>> {
|
||||||
let root = params.get("root").map(|p| PathBuf::from(p)).unwrap_or_else(|| PathBuf::from("/data"));
|
let root = params.get("root").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("/data"));
|
||||||
let backend = LocalFs::new();
|
let backend = LocalFs::new();
|
||||||
match backend.list_snapshots(&root) {
|
match backend.list_snapshots(&root) {
|
||||||
Ok(list) => Json(list),
|
Ok(list) => Json(list),
|
||||||
@@ -2853,7 +2853,7 @@ async fn create_snapshot_handler(
|
|||||||
Path(name): Path<String>,
|
Path(name): Path<String>,
|
||||||
Query(params): Query<std::collections::HashMap<String, String>>,
|
Query(params): Query<std::collections::HashMap<String, String>>,
|
||||||
) -> Json<serde_json::Value> {
|
) -> Json<serde_json::Value> {
|
||||||
let root = params.get("root").map(|p| PathBuf::from(p)).unwrap_or_else(|| PathBuf::from("/data"));
|
let root = params.get("root").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("/data"));
|
||||||
let backend = LocalFs::new();
|
let backend = LocalFs::new();
|
||||||
match backend.create_snapshot(&root, &name) {
|
match backend.create_snapshot(&root, &name) {
|
||||||
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
||||||
@@ -2865,7 +2865,7 @@ async fn delete_snapshot_handler(
|
|||||||
Path(name): Path<String>,
|
Path(name): Path<String>,
|
||||||
Query(params): Query<std::collections::HashMap<String, String>>,
|
Query(params): Query<std::collections::HashMap<String, String>>,
|
||||||
) -> Json<serde_json::Value> {
|
) -> Json<serde_json::Value> {
|
||||||
let root = params.get("root").map(|p| PathBuf::from(p)).unwrap_or_else(|| PathBuf::from("/data"));
|
let root = params.get("root").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("/data"));
|
||||||
let backend = LocalFs::new();
|
let backend = LocalFs::new();
|
||||||
match backend.delete_snapshot(&root, &name) {
|
match backend.delete_snapshot(&root, &name) {
|
||||||
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
||||||
@@ -2877,7 +2877,7 @@ async fn restore_snapshot_handler(
|
|||||||
Path(name): Path<String>,
|
Path(name): Path<String>,
|
||||||
Query(params): Query<std::collections::HashMap<String, String>>,
|
Query(params): Query<std::collections::HashMap<String, String>>,
|
||||||
) -> Json<serde_json::Value> {
|
) -> Json<serde_json::Value> {
|
||||||
let root = params.get("root").map(|p| PathBuf::from(p)).unwrap_or_else(|| PathBuf::from("/data"));
|
let root = params.get("root").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("/data"));
|
||||||
let backend = LocalFs::new();
|
let backend = LocalFs::new();
|
||||||
match backend.restore_snapshot(&root, &name) {
|
match backend.restore_snapshot(&root, &name) {
|
||||||
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
Ok(_) => Json(serde_json::json!({"success": true, "name": name})),
|
||||||
@@ -2886,7 +2886,7 @@ async fn restore_snapshot_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_storage_stats_handler(Query(params): Query<std::collections::HashMap<String, String>>) -> Json<StorageStatsResponse> {
|
async fn get_storage_stats_handler(Query(params): Query<std::collections::HashMap<String, String>>) -> Json<StorageStatsResponse> {
|
||||||
let root = params.get("root").map(|p| PathBuf::from(p)).unwrap_or_else(|| PathBuf::from("/data"));
|
let root = params.get("root").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("/data"));
|
||||||
let backend = LocalFs::new();
|
let backend = LocalFs::new();
|
||||||
match backend.stat(&root) {
|
match backend.stat(&root) {
|
||||||
Ok(stat) => Json(StorageStatsResponse {
|
Ok(stat) => Json(StorageStatsResponse {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//! Based on OpenSSH AllowTcpForwarding, PermitOpen, PermitListen directives.
|
//! Based on OpenSSH AllowTcpForwarding, PermitOpen, PermitListen directives.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
/// Forward rule type
|
/// Forward rule type
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use anyhow::{anyhow, Result};
|
|||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
//! Compatible with ZFS send/receive and Proxmox Backup Server format
|
//! Compatible with ZFS send/receive and Proxmox Backup Server format
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use sha2::{Sha256, Digest};
|
use sha2::Digest;
|
||||||
|
|
||||||
use super::{VfsCompression};
|
use super::{VfsCompression};
|
||||||
use super::checksum::VfsChecksumFile;
|
use super::checksum::VfsChecksumFile;
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ impl BackupScheduler {
|
|||||||
|
|
||||||
let final_data = if self.config.compress != super::VfsCompression::None {
|
let final_data = if self.config.compress != super::VfsCompression::None {
|
||||||
let compressor = Compressor::new(VfsCompressionConfig {
|
let compressor = Compressor::new(VfsCompressionConfig {
|
||||||
algorithm: self.config.compress.clone(),
|
algorithm: self.config.compress,
|
||||||
min_size: 1024,
|
min_size: 1024,
|
||||||
level: 3,
|
level: 3,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
//!
|
//!
|
||||||
//! MarkBase uses SHA-256 (32 bytes) per 4KB block for integrity verification.
|
//! MarkBase uses SHA-256 (32 bytes) per 4KB block for integrity verification.
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::io::{Read, Write, Seek, SeekFrom};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use sha2::{Sha256, Digest};
|
use sha2::{Sha256, Digest};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use super::{VfsBackend, VfsFile, VfsError, VfsStat};
|
use super::{VfsBackend, VfsFile, VfsError};
|
||||||
|
|
||||||
pub const BLOCK_SIZE: usize = 4096;
|
pub const BLOCK_SIZE: usize = 4096;
|
||||||
pub const HASH_SIZE: usize = 32; // SHA-256
|
pub const HASH_SIZE: usize = 32; // SHA-256
|
||||||
@@ -71,7 +70,7 @@ impl VfsChecksumFile {
|
|||||||
|
|
||||||
pub fn block_count(&self) -> usize {
|
pub fn block_count(&self) -> usize {
|
||||||
(self.file_size as usize / BLOCK_SIZE) +
|
(self.file_size as usize / BLOCK_SIZE) +
|
||||||
if self.file_size as usize % BLOCK_SIZE > 0 { 1 } else { 0 }
|
if !(self.file_size as usize).is_multiple_of(BLOCK_SIZE) { 1 } else { 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +213,7 @@ pub fn scrub_file(
|
|||||||
corrupted_blocks.push(offset);
|
corrupted_blocks.push(offset);
|
||||||
|
|
||||||
if repair {
|
if repair {
|
||||||
if let Ok(_) = repair_block(backend, file_path, offset, &buffer) {
|
if repair_block(backend, file_path, offset, &buffer).is_ok() {
|
||||||
repaired_blocks.push(offset);
|
repaired_blocks.push(offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,10 +282,10 @@ fn scrub_recursive(
|
|||||||
///
|
///
|
||||||
/// Tries RAID repair first (if backend is RAID), then Dedup repair.
|
/// Tries RAID repair first (if backend is RAID), then Dedup repair.
|
||||||
pub fn repair_block(
|
pub fn repair_block(
|
||||||
backend: &dyn VfsBackend,
|
_backend: &dyn VfsBackend,
|
||||||
file_path: &PathBuf,
|
_file_path: &PathBuf,
|
||||||
offset: u64,
|
_offset: u64,
|
||||||
expected_checksum: &[u8],
|
_expected_checksum: &[u8],
|
||||||
) -> Result<Vec<u8>, VfsError> {
|
) -> Result<Vec<u8>, VfsError> {
|
||||||
// Try Dedup repair first (check if block exists in dedup store)
|
// Try Dedup repair first (check if block exists in dedup store)
|
||||||
// This requires the backend to have dedup integration
|
// This requires the backend to have dedup integration
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use super::checksum::{
|
|||||||
BLOCK_SIZE, compute_block_hash, verify_block_hash,
|
BLOCK_SIZE, compute_block_hash, verify_block_hash,
|
||||||
checksum_path_for_file, ensure_checksum_dir,
|
checksum_path_for_file, ensure_checksum_dir,
|
||||||
};
|
};
|
||||||
use sha2::{Sha256, Digest};
|
use sha2::Digest;
|
||||||
|
|
||||||
pub struct ChecksumFile {
|
pub struct ChecksumFile {
|
||||||
inner: Box<dyn VfsFile>,
|
inner: Box<dyn VfsFile>,
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ use aes_gcm::{
|
|||||||
};
|
};
|
||||||
use sha2::{Sha256, Digest};
|
use sha2::{Sha256, Digest};
|
||||||
|
|
||||||
use super::{VfsBackend, VfsFile, VfsStat, VfsError, VfsDirEntry};
|
use super::{VfsBackend, VfsFile, VfsStat, VfsError};
|
||||||
use super::open_flags::OpenFlags;
|
|
||||||
use super::local_fs::LocalFs;
|
use super::local_fs::LocalFs;
|
||||||
|
|
||||||
const ENCRYPTED_MAGIC: &[u8] = b"MBE1"; // MarkBase Encrypted v1
|
const ENCRYPTED_MAGIC: &[u8] = b"MBE1"; // MarkBase Encrypted v1
|
||||||
@@ -62,7 +61,7 @@ impl EncryptedVfs {
|
|||||||
Self { inner, config }
|
Self { inner, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wrap_local_fs(root: PathBuf, config: EncryptedVfsConfig) -> Self {
|
pub fn wrap_local_fs(_root: PathBuf, config: EncryptedVfsConfig) -> Self {
|
||||||
Self::new(Box::new(LocalFs::new()), config)
|
Self::new(Box::new(LocalFs::new()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,8 +131,8 @@ fn rand_key(len: usize) -> Vec<u8> {
|
|||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
|
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(&now.to_le_bytes());
|
hasher.update(now.to_le_bytes());
|
||||||
hasher.update(&[0u8; 32]);
|
hasher.update([0u8; 32]);
|
||||||
let hash = hasher.finalize();
|
let hash = hasher.finalize();
|
||||||
hash[..len].to_vec()
|
hash[..len].to_vec()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ impl VfsBackend for LocalFs {
|
|||||||
fn get_xattr(&self, path: &Path, name: &str) -> Result<Vec<u8>, VfsError> {
|
fn get_xattr(&self, path: &Path, name: &str) -> Result<Vec<u8>, VfsError> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
use std::os::unix::fs::MetadataExt;
|
|
||||||
let _meta = path.metadata().map_err(|e| util::map_io_error(path, e))?;
|
let _meta = path.metadata().map_err(|e| util::map_io_error(path, e))?;
|
||||||
xattr::get(path, name)
|
xattr::get(path, name)
|
||||||
.map_err(|e| VfsError::Io(e.to_string()))?
|
.map_err(|e| VfsError::Io(e.to_string()))?
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl VfsRaidBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn level(&self) -> VfsRaidLevel {
|
pub fn level(&self) -> VfsRaidLevel {
|
||||||
self.config.level.clone()
|
self.config.level
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backends(&self) -> &[Box<dyn VfsBackend>] {
|
pub fn backends(&self) -> &[Box<dyn VfsBackend>] {
|
||||||
@@ -213,7 +213,7 @@ impl VfsRaidBackend {
|
|||||||
|
|
||||||
match self.config.level {
|
match self.config.level {
|
||||||
VfsRaidLevel::RaidZ1 => {
|
VfsRaidLevel::RaidZ1 => {
|
||||||
if parity_blocks.len() < 1 {
|
if parity_blocks.is_empty() {
|
||||||
return Err(VfsError::Io("Not enough parity for RaidZ1 repair".to_string()));
|
return Err(VfsError::Io("Not enough parity for RaidZ1 repair".to_string()));
|
||||||
}
|
}
|
||||||
let reconstructed = Self::reconstruct_from_p(
|
let reconstructed = Self::reconstruct_from_p(
|
||||||
@@ -284,7 +284,7 @@ impl VfsRaidBackend {
|
|||||||
fn reconstruct_from_pq(
|
fn reconstruct_from_pq(
|
||||||
data_blocks: &[Option<Vec<u8>>],
|
data_blocks: &[Option<Vec<u8>>],
|
||||||
p_block: &[u8],
|
p_block: &[u8],
|
||||||
q_block: &[u8],
|
_q_block: &[u8],
|
||||||
missing_index: usize,
|
missing_index: usize,
|
||||||
data_disk_count: usize,
|
data_disk_count: usize,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
@@ -294,8 +294,8 @@ impl VfsRaidBackend {
|
|||||||
fn reconstruct_from_pqr(
|
fn reconstruct_from_pqr(
|
||||||
data_blocks: &[Option<Vec<u8>>],
|
data_blocks: &[Option<Vec<u8>>],
|
||||||
p_block: &[u8],
|
p_block: &[u8],
|
||||||
q_block: &[u8],
|
_q_block: &[u8],
|
||||||
r_block: &[u8],
|
_r_block: &[u8],
|
||||||
missing_index: usize,
|
missing_index: usize,
|
||||||
data_disk_count: usize,
|
data_disk_count: usize,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use super::{VfsBackend, VfsError};
|
use super::{VfsBackend, VfsError};
|
||||||
use super::checksum::{scrub_all, ScrubResult};
|
use super::checksum::{scrub_all, ScrubResult};
|
||||||
@@ -180,7 +179,7 @@ impl ScrubStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_timestamp(secs: u64) -> String {
|
fn format_timestamp(secs: u64) -> String {
|
||||||
use chrono::{DateTime, Utc, TimeZone};
|
use chrono::{Utc, TimeZone};
|
||||||
Utc.timestamp_opt(secs as i64, 0)
|
Utc.timestamp_opt(secs as i64, 0)
|
||||||
.single()
|
.single()
|
||||||
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S UTC").to_string())
|
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S UTC").to_string())
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use super::{VfsBackend, VfsError, VfsCompression};
|
use super::{VfsBackend, VfsError, VfsCompression};
|
||||||
use super::backup_manifest::{BackupManifest, BackupStream, SendFormat, MANIFEST_FILE};
|
use super::backup_manifest::{BackupManifest, BackupStream, SendFormat, MANIFEST_FILE};
|
||||||
use super::checksum::{VfsChecksumFile, create_checksums_for_file, scrub_file};
|
use super::checksum::{VfsChecksumFile, scrub_file};
|
||||||
use super::dedup::{DedupStore, DedupManifest};
|
|
||||||
|
|
||||||
pub struct SendOptions {
|
pub struct SendOptions {
|
||||||
pub format: SendFormat,
|
pub format: SendFormat,
|
||||||
@@ -107,7 +106,7 @@ pub fn receive_snapshot(
|
|||||||
|
|
||||||
restore_snapshot_data(backend, &stream.data, &snapshot_dir)?;
|
restore_snapshot_data(backend, &stream.data, &snapshot_dir)?;
|
||||||
|
|
||||||
stream.manifest.save(&snapshot_dir).map_err(|e| VfsError::Io(e))?;
|
stream.manifest.save(&snapshot_dir).map_err(VfsError::Io)?;
|
||||||
|
|
||||||
if options.verify_checksums {
|
if options.verify_checksums {
|
||||||
verify_snapshot_checksums(backend, &snapshot_dir, root)?;
|
verify_snapshot_checksums(backend, &snapshot_dir, root)?;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::{VfsBackend, VfsError, VfsStat, VfsCompression, VfsRaidLevel};
|
use super::{VfsBackend, VfsError, VfsCompression, VfsRaidLevel};
|
||||||
use super::dedup::DedupStats;
|
use super::dedup::DedupStats;
|
||||||
use super::raid::VfsRaidBackend;
|
use super::raid::VfsRaidBackend;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user