mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
restore interfaces before creating manager (#1982)
This commit is contained in:
@@ -4,11 +4,10 @@ use std::path::{Path, PathBuf};
|
||||
use chrono::{DateTime, Utc};
|
||||
use color_eyre::eyre::eyre;
|
||||
use helpers::AtomicFile;
|
||||
use patch_db::{DbHandle, HasModel, LockType};
|
||||
use patch_db::{DbHandle, HasModel};
|
||||
use reqwest::Url;
|
||||
use rpc_toolkit::command;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{Executor, Postgres};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::instrument;
|
||||
@@ -184,20 +183,16 @@ impl BackupActions {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, secrets))]
|
||||
pub async fn restore<Ex, Db: DbHandle>(
|
||||
#[instrument(skip(ctx, db))]
|
||||
pub async fn restore<Db: DbHandle>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
secrets: &mut Ex,
|
||||
pkg_id: &PackageId,
|
||||
pkg_version: &Version,
|
||||
interfaces: &Interfaces,
|
||||
volumes: &Volumes,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
for<'a> &'a mut Ex: Executor<'a, Database = Postgres>,
|
||||
{
|
||||
) -> Result<(), Error> {
|
||||
let mut volumes = volumes.clone();
|
||||
volumes.insert(VolumeId::Backup, Volume::Backup { readonly: true });
|
||||
self.restore
|
||||
@@ -222,27 +217,6 @@ impl BackupActions {
|
||||
)
|
||||
})?,
|
||||
)?;
|
||||
for (iface, key) in metadata.tor_keys {
|
||||
let key_vec = base32::decode(base32::Alphabet::RFC4648 { padding: true }, &key)
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("invalid base32 string"),
|
||||
crate::ErrorKind::Deserialization,
|
||||
)
|
||||
})?;
|
||||
sqlx::query!(
|
||||
"INSERT INTO tor (package, interface, key) VALUES ($1, $2, $3) ON CONFLICT (package, interface) DO UPDATE SET key = $3",
|
||||
**pkg_id,
|
||||
*iface,
|
||||
key_vec,
|
||||
)
|
||||
.execute(&mut *secrets)
|
||||
.await?;
|
||||
}
|
||||
crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.lock(db, LockType::Write)
|
||||
.await?;
|
||||
let pde = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(pkg_id)
|
||||
@@ -251,10 +225,6 @@ impl BackupActions {
|
||||
.installed()
|
||||
.expect(db)
|
||||
.await?;
|
||||
pde.clone()
|
||||
.interface_addresses()
|
||||
.put(db, &interfaces.install(&mut *secrets, pkg_id).await?)
|
||||
.await?;
|
||||
pde.marketplace_url()
|
||||
.put(db, &metadata.marketplace_url)
|
||||
.await?;
|
||||
|
||||
@@ -18,6 +18,7 @@ use tracing::instrument;
|
||||
|
||||
use super::target::BackupTargetId;
|
||||
use crate::backup::backup_bulk::OsBackup;
|
||||
use crate::backup::BackupMetadata;
|
||||
use crate::context::{RpcContext, SetupContext};
|
||||
use crate::db::model::{PackageDataEntry, StaticFiles};
|
||||
use crate::disk::mount::backup::{BackupMountGuard, PackageBackupMountGuard};
|
||||
@@ -419,9 +420,37 @@ async fn restore_package<'a>(
|
||||
manifest: Manifest,
|
||||
guard: PackageBackupMountGuard,
|
||||
) -> Result<(Arc<InstallProgress>, BoxFuture<'static, Result<(), Error>>), Error> {
|
||||
let id = manifest.id.clone();
|
||||
let s9pk_path = Path::new(BACKUP_DIR)
|
||||
.join(&manifest.id)
|
||||
.join(format!("{}.s9pk", manifest.id));
|
||||
.join(format!("{}.s9pk", id));
|
||||
|
||||
let metadata_path = Path::new(BACKUP_DIR).join(&id).join("metadata.cbor");
|
||||
let metadata: BackupMetadata =
|
||||
IoFormat::Cbor.from_slice(&tokio::fs::read(&metadata_path).await.with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Filesystem,
|
||||
metadata_path.display().to_string(),
|
||||
)
|
||||
})?)?;
|
||||
for (iface, key) in metadata.tor_keys {
|
||||
let key_vec = base32::decode(base32::Alphabet::RFC4648 { padding: true }, &key)
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("invalid base32 string"),
|
||||
crate::ErrorKind::Deserialization,
|
||||
)
|
||||
})?;
|
||||
sqlx::query!(
|
||||
"INSERT INTO tor (package, interface, key) VALUES ($1, $2, $3) ON CONFLICT (package, interface) DO UPDATE SET key = $3",
|
||||
*id,
|
||||
*iface,
|
||||
key_vec,
|
||||
)
|
||||
.execute(&ctx.secret_store)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let len = tokio::fs::metadata(&s9pk_path)
|
||||
.await
|
||||
.with_ctx(|_| {
|
||||
|
||||
@@ -1331,7 +1331,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
||||
.restore(
|
||||
ctx,
|
||||
&mut tx,
|
||||
&mut sql_tx,
|
||||
pkg_id,
|
||||
version,
|
||||
&manifest.interfaces,
|
||||
|
||||
@@ -81,11 +81,16 @@ async fn maybe_do_update(
|
||||
marketplace_url: Url,
|
||||
) -> Result<Option<Arc<Revision>>, Error> {
|
||||
let mut db = ctx.db.handle();
|
||||
let arch = if *IS_RASPBERRY_PI {
|
||||
"raspberrypi"
|
||||
} else {
|
||||
*crate::ARCH
|
||||
};
|
||||
let latest_version: Version = reqwest::get(format!(
|
||||
"{}/eos/v0/latest?eos-version={}&arch={}",
|
||||
marketplace_url,
|
||||
Current::new().semver(),
|
||||
&*crate::ARCH,
|
||||
arch,
|
||||
))
|
||||
.await
|
||||
.with_kind(ErrorKind::Network)?
|
||||
@@ -121,13 +126,6 @@ async fn maybe_do_update(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// mount httpdirfs
|
||||
// losetup remote fs
|
||||
// BEGIN TASK
|
||||
// rsync fs
|
||||
// validate (hash) fs
|
||||
// kernel update?
|
||||
// swap selected fs
|
||||
let eos_url = EosUrl {
|
||||
base: marketplace_url,
|
||||
version: latest_version,
|
||||
@@ -243,7 +241,7 @@ impl EosUrl {
|
||||
.ok_or_else(|| Error::new(eyre!("Could not get host of base"), ErrorKind::ParseUrl))?;
|
||||
let version: &Version = &self.version;
|
||||
let arch = if *IS_RASPBERRY_PI {
|
||||
"raspberry_pi"
|
||||
"raspberrypi"
|
||||
} else {
|
||||
*crate::ARCH
|
||||
};
|
||||
@@ -310,23 +308,25 @@ async fn sync_boot() -> Result<(), Error> {
|
||||
)?
|
||||
.wait()
|
||||
.await?;
|
||||
let dev_mnt =
|
||||
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
||||
let sys_mnt =
|
||||
MountGuard::mount(&Bind::new("/sys"), "/media/embassy/next/sys", ReadWrite).await?;
|
||||
let proc_mnt =
|
||||
MountGuard::mount(&Bind::new("/proc"), "/media/embassy/next/proc", ReadWrite).await?;
|
||||
let boot_mnt =
|
||||
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
||||
Command::new("chroot")
|
||||
.arg("/media/embassy/next")
|
||||
.arg("update-grub")
|
||||
.invoke(ErrorKind::MigrationFailed)
|
||||
.await?;
|
||||
boot_mnt.unmount().await?;
|
||||
proc_mnt.unmount().await?;
|
||||
sys_mnt.unmount().await?;
|
||||
dev_mnt.unmount().await?;
|
||||
if !*IS_RASPBERRY_PI {
|
||||
let dev_mnt =
|
||||
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
||||
let sys_mnt =
|
||||
MountGuard::mount(&Bind::new("/sys"), "/media/embassy/next/sys", ReadWrite).await?;
|
||||
let proc_mnt =
|
||||
MountGuard::mount(&Bind::new("/proc"), "/media/embassy/next/proc", ReadWrite).await?;
|
||||
let boot_mnt =
|
||||
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
||||
Command::new("chroot")
|
||||
.arg("/media/embassy/next")
|
||||
.arg("update-grub")
|
||||
.invoke(ErrorKind::MigrationFailed)
|
||||
.await?;
|
||||
boot_mnt.unmount().await?;
|
||||
proc_mnt.unmount().await?;
|
||||
sys_mnt.unmount().await?;
|
||||
dev_mnt.unmount().await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user