Fix/backups (#2659)

* fix master build (#2639)

* feat: Change ts to use rsync
Chore: Update the ts to use types over interface

* feat: Get the rust and the js to do a backup

* Wip: Got the backup working?

* fix permissions

* remove trixie list

* update tokio to fix timer bug

* fix error handling on backup

* wip

* remove idmap

* run restore before init, and init with own version on restore

---------

Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Jade
2024-07-17 15:46:27 -06:00
committed by GitHub
parent 95611e9c4b
commit 8f0bdcd172
23 changed files with 445 additions and 380 deletions

View File

@@ -106,8 +106,11 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
)
})?;
}
let encrypted_guard =
TmpMountGuard::mount(&BackupFS::new(&crypt_path, &enc_key), ReadWrite).await?;
let encrypted_guard = TmpMountGuard::mount(
&BackupFS::new(&crypt_path, &enc_key, vec![(100000, 65536)]),
ReadWrite,
)
.await?;
let metadata_path = encrypted_guard.path().join("metadata.json");
let metadata: BackupInfo = if tokio::fs::metadata(&metadata_path).await.is_ok() {
@@ -148,8 +151,23 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
}
#[instrument(skip_all)]
pub fn package_backup(self: &Arc<Self>, id: &PackageId) -> SubPath<Arc<Self>> {
SubPath::new(self.clone(), id)
pub async fn package_backup(
self: &Arc<Self>,
id: &PackageId,
) -> Result<SubPath<Arc<Self>>, Error> {
let package_guard = SubPath::new(self.clone(), id);
let package_path = package_guard.path();
if tokio::fs::metadata(&package_path).await.is_err() {
tokio::fs::create_dir_all(&package_path)
.await
.with_ctx(|_| {
(
crate::ErrorKind::Filesystem,
package_path.display().to_string(),
)
})?;
}
Ok(package_guard)
}
#[instrument(skip_all)]

View File

@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::fmt::{self, Display};
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
@@ -12,10 +13,15 @@ use crate::prelude::*;
pub struct BackupFS<DataDir: AsRef<Path>, Password: fmt::Display> {
data_dir: DataDir,
password: Password,
idmapped_root: Vec<(u32, u32)>,
}
impl<DataDir: AsRef<Path>, Password: fmt::Display> BackupFS<DataDir, Password> {
pub fn new(data_dir: DataDir, password: Password) -> Self {
BackupFS { data_dir, password }
pub fn new(data_dir: DataDir, password: Password, idmapped_root: Vec<(u32, u32)>) -> Self {
BackupFS {
data_dir,
password,
idmapped_root,
}
}
}
impl<DataDir: AsRef<Path> + Send + Sync, Password: fmt::Display + Send + Sync> FileSystem
@@ -26,9 +32,16 @@ impl<DataDir: AsRef<Path> + Send + Sync, Password: fmt::Display + Send + Sync> F
}
fn mount_options(&self) -> impl IntoIterator<Item = impl Display> {
[
format!("password={}", self.password),
format!("file-size-padding=0.05"),
Cow::Owned(format!("password={}", self.password)),
Cow::Borrowed("file-size-padding=0.05"),
Cow::Borrowed("allow_other"),
]
.into_iter()
.chain(
self.idmapped_root
.iter()
.map(|(root, range)| Cow::Owned(format!("idmapped-root={root}:{range}"))),
)
}
async fn source(&self) -> Result<Option<impl AsRef<Path>>, Error> {
Ok(Some(&self.data_dir))