Skip to content

Multirack join service part 4 - #11143

Open
andrewjstone wants to merge 34 commits into
mainfrom
multirack-join-service-part-4
Open

andrewjstone wants to merge 34 commits into
mainfrom
multirack-join-service-part-4

Conversation

@andrewjstone

@andrewjstone andrewjstone commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Note to reviewers: This is not as bad as it looks there's at least 800 lines of JSON here.

This is the last bit of work for #10637 that got us to Friday's demo where
/64 addresses for sleds were published via DDM running over front ports.

There's a bunch of stuff in here, but at a high level it comes down to the following:

  • Adding a wicketd commission api endpoint for submitting a MultirackJoinRequest to the multirack join service.
  • The multirack join service being completed by putting the RackNetworkConfig into the bootstore so that it can be reconciled.
  • The reconciliation resulting in front ports being configured to allow_ddm_traffic via dpd-client
  • The reconciliation resulting in DDM state machines being started for those front ports via use of ddm-admin-client.

This code relies on new maghemite code on branch ry/external-peers. The necessary dendrite changes are already merged into main. The maghemite PR must be completed and merged before this goes in.

All of this was tested using a voxel PR that must be merged after this PR.

Comment thread sled-agent/scrimlet-reconcilers/src/handle.rs Outdated
Comment thread sled-agent/src/services.rs Outdated
Comment thread Cargo.toml Outdated
@andrewjstone
andrewjstone marked this pull request as ready for review September 21, 2026 19:22
@andrewjstone

Copy link
Copy Markdown
Contributor Author

This is finally ready for a review.

andrewjstone added a commit to oxidecomputer/voxel that referenced this pull request Sep 29, 2026
This relies on oxidecomputer/omicron#11143 which
must be merged first.

It removes the pre-existing shell commands and uses actual omicron
reconcilliation of dendrite and maghemite to ensure interconnect ports
are created and DDM routes exchanged over them.
Comment thread sled-agent/scrimlet-reconcilers/src/reconciler_task.rs Outdated
Comment thread sled-agent/scrimlet-reconcilers/src/ddmd_reconciler.rs Outdated
Comment thread sled-agent/scrimlet-reconcilers/src/ddmd_reconciler/tests.rs
}

fn switch_zone_ddm_router_id(baseboard: &Baseboard) -> String {
format!("sw{}", baseboard.identifier())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is the sw prefix special or meaningful to ddm?

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.

@rcgoodfellow added that one. I'm not sure what the goal was there.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we at least need some comments explaining this. I'm not sure if it's:

  • we're prefixing sw for humans to debug that this is something in a switch zone, but it doesn't matter for correctness
  • the prefix of sw is special to ddm in some way
  • we need any kind of prefix/suffix because if we used just baseboard.identifier().to_string() something would break because now the switch zone ID matches the gz ID

or something else

Comment thread wicket/src/cli/rack_setup/config_toml.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
Comment thread dev-tools/ls-apis/api-manifest.toml Outdated
Comment thread wicketd-commission-api/src/lib.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
Comment thread wicketd/src/rss_config.rs
};

let ports = UplinkPorts::new(ports)
.context("rack network config must specify at least one uplink port")?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Will this still fail if the config specifies only DDM ports and no uplink ports? (We should reject that combo somehow, right?)

Similarly, but not sure where, should we reject any configs targeting the multirack join service that don't specify any DDM ports? (Or in the future, don't specify any ports configured for connection to a proto rack?)

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.

Ah you're correct. I fixed the implementation so it does so now in afdd508.

Unfortunately, the name is still confusingly UplinkPorts. But that really is not on the table to change right now.

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'll have to think a bit more about your second question tomorrow.

@andrewjstone andrewjstone Oct 6, 2026 •

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.

This change actually resulted in a couple of tests failing. In particular we can't just have a single port that has allow_ddm_traffic = true. That messes with the proptest change I made to populate that field rather than hardcode to false. I reverted that prior change so that we don't set allow_ddm_traffic = true in the Arbitrary. I don't think it's that big a deal for testing here.

Changed in 59d655b

Comment thread sled-agent/scrimlet-reconcilers/src/ddmd_reconciler.rs Outdated
Comment thread sled-agent/src/services.rs Outdated
Comment thread wicketd-commission-types/versions/src/multirack_join/rack_setup.rs Outdated
}

fn switch_zone_ddm_router_id(baseboard: &Baseboard) -> String {
format!("sw{}", baseboard.identifier())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we at least need some comments explaining this. I'm not sure if it's:

  • we're prefixing sw for humans to debug that this is something in a switch zone, but it doesn't matter for correctness
  • the prefix of sw is special to ddm in some way
  • we need any kind of prefix/suffix because if we used just baseboard.identifier().to_string() something would break because now the switch zone ID matches the gz ID

or something else

Comment on lines +340 to +341
// The two variants name their speed and FEC fields differently, so the
// required speed key is what selects the variant.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems pretty janky for a few reasons:

  1. The comment may not even be right - the FEC fields are both fec, right?
  2. Why would their speed fields be named differently when they're specifying the same thing?
  3. If we fix 2, do we now break our ability to distinguish between the variants?

Should we either have some explicit kind = "ddm|uplink" field in UnvalidatedPortConfig, or make it itself an enum and push this up a level?

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.

Agreed. This was gross, and I'm ashamed of sending it out for review that way. I changed this to properly serialize UserSpecifiedPortConfig with a tag, and then deserialize into UnvalidatedPortConfig as an intermediate so that we could handle untagged uplink versions still, which is what we currently use in our production RSS files.

This still needs a bit of testing on my side, but looks right to me.

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.

This doesn't work right. The direction is correct, but I'm going to have to play around with the structure a bit.

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.

Ok, this works now as of 3f57914.

I added intermediate untagged values to deserialize into and utilized adjacent tagging. This allows automated serialization and deserialization of UserSpecifiedPortConfig that also deals with legacy untagged uplinks.

@andrewjstone

Copy link
Copy Markdown
Contributor Author

I think this is pretty close @jgallagher except for the question around the sw prefix.

Given all the changes though, I want to give it another run through voxel tomorrow.

This branch has not been deployed

No deployments
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.

4 participants