mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +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 chrono::{DateTime, Utc};
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use helpers::AtomicFile;
|
use helpers::AtomicFile;
|
||||||
use patch_db::{DbHandle, HasModel, LockType};
|
use patch_db::{DbHandle, HasModel};
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use rpc_toolkit::command;
|
use rpc_toolkit::command;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{Executor, Postgres};
|
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
@@ -184,20 +183,16 @@ impl BackupActions {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(ctx, db, secrets))]
|
#[instrument(skip(ctx, db))]
|
||||||
pub async fn restore<Ex, Db: DbHandle>(
|
pub async fn restore<Db: DbHandle>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &RpcContext,
|
ctx: &RpcContext,
|
||||||
db: &mut Db,
|
db: &mut Db,
|
||||||
secrets: &mut Ex,
|
|
||||||
pkg_id: &PackageId,
|
pkg_id: &PackageId,
|
||||||
pkg_version: &Version,
|
pkg_version: &Version,
|
||||||
interfaces: &Interfaces,
|
interfaces: &Interfaces,
|
||||||
volumes: &Volumes,
|
volumes: &Volumes,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error> {
|
||||||
where
|
|
||||||
for<'a> &'a mut Ex: Executor<'a, Database = Postgres>,
|
|
||||||
{
|
|
||||||
let mut volumes = volumes.clone();
|
let mut volumes = volumes.clone();
|
||||||
volumes.insert(VolumeId::Backup, Volume::Backup { readonly: true });
|
volumes.insert(VolumeId::Backup, Volume::Backup { readonly: true });
|
||||||
self.restore
|
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()
|
let pde = crate::db::DatabaseModel::new()
|
||||||
.package_data()
|
.package_data()
|
||||||
.idx_model(pkg_id)
|
.idx_model(pkg_id)
|
||||||
@@ -251,10 +225,6 @@ impl BackupActions {
|
|||||||
.installed()
|
.installed()
|
||||||
.expect(db)
|
.expect(db)
|
||||||
.await?;
|
.await?;
|
||||||
pde.clone()
|
|
||||||
.interface_addresses()
|
|
||||||
.put(db, &interfaces.install(&mut *secrets, pkg_id).await?)
|
|
||||||
.await?;
|
|
||||||
pde.marketplace_url()
|
pde.marketplace_url()
|
||||||
.put(db, &metadata.marketplace_url)
|
.put(db, &metadata.marketplace_url)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use tracing::instrument;
|
|||||||
|
|
||||||
use super::target::BackupTargetId;
|
use super::target::BackupTargetId;
|
||||||
use crate::backup::backup_bulk::OsBackup;
|
use crate::backup::backup_bulk::OsBackup;
|
||||||
|
use crate::backup::BackupMetadata;
|
||||||
use crate::context::{RpcContext, SetupContext};
|
use crate::context::{RpcContext, SetupContext};
|
||||||
use crate::db::model::{PackageDataEntry, StaticFiles};
|
use crate::db::model::{PackageDataEntry, StaticFiles};
|
||||||
use crate::disk::mount::backup::{BackupMountGuard, PackageBackupMountGuard};
|
use crate::disk::mount::backup::{BackupMountGuard, PackageBackupMountGuard};
|
||||||
@@ -419,9 +420,37 @@ async fn restore_package<'a>(
|
|||||||
manifest: Manifest,
|
manifest: Manifest,
|
||||||
guard: PackageBackupMountGuard,
|
guard: PackageBackupMountGuard,
|
||||||
) -> Result<(Arc<InstallProgress>, BoxFuture<'static, Result<(), Error>>), Error> {
|
) -> Result<(Arc<InstallProgress>, BoxFuture<'static, Result<(), Error>>), Error> {
|
||||||
|
let id = manifest.id.clone();
|
||||||
let s9pk_path = Path::new(BACKUP_DIR)
|
let s9pk_path = Path::new(BACKUP_DIR)
|
||||||
.join(&manifest.id)
|
.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)
|
let len = tokio::fs::metadata(&s9pk_path)
|
||||||
.await
|
.await
|
||||||
.with_ctx(|_| {
|
.with_ctx(|_| {
|
||||||
|
|||||||
@@ -1331,7 +1331,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
|||||||
.restore(
|
.restore(
|
||||||
ctx,
|
ctx,
|
||||||
&mut tx,
|
&mut tx,
|
||||||
&mut sql_tx,
|
|
||||||
pkg_id,
|
pkg_id,
|
||||||
version,
|
version,
|
||||||
&manifest.interfaces,
|
&manifest.interfaces,
|
||||||
|
|||||||
@@ -81,11 +81,16 @@ async fn maybe_do_update(
|
|||||||
marketplace_url: Url,
|
marketplace_url: Url,
|
||||||
) -> Result<Option<Arc<Revision>>, Error> {
|
) -> Result<Option<Arc<Revision>>, Error> {
|
||||||
let mut db = ctx.db.handle();
|
let mut db = ctx.db.handle();
|
||||||
|
let arch = if *IS_RASPBERRY_PI {
|
||||||
|
"raspberrypi"
|
||||||
|
} else {
|
||||||
|
*crate::ARCH
|
||||||
|
};
|
||||||
let latest_version: Version = reqwest::get(format!(
|
let latest_version: Version = reqwest::get(format!(
|
||||||
"{}/eos/v0/latest?eos-version={}&arch={}",
|
"{}/eos/v0/latest?eos-version={}&arch={}",
|
||||||
marketplace_url,
|
marketplace_url,
|
||||||
Current::new().semver(),
|
Current::new().semver(),
|
||||||
&*crate::ARCH,
|
arch,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.with_kind(ErrorKind::Network)?
|
.with_kind(ErrorKind::Network)?
|
||||||
@@ -121,13 +126,6 @@ async fn maybe_do_update(
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mount httpdirfs
|
|
||||||
// losetup remote fs
|
|
||||||
// BEGIN TASK
|
|
||||||
// rsync fs
|
|
||||||
// validate (hash) fs
|
|
||||||
// kernel update?
|
|
||||||
// swap selected fs
|
|
||||||
let eos_url = EosUrl {
|
let eos_url = EosUrl {
|
||||||
base: marketplace_url,
|
base: marketplace_url,
|
||||||
version: latest_version,
|
version: latest_version,
|
||||||
@@ -243,7 +241,7 @@ impl EosUrl {
|
|||||||
.ok_or_else(|| Error::new(eyre!("Could not get host of base"), ErrorKind::ParseUrl))?;
|
.ok_or_else(|| Error::new(eyre!("Could not get host of base"), ErrorKind::ParseUrl))?;
|
||||||
let version: &Version = &self.version;
|
let version: &Version = &self.version;
|
||||||
let arch = if *IS_RASPBERRY_PI {
|
let arch = if *IS_RASPBERRY_PI {
|
||||||
"raspberry_pi"
|
"raspberrypi"
|
||||||
} else {
|
} else {
|
||||||
*crate::ARCH
|
*crate::ARCH
|
||||||
};
|
};
|
||||||
@@ -310,23 +308,25 @@ async fn sync_boot() -> Result<(), Error> {
|
|||||||
)?
|
)?
|
||||||
.wait()
|
.wait()
|
||||||
.await?;
|
.await?;
|
||||||
let dev_mnt =
|
if !*IS_RASPBERRY_PI {
|
||||||
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
let dev_mnt =
|
||||||
let sys_mnt =
|
MountGuard::mount(&Bind::new("/dev"), "/media/embassy/next/dev", ReadWrite).await?;
|
||||||
MountGuard::mount(&Bind::new("/sys"), "/media/embassy/next/sys", ReadWrite).await?;
|
let sys_mnt =
|
||||||
let proc_mnt =
|
MountGuard::mount(&Bind::new("/sys"), "/media/embassy/next/sys", ReadWrite).await?;
|
||||||
MountGuard::mount(&Bind::new("/proc"), "/media/embassy/next/proc", ReadWrite).await?;
|
let proc_mnt =
|
||||||
let boot_mnt =
|
MountGuard::mount(&Bind::new("/proc"), "/media/embassy/next/proc", ReadWrite).await?;
|
||||||
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
let boot_mnt =
|
||||||
Command::new("chroot")
|
MountGuard::mount(&Bind::new("/boot"), "/media/embassy/next/boot", ReadWrite).await?;
|
||||||
.arg("/media/embassy/next")
|
Command::new("chroot")
|
||||||
.arg("update-grub")
|
.arg("/media/embassy/next")
|
||||||
.invoke(ErrorKind::MigrationFailed)
|
.arg("update-grub")
|
||||||
.await?;
|
.invoke(ErrorKind::MigrationFailed)
|
||||||
boot_mnt.unmount().await?;
|
.await?;
|
||||||
proc_mnt.unmount().await?;
|
boot_mnt.unmount().await?;
|
||||||
sys_mnt.unmount().await?;
|
proc_mnt.unmount().await?;
|
||||||
dev_mnt.unmount().await?;
|
sys_mnt.unmount().await?;
|
||||||
|
dev_mnt.unmount().await?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user