reconfigures dependents with live pointers when package is installed … (#1053)

* reconfigures dependents with live pointers when package is installed or removed

* fixes bugs with pointer remapping
This commit is contained in:
Keagan McClelland
2022-01-13 16:32:21 -07:00
committed by Aiden McClelland
parent b1c63aafa7
commit 4189da20e1
5 changed files with 74 additions and 7 deletions

View File

@@ -3,7 +3,7 @@ use std::path::Path;
use chrono::{DateTime, Utc};
use color_eyre::eyre::eyre;
use patch_db::{DbHandle, HasModel};
use patch_db::{DbHandle, HasModel, LockType};
use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use sqlx::{Executor, Sqlite};
@@ -14,6 +14,7 @@ use tracing::instrument;
use self::target::PackageBackupInfo;
use crate::action::{ActionImplementation, NoOutput};
use crate::context::RpcContext;
use crate::dependencies::reconfigure_dependents_with_live_pointers;
use crate::install::PKG_ARCHIVE_DIR;
use crate::net::interface::{InterfaceId, Interfaces};
use crate::s9pk::manifest::PackageId;
@@ -201,6 +202,10 @@ impl BackupActions {
.execute(&mut *secrets)
.await?;
}
crate::db::DatabaseModel::new()
.package_data()
.lock(db, LockType::Write)
.await?;
crate::db::DatabaseModel::new()
.package_data()
.idx_model(pkg_id)
@@ -212,6 +217,20 @@ impl BackupActions {
.interface_addresses()
.put(db, &interfaces.install(&mut *secrets, pkg_id).await?)
.await?;
let entry = crate::db::DatabaseModel::new()
.package_data()
.idx_model(pkg_id)
.expect(db)
.await?
.installed()
.expect(db)
.await?
.get(db, true)
.await?;
reconfigure_dependents_with_live_pointers(ctx, db, &entry).await?;
Ok(())
}
}

View File

@@ -1636,7 +1636,7 @@ impl ValueSpec for PackagePointerSpec {
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct TorAddressPointer {
package_id: PackageId,
pub package_id: PackageId,
interface: InterfaceId,
}
impl TorAddressPointer {
@@ -1667,7 +1667,7 @@ impl fmt::Display for TorAddressPointer {
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct LanAddressPointer {
package_id: PackageId,
pub package_id: PackageId,
interface: InterfaceId,
}
impl fmt::Display for LanAddressPointer {

View File

@@ -14,9 +14,10 @@ use tracing::instrument;
use crate::action::{ActionImplementation, NoOutput};
use crate::config::action::ConfigRes;
use crate::config::spec::PackagePointerSpec;
use crate::config::{Config, ConfigSpec};
use crate::context::RpcContext;
use crate::db::model::CurrentDependencyInfo;
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntry};
use crate::error::ResultExt;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::status::health_check::{HealthCheckId, HealthCheckResult};
@@ -876,3 +877,35 @@ pub fn heal_transitive<'a, Db: DbHandle>(
}
.boxed()
}
pub async fn reconfigure_dependents_with_live_pointers(
ctx: &RpcContext,
mut tx: impl DbHandle,
pde: &InstalledPackageDataEntry,
) -> Result<(), Error> {
let dependents = &pde.current_dependents;
let me = &pde.manifest.id;
for (dependent_id, dependency_info) in dependents {
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,
PackagePointerSpec::LanAddress(ptr) => &ptr.package_id == me && dependent_id != me,
// we never need to retarget these
PackagePointerSpec::TorKey(_) => false,
PackagePointerSpec::Config(_) => false,
}) {
crate::config::configure(
ctx,
&mut tx,
dependent_id,
None,
&None,
false,
&mut BTreeMap::new(),
&mut BTreeMap::new(),
)
.await?;
}
}
Ok(())
}

View File

@@ -2,12 +2,13 @@ use std::collections::{BTreeMap, HashMap};
use bollard::image::ListImagesOptions;
use color_eyre::eyre::eyre;
use patch_db::{DbHandle, PatchDbHandle};
use patch_db::{DbHandle, LockType, PatchDbHandle};
use tracing::instrument;
use super::{PKG_ARCHIVE_DIR, PKG_DOCKER_DIR};
use crate::context::RpcContext;
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry};
use crate::dependencies::reconfigure_dependents_with_live_pointers;
use crate::error::ErrorCollection;
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::util::{Apply, Version};
@@ -235,6 +236,10 @@ pub async fn uninstall(
id: &PackageId,
) -> Result<(), Error> {
let mut tx = db.begin().await?;
crate::db::DatabaseModel::new()
.package_data()
.lock(&mut tx, LockType::Write)
.await?;
let entry = crate::db::DatabaseModel::new()
.package_data()
.idx_model(id)
@@ -249,10 +254,15 @@ pub async fn uninstall(
)
})?;
cleanup(ctx, &entry.manifest.id, &entry.manifest.version).await?;
crate::db::DatabaseModel::new()
.package_data()
.remove(&mut tx, id)
.await?;
// once we have removed the package entry, we can change all the dependent pointers to null
reconfigure_dependents_with_live_pointers(ctx, &mut tx, &entry).await?;
remove_from_current_dependents_lists(
&mut tx,
&entry.manifest.id,

View File

@@ -32,8 +32,8 @@ use crate::db::model::{
};
use crate::db::util::WithRevision;
use crate::dependencies::{
add_dependent_to_current_dependents_lists, break_all_dependents_transitive, BreakageRes,
DependencyError, DependencyErrors,
add_dependent_to_current_dependents_lists, break_all_dependents_transitive,
reconfigure_dependents_with_live_pointers, BreakageRes, DependencyError, DependencyErrors,
};
use crate::install::cleanup::{cleanup, update_dependency_errors_of_dependents};
use crate::install::progress::{InstallProgress, InstallProgressTracker};
@@ -899,6 +899,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
current_dependencies: current_dependencies.clone(),
interface_addresses,
};
let prev = std::mem::replace(
&mut *pde,
PackageDataEntry::Installed {
@@ -1048,6 +1049,10 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
.remove(&mut tx, pkg_id)
.await?;
if let Some(installed) = pde.installed() {
reconfigure_dependents_with_live_pointers(ctx, &mut tx, installed).await?;
}
sql_tx.commit().await?;
tx.commit(None).await?;