-
Notifications
You must be signed in to change notification settings - Fork 64
Fix broken disk list #9553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix broken disk list #9553
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -445,46 +445,16 @@ impl DataStore { | |||||
| .await | ||||||
| } | ||||||
|
|
||||||
| /// List disks associated with a given instance by name. | ||||||
| pub async fn instance_list_disks_on_conn( | ||||||
| &self, | ||||||
| /// Consume a query result listing all parts of the higher level Disk type, | ||||||
| /// and assemble it. | ||||||
| async fn process_tuples_to_disk_list( | ||||||
| conn: &async_bb8_diesel::Connection<DbConnection>, | ||||||
| instance_id: Uuid, | ||||||
| pagparams: &PaginatedBy<'_>, | ||||||
| results: Vec<( | ||||||
| model::Disk, | ||||||
| Option<DiskTypeCrucible>, | ||||||
| Option<DiskTypeLocalStorage>, | ||||||
| )>, | ||||||
| ) -> ListResultVec<Disk> { | ||||||
| use nexus_db_schema::schema::disk::dsl; | ||||||
| use nexus_db_schema::schema::disk_type_crucible::dsl as disk_type_crucible_dsl; | ||||||
| use nexus_db_schema::schema::disk_type_local_storage::dsl as disk_type_local_storage_dsl; | ||||||
|
|
||||||
| let results = match pagparams { | ||||||
| PaginatedBy::Id(pagparams) => { | ||||||
| paginated(dsl::disk, dsl::id, &pagparams) | ||||||
| } | ||||||
| PaginatedBy::Name(pagparams) => paginated( | ||||||
| dsl::disk, | ||||||
| dsl::name, | ||||||
| &pagparams.map_name(|n| Name::ref_cast(n)), | ||||||
| ), | ||||||
| } | ||||||
| .left_join( | ||||||
| disk_type_crucible_dsl::disk_type_crucible | ||||||
| .on(dsl::id.eq(disk_type_crucible_dsl::disk_id)), | ||||||
| ) | ||||||
| .left_join( | ||||||
| disk_type_local_storage_dsl::disk_type_local_storage | ||||||
| .on(dsl::id.eq(disk_type_local_storage_dsl::disk_id)), | ||||||
| ) | ||||||
| .filter(dsl::time_deleted.is_null()) | ||||||
| .filter(dsl::attach_instance_id.eq(instance_id)) | ||||||
| .select(( | ||||||
| model::Disk::as_select(), | ||||||
| Option::<DiskTypeCrucible>::as_select(), | ||||||
| Option::<DiskTypeLocalStorage>::as_select(), | ||||||
| )) | ||||||
| .get_results_async(conn) | ||||||
| .await | ||||||
| .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; | ||||||
|
|
||||||
| let mut list = Vec::with_capacity(results.len()); | ||||||
|
|
||||||
| for result in results { | ||||||
|
|
@@ -555,6 +525,49 @@ impl DataStore { | |||||
| Ok(list) | ||||||
| } | ||||||
|
|
||||||
| /// List disks associated with a given instance by name. | ||||||
| pub async fn instance_list_disks_on_conn( | ||||||
| &self, | ||||||
| conn: &async_bb8_diesel::Connection<DbConnection>, | ||||||
| instance_id: Uuid, | ||||||
| pagparams: &PaginatedBy<'_>, | ||||||
| ) -> ListResultVec<Disk> { | ||||||
| use nexus_db_schema::schema::disk::dsl; | ||||||
| use nexus_db_schema::schema::disk_type_crucible::dsl as disk_type_crucible_dsl; | ||||||
| use nexus_db_schema::schema::disk_type_local_storage::dsl as disk_type_local_storage_dsl; | ||||||
|
|
||||||
| let results = match pagparams { | ||||||
| PaginatedBy::Id(pagparams) => { | ||||||
| paginated(dsl::disk, dsl::id, &pagparams) | ||||||
| } | ||||||
| PaginatedBy::Name(pagparams) => paginated( | ||||||
| dsl::disk, | ||||||
| dsl::name, | ||||||
| &pagparams.map_name(|n| Name::ref_cast(n)), | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unimportant turbo-nit: this could be
Suggested change
|
||||||
| ), | ||||||
| } | ||||||
| .left_join( | ||||||
| disk_type_crucible_dsl::disk_type_crucible | ||||||
| .on(dsl::id.eq(disk_type_crucible_dsl::disk_id)), | ||||||
| ) | ||||||
| .left_join( | ||||||
| disk_type_local_storage_dsl::disk_type_local_storage | ||||||
| .on(dsl::id.eq(disk_type_local_storage_dsl::disk_id)), | ||||||
| ) | ||||||
| .filter(dsl::time_deleted.is_null()) | ||||||
| .filter(dsl::attach_instance_id.eq(instance_id)) | ||||||
| .select(( | ||||||
| model::Disk::as_select(), | ||||||
| Option::<DiskTypeCrucible>::as_select(), | ||||||
| Option::<DiskTypeLocalStorage>::as_select(), | ||||||
| )) | ||||||
|
Comment on lines
+539
to
+563
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it occurs to me that we might be able to share more code between the two functions by pulling everything here except for the on one hand, that also would have prevented the original bug, but on the other, well...figuring out the Diesel type of that query is probably gonna hurt, and i think the so, the current thing is fine and this doesn't matter. |
||||||
| .get_results_async(conn) | ||||||
| .await | ||||||
| .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; | ||||||
|
|
||||||
| Self::process_tuples_to_disk_list(conn, results).await | ||||||
| } | ||||||
|
|
||||||
| pub(super) async fn project_create_disk_in_txn( | ||||||
| conn: &async_bb8_diesel::Connection<DbConnection>, | ||||||
| err: OptionalError<Error>, | ||||||
|
|
@@ -702,6 +715,9 @@ impl DataStore { | |||||
|
|
||||||
| use nexus_db_schema::schema::disk::dsl; | ||||||
| use nexus_db_schema::schema::disk_type_crucible::dsl as disk_type_crucible_dsl; | ||||||
| use nexus_db_schema::schema::disk_type_local_storage::dsl as disk_type_local_storage_dsl; | ||||||
|
|
||||||
| let conn = self.pool_connection_authorized(opctx).await?; | ||||||
|
|
||||||
| let results = match pagparams { | ||||||
| PaginatedBy::Id(pagparams) => { | ||||||
|
|
@@ -717,37 +733,22 @@ impl DataStore { | |||||
| disk_type_crucible_dsl::disk_type_crucible | ||||||
| .on(dsl::id.eq(disk_type_crucible_dsl::disk_id)), | ||||||
| ) | ||||||
| .left_join( | ||||||
| disk_type_local_storage_dsl::disk_type_local_storage | ||||||
| .on(dsl::id.eq(disk_type_local_storage_dsl::disk_id)), | ||||||
| ) | ||||||
| .filter(dsl::time_deleted.is_null()) | ||||||
| .filter(dsl::project_id.eq(authz_project.id())) | ||||||
| .select(( | ||||||
| model::Disk::as_select(), | ||||||
| Option::<DiskTypeCrucible>::as_select(), | ||||||
| Option::<DiskTypeLocalStorage>::as_select(), | ||||||
| )) | ||||||
| .get_results_async(&*self.pool_connection_authorized(opctx).await?) | ||||||
| .get_results_async(&*conn) | ||||||
| .await | ||||||
| .map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?; | ||||||
|
|
||||||
| let mut list = Vec::with_capacity(results.len()); | ||||||
|
|
||||||
| for result in results { | ||||||
| match result { | ||||||
| (disk, Some(disk_type_crucible)) => { | ||||||
| list.push(Disk::Crucible(CrucibleDisk { | ||||||
| disk, | ||||||
| disk_type_crucible, | ||||||
| })); | ||||||
| } | ||||||
|
|
||||||
| (disk, None) => { | ||||||
| return Err(Error::internal_error(&format!( | ||||||
| "disk {} is invalid!", | ||||||
| disk.id(), | ||||||
| ))); | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Ok(list) | ||||||
| Self::process_tuples_to_disk_list(&conn, results).await | ||||||
| } | ||||||
|
|
||||||
| /// Attaches a disk to an instance, if both objects: | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
part of me wonders if we might be better off having some kinda
so that we can use named fields in the
matchlater, but perhaps that's not worth the effort... i dunno.