mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
backup luks headers
This commit is contained in:
committed by
Aiden McClelland
parent
a11bf5b5c7
commit
483f353fd0
@@ -1,5 +1,5 @@
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use chrono::Utc;
|
||||
use clap::ArgMatches;
|
||||
@@ -8,6 +8,7 @@ use helpers::AtomicFile;
|
||||
use patch_db::{DbHandle, LockType, PatchDbHandle};
|
||||
use rpc_toolkit::command;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::process::Command;
|
||||
use tracing::instrument;
|
||||
|
||||
use super::target::BackupTargetId;
|
||||
@@ -23,8 +24,8 @@ use crate::disk::mount::guard::TmpMountGuard;
|
||||
use crate::notifications::NotificationLevel;
|
||||
use crate::s9pk::manifest::PackageId;
|
||||
use crate::status::MainStatus;
|
||||
use crate::util::display_none;
|
||||
use crate::util::serde::IoFormat;
|
||||
use crate::util::{display_none, Invoke};
|
||||
use crate::version::VersionT;
|
||||
use crate::{Error, ErrorKind, ResultExt};
|
||||
|
||||
@@ -358,6 +359,24 @@ async fn perform_backup<Db: DbHandle>(
|
||||
.await
|
||||
.with_kind(ErrorKind::Filesystem)?;
|
||||
|
||||
let luks_folder_old = backup_guard.as_ref().join("luks.old");
|
||||
if tokio::fs::metadata(&luks_folder_old).await.is_ok() {
|
||||
tokio::fs::remove_dir_all(&luks_folder_old).await?;
|
||||
}
|
||||
let luks_folder_bak = backup_guard.as_ref().join("luks");
|
||||
if tokio::fs::metadata(&luks_folder_bak).await.is_ok() {
|
||||
tokio::fs::rename(&luks_folder_bak, &luks_folder_old).await?;
|
||||
}
|
||||
let luks_folder = Path::new("/media/embassy/config/luks");
|
||||
if tokio::fs::metadata(&luks_folder).await.is_ok() {
|
||||
Command::new("cp")
|
||||
.arg("-r")
|
||||
.arg(&luks_folder)
|
||||
.arg(&luks_folder_bak)
|
||||
.invoke(ErrorKind::Filesystem)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let timestamp = Some(Utc::now());
|
||||
|
||||
backup_guard.unencrypted_metadata.version = crate::version::Current::new().semver().into();
|
||||
|
||||
@@ -106,12 +106,13 @@ pub async fn create_fs<P: AsRef<Path>>(
|
||||
.arg(guid)
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
let crypt_path = Path::new("/dev").join(guid).join(name);
|
||||
Command::new("cryptsetup")
|
||||
.arg("-q")
|
||||
.arg("luksFormat")
|
||||
.arg(format!("--key-file={}", PASSWORD_PATH))
|
||||
.arg(format!("--keyfile-size={}", password.len()))
|
||||
.arg(Path::new("/dev").join(guid).join(name))
|
||||
.arg(&crypt_path)
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
Command::new("cryptsetup")
|
||||
@@ -119,7 +120,7 @@ pub async fn create_fs<P: AsRef<Path>>(
|
||||
.arg("luksOpen")
|
||||
.arg(format!("--key-file={}", PASSWORD_PATH))
|
||||
.arg(format!("--keyfile-size={}", password.len()))
|
||||
.arg(Path::new("/dev").join(guid).join(name))
|
||||
.arg(&crypt_path)
|
||||
.arg(format!("{}_{}", guid, name))
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
@@ -265,17 +266,36 @@ pub async fn mount_fs<P: AsRef<Path>>(
|
||||
tokio::fs::write(PASSWORD_PATH, password)
|
||||
.await
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?;
|
||||
let crypt_path = Path::new("/dev").join(guid).join(name);
|
||||
let full_name = format!("{}_{}", guid, name);
|
||||
Command::new("cryptsetup")
|
||||
.arg("-q")
|
||||
.arg("luksOpen")
|
||||
.arg(format!("--key-file={}", PASSWORD_PATH))
|
||||
.arg(format!("--keyfile-size={}", password.len()))
|
||||
.arg(Path::new("/dev").join(guid).join(name))
|
||||
.arg(format!("{}_{}", guid, name))
|
||||
.arg(&crypt_path)
|
||||
.arg(&full_name)
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
let mapper_path = Path::new("/dev/mapper").join(format!("{}_{}", guid, name));
|
||||
let mapper_path = Path::new("/dev/mapper").join(&full_name);
|
||||
let reboot = repair.e2fsck(&mapper_path).await?;
|
||||
// Backup LUKS header if e2fsck succeeded
|
||||
let luks_folder = Path::new("/media/embassy/config/luks");
|
||||
tokio::fs::create_dir_all(luks_folder).await?;
|
||||
let tmp_luks_bak = luks_folder.join(format!(".{full_name}.luks.bak.tmp"));
|
||||
if tokio::fs::metadata(&tmp_luks_bak).await.is_ok() {
|
||||
tokio::fs::remove_file(&tmp_luks_bak).await?;
|
||||
}
|
||||
let luks_bak = luks_folder.join(format!("{full_name}.luks.bak"));
|
||||
Command::new("cryptsetup")
|
||||
.arg("-q")
|
||||
.arg("luksHeaderBackup")
|
||||
.arg("--header-backup-file")
|
||||
.arg(&tmp_luks_bak)
|
||||
.arg(&crypt_path)
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
tokio::fs::rename(&tmp_luks_bak, &luks_bak).await?;
|
||||
mount(&mapper_path, datadir.as_ref().join(name), ReadWrite).await?;
|
||||
|
||||
tokio::fs::remove_file(PASSWORD_PATH)
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::context::InstallContext;
|
||||
use crate::disk::mount::filesystem::bind::Bind;
|
||||
use crate::disk::mount::filesystem::block_dev::BlockDev;
|
||||
use crate::disk::mount::filesystem::efivarfs::EfiVarFs;
|
||||
use crate::disk::mount::filesystem::ReadWrite;
|
||||
use crate::disk::mount::filesystem::{MountType, ReadWrite};
|
||||
use crate::disk::mount::guard::{MountGuard, TmpMountGuard};
|
||||
use crate::disk::util::{DiskInfo, PartitionTable};
|
||||
use crate::disk::OsPartitionInfo;
|
||||
@@ -147,6 +147,34 @@ pub async fn execute(
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
.await?;
|
||||
|
||||
if !overwrite {
|
||||
if let Ok(guard) =
|
||||
TmpMountGuard::mount(&BlockDev::new(part_info.root.clone()), MountType::ReadOnly).await
|
||||
{
|
||||
if let Err(e) = async {
|
||||
// cp -r ${guard}/config /tmp/config
|
||||
Command::new("cp")
|
||||
.arg("-r")
|
||||
.arg(guard.as_ref().join("config"))
|
||||
.arg("/tmp/config.bak")
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
if tokio::fs::metadata(guard.as_ref().join("config/upgrade"))
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
tokio::fs::remove_file(guard.as_ref().join("config/upgrade")).await?;
|
||||
}
|
||||
guard.unmount().await
|
||||
}
|
||||
.await
|
||||
{
|
||||
tracing::error!("Error recovering previous config: {e}");
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Command::new("mkfs.ext4")
|
||||
.arg(&part_info.root)
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
@@ -158,7 +186,16 @@ pub async fn execute(
|
||||
.await?;
|
||||
|
||||
let rootfs = TmpMountGuard::mount(&BlockDev::new(&part_info.root), ReadWrite).await?;
|
||||
tokio::fs::create_dir(rootfs.as_ref().join("config")).await?;
|
||||
if tokio::fs::metadata("/tmp/config.bak").await.is_ok() {
|
||||
Command::new("cp")
|
||||
.arg("-r")
|
||||
.arg("/tmp/config.bak")
|
||||
.arg(rootfs.as_ref().join("config"))
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
} else {
|
||||
tokio::fs::create_dir(rootfs.as_ref().join("config")).await?;
|
||||
}
|
||||
tokio::fs::create_dir(rootfs.as_ref().join("next")).await?;
|
||||
let current = rootfs.as_ref().join("current");
|
||||
tokio::fs::create_dir(¤t).await?;
|
||||
|
||||
Reference in New Issue
Block a user