Skip to content

api/types: fix Plugin.Config.Interface.Types Swagger definition#50519

Merged
thaJeztah merged 2 commits intomoby:masterfrom
corhere:plugin-interface-type-pkg
Aug 1, 2025
Merged

api/types: fix Plugin.Config.Interface.Types Swagger definition#50519
thaJeztah merged 2 commits intomoby:masterfrom
corhere:plugin-interface-type-pkg

Conversation

@corhere
Copy link
Contributor

@corhere corhere commented Jul 25, 2025

- What I did

I fixed up the Swagger definition for Plugin.Config.Interface.Types to accurately express that it is an array of strings over the wire while maintaining the parsed struct type on the Go side.

- How I did it
I upgraded to the latest go-swagger to make use of x-go-type external type extensions so the generated Go struct field uses the type of my choice instead of plain strings. I customized the Swagger generation templates to suppress generating validators or marshal/unmarshal code.

- How to verify it
CI

- Human readable description for the release notes

- A picture of a cute animal (not mandatory but encouraged)

@corhere corhere added this to the 29.0.0 milestone Jul 25, 2025
@corhere corhere requested review from dmcgowan and thaJeztah July 25, 2025 23:49
@corhere corhere requested a review from tianon as a code owner July 25, 2025 23:49
@corhere corhere added area/api API kind/refactor PR's that refactor, or clean-up code labels Jul 25, 2025
@corhere corhere requested review from Copilot and vvoland July 25, 2025 23:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes the Swagger definition for Plugin.Config.Interface.Types to properly represent it as an array of strings in the API while maintaining structured type information in Go code. The change addresses issues with plugin interface type representation and updates the go-swagger tooling to support external type extensions.

Key changes:

  • Updated Swagger definition to use array of strings with external Go type mapping
  • Created new CapabilityID type in pkg/plugins/pluginmeta package with proper marshaling/unmarshaling
  • Upgraded go-swagger version and modified generation templates
  • Updated all references throughout codebase to use the new type

Reviewed Changes

Copilot reviewed 40 out of 72 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
api/swagger.yaml Updated plugin interface types definition to use string array with external type mapping
pkg/plugins/pluginmeta/capability.go New CapabilityID type with text marshaling/unmarshaling implementation
pkg/plugins/pluginmeta/capability_test.go Comprehensive tests for the new CapabilityID type
api/types/plugin.go Updated to use new CapabilityID type and added import
api/types/plugin_interface_type.go Removed old PluginInterfaceType definition
api/types/plugin_responses.go Removed marshaling/unmarshaling methods for old type
hack/generate-swagger-api.sh Updated swagger generation commands and removed old type
Dockerfile Upgraded go-swagger version to v0.32.3
Multiple test files Updated to use new CapabilityID type
Multiple generated files Updated with new swagger generation output

@corhere corhere force-pushed the plugin-interface-type-pkg branch 2 times, most recently from b1ac092 to efdb0e3 Compare July 28, 2025 16:52
@corhere
Copy link
Contributor Author

corhere commented Jul 28, 2025

I tried putting the CapabilityID definition into pkg/plugins but that would lead to a module dependency cycle (github.com/moby/moby -> github.com/moby/moby/api -> github.com/moby/moby) so I took the path of least resistance and moved the type definition back into the api module.

@corhere corhere force-pushed the plugin-interface-type-pkg branch 2 times, most recently from 4c47558 to c1c0aab Compare July 28, 2025 20:21
@thaJeztah thaJeztah added the release-blocker PRs we want to block a release on label Jul 29, 2025
@thompson-shaun thompson-shaun moved this from New to Complete in 🔦 Maintainer spotlight Jul 31, 2025
@corhere corhere force-pushed the plugin-interface-type-pkg branch from c1c0aab to 9de1602 Compare July 31, 2025 20:23
@thaJeztah
Copy link
Member

do we want to do the move of these types to api/types/plugin (and remove the "Plugin" prefix) as well as part of this PR, or in a follow up?

@corhere
Copy link
Contributor Author

corhere commented Jul 31, 2025

@thaJeztah I structured this PR to not conflict with your PR that moves the plugin type definitions. I say we keep the PRs separate

@thaJeztah
Copy link
Member

Gotcha! Happy to do the follow up; I wasn't sure if it was intentional.

@corhere this one needs a rebase now (as the module PR was merged)

corhere added 2 commits August 1, 2025 13:30
Override some of the templates to suppress emitting unwanted validation
and marshal/unmarshal code.

Signed-off-by: Cory Snider <csnider@mirantis.com>
The wire type of Plugin.Config.Interface.Types is an array of strings,
not of objects with three properties. We just so happen to have a Go
struct type to represent a plugin-interface-type value in memory with
all the fields parsed out for convenience, but that is not part of the
REST API contract documented by the Swager spec.U pdate the Swagger spec
to correctly document that the Types property is an array of strings in
the API, while still generating Go definitions that unmarshal into the
convenient struct type.

Move the definition and marshal/unmarshal methods for
PluginInterfaceType into a more appropriate location than api/types.
Rename the type to one that does not stutter or overload already
heavily overloaded terminology.

Modernize the parser and use property-based testing to assert that it
behaves the same as the old parser for all well-formed inputs.

Signed-off-by: Cory Snider <csnider@mirantis.com>
@corhere corhere force-pushed the plugin-interface-type-pkg branch from 9de1602 to ee560a3 Compare August 1, 2025 17:38
@corhere corhere requested a review from thaJeztah August 1, 2025 20:50
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

Thank YOU! Really happy we finally got rid of that swagger fork 🎉

@thaJeztah thaJeztah merged commit 0f9c087 into moby:master Aug 1, 2025
207 of 208 checks passed
Comment on lines +44 to +47
// Assert that the value can be round-tripped successfully.
if strings.Contains(t.Capability, ".") {
return nil, fmt.Errorf("capability %q cannot contain a dot", t.Capability)
}
Copy link
Member

Choose a reason for hiding this comment

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

Interesting; getting a failure in some e2e test in the CLI - not unlikely that the dummy value it used was supposed to be valid 🤔 ;

=== Failed
=== FAIL: e2e/global TestPromptExitCode/plugin_install (0.28s)
    cli_test.go:203: assertion failed: error is not nil: json: error calling MarshalText for type plugin.CapabilityID: capability "docker.dummy/1.0" cannot contain a dot

=== FAIL: e2e/global TestPromptExitCode/plugin_upgrade (0.26s)
    cli_test.go:203: assertion failed: error is not nil: json: error calling MarshalText for type plugin.CapabilityID: capability "docker.dummy/1.0" cannot contain a dot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes; PluginInterfaceType was frequently misused by setting the Capability field to the fully-qualified capability ID and leaving the other two fields blank. A value such as PluginInterfaceType{Capability: "docker.dummy/1.0"} would marshal to the string ".docker.dummy/1.0/" which is not well-formed and does not round-trip to the same value even with the old parser

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I later realised that was probably what happened.

In all honesty, I don't think there will be many (if any) users of these types; plugins are not widely used, and I doubt there's many users that consume that part of the client (and API).

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

Labels

area/api API kind/refactor PR's that refactor, or clean-up code release-blocker PRs we want to block a release on

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

[Documentation] PluginInterfaceType does not match data returned Remove use of "go-swagger" fork, and update to current version

7 participants