Skip to content

omdb: show instances grouped by sled#10289

Open
leftwo wants to merge 6 commits intomainfrom
alan/omdb-sled-instances
Open

omdb: show instances grouped by sled#10289
leftwo wants to merge 6 commits intomainfrom
alan/omdb-sled-instances

Conversation

@leftwo
Copy link
Copy Markdown
Contributor

@leftwo leftwo commented Apr 20, 2026

I'm not in love with the command name, omdb db sled-instances, and open to other possible choices.

Here is an example of how this looks:

root@oxz_switch0:~# /tmp/omdb db sled-instances                                                                                                                   
Sled 14 (serial: BRM42220081)  sled_id: be78edd2-605a-4015-bded-f3cd12274d31                                                                      
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME                                                            
27a6f95b-7594-4de6-a156-1ac7165fe083 23f5894e-5331-4c40-8c1d-a15525d93356 running many-16-inst                                                    
a90a0c87-396c-46b2-823b-5b930a57b1ba 24b535fd-5071-41df-895f-ec36d4998a49 running many-13-inst                                                    
0fbe5571-3869-4a8a-b036-aee52d24d0be bbe93355-c7ca-4353-8a66-f28bfcf3407d running many-17-inst                                                    
fe0c2ac0-7bee-42f9-8aa6-5e8284b80889 e288b49d-6c25-4ab4-af69-180dadf8779a running many-7-inst                                                     
9b729e1c-8e1a-49cb-bae2-e2fd61b8bce6 e380978a-cb7d-4f04-b9bd-db76dfc1332f running many-11-inst                                                    
9cbb1c9c-6573-4f12-a1d6-b747bb3cf1a3 ec706734-b1d0-4c35-827e-7971f4819241 running many-8-inst                                                     
                                                                                                                                                  
Sled 15 (serial: BRM42220046)  sled_id: 20d857aa-043c-49bd-946e-b3a66f849f5b                                                                      
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME                                                            
0ac44fac-7d3d-4e98-996d-eaa7f130cdf7 1c7c3973-66eb-4ff0-b9d2-a22d2efc4569 running four-inst                                                       
f486a222-871e-439e-9e5f-9593ec617aa1 2c66acdb-97a0-47dc-983d-74546a6723c2 running many-14-inst                                                    
b5fcae99-f87c-420b-b2fa-2055c148f804 ad270ace-e1ee-431b-8180-7bf1b8be2769 running many-10-inst                                                    
48d8364f-26bd-4ca5-a99b-70390998832f e2ce08c6-40d2-46d1-89e4-9e298d3dbb93 running many-18-inst                                                    
                                                                                                                                                  
Sled 16 (serial: BRM42220007)  sled_id: a0653160-81f7-4e78-97ef-721eae8e8c38                                                                      
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME                                                            
5cb00f31-1283-4db2-a97e-7276b3da9600 0a0cde5f-7a94-4205-b75d-0df48f0f6226 running many-19-inst                                                    
750aeb06-8b6e-4f93-944f-73cff1f3e26a 0f4deb3d-d7c3-4bc0-8d77-76a1ebad9914 running focal                                                           
c66a10d6-542d-4678-861e-563a0f59c19a 27ef10d5-8d3e-4c26-af31-70a2f928ebad running many-15-inst                                                    
573efd67-c58b-4fca-b64e-d1cb7560b12a 2bb44274-2bcf-49ac-bd90-d2ff22ed1681 running many-5-inst                                                     
428396d5-36e5-42c7-9f21-a891410be917 e6cd1fdb-afb7-41c3-8ffd-e23bc39adf44 running many-12-inst                                                    
                                                                                                                                                  
Sled 17 (serial: BRM42220004)  sled_id: 838f8168-d9a5-4bf3-8cf5-091c781d7339                                                                      
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME                                                            
0f5133b0-5dbb-40d6-9e3f-2284ccc00579 9c6bfe0b-e73a-492b-b654-5313cea9e493 running three-inst                                                      
90bd694e-89ee-4a6f-b92f-034d859e4617 bce448ac-4f76-4172-8fea-3b834c6cc3c7 running many-6-inst                                                     
63afd923-9175-47c4-925a-b37d0b765398 de0ab380-e787-4711-8d7a-5d81d3c1457b running two-inst                                                        
06912bfd-63e8-4337-8529-28605c6cdcd0 e3d9da1a-9500-45e3-aad0-247229efa5f7 running many-9-inst                                                     
702e9b02-afae-42a2-abcd-afda4477c742 f544889d-4568-4516-a535-1aadecb6e5c2 running many-20-inst

leftwo added 4 commits April 20, 2026 08:54
Group instances by the sleds they are running on.

