Skip to content

Conversation

@gjcolombo
Copy link
Contributor

The next step toward implementing virtual platforms in Omicron is to move instance spec construction from sled-agent up to Nexus. This requires instance spec types to appear in sled-agent's API. To allow this:

  • Direct the generated client to add a schemars::JsonSchema derive to all generated types.
  • Add rename = snake_case attributes to instance spec enum types that sled-agent expects to reuse. Omicron requires all of its API specifications to pass the OpenAPI linting rules defined in the openapi-lint crate (https://github.com/oxidecomputer/openapi-lint); among these is a requirement that enum variants all have snake case names.

Also add a note explaining special rules for the use of the SpecKey type (generated clients that include this type need to make sure that they furnish the correct Serialize implementation for it).

Tests: cargo test; PHD; verified that it's possible to write the desired Omicron changes using this change; verified that the Falcon repo continues to build with its propolis-client dependency pointed to this commit.

The next step toward implementing virtual platforms in Omicron is to
move instance spec construction from sled-agent up to Nexus. This
requires instance spec types to appear in sled-agent's API. To allow
this:

- Direct the generated client to add a `schemars::JsonSchema` derive to
  all generated types.
- Add `rename = snake_case` attributes to instance spec enum types that
  sled-agent expects to reuse. Omicron requires all of its API
  specifications to pass the OpenAPI linting rules defined in the
  openapi-lint crate (https://github.com/oxidecomputer/openapi-lint);
  among these is a requirement that enum variants all have snake case
  names.

Tests: cargo test; PHD; verified that it's possible to write the desired
Omicron changes using this change; verified that the Falcon repo
continues to build with its propolis-client dependency pointed to this
commit.
@gjcolombo
Copy link
Contributor Author

The migrate_from_base failure is expected; the new PHD client is using snake-case type definitions that the old server doesn't expect.

Also, for the record: I looked into writing a test that runs the OpenAPI linter over the entire propolis-server API document (instead of just cherry-picking fixes for errors in sled-agent). This test is trivial to write, but it immediately turns up several dozen errors that we'd have to go fix, so I've punted that to another PR. (I may come to regret this as I keep working on my sled-agent changes...)

@gjcolombo gjcolombo requested a review from hawkw April 14, 2025 22:38
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

I had one thought about potentially changing the schema for SpecKey, but otherwise, this seems good to me!

Comment on lines 195 to 200
// WARNING: Progenitor-generated versions of this type will use serde's default
// derived Serialize and Deserialize implementations, not the serde_with
// implementations. This can cause clients to serialize spec keys in a form that
// the server can't deserialize. To get around this, Progenitor clients that
// use spec keys should use a `replace` directive to replace the generated
// type with this type.
Copy link
Member

Choose a reason for hiding this comment

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

It occurs to me that there might be an alternative solution to this that doesn't require "WARNING: remember to do this extra stuff when generating clients": we are presently deriving JsonSchema, and I assume the generated schema is for a tagged enum representation. Could we, instead, add serde(untagged) and hand-implement JsonSchema for SpecKey, the way we do for NameOrId in omicron-common? That way, I think we should instead generate an OpenAPI spec that represents this as just a String but with hints suggesting it could be a UUID. I'm not 100% sure that will get us the desired behavior but it seems worth looking into.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am embarrassed to admit that I did not see the parallel between this and NameOrId! I'll give this a try.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was able to get this to work in fc7a85f. It didn't exactly spark joy, but it does get rid of the serde_with dependency and makes things slightly nicer for sled-agent, so I think I'm leaning toward going with it anyway. Would be interested to hear what you think!

Copy link
Member

Choose a reason for hiding this comment

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

I'll take a look!

This obviates the need to use re-exports and Progenitor replace
directives in sled-agent's API.
@gjcolombo gjcolombo requested a review from hawkw April 16, 2025 22:52
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

The untagged enum seems fine to me. The "order matters" comment is certainly a bit sad, but I think if we added a test for it we could safely just forget about it and be fine. Everything else seems good.

Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

looks good to me

@gjcolombo gjcolombo merged commit 0b1c7c5 into master Apr 17, 2025
10 of 11 checks passed
@gjcolombo gjcolombo deleted the gjcolombo/client-jsonschema branch April 17, 2025 20:22
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.

3 participants