mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
Feature/backup fs (#2665)
* port 040 config, WIP * update fixtures * use taiga modal for backups too * fix: update Taiga UI and refactor everything to work * chore: package-lock * fix interfaces and mocks for interfaces * better mocks * function to transform old spec to new * delete unused fns * delete unused FE config utils * fix exports from sdk * reorganize exports * functions to translate config * rename unionSelectKey and unionValueKey * new backup fs * update sdk types * change types, include fuse module * fix casing * rework setup wiz * rework UI * only fuse3 * fix arm build * misc fixes * fix duplicate server select * fix: fix throwing inside dialog --------- Co-authored-by: Matt Hill <mattnine@protonmail.com> Co-authored-by: waterplea <alexander@inkin.ru> Co-authored-by: Matt Hill <MattDHill@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -25,7 +26,7 @@ use crate::disk::main::DEFAULT_PASSWORD;
|
||||
use crate::disk::mount::filesystem::cifs::Cifs;
|
||||
use crate::disk::mount::filesystem::ReadWrite;
|
||||
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
|
||||
use crate::disk::util::{pvscan, recovery_info, DiskInfo, EmbassyOsRecoveryInfo};
|
||||
use crate::disk::util::{pvscan, recovery_info, DiskInfo, StartOsRecoveryInfo};
|
||||
use crate::disk::REPAIR_DISK_PATH;
|
||||
use crate::init::{init, InitPhases, InitResult};
|
||||
use crate::net::net_controller::PreInitNetController;
|
||||
@@ -237,7 +238,7 @@ pub async fn verify_cifs(
|
||||
username,
|
||||
password,
|
||||
}: VerifyCifsParams,
|
||||
) -> Result<EmbassyOsRecoveryInfo, Error> {
|
||||
) -> Result<BTreeMap<String, StartOsRecoveryInfo>, Error> {
|
||||
let password: Option<String> = password.map(|x| x.decrypt(&ctx)).flatten();
|
||||
let guard = TmpMountGuard::mount(
|
||||
&Cifs {
|
||||
@@ -251,15 +252,28 @@ pub async fn verify_cifs(
|
||||
.await?;
|
||||
let start_os = recovery_info(guard.path()).await?;
|
||||
guard.unmount().await?;
|
||||
start_os.ok_or_else(|| Error::new(eyre!("No Backup Found"), crate::ErrorKind::NotFound))
|
||||
if start_os.is_empty() {
|
||||
return Err(Error::new(
|
||||
eyre!("No Backup Found"),
|
||||
crate::ErrorKind::NotFound,
|
||||
));
|
||||
}
|
||||
Ok(start_os)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, TS)]
|
||||
#[serde(tag = "type")]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum RecoverySource {
|
||||
Migrate { guid: String },
|
||||
Backup { target: BackupTargetFS },
|
||||
#[serde(rename_all_fields = "camelCase")]
|
||||
pub enum RecoverySource<Password> {
|
||||
Migrate {
|
||||
guid: String,
|
||||
},
|
||||
Backup {
|
||||
target: BackupTargetFS,
|
||||
password: Password,
|
||||
server_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, TS)]
|
||||
@@ -268,8 +282,7 @@ pub enum RecoverySource {
|
||||
pub struct SetupExecuteParams {
|
||||
start_os_logicalname: PathBuf,
|
||||
start_os_password: EncryptedWire,
|
||||
recovery_source: Option<RecoverySource>,
|
||||
recovery_password: Option<EncryptedWire>,
|
||||
recovery_source: Option<RecoverySource<EncryptedWire>>,
|
||||
}
|
||||
|
||||
// #[command(rpc_only)]
|
||||
@@ -279,7 +292,6 @@ pub async fn execute(
|
||||
start_os_logicalname,
|
||||
start_os_password,
|
||||
recovery_source,
|
||||
recovery_password,
|
||||
}: SetupExecuteParams,
|
||||
) -> Result<SetupProgress, Error> {
|
||||
let start_os_password = match start_os_password.decrypt(&ctx) {
|
||||
@@ -291,29 +303,27 @@ pub async fn execute(
|
||||
))
|
||||
}
|
||||
};
|
||||
let recovery_password: Option<String> = match recovery_password {
|
||||
Some(a) => match a.decrypt(&ctx) {
|
||||
Some(a) => Some(a),
|
||||
None => {
|
||||
return Err(Error::new(
|
||||
let recovery = match recovery_source {
|
||||
Some(RecoverySource::Backup {
|
||||
target,
|
||||
password,
|
||||
server_id,
|
||||
}) => Some(RecoverySource::Backup {
|
||||
target,
|
||||
password: password.decrypt(&ctx).ok_or_else(|| {
|
||||
Error::new(
|
||||
color_eyre::eyre::eyre!("Couldn't decode recoveryPassword"),
|
||||
crate::ErrorKind::Unknown,
|
||||
))
|
||||
}
|
||||
},
|
||||
)
|
||||
})?,
|
||||
server_id,
|
||||
}),
|
||||
Some(RecoverySource::Migrate { guid }) => Some(RecoverySource::Migrate { guid }),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let setup_ctx = ctx.clone();
|
||||
ctx.run_setup(|| {
|
||||
execute_inner(
|
||||
setup_ctx,
|
||||
start_os_logicalname,
|
||||
start_os_password,
|
||||
recovery_source,
|
||||
recovery_password,
|
||||
)
|
||||
})?;
|
||||
ctx.run_setup(|| execute_inner(setup_ctx, start_os_logicalname, start_os_password, recovery))?;
|
||||
|
||||
Ok(ctx.progress().await)
|
||||
}
|
||||
@@ -348,12 +358,11 @@ pub async fn execute_inner(
|
||||
ctx: SetupContext,
|
||||
start_os_logicalname: PathBuf,
|
||||
start_os_password: String,
|
||||
recovery_source: Option<RecoverySource>,
|
||||
recovery_password: Option<String>,
|
||||
recovery_source: Option<RecoverySource<String>>,
|
||||
) -> Result<(SetupResult, RpcContext), Error> {
|
||||
let progress = &ctx.progress;
|
||||
let mut disk_phase = progress.add_phase("Formatting data drive".into(), Some(10));
|
||||
let restore_phase = match &recovery_source {
|
||||
let restore_phase = match recovery_source.as_ref() {
|
||||
Some(RecoverySource::Backup { .. }) => {
|
||||
Some(progress.add_phase("Restoring backup".into(), Some(100)))
|
||||
}
|
||||
@@ -396,13 +405,18 @@ pub async fn execute_inner(
|
||||
};
|
||||
|
||||
match recovery_source {
|
||||
Some(RecoverySource::Backup { target }) => {
|
||||
Some(RecoverySource::Backup {
|
||||
target,
|
||||
password,
|
||||
server_id,
|
||||
}) => {
|
||||
recover(
|
||||
&ctx,
|
||||
guid,
|
||||
start_os_password,
|
||||
target,
|
||||
recovery_password,
|
||||
server_id,
|
||||
password,
|
||||
progress,
|
||||
)
|
||||
.await
|
||||
@@ -448,7 +462,8 @@ async fn recover(
|
||||
guid: Arc<String>,
|
||||
start_os_password: String,
|
||||
recovery_source: BackupTargetFS,
|
||||
recovery_password: Option<String>,
|
||||
server_id: String,
|
||||
recovery_password: String,
|
||||
progress: SetupExecuteProgress,
|
||||
) -> Result<(SetupResult, RpcContext), Error> {
|
||||
let recovery_source = TmpMountGuard::mount(&recovery_source, ReadWrite).await?;
|
||||
@@ -457,7 +472,8 @@ async fn recover(
|
||||
guid.clone(),
|
||||
start_os_password,
|
||||
recovery_source,
|
||||
recovery_password,
|
||||
&server_id,
|
||||
&recovery_password,
|
||||
progress,
|
||||
)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user