feat: Change all the dependency errors at once (#2427)

* feat: Change all the dependency errors at once

* remove deprecated dependency-errors field

* set pointers to [] by default

* chore: Something about fixing the build

* fix migration

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
J H
2023-09-29 12:08:53 -06:00
committed by GitHub
parent e6e4cd63f3
commit 5e3412d735
12 changed files with 170 additions and 34 deletions

4
backend/Cargo.lock generated
View File

@@ -2120,9 +2120,9 @@ dependencies = [
[[package]]
name = "indicatif"
version = "0.17.6"
version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730"
checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25"
dependencies = [
"console",
"instant",

View File

@@ -22,6 +22,7 @@ use crate::account::AccountInfo;
use crate::core::rpc_continuations::{RequestGuid, RestHandler, RpcContinuation};
use crate::db::model::{CurrentDependents, Database, PackageDataEntryMatchModelRef};
use crate::db::prelude::PatchDbExt;
use crate::dependencies::compute_dependency_config_errs;
use crate::disk::OsPartitionInfo;
use crate::init::init_postgres;
use crate::install::cleanup::{cleanup_failed, uninstall};
@@ -155,8 +156,7 @@ impl RpcContext {
.unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))),
tor_proxy,
base.dns_bind
.as_ref()
.map(|v| v.as_slice())
.as_deref()
.unwrap_or(&[SocketAddr::from(([127, 0, 0, 1], 53))]),
SslManager::new(&account)?,
&account.hostname,
@@ -217,11 +217,8 @@ impl RpcContext {
});
let res = Self(seed.clone());
res.cleanup().await?;
res.cleanup_and_initialize().await?;
tracing::info!("Cleaned up transient states");
let peeked = res.db.peek().await?;
res.managers.init(res.clone(), peeked).await?;
tracing::info!("Initialized Package Managers");
Ok(res)
}
@@ -236,7 +233,7 @@ impl RpcContext {
}
#[instrument(skip(self))]
pub async fn cleanup(&self) -> Result<(), Error> {
pub async fn cleanup_and_initialize(&self) -> Result<(), Error> {
self.db
.mutate(|f| {
let mut current_dependents = f
@@ -278,9 +275,10 @@ impl RpcContext {
Ok(())
})
.await?;
let peek = self.db.peek().await?;
for (package_id, package) in peek.as_package_data().as_entries()?.into_iter() {
let package = package.clone();
let action = match package.as_match() {
PackageDataEntryMatchModelRef::Installing(_)
| PackageDataEntryMatchModelRef::Restoring(_)
@@ -298,7 +296,7 @@ impl RpcContext {
&self.datadir,
&package_id,
&version,
&volume_id,
volume_id,
))
.with_kind(ErrorKind::Filesystem)?;
if tokio::fs::metadata(&tmp_path).await.is_ok() {
@@ -314,7 +312,8 @@ impl RpcContext {
tracing::debug!("{:?}", e);
}
}
self.db
let peek = self
.db
.mutate(|v| {
for (_, pde) in v.as_package_data_mut().as_entries_mut()? {
let status = pde
@@ -329,9 +328,49 @@ impl RpcContext {
MainStatus::Stopped
})?;
}
Ok(v.clone())
})
.await?;
self.managers.init(self.clone(), peek.clone()).await?;
tracing::info!("Initialized Package Managers");
let mut all_dependency_config_errs = BTreeMap::new();
for (package_id, package) in peek.as_package_data().as_entries()?.into_iter() {
let package = package.clone();
if let Some(current_dependencies) = package
.as_installed()
.and_then(|x| x.as_current_dependencies().de().ok())
{
let manifest = package.as_manifest().de()?;
all_dependency_config_errs.insert(
package_id.clone(),
compute_dependency_config_errs(
self,
&peek,
&manifest,
&current_dependencies,
&Default::default(),
)
.await?,
);
}
}
self.db
.mutate(|v| {
for (package_id, errs) in all_dependency_config_errs {
if let Some(config_errors) = v
.as_package_data_mut()
.as_idx_mut(&package_id)
.and_then(|pde| pde.as_installed_mut())
.map(|i| i.as_status_mut().as_dependency_config_errors_mut())
{
config_errors.ser(&errs)?;
}
}
Ok(())
})
.await?;
Ok(())
}
@@ -389,7 +428,7 @@ impl RpcContext {
}
impl AsRef<Jwk> for RpcContext {
fn as_ref(&self) -> &Jwk {
&*CURRENT_SECRET
&CURRENT_SECRET
}
}
impl Context for RpcContext {}
@@ -403,7 +442,7 @@ impl Deref for RpcContext {
tracing_error::SpanTrace::capture()
);
}
&*self.0
&self.0
}
}
impl Drop for RpcContext {

View File

@@ -480,6 +480,7 @@ pub struct StaticDependencyInfo {
#[serde(rename_all = "kebab-case")]
#[model = "Model<Self>"]
pub struct CurrentDependencyInfo {
#[serde(default)]
pub pointers: BTreeSet<PackagePointerSpec>,
pub health_checks: BTreeSet<HealthCheckId>,
}

View File

@@ -200,11 +200,6 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
let account = AccountInfo::load(&secret_store).await?;
let db = cfg.db(&account).await?;
db.mutate(|d| {
let model = d.de()?;
d.ser(&model)
})
.await?;
tracing::info!("Opened PatchDB");
let peek = db.peek().await?;
let mut server_info = peek.as_server_info().de()?;
@@ -375,6 +370,12 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
crate::version::init(&db, &secret_store).await?;
db.mutate(|d| {
let model = d.de()?;
d.ser(&model)
})
.await?;
if should_rebuild {
match tokio::fs::remove_file(SYSTEM_REBUILD_PATH).await {
Ok(()) => Ok(()),

View File

@@ -1105,7 +1105,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
status: Status {
configured: manifest.config.is_none(),
main: MainStatus::Stopped,
dependency_errors: Default::default(),
dependency_config_errors: compute_dependency_config_errs(
&ctx,
&peek,

View File

@@ -16,8 +16,6 @@ pub struct Status {
pub configured: bool,
pub main: MainStatus,
#[serde(default)]
pub dependency_errors: BTreeMap<(), ()>, // TODO: remove
#[serde(default)]
pub dependency_config_errors: DependencyConfigErrors,
}

View File

@@ -13,8 +13,9 @@ mod v0_3_4_1;
mod v0_3_4_2;
mod v0_3_4_3;
mod v0_3_4_4;
mod v0_3_5;
pub type Current = v0_3_4_4::Version;
pub type Current = v0_3_5::Version;
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(untagged)]
@@ -24,6 +25,7 @@ enum Version {
V0_3_4_2(Wrapper<v0_3_4_2::Version>),
V0_3_4_3(Wrapper<v0_3_4_3::Version>),
V0_3_4_4(Wrapper<v0_3_4_4::Version>),
V0_3_5(Wrapper<v0_3_5::Version>),
Other(emver::Version),
}
@@ -44,6 +46,7 @@ impl Version {
Version::V0_3_4_2(Wrapper(x)) => x.semver(),
Version::V0_3_4_3(Wrapper(x)) => x.semver(),
Version::V0_3_4_4(Wrapper(x)) => x.semver(),
Version::V0_3_5(Wrapper(x)) => x.semver(),
Version::Other(x) => x.clone(),
}
}
@@ -168,6 +171,7 @@ pub async fn init(db: &PatchDb, secrets: &PgPool) -> Result<(), Error> {
Version::V0_3_4_2(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
Version::V0_3_4_3(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
Version::V0_3_4_4(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
Version::V0_3_5(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
Version::Other(_) => {
return Err(Error::new(
eyre!("Cannot downgrade"),

View File

@@ -0,0 +1,98 @@
use std::collections::BTreeMap;
use std::path::Path;
use async_trait::async_trait;
use emver::VersionRange;
use models::DataUrl;
use sqlx::PgPool;
use super::v0_3_4::V0_3_0_COMPAT;
use super::{v0_3_4_4, VersionT};
use crate::prelude::*;
const V0_3_5: emver::Version = emver::Version::new(0, 3, 5, 0);
#[derive(Clone, Debug)]
pub struct Version;
#[async_trait]
impl VersionT for Version {
type Previous = v0_3_4_4::Version;
fn new() -> Self {
Version
}
fn semver(&self) -> emver::Version {
V0_3_5
}
fn compat(&self) -> &'static VersionRange {
&V0_3_0_COMPAT
}
async fn up(&self, db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
let peek = db.peek().await?;
let mut url_replacements = BTreeMap::new();
for (_, pde) in peek.as_package_data().as_entries()? {
for (dependency, info) in pde
.as_installed()
.map(|i| i.as_dependency_info().as_entries())
.transpose()?
.into_iter()
.flatten()
{
if !url_replacements.contains_key(&dependency) {
url_replacements.insert(
dependency,
DataUrl::from_path(
<&Value>::from(info.as_icon())
.as_str()
.and_then(|i| i.strip_prefix("/public/package-data/"))
.map(|path| {
Path::new("/embassy-data/package-data/public").join(path)
})
.unwrap_or_default(),
)
.await
.unwrap_or_else(|_| {
DataUrl::from_slice(
"image/png",
include_bytes!("../install/package-icon.png"),
)
}),
);
}
}
}
db.mutate(|v| {
for (_, pde) in v.as_package_data_mut().as_entries_mut()? {
for (dependency, info) in pde
.as_installed_mut()
.map(|i| i.as_dependency_info_mut().as_entries_mut())
.transpose()?
.into_iter()
.flatten()
{
if let Some(url) = url_replacements.get(&dependency) {
info.as_icon_mut().ser(url)?;
}
let manifest = <&mut Value>::from(&mut *info)
.as_object_mut()
.and_then(|o| o.remove("manifest"));
if let Some(title) = manifest
.as_ref()
.and_then(|m| m.as_object())
.and_then(|m| m.get("title"))
.and_then(|t| t.as_str())
.map(|s| s.to_owned())
{
info.as_title_mut().ser(&title)?;
}
}
}
Ok(())
})
.await?;
Ok(())
}
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
Ok(())
}
}

View File

@@ -120,7 +120,7 @@ export class AppShowPage {
return {
id: depId,
version: pkgInstalled.manifest.dependencies[depId].version, // do we want this version range?
title: depInfo?.manifest?.title || depId,
title: depInfo?.title || depId,
icon: depInfo?.icon || '',
errorText: errorText
? `${errorText}. ${pkgInstalled.manifest.title} will not work as expected.`

View File

@@ -1958,7 +1958,7 @@ export module Mock {
},
'dependency-info': {
bitcoind: {
manifest: Mock.MockManifestBitcoind,
title: Mock.MockManifestBitcoind.title,
icon: 'assets/img/service-icons/bitcoind.svg',
},
},
@@ -2012,11 +2012,11 @@ export module Mock {
},
'dependency-info': {
bitcoind: {
manifest: Mock.MockManifestBitcoind,
title: Mock.MockManifestBitcoind.title,
icon: 'assets/img/service-icons/bitcoind.svg',
},
'btc-rpc-proxy': {
manifest: Mock.MockManifestBitcoinProxy,
title: Mock.MockManifestBitcoinProxy.title,
icon: 'assets/img/service-icons/btc-rpc-proxy.png',
},
},

View File

@@ -664,15 +664,11 @@ export const mockPatchData: DataModel = {
},
'dependency-info': {
bitcoind: {
manifest: {
title: 'Bitcoin Core',
} as Manifest,
title: 'Bitcoin Core',
icon: 'assets/img/service-icons/bitcoind.svg',
},
'btc-rpc-proxy': {
manifest: {
title: 'Bitcoin Proxy',
} as Manifest,
title: 'Bitcoin Proxy',
icon: 'assets/img/service-icons/btc-rpc-proxy.png',
},
},

View File

@@ -132,7 +132,7 @@ export interface InstalledPackageDataEntry {
'current-dependencies': { [id: string]: CurrentDependencyInfo }
'dependency-info': {
[id: string]: {
manifest: Manifest
title: string
icon: Url
}
}