restore interfaces before creating manager (#1982)

This commit is contained in:
Aiden McClelland
2022-11-27 17:35:02 -07:00
parent 78f6bbf7fe
commit a3a4fdd7fc
4 changed files with 60 additions and 62 deletions

View File

@@ -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?;

View File

@@ -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(|_| {

View File

@@ -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,

View File

@@ -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(())
}