Options to display specific sleds by cubby or serial number, or a
range of cubbies.
@hawkw hawkw self-requested a review April 20, 2026 21:22
Comment on lines +4891 to +4894
struct SledInstanceRow {
instance_id: String,
state: String,
name: String,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of feel like there is more data i would want to have in here; at minimum, I would hope that we also included the instance's Propolis UUID. Perhaps we could refactor this to share more code with the CustomerInstanceRow in omdb db instances? We could change this:

let cir = CustomerInstanceRow {
id: i.instance().id().to_string(),
name: i.instance().name().to_string(),
state: i.effective_state().to_string(),
intent: i.instance().intended_state,
propolis_id: (&i).into(),
?
so that the common fields are in a struct that we would also use here, and then have omdb db instance list embed that struct in one that also adds the host serial/ID?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is how propolis IDs could look after making the change above:

root@oxz_switch0:~# /tmp/omdb db sled-instances --sled 15,16 2> /dev/null
Sled 15 (serial: BRM42220046)  sled_id: 20d857aa-043c-49bd-946e-b3a66f849f5b
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME         
0ac44fac-7d3d-4e98-996d-eaa7f130cdf7 1c7c3973-66eb-4ff0-b9d2-a22d2efc4569 running four-inst    
f486a222-871e-439e-9e5f-9593ec617aa1 2c66acdb-97a0-47dc-983d-74546a6723c2 running many-14-inst 
b5fcae99-f87c-420b-b2fa-2055c148f804 ad270ace-e1ee-431b-8180-7bf1b8be2769 running many-10-inst 
48d8364f-26bd-4ca5-a99b-70390998832f e2ce08c6-40d2-46d1-89e4-9e298d3dbb93 running many-18-inst 

Sled 16 (serial: BRM42220007)  sled_id: a0653160-81f7-4e78-97ef-721eae8e8c38
INSTANCE_ID                          PROPOLIS_ID                          STATE   NAME         
5cb00f31-1283-4db2-a97e-7276b3da9600 0a0cde5f-7a94-4205-b75d-0df48f0f6226 running many-19-inst 
750aeb06-8b6e-4f93-944f-73cff1f3e26a 0f4deb3d-d7c3-4bc0-8d77-76a1ebad9914 running focal        
c66a10d6-542d-4678-861e-563a0f59c19a 27ef10d5-8d3e-4c26-af31-70a2f928ebad running many-15-inst 
573efd67-c58b-4fca-b64e-d1cb7560b12a 2bb44274-2bcf-49ac-bd90-d2ff22ed1681 running many-5-inst  
428396d5-36e5-42c7-9f21-a891410be917 e6cd1fdb-afb7-41c3-8ffd-e23bc39adf44 running many-12-inst

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think that's great!

Comment thread dev-tools/omdb/src/bin/omdb/db.rs Outdated
Comment on lines +4795 to +4833
// Step 2: Fetch all non-deleted instances joined with their
// active VMMs.
let limit = fetch_opts.fetch_limit;
let instances: Vec<InstanceAndActiveVmm> = dsl::instance
.filter(dsl::time_deleted.is_null())
.left_join(
vmm_dsl::vmm.on(vmm_dsl::id
.nullable()
.eq(dsl::active_propolis_id)
.and(vmm_dsl::time_deleted.is_null())),
)
.limit(i64::from(u32::from(limit)))
.select((Instance::as_select(), Option::<Vmm>::as_select()))
.load_async(&*datastore.pool_connection_for_tests().await?)
.await
.context("loading instances")?
.into_iter()
.map(|i: (Instance, Option<Vmm>)| i.into())
.collect();

check_limit(&instances, limit, || "listing instances".to_string());

// Step 3: Group instances by sled_id (skip those with no
// active VMM / no sled).
let mut instances_by_sled: BTreeMap<SledUuid, Vec<&InstanceAndActiveVmm>> =
BTreeMap::new();
let mut unmatched: Vec<&InstanceAndActiveVmm> = Vec::new();

for inst in &instances {
let sled_id = match inst.sled_id() {
Some(id) => id,
None => continue, // no active VMM, skip
};
if sled_info.contains_key(&sled_id) {
instances_by_sled.entry(sled_id).or_default().push(inst);
} else {
unmatched.push(inst);
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it feels a bit odd to me that we do one big query to fetch every non-deleted instance, with one big fetch limit, and then we add them to a map of instances by sled, when we could just filter on the VMM record's sled UUID?

wouldn't it be nicer to implement this as:

  1. fetch all matching sleds and filter them as we do above
  2. sort sleds
  3. loop over sorted sleds, query for instances belong to that sled, and print the table sled-by-sled

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the loop, and yeah, it's much cleaner.

This new way means we won't print any instances that don't have a matching sled, which would be an error any way and unlikely to happen, or happen if things are inflight between making the list of sleds and gathering the list of instances.

leftwo added 2 commits April 20, 2026 19:35
Make a common instance struct that can be shared
vmm_dsl::vmm.on(vmm_dsl::id
.nullable()
.eq(dsl::active_propolis_id)
.and(vmm_dsl::time_deleted.is_null())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if we might want to have the include_deleted option be honored here? if so, we would want to indicated deletedness in the output...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants