mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix: Dependency vs dependents (#1462)
* fix: Dependency vs dependents * chore: Remove the debugging
This commit is contained in:
@@ -14,6 +14,7 @@ use serde_json::Value;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::context::RpcContext;
|
||||
use crate::db::model::{CurrentDependencies, CurrentDependents};
|
||||
use crate::dependencies::{
|
||||
add_dependent_to_current_dependents_lists, break_transitive, heal_all_dependents_transitive,
|
||||
BreakageRes, DependencyConfig, DependencyError, DependencyErrors, TaggedDependencyError,
|
||||
@@ -276,7 +277,8 @@ pub struct ConfigReceipts {
|
||||
version: LockReceipt<crate::util::Version, String>,
|
||||
manifest: LockReceipt<Manifest, String>,
|
||||
system_pointers: LockReceipt<Vec<spec::SystemPointerSpec>, String>,
|
||||
pub current_dependents: LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
pub current_dependents: LockReceipt<CurrentDependents, String>,
|
||||
pub current_dependencies: LockReceipt<CurrentDependencies, String>,
|
||||
dependency_errors: LockReceipt<DependencyErrors, String>,
|
||||
manifest_dependencies_config: LockReceipt<DependencyConfig, (String, String)>,
|
||||
}
|
||||
@@ -360,6 +362,14 @@ impl ConfigReceipts {
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(locks);
|
||||
|
||||
let current_dependencies = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.star()
|
||||
.installed()
|
||||
.map(|x| x.current_dependencies())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(locks);
|
||||
|
||||
let dependency_errors = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.star()
|
||||
@@ -391,6 +401,7 @@ impl ConfigReceipts {
|
||||
manifest: manifest.verify(skeleton_key)?,
|
||||
system_pointers: system_pointers.verify(skeleton_key)?,
|
||||
current_dependents: current_dependents.verify(skeleton_key)?,
|
||||
current_dependencies: current_dependencies.verify(skeleton_key)?,
|
||||
dependency_errors: dependency_errors.verify(skeleton_key)?,
|
||||
manifest_dependencies_config: manifest_dependencies_config.verify(skeleton_key)?,
|
||||
})
|
||||
@@ -544,26 +555,28 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
.await?
|
||||
.ok_or_else(not_found)?;
|
||||
sys.truncate(0);
|
||||
let mut current_dependencies: BTreeMap<PackageId, CurrentDependencyInfo> = dependencies
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(id, info)| {
|
||||
if info.requirement.required() {
|
||||
Some((id.clone(), CurrentDependencyInfo::default()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let mut current_dependencies: CurrentDependencies = CurrentDependencies(
|
||||
dependencies
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(id, info)| {
|
||||
if info.requirement.required() {
|
||||
Some((id.clone(), CurrentDependencyInfo::default()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
for ptr in spec.pointers(&config)? {
|
||||
match ptr {
|
||||
ValueSpecPointer::Package(pkg_ptr) => {
|
||||
if let Some(current_dependency) =
|
||||
current_dependencies.get_mut(pkg_ptr.package_id())
|
||||
current_dependencies.0.get_mut(pkg_ptr.package_id())
|
||||
{
|
||||
current_dependency.pointers.push(pkg_ptr);
|
||||
} else {
|
||||
current_dependencies.insert(
|
||||
current_dependencies.0.insert(
|
||||
pkg_ptr.package_id().to_owned(),
|
||||
CurrentDependencyInfo {
|
||||
pointers: vec![pkg_ptr],
|
||||
@@ -585,10 +598,10 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
|
||||
// track dependencies with no pointers
|
||||
for (package_id, health_checks) in res.depends_on.into_iter() {
|
||||
if let Some(current_dependency) = current_dependencies.get_mut(&package_id) {
|
||||
if let Some(current_dependency) = current_dependencies.0.get_mut(&package_id) {
|
||||
current_dependency.health_checks.extend(health_checks);
|
||||
} else {
|
||||
current_dependencies.insert(
|
||||
current_dependencies.0.insert(
|
||||
package_id,
|
||||
CurrentDependencyInfo {
|
||||
pointers: Vec::new(),
|
||||
@@ -599,17 +612,18 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
}
|
||||
|
||||
// track dependency health checks
|
||||
current_dependencies = current_dependencies
|
||||
.into_iter()
|
||||
.filter(|(dep_id, _)| {
|
||||
if dep_id != id && !manifest.dependencies.0.contains_key(dep_id) {
|
||||
tracing::warn!("Illegal dependency specified: {}", dep_id);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
current_dependencies = current_dependencies.map(|x| {
|
||||
x.into_iter()
|
||||
.filter(|(dep_id, _)| {
|
||||
if dep_id != id && !manifest.dependencies.0.contains_key(dep_id) {
|
||||
tracing::warn!("Illegal dependency specified: {}", dep_id);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
res.signal
|
||||
} else {
|
||||
None
|
||||
@@ -619,7 +633,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
remove_from_current_dependents_lists(
|
||||
db,
|
||||
id,
|
||||
current_dependencies.keys(),
|
||||
¤t_dependencies,
|
||||
&receipts.current_dependents,
|
||||
)
|
||||
.await?; // remove previous
|
||||
@@ -630,9 +644,9 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
&receipts.current_dependents,
|
||||
)
|
||||
.await?; // add new
|
||||
current_dependencies.remove(id);
|
||||
current_dependencies.0.remove(id);
|
||||
receipts
|
||||
.current_dependents
|
||||
.current_dependencies
|
||||
.set(db, current_dependencies.clone(), &id)
|
||||
.await?;
|
||||
|
||||
@@ -656,12 +670,16 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
overrides.insert(id.clone(), config.clone());
|
||||
|
||||
// handle dependents
|
||||
let dependents = current_dependencies;
|
||||
let dependents = receipts
|
||||
.current_dependents
|
||||
.get(db, id)
|
||||
.await?
|
||||
.ok_or_else(not_found)?;
|
||||
let prev = if is_needs_config { None } else { old_config }
|
||||
.map(Value::Object)
|
||||
.unwrap_or_default();
|
||||
let next = Value::Object(config.clone());
|
||||
for (dependent, dep_info) in dependents.iter().filter(|(dep_id, _)| dep_id != &id) {
|
||||
for (dependent, dep_info) in dependents.0.iter().filter(|(dep_id, _)| dep_id != &id) {
|
||||
// check if config passes dependent check
|
||||
if let Some(cfg) = receipts
|
||||
.manifest_dependencies_config
|
||||
|
||||
@@ -265,13 +265,61 @@ pub struct InstalledPackageDataEntry {
|
||||
#[model]
|
||||
pub dependency_info: BTreeMap<PackageId, StaticDependencyInfo>,
|
||||
#[model]
|
||||
pub current_dependents: BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
pub current_dependents: CurrentDependents,
|
||||
#[model]
|
||||
pub current_dependencies: BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
pub current_dependencies: CurrentDependencies,
|
||||
#[model]
|
||||
pub interface_addresses: InterfaceAddressMap,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct CurrentDependents(pub BTreeMap<PackageId, CurrentDependencyInfo>);
|
||||
impl CurrentDependents {
|
||||
pub fn map(
|
||||
mut self,
|
||||
transform: impl Fn(
|
||||
BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
) -> BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
) -> Self {
|
||||
self.0 = transform(self.0);
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Map for CurrentDependents {
|
||||
type Key = PackageId;
|
||||
type Value = CurrentDependencyInfo;
|
||||
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
|
||||
self.0.get(key)
|
||||
}
|
||||
}
|
||||
impl HasModel for CurrentDependents {
|
||||
type Model = MapModel<Self>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct CurrentDependencies(pub BTreeMap<PackageId, CurrentDependencyInfo>);
|
||||
impl CurrentDependencies {
|
||||
pub fn map(
|
||||
mut self,
|
||||
transform: impl Fn(
|
||||
BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
) -> BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
) -> Self {
|
||||
self.0 = transform(self.0);
|
||||
self
|
||||
}
|
||||
}
|
||||
impl Map for CurrentDependencies {
|
||||
type Key = PackageId;
|
||||
type Value = CurrentDependencyInfo;
|
||||
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
|
||||
self.0.get(key)
|
||||
}
|
||||
}
|
||||
impl HasModel for CurrentDependencies {
|
||||
type Model = MapModel<Self>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct StaticDependencyInfo {
|
||||
|
||||
@@ -17,7 +17,9 @@ use tracing::instrument;
|
||||
use crate::config::spec::PackagePointerSpec;
|
||||
use crate::config::{not_found, Config, ConfigReceipts, ConfigSpec};
|
||||
use crate::context::RpcContext;
|
||||
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntry};
|
||||
use crate::db::model::{
|
||||
CurrentDependencies, CurrentDependencyInfo, CurrentDependents, InstalledPackageDataEntry,
|
||||
};
|
||||
use crate::procedure::{NoOutput, PackageProcedure};
|
||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||
use crate::status::health_check::{HealthCheckId, HealthCheckResult};
|
||||
@@ -64,7 +66,7 @@ pub struct TryHealReceipts {
|
||||
status: LockReceipt<Status, String>,
|
||||
manifest: LockReceipt<Manifest, String>,
|
||||
manifest_version: LockReceipt<Version, String>,
|
||||
current_dependencies: LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependencies: LockReceipt<CurrentDependencies, String>,
|
||||
dependency_errors: LockReceipt<DependencyErrors, String>,
|
||||
}
|
||||
|
||||
@@ -541,6 +543,7 @@ impl DependencyConfig {
|
||||
}
|
||||
|
||||
pub struct DependencyConfigReceipts {
|
||||
config: ConfigReceipts,
|
||||
dependencies: LockReceipt<Dependencies, ()>,
|
||||
dependency_volumes: LockReceipt<Volumes, ()>,
|
||||
dependency_version: LockReceipt<Version, ()>,
|
||||
@@ -550,65 +553,76 @@ pub struct DependencyConfigReceipts {
|
||||
}
|
||||
|
||||
impl DependencyConfigReceipts {
|
||||
pub async fn new(
|
||||
db: &'_ mut impl DbHandle,
|
||||
pub async fn new<'a>(
|
||||
db: &'a mut impl DbHandle,
|
||||
package_id: &PackageId,
|
||||
dependency_id: &PackageId,
|
||||
) -> Result<Self, Error> {
|
||||
let mut locks = Vec::new();
|
||||
|
||||
let setup = Self::setup(&mut locks, package_id, dependency_id);
|
||||
Ok(setup(&db.lock_all(locks).await?)?)
|
||||
}
|
||||
|
||||
pub fn setup(
|
||||
locks: &mut Vec<LockTargetId>,
|
||||
package_id: &PackageId,
|
||||
dependency_id: &PackageId,
|
||||
) -> impl FnOnce(&Verifier) -> Result<Self, Error> {
|
||||
let config = ConfigReceipts::setup(locks);
|
||||
let dependencies = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(package_id)
|
||||
.and_then(|x| x.installed())
|
||||
.map(|x| x.manifest().dependencies())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
.add_to_keys(locks);
|
||||
let dependency_volumes = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(dependency_id)
|
||||
.and_then(|x| x.installed())
|
||||
.map(|x| x.manifest().volumes())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
.add_to_keys(locks);
|
||||
let dependency_version = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(dependency_id)
|
||||
.and_then(|x| x.installed())
|
||||
.map(|x| x.manifest().version())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
.add_to_keys(locks);
|
||||
let dependency_config_action = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(dependency_id)
|
||||
.and_then(|x| x.installed())
|
||||
.and_then(|x| x.manifest().config())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
.add_to_keys(locks);
|
||||
let package_volumes = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(package_id)
|
||||
.and_then(|x| x.installed())
|
||||
.map(|x| x.manifest().volumes())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
.add_to_keys(locks);
|
||||
let package_version = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(package_id)
|
||||
.and_then(|x| x.installed())
|
||||
.map(|x| x.manifest().version())
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(&mut locks);
|
||||
|
||||
let skeleton_key = db.lock_all(locks).await?;
|
||||
Ok(Self {
|
||||
dependencies: dependencies.verify(&skeleton_key)?,
|
||||
dependency_volumes: dependency_volumes.verify(&skeleton_key)?,
|
||||
dependency_version: dependency_version.verify(&skeleton_key)?,
|
||||
dependency_config_action: dependency_config_action.verify(&skeleton_key)?,
|
||||
package_volumes: package_volumes.verify(&skeleton_key)?,
|
||||
package_version: package_version.verify(&skeleton_key)?,
|
||||
})
|
||||
.add_to_keys(locks);
|
||||
move |skeleton_key| {
|
||||
Ok(Self {
|
||||
config: config(skeleton_key)?,
|
||||
dependencies: dependencies.verify(&skeleton_key)?,
|
||||
dependency_volumes: dependency_volumes.verify(&skeleton_key)?,
|
||||
dependency_version: dependency_version.verify(&skeleton_key)?,
|
||||
dependency_config_action: dependency_config_action.verify(&skeleton_key)?,
|
||||
package_volumes: package_volumes.verify(&skeleton_key)?,
|
||||
package_version: package_version.verify(&skeleton_key)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +649,7 @@ pub async fn configure_impl(
|
||||
spec: _,
|
||||
} = configure_logic(ctx.clone(), &mut db, (pkg_id, dep_id.clone()), &receipts).await?;
|
||||
|
||||
let locks = ConfigReceipts::new(&mut db).await?;
|
||||
let locks = &receipts.config;
|
||||
Ok(crate::config::configure(
|
||||
&ctx,
|
||||
&mut db,
|
||||
@@ -645,7 +659,7 @@ pub async fn configure_impl(
|
||||
false,
|
||||
&mut BTreeMap::new(),
|
||||
&mut BTreeMap::new(),
|
||||
&locks,
|
||||
locks,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
@@ -749,21 +763,19 @@ pub async fn configure_logic(
|
||||
})
|
||||
}
|
||||
#[instrument(skip(db, current_dependencies, current_dependent_receipt))]
|
||||
pub async fn add_dependent_to_current_dependents_lists<
|
||||
'a,
|
||||
Db: DbHandle,
|
||||
I: IntoIterator<Item = (&'a PackageId, &'a CurrentDependencyInfo)>,
|
||||
>(
|
||||
pub async fn add_dependent_to_current_dependents_lists<'a, Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
dependent_id: &PackageId,
|
||||
current_dependencies: I,
|
||||
current_dependent_receipt: &LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependencies: &CurrentDependencies,
|
||||
current_dependent_receipt: &LockReceipt<CurrentDependents, String>,
|
||||
) -> Result<(), Error> {
|
||||
for (dependency, dep_info) in current_dependencies {
|
||||
for (dependency, dep_info) in ¤t_dependencies.0 {
|
||||
if let Some(mut dependency_dependents) =
|
||||
current_dependent_receipt.get(db, dependency).await?
|
||||
{
|
||||
dependency_dependents.insert(dependent_id.clone(), dep_info.clone());
|
||||
dependency_dependents
|
||||
.0
|
||||
.insert(dependent_id.clone(), dep_info.clone());
|
||||
current_dependent_receipt
|
||||
.set(db, dependency_dependents, dependency)
|
||||
.await?;
|
||||
@@ -789,11 +801,11 @@ impl DependencyErrors {
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
manifest: &Manifest,
|
||||
current_dependencies: &BTreeMap<PackageId, CurrentDependencyInfo>,
|
||||
current_dependencies: &CurrentDependencies,
|
||||
receipts: &TryHealReceipts,
|
||||
) -> Result<DependencyErrors, Error> {
|
||||
let mut res = BTreeMap::new();
|
||||
for (dependency_id, info) in current_dependencies.keys().filter_map(|dependency_id| {
|
||||
for (dependency_id, info) in current_dependencies.0.keys().filter_map(|dependency_id| {
|
||||
manifest
|
||||
.dependencies
|
||||
.0
|
||||
@@ -836,7 +848,7 @@ pub async fn break_all_dependents_transitive<'a, Db: DbHandle>(
|
||||
.get(db, id)
|
||||
.await?
|
||||
.iter()
|
||||
.flat_map(|x| x.keys())
|
||||
.flat_map(|x| x.0.keys())
|
||||
.filter(|dependent| id != *dependent)
|
||||
{
|
||||
break_transitive(db, dependent, id, error.clone(), breakages, receipts).await?;
|
||||
@@ -848,7 +860,7 @@ pub async fn break_all_dependents_transitive<'a, Db: DbHandle>(
|
||||
pub struct BreakTransitiveReceipts {
|
||||
pub dependency_receipt: DependencyReceipt,
|
||||
dependency_errors: LockReceipt<DependencyErrors, String>,
|
||||
current_dependents: LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependents: LockReceipt<CurrentDependents, String>,
|
||||
}
|
||||
|
||||
impl BreakTransitiveReceipts {
|
||||
@@ -964,7 +976,7 @@ pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>(
|
||||
.get(db, id)
|
||||
.await?
|
||||
.ok_or_else(not_found)?;
|
||||
for dependent in dependents.keys().filter(|dependent| id != *dependent) {
|
||||
for dependent in dependents.0.keys().filter(|dependent| id != *dependent) {
|
||||
heal_transitive(ctx, db, dependent, id, locks).await?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -1014,7 +1026,7 @@ pub async fn reconfigure_dependents_with_live_pointers(
|
||||
) -> Result<(), Error> {
|
||||
let dependents = &pde.current_dependents;
|
||||
let me = &pde.manifest.id;
|
||||
for (dependent_id, dependency_info) in dependents {
|
||||
for (dependent_id, dependency_info) in &dependents.0 {
|
||||
if dependency_info.pointers.iter().any(|ptr| match ptr {
|
||||
// dependency id matches the package being uninstalled
|
||||
PackagePointerSpec::TorAddress(ptr) => &ptr.package_id == me && dependent_id != me,
|
||||
@@ -1043,7 +1055,7 @@ pub async fn reconfigure_dependents_with_live_pointers(
|
||||
#[derive(Clone)]
|
||||
pub struct DependencyReceipt {
|
||||
pub try_heal: TryHealReceipts,
|
||||
current_dependents: LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependents: LockReceipt<CurrentDependents, String>,
|
||||
status: LockReceipt<Status, String>,
|
||||
dependency: LockReceipt<DepInfo, (String, String)>,
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ use super::{PKG_ARCHIVE_DIR, PKG_DOCKER_DIR};
|
||||
use crate::config::{not_found, ConfigReceipts};
|
||||
use crate::context::RpcContext;
|
||||
use crate::db::model::{
|
||||
AllPackageData, CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry,
|
||||
AllPackageData, CurrentDependencies, CurrentDependencyInfo, CurrentDependents,
|
||||
InstalledPackageDataEntry, PackageDataEntry,
|
||||
};
|
||||
use crate::dependencies::{
|
||||
reconfigure_dependents_with_live_pointers, DependencyErrors, TryHealReceipts,
|
||||
@@ -60,18 +61,14 @@ impl UpdateDependencyReceipts {
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, deps, receipts))]
|
||||
pub async fn update_dependency_errors_of_dependents<
|
||||
'a,
|
||||
Db: DbHandle,
|
||||
I: IntoIterator<Item = &'a PackageId>,
|
||||
>(
|
||||
pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
id: &PackageId,
|
||||
deps: I,
|
||||
deps: &CurrentDependents,
|
||||
receipts: &UpdateDependencyReceipts,
|
||||
) -> Result<(), Error> {
|
||||
for dep in deps {
|
||||
for dep in deps.0.keys() {
|
||||
if let Some(man) = receipts.manifest.get(db, dep).await? {
|
||||
if let Err(e) = if let Some(info) = man.dependencies.0.get(id) {
|
||||
info.satisfied(ctx, db, id, None, dep, &receipts.try_heal)
|
||||
@@ -269,19 +266,15 @@ pub async fn cleanup_failed<Db: DbHandle>(
|
||||
}
|
||||
|
||||
#[instrument(skip(db, current_dependencies, current_dependent_receipt))]
|
||||
pub async fn remove_from_current_dependents_lists<
|
||||
'a,
|
||||
Db: DbHandle,
|
||||
I: IntoIterator<Item = &'a PackageId>,
|
||||
>(
|
||||
pub async fn remove_from_current_dependents_lists<'a, Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
id: &'a PackageId,
|
||||
current_dependencies: I,
|
||||
current_dependent_receipt: &LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependencies: &'a CurrentDependencies,
|
||||
current_dependent_receipt: &LockReceipt<CurrentDependents, String>,
|
||||
) -> Result<(), Error> {
|
||||
for dep in current_dependencies.into_iter().chain(std::iter::once(id)) {
|
||||
for dep in current_dependencies.0.keys().chain(std::iter::once(id)) {
|
||||
if let Some(mut current_dependents) = current_dependent_receipt.get(db, dep).await? {
|
||||
if current_dependents.remove(id).is_some() {
|
||||
if current_dependents.0.remove(id).is_some() {
|
||||
current_dependent_receipt
|
||||
.set(db, current_dependents, dep)
|
||||
.await?;
|
||||
@@ -294,7 +287,7 @@ pub struct UninstallReceipts {
|
||||
config: ConfigReceipts,
|
||||
removing: LockReceipt<InstalledPackageDataEntry, ()>,
|
||||
packages: LockReceipt<AllPackageData, ()>,
|
||||
current_dependents: LockReceipt<BTreeMap<PackageId, CurrentDependencyInfo>, String>,
|
||||
current_dependents: LockReceipt<CurrentDependents, String>,
|
||||
update_depenency_receipts: UpdateDependencyReceipts,
|
||||
}
|
||||
impl UninstallReceipts {
|
||||
@@ -367,7 +360,7 @@ where
|
||||
remove_from_current_dependents_lists(
|
||||
&mut tx,
|
||||
&entry.manifest.id,
|
||||
entry.current_dependencies.keys(),
|
||||
&entry.current_dependencies,
|
||||
&receipts.current_dependents,
|
||||
)
|
||||
.await?;
|
||||
@@ -375,7 +368,7 @@ where
|
||||
ctx,
|
||||
&mut tx,
|
||||
&entry.manifest.id,
|
||||
entry.current_dependents.keys(),
|
||||
&entry.current_dependents,
|
||||
&receipts.update_depenency_receipts,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -29,8 +29,8 @@ use crate::config::ConfigReceipts;
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
|
||||
use crate::db::model::{
|
||||
CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry, RecoveredPackageInfo,
|
||||
StaticDependencyInfo, StaticFiles,
|
||||
CurrentDependencies, CurrentDependencyInfo, CurrentDependents, InstalledPackageDataEntry,
|
||||
PackageDataEntry, RecoveredPackageInfo, StaticDependencyInfo, StaticFiles,
|
||||
};
|
||||
use crate::db::util::WithRevision;
|
||||
use crate::dependencies::{
|
||||
@@ -1168,18 +1168,20 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
tracing::info!("Install {}@{}: Created manager", pkg_id, version);
|
||||
|
||||
let static_files = StaticFiles::local(pkg_id, version, manifest.assets.icon_type());
|
||||
let current_dependencies: BTreeMap<_, _> = manifest
|
||||
.dependencies
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(id, info)| {
|
||||
if info.requirement.required() {
|
||||
Some((id.clone(), CurrentDependencyInfo::default()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let current_dependencies: CurrentDependencies = CurrentDependencies(
|
||||
manifest
|
||||
.dependencies
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(id, info)| {
|
||||
if info.requirement.required() {
|
||||
Some((id.clone(), CurrentDependencyInfo::default()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
let current_dependents = {
|
||||
let mut deps = BTreeMap::new();
|
||||
for package in crate::db::DatabaseModel::new()
|
||||
@@ -1225,7 +1227,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
deps.insert(package, dep);
|
||||
}
|
||||
}
|
||||
deps
|
||||
CurrentDependents(deps)
|
||||
};
|
||||
let mut pde = model
|
||||
.clone()
|
||||
@@ -1360,7 +1362,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
remove_from_current_dependents_lists(
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
prev.current_dependencies.keys(),
|
||||
&prev.current_dependencies,
|
||||
&receipts.config.current_dependents,
|
||||
)
|
||||
.await?; // remove previous
|
||||
@@ -1375,10 +1377,11 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
ctx,
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
current_dependents
|
||||
.keys()
|
||||
.chain(prev.current_dependents.keys())
|
||||
.collect::<BTreeSet<_>>(),
|
||||
&CurrentDependents({
|
||||
let mut current_dependents = current_dependents.0.clone();
|
||||
current_dependents.append(&mut prev.current_dependents.0.clone());
|
||||
current_dependents
|
||||
}),
|
||||
&receipts.config.update_dependency_receipts,
|
||||
)
|
||||
.await?;
|
||||
@@ -1409,7 +1412,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
ctx,
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
current_dependents.keys(),
|
||||
¤t_dependents,
|
||||
&receipts.config.update_dependency_receipts,
|
||||
)
|
||||
.await?;
|
||||
@@ -1441,7 +1444,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
ctx,
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
current_dependents.keys(),
|
||||
¤t_dependents,
|
||||
&receipts.config.update_dependency_receipts,
|
||||
)
|
||||
.await?;
|
||||
@@ -1457,7 +1460,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
ctx,
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
current_dependents.keys(),
|
||||
¤t_dependents,
|
||||
&receipts.config.update_dependency_receipts,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -102,7 +102,7 @@ pub async fn check<Db: DbHandle>(
|
||||
let receipts = crate::dependencies::BreakTransitiveReceipts::new(&mut tx).await?;
|
||||
tracing::debug!("Got receipts {}", id);
|
||||
|
||||
for (dependent, info) in &*current_dependents {
|
||||
for (dependent, info) in (*current_dependents).0.iter() {
|
||||
let failures: BTreeMap<HealthCheckId, HealthCheckResult> = health_results
|
||||
.iter()
|
||||
.filter(|(_, hc_res)| !matches!(hc_res, HealthCheckResult::Success { .. }))
|
||||
|
||||
@@ -159,6 +159,7 @@ impl PackageProcedure {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NoOutput;
|
||||
impl<'de> Deserialize<'de> for NoOutput {
|
||||
fn deserialize<D>(_: D) -> Result<Self, D::Error>
|
||||
|
||||
Reference in New Issue
Block a user