diff --git a/nexus/db-queries/src/db/datastore/zpool.rs b/nexus/db-queries/src/db/datastore/zpool.rs index 0938ed5ba6..8c85b43ed6 100644 --- a/nexus/db-queries/src/db/datastore/zpool.rs +++ b/nexus/db-queries/src/db/datastore/zpool.rs @@ -15,6 +15,7 @@ use crate::db::error::public_error_from_diesel; use crate::db::error::ErrorHandler; use crate::db::identity::Asset; use crate::db::model::PhysicalDisk; +use crate::db::model::PhysicalDiskPolicy; use crate::db::model::PhysicalDiskState; use crate::db::model::Sled; use crate::db::model::Zpool; @@ -273,19 +274,28 @@ impl DataStore { Ok(()) } - pub async fn zpool_get_sled( + pub async fn zpool_get_sled_if_in_service( &self, opctx: &OpContext, id: ZpoolUuid, ) -> LookupResult { opctx.authorize(authz::Action::ListChildren, &authz::FLEET).await?; - use db::schema::zpool::dsl; + use db::schema::physical_disk::dsl as physical_disk_dsl; + use db::schema::zpool::dsl as zpool_dsl; let conn = self.pool_connection_authorized(opctx).await?; - let id = dsl::zpool - .filter(dsl::id.eq(id.into_untyped_uuid())) - .filter(dsl::time_deleted.is_null()) - .select(dsl::sled_id) + let id = zpool_dsl::zpool + .filter(zpool_dsl::id.eq(id.into_untyped_uuid())) + .filter(zpool_dsl::time_deleted.is_null()) + .inner_join( + physical_disk_dsl::physical_disk + .on(zpool_dsl::physical_disk_id.eq(physical_disk_dsl::id)), + ) + .filter( + physical_disk_dsl::disk_policy + .eq(PhysicalDiskPolicy::InService), + ) + .select(zpool_dsl::sled_id) .first_async::(&*conn) .await .map_err(|e| { diff --git a/nexus/src/app/background/tasks/support_bundle_collector.rs b/nexus/src/app/background/tasks/support_bundle_collector.rs index ad0e3d85b5..5a8a114a3e 100644 --- a/nexus/src/app/background/tasks/support_bundle_collector.rs +++ b/nexus/src/app/background/tasks/support_bundle_collector.rs @@ -264,10 +264,10 @@ impl SupportBundleCollector { // Find the sled where we're storing this bundle. let result = self .datastore - .zpool_get_sled(&opctx, bundle.zpool_id.into()) + .zpool_get_sled_if_in_service(&opctx, bundle.zpool_id.into()) .await; - println!("zpool_get_sled result: {result:?}"); + println!("zpool_get_sled_if_in_service result: {result:?}"); let delete_from_db = match result { Ok(sled_id) => { @@ -473,7 +473,10 @@ impl<'a> BundleCollection<'a> { let sled_id = self .collector .datastore - .zpool_get_sled(&self.opctx, self.bundle.zpool_id.into()) + .zpool_get_sled_if_in_service( + &self.opctx, + self.bundle.zpool_id.into(), + ) .await?; let sled_client = nexus_networking::sled_client( &self.collector.datastore, @@ -1397,7 +1400,7 @@ mod test { // Delete the zpool holding the bundle. // - // This should call the "zpool_get_sled" call to fail! + // This should call the "zpool_get_sled_if_in_service" call to fail! datastore .zpool_delete_self_and_all_datasets(&opctx, bundle.zpool_id.into()) .await