Bugfix/incoherent (#2293)

* debug incoherent error

* fix incoherent error

* use new debspawn
This commit is contained in:
Aiden McClelland
2023-06-07 23:10:52 +00:00
committed by Matt Hill
parent b86a97c9c0
commit b0503fa507
7 changed files with 89 additions and 38 deletions

View File

@@ -107,9 +107,9 @@ jobs:
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y qemu-user-static 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 wget https://deb.debian.org/debian/pool/main/d/debspawn/debspawn_0.6.2-1_all.deb
sha256sum ./debspawn_0.6.1-1_all.deb | grep fb8a3f588438ff9ef51e713ec1d83306db893f0aa97447565e28bbba9c6e90c6 sha256sum ./debspawn_0.6.2-1_all.deb | grep 37ef27458cb1e35e8bce4d4f639b06b4b3866fc0b9191ec6b9bd157afd06a817
sudo apt-get install -y ./debspawn_0.6.1-1_all.deb sudo apt-get install -y ./debspawn_0.6.2-1_all.deb
- name: Configure debspawn - name: Configure debspawn
run: | run: |

View File

@@ -503,19 +503,27 @@ pub fn configure_rec<'a, Db: DbHandle>(
.config_actions .config_actions
.get(db, id) .get(db, id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
let dependencies = receipts let dependencies = receipts
.dependencies .dependencies
.get(db, id) .get(db, id)
.await? .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)?; let volumes = receipts
.volumes
.get(db, id)
.await?
.ok_or_else(|| not_found!(id))?;
let is_needs_config = !receipts let is_needs_config = !receipts
.configured .configured
.get(db, id) .get(db, id)
.await? .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)?; let version = receipts
.version
.get(db, id)
.await?
.ok_or_else(|| not_found!(id))?;
// get current config and current spec // get current config and current spec
let ConfigRes { let ConfigRes {
@@ -530,7 +538,11 @@ pub fn configure_rec<'a, Db: DbHandle>(
spec.gen(&mut rand::rngs::StdRng::from_entropy(), timeout)? 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.validate(&manifest)?;
spec.matches(&config)?; // check that new config matches spec spec.matches(&config)?; // check that new config matches spec
@@ -549,7 +561,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
.system_pointers .system_pointers
.get(db, &id) .get(db, &id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
sys.truncate(0); sys.truncate(0);
let mut current_dependencies: CurrentDependencies = CurrentDependencies( let mut current_dependencies: CurrentDependencies = CurrentDependencies(
dependencies dependencies
@@ -655,7 +667,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
.dependency_errors .dependency_errors
.get(db, &id) .get(db, &id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
tracing::warn!("Dependency Errors: {:?}", errs); tracing::warn!("Dependency Errors: {:?}", errs);
let errs = DependencyErrors::init( let errs = DependencyErrors::init(
ctx, ctx,
@@ -675,7 +687,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
.current_dependents .current_dependents
.get(db, id) .get(db, id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
let prev = if is_needs_config { None } else { old_config } let prev = if is_needs_config { None } else { old_config }
.map(Value::Object) .map(Value::Object)
.unwrap_or_default(); .unwrap_or_default();
@@ -693,7 +705,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
.manifest .manifest
.get(db, &dependent) .get(db, &dependent)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
if let Err(error) = cfg if let Err(error) = cfg
.check( .check(
ctx, ctx,
@@ -771,10 +783,16 @@ pub fn configure_rec<'a, Db: DbHandle>(
} }
.boxed() .boxed()
} }
#[instrument(skip_all)]
pub fn not_found() -> Error { macro_rules! not_found {
Error::new(eyre!("Could not find"), crate::ErrorKind::Incoherent) ($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. /// 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. /// Found that earlier the paths where not what we expected them to be.

View File

@@ -21,7 +21,7 @@ use tracing::instrument;
use crate::account::AccountInfo; use crate::account::AccountInfo;
use crate::core::rpc_continuations::{RequestGuid, RestHandler, RpcContinuation}; 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::disk::OsPartitionInfo;
use crate::init::{init_postgres, pgloader}; use crate::init::{init_postgres, pgloader};
use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts}; use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts};
@@ -345,6 +345,31 @@ impl RpcContext {
tracing::debug!("{:?}", e); 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(()) Ok(())
} }

View File

@@ -237,13 +237,16 @@ impl DependencyError {
} }
} }
DependencyError::ConfigUnsatisfied { .. } => { DependencyError::ConfigUnsatisfied { .. } => {
let dependent_manifest = let dependent_manifest = receipts
receipts.manifest.get(db, id).await?.ok_or_else(not_found)?; .manifest
.get(db, id)
.await?
.ok_or_else(|| not_found!(id))?;
let dependency_manifest = receipts let dependency_manifest = receipts
.manifest .manifest
.get(db, dependency) .get(db, dependency)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(dependency))?;
let dependency_config = if let Some(cfg) = dependency_config.take() { let dependency_config = if let Some(cfg) = dependency_config.take() {
cfg cfg
@@ -294,7 +297,7 @@ impl DependencyError {
.status .status
.get(db, dependency) .get(db, dependency)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(dependency))?;
if status.main.running() { if status.main.running() {
DependencyError::HealthChecksFailed { DependencyError::HealthChecksFailed {
failures: BTreeMap::new(), failures: BTreeMap::new(),
@@ -310,7 +313,7 @@ impl DependencyError {
.status .status
.get(db, dependency) .get(db, dependency)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(dependency))?;
match status.main { match status.main {
MainStatus::BackingUp { MainStatus::BackingUp {
started: Some(_), started: Some(_),
@@ -324,7 +327,7 @@ impl DependencyError {
.current_dependencies .current_dependencies
.get(db, id) .get(db, id)
.await? .await?
.ok_or_else(not_found)? .ok_or_else(|| not_found!(id))?
.get(dependency) .get(dependency)
.map(|x| x.health_checks.contains(&check)) .map(|x| x.health_checks.contains(&check))
.unwrap_or(false) .unwrap_or(false)
@@ -934,7 +937,7 @@ pub fn break_transitive<'a, Db: DbHandle>(
.dependency_errors .dependency_errors
.get(&mut tx, id) .get(&mut tx, id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
let old = dependency_errors.0.remove(dependency); let old = dependency_errors.0.remove(dependency);
let newly_broken = if let Some(e) = &old { let newly_broken = if let Some(e) = &old {
@@ -997,7 +1000,7 @@ pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>(
.current_dependents .current_dependents
.get(db, id) .get(db, id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
for dependent in dependents.0.keys().filter(|dependent| id != *dependent) { for dependent in dependents.0.keys().filter(|dependent| id != *dependent) {
heal_transitive(ctx, db, dependent, id, locks).await?; heal_transitive(ctx, db, dependent, id, locks).await?;
} }
@@ -1013,7 +1016,11 @@ pub fn heal_transitive<'a, Db: DbHandle>(
receipts: &'a DependencyReceipt, receipts: &'a DependencyReceipt,
) -> BoxFuture<'a, Result<(), Error>> { ) -> BoxFuture<'a, Result<(), Error>> {
async move { 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); let old = status.dependency_errors.0.remove(dependency);
@@ -1022,7 +1029,7 @@ pub fn heal_transitive<'a, Db: DbHandle>(
.dependency .dependency
.get(db, (id, dependency)) .get(db, (id, dependency))
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(format!("{id}'s dependency: {dependency}")))?;
if let Some(new) = old if let Some(new) = old
.try_heal(ctx, db, id, dependency, None, &info, &receipts.try_heal) .try_heal(ctx, db, id, dependency, None, &info, &receipts.try_heal)
.await? .await?

View File

@@ -82,7 +82,7 @@ pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>(
.dependency_errors .dependency_errors
.get(db, dep) .get(db, dep)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(dep))?;
errs.0.insert(id.clone(), e); errs.0.insert(id.clone(), e);
receipts.dependency_errors.set(db, errs, dep).await? receipts.dependency_errors.set(db, errs, dep).await?
} else { } else {
@@ -90,7 +90,7 @@ pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>(
.dependency_errors .dependency_errors
.get(db, dep) .get(db, dep)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(dep))?;
errs.0.remove(id); errs.0.remove(id);
receipts.dependency_errors.set(db, errs, dep).await? receipts.dependency_errors.set(db, errs, dep).await?
} }
@@ -215,7 +215,7 @@ pub async fn cleanup_failed<Db: DbHandle>(
.package_data_entry .package_data_entry
.get(db, id) .get(db, id)
.await? .await?
.ok_or_else(not_found)?; .ok_or_else(|| not_found!(id))?;
if let Some(manifest) = match &pde { if let Some(manifest) = match &pde {
PackageDataEntry::Installing { manifest, .. } PackageDataEntry::Installing { manifest, .. }
| PackageDataEntry::Restoring { manifest, .. } => Some(manifest), | PackageDataEntry::Restoring { manifest, .. } => Some(manifest),

View File

@@ -1279,6 +1279,14 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
migration.or(prev_migration) 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 { let configured = if let Some(f) = viable_migration {
f.await?.configured && prev_is_configured f.await?.configured && prev_is_configured
} else { } else {
@@ -1298,13 +1306,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
) )
.await?; .await?;
} else { } 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( add_dependent_to_current_dependents_lists(
&mut tx, &mut tx,
pkg_id, pkg_id,

View File

@@ -76,7 +76,7 @@ pub async fn dry(
.current_dependents .current_dependents
.get(&mut tx, &id) .get(&mut tx, &id)
.await? .await?
.ok_or_else(not_found)? .ok_or_else(|| not_found!(id))?
.0 .0
.keys() .keys()
.into_iter() .into_iter()