diff --git a/.github/workflows/startos-iso.yaml b/.github/workflows/startos-iso.yaml index 44503172e..76b2f6e31 100644 --- a/.github/workflows/startos-iso.yaml +++ b/.github/workflows/startos-iso.yaml @@ -107,9 +107,9 @@ jobs: run: | sudo apt-get update sudo apt-get install -y qemu-user-static - wget http://ftp.us.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.1-1_all.deb - sha256sum ./debspawn_0.6.1-1_all.deb | grep fb8a3f588438ff9ef51e713ec1d83306db893f0aa97447565e28bbba9c6e90c6 - sudo apt-get install -y ./debspawn_0.6.1-1_all.deb + wget https://deb.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.2-1_all.deb + sha256sum ./debspawn_0.6.2-1_all.deb | grep 37ef27458cb1e35e8bce4d4f639b06b4b3866fc0b9191ec6b9bd157afd06a817 + sudo apt-get install -y ./debspawn_0.6.2-1_all.deb - name: Configure debspawn run: | diff --git a/backend/src/config/mod.rs b/backend/src/config/mod.rs index 2beef4fa1..e13db5c57 100644 --- a/backend/src/config/mod.rs +++ b/backend/src/config/mod.rs @@ -503,19 +503,27 @@ pub fn configure_rec<'a, Db: DbHandle>( .config_actions .get(db, id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; let dependencies = receipts .dependencies .get(db, id) .await? - .ok_or_else(not_found)?; - let volumes = receipts.volumes.get(db, id).await?.ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; + let volumes = receipts + .volumes + .get(db, id) + .await? + .ok_or_else(|| not_found!(id))?; let is_needs_config = !receipts .configured .get(db, id) .await? - .ok_or_else(not_found)?; - let version = receipts.version.get(db, id).await?.ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; + let version = receipts + .version + .get(db, id) + .await? + .ok_or_else(|| not_found!(id))?; // get current config and current spec let ConfigRes { @@ -530,7 +538,11 @@ pub fn configure_rec<'a, Db: DbHandle>( spec.gen(&mut rand::rngs::StdRng::from_entropy(), timeout)? }; - let manifest = receipts.manifest.get(db, id).await?.ok_or_else(not_found)?; + let manifest = receipts + .manifest + .get(db, id) + .await? + .ok_or_else(|| not_found!(id))?; spec.validate(&manifest)?; spec.matches(&config)?; // check that new config matches spec @@ -549,7 +561,7 @@ pub fn configure_rec<'a, Db: DbHandle>( .system_pointers .get(db, &id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; sys.truncate(0); let mut current_dependencies: CurrentDependencies = CurrentDependencies( dependencies @@ -655,7 +667,7 @@ pub fn configure_rec<'a, Db: DbHandle>( .dependency_errors .get(db, &id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; tracing::warn!("Dependency Errors: {:?}", errs); let errs = DependencyErrors::init( ctx, @@ -675,7 +687,7 @@ pub fn configure_rec<'a, Db: DbHandle>( .current_dependents .get(db, id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; let prev = if is_needs_config { None } else { old_config } .map(Value::Object) .unwrap_or_default(); @@ -693,7 +705,7 @@ pub fn configure_rec<'a, Db: DbHandle>( .manifest .get(db, &dependent) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; if let Err(error) = cfg .check( ctx, @@ -771,10 +783,16 @@ pub fn configure_rec<'a, Db: DbHandle>( } .boxed() } -#[instrument(skip_all)] -pub fn not_found() -> Error { - Error::new(eyre!("Could not find"), crate::ErrorKind::Incoherent) + +macro_rules! not_found { + ($x:expr) => { + crate::Error::new( + color_eyre::eyre::eyre!("Could not find {} at {}:{}", $x, module_path!(), line!()), + crate::ErrorKind::Incoherent, + ) + }; } +pub(crate) use not_found; /// We want to have a double check that the paths are what we expect them to be. /// Found that earlier the paths where not what we expected them to be. diff --git a/backend/src/context/rpc.rs b/backend/src/context/rpc.rs index cdb9ec909..9acb1cd4e 100644 --- a/backend/src/context/rpc.rs +++ b/backend/src/context/rpc.rs @@ -21,7 +21,7 @@ use tracing::instrument; use crate::account::AccountInfo; use crate::core::rpc_continuations::{RequestGuid, RestHandler, RpcContinuation}; -use crate::db::model::{Database, InstalledPackageDataEntry, PackageDataEntry}; +use crate::db::model::{CurrentDependents, Database, InstalledPackageDataEntry, PackageDataEntry}; use crate::disk::OsPartitionInfo; use crate::init::{init_postgres, pgloader}; use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts}; @@ -345,6 +345,31 @@ impl RpcContext { tracing::debug!("{:?}", e); } } + let mut current_dependents = BTreeMap::new(); + for (package_id, package) in receipts.packages.get(&mut db).await?.0 { + for (k, v) in package + .into_installed() + .into_iter() + .flat_map(|i| i.current_dependencies.0) + { + let mut entry: BTreeMap<_, _> = current_dependents.remove(&k).unwrap_or_default(); + entry.insert(package_id.clone(), v); + current_dependents.insert(k, entry); + } + } + for (package_id, current_dependents) in current_dependents { + if let Some(deps) = crate::db::DatabaseModel::new() + .package_data() + .idx_model(&package_id) + .and_then(|pde| pde.installed()) + .map::<_, CurrentDependents>(|i| i.current_dependents()) + .check(&mut db) + .await? + { + deps.put(&mut db, &CurrentDependents(current_dependents)) + .await?; + } + } Ok(()) } diff --git a/backend/src/dependencies.rs b/backend/src/dependencies.rs index 96c1562b2..e86c5eee9 100644 --- a/backend/src/dependencies.rs +++ b/backend/src/dependencies.rs @@ -237,13 +237,16 @@ impl DependencyError { } } DependencyError::ConfigUnsatisfied { .. } => { - let dependent_manifest = - receipts.manifest.get(db, id).await?.ok_or_else(not_found)?; + let dependent_manifest = receipts + .manifest + .get(db, id) + .await? + .ok_or_else(|| not_found!(id))?; let dependency_manifest = receipts .manifest .get(db, dependency) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(dependency))?; let dependency_config = if let Some(cfg) = dependency_config.take() { cfg @@ -294,7 +297,7 @@ impl DependencyError { .status .get(db, dependency) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(dependency))?; if status.main.running() { DependencyError::HealthChecksFailed { failures: BTreeMap::new(), @@ -310,7 +313,7 @@ impl DependencyError { .status .get(db, dependency) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(dependency))?; match status.main { MainStatus::BackingUp { started: Some(_), @@ -324,7 +327,7 @@ impl DependencyError { .current_dependencies .get(db, id) .await? - .ok_or_else(not_found)? + .ok_or_else(|| not_found!(id))? .get(dependency) .map(|x| x.health_checks.contains(&check)) .unwrap_or(false) @@ -934,7 +937,7 @@ pub fn break_transitive<'a, Db: DbHandle>( .dependency_errors .get(&mut tx, id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; let old = dependency_errors.0.remove(dependency); let newly_broken = if let Some(e) = &old { @@ -997,7 +1000,7 @@ pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>( .current_dependents .get(db, id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; for dependent in dependents.0.keys().filter(|dependent| id != *dependent) { heal_transitive(ctx, db, dependent, id, locks).await?; } @@ -1013,7 +1016,11 @@ pub fn heal_transitive<'a, Db: DbHandle>( receipts: &'a DependencyReceipt, ) -> BoxFuture<'a, Result<(), Error>> { async move { - let mut status = receipts.status.get(db, id).await?.ok_or_else(not_found)?; + let mut status = receipts + .status + .get(db, id) + .await? + .ok_or_else(|| not_found!(id))?; let old = status.dependency_errors.0.remove(dependency); @@ -1022,7 +1029,7 @@ pub fn heal_transitive<'a, Db: DbHandle>( .dependency .get(db, (id, dependency)) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(format!("{id}'s dependency: {dependency}")))?; if let Some(new) = old .try_heal(ctx, db, id, dependency, None, &info, &receipts.try_heal) .await? diff --git a/backend/src/install/cleanup.rs b/backend/src/install/cleanup.rs index f56c733c3..8d4b4c908 100644 --- a/backend/src/install/cleanup.rs +++ b/backend/src/install/cleanup.rs @@ -82,7 +82,7 @@ pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>( .dependency_errors .get(db, dep) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(dep))?; errs.0.insert(id.clone(), e); receipts.dependency_errors.set(db, errs, dep).await? } else { @@ -90,7 +90,7 @@ pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>( .dependency_errors .get(db, dep) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(dep))?; errs.0.remove(id); receipts.dependency_errors.set(db, errs, dep).await? } @@ -215,7 +215,7 @@ pub async fn cleanup_failed( .package_data_entry .get(db, id) .await? - .ok_or_else(not_found)?; + .ok_or_else(|| not_found!(id))?; if let Some(manifest) = match &pde { PackageDataEntry::Installing { manifest, .. } | PackageDataEntry::Restoring { manifest, .. } => Some(manifest), diff --git a/backend/src/install/mod.rs b/backend/src/install/mod.rs index 3e588431f..23d87426b 100644 --- a/backend/src/install/mod.rs +++ b/backend/src/install/mod.rs @@ -1279,6 +1279,14 @@ pub async fn install_s9pk( migration.or(prev_migration) }; + remove_from_current_dependents_lists( + &mut tx, + pkg_id, + &prev.current_dependencies, + &receipts.config.current_dependents, + ) + .await?; // remove previous + let configured = if let Some(f) = viable_migration { f.await?.configured && prev_is_configured } else { @@ -1298,13 +1306,6 @@ pub async fn install_s9pk( ) .await?; } else { - remove_from_current_dependents_lists( - &mut tx, - pkg_id, - &prev.current_dependencies, - &receipts.config.current_dependents, - ) - .await?; // remove previous add_dependent_to_current_dependents_lists( &mut tx, pkg_id, diff --git a/backend/src/install/update.rs b/backend/src/install/update.rs index 6bd062c99..bafbf04ec 100644 --- a/backend/src/install/update.rs +++ b/backend/src/install/update.rs @@ -76,7 +76,7 @@ pub async fn dry( .current_dependents .get(&mut tx, &id) .await? - .ok_or_else(not_found)? + .ok_or_else(|| not_found!(id))? .0 .keys() .into_iter()