Skip to content

Conversation

@abendrothj
Copy link

@abendrothj abendrothj commented Oct 27, 2025

Status: Draft
Author: Jake Abendroth (abendrothj)
Related issue: #3210
Related implementation PR: #9352
Target release: v1.19 (note: v1.18 feature freeze is near)

Summary

This proposal improves Velero's CLI/plugin UX by clearly indicating which plugins are built into the Velero server binary and by allowing velero plugin remove <plugin-name> semantics that map user-facing plugin names (e.g., velero.io/aws) to init-container images/names. The changes are intentionally limited to CLI/API metadata and removal UX; they do not change plugin discovery or plugin runtime registration.

The implementation work is in #9352 and this design PR is intended to let maintainers review the design independent of the implementation.

Motivation

  • Users see plugins via velero plugin get but cannot tell which plugins are built-in (and therefore cannot be removed).
  • velero plugin remove currently requires the init container name or image string; users expect to use plugin names shown in velero plugin get instead.
  • Provide clearer diagnostics and safer removal workflows.

Goals

  • Add plugin metadata indicating built-in status and registering command for diagnostics.
  • Display built-in status in CLI output.
  • Allow velero plugin remove <plugin-name> that resolves to an init container image/name and refuses removal of built-in plugins.
  • Preserve existing velero plugin remove <image|container> behavior for backwards compatibility.

Non-Goals

  • Changing plugin registration/discovery mechanisms.
  • Adding package/registry systems for plugins.
  • Major runtime or packaging redesign.

Proposed API changes

Modify the ServerStatusRequest API plugin information to carry additional optional fields:

File: pkg/apis/velero/v1/server_status_request_types.go

  • Add fields to PluginInfo:
type PluginInfo struct {
  Name    string `json:"name"`
  Kind    string `json:"kind"`
  // Command is the command/binary that registered the plugin on the server.
  // +optional
  Command string `json:"command,omitempty"`
  // BuiltIn indicates whether the plugin is provided by the Velero server
  // binary (i.e. a system plugin that cannot be removed by changing init containers).
  // +optional
  BuiltIn bool `json:"builtIn,omitempty"`
}

These fields are optional to preserve API compatibility with older clients.

Server-side behavior

File: internal/velero/serverstatusrequest.go

  • GetInstalledPluginInfo should set PluginInfo.Command (the registering process/binary) and PluginInfo.BuiltIn.
  • Heuristic for BuiltIn: plugin.Command == os.Args[0] OR another reliable indicator that the plugin was registered by the Velero server binary.

CLI output

File: pkg/cmd/util/output/plugin_printer.go

  • Add a "BuiltIn" column to the plugin table output. This gives operators a clear, at-a-glance indicator of mandatory built-in plugins vs external ones.

Plugin removal command

File: pkg/cmd/cli/plugin/remove.go

  • Accept plugin names (e.g., velero.io/aws) as input in addition to existing image/container names.

  • Workflow:

    1. Query server status (ServerStatusRequest) to check whether specified plugin name exists and whether it has BuiltIn==true. If built-in — refuse removal with a clear error message.
    2. If not built-in, resolve the plugin name to an init container via heuristics:
      • Exact init container name match.
      • Exact init container image match.
      • Sanitized plugin name match (e.g., convert velero.io/aws -> aws) to container name or image substring.
      • Substring match on init container image or name.
    3. If zero matches, error with a message listing the available init containers and their images.
    4. If multiple matches, error asking for disambiguation (or accept a --image/--container flag).
    5. If a single match, remove that init container as existing behavior does (patch the Velero Deployment).
  • Maintain backwards compatibility: velero plugin remove <image|container> remains valid.

Compatibility

  • API backward compatible: new PluginInfo fields are optional.
  • CLI backward compatible: existing usage of velero plugin remove <image|container> continues to work.
  • No changes required to existing Velero deployments.

Security considerations

  • Built-in protection prevents accidental removal of mandatory plugins that ship with the Velero server binary.
  • The ServerStatusRequest remains a read-only status resource; no elevated privileges are introduced by these read-only fields.
  • Removal still requires permissions to patch the Velero Deployment (existing requirement).

Tests

  • Unit tests: server-side population of PluginInfo fields; printer output; remove command heuristics and error cases.
  • Integration tests: velero plugin get shows BuiltIn flags; velero plugin remove <plugin-name> resolves correctly and patches Deployment; refusing removal for BuiltIn plugins.

Implementation references

Lyndon-Li and others added 8 commits October 19, 2025 02:20
Signed-off-by: Lyndon-Li <[email protected]>
Signed-off-by: Jake Abendroth <[email protected]>
Signed-off-by: Lyndon-Li <[email protected]>
Signed-off-by: Jake Abendroth <[email protected]>
- Introduced 'Command' and 'BuiltIn' fields in PluginInfo for better plugin management.
- Updated GetInstalledPluginInfo to mark built-in plugins.
- Enhanced remove command to prevent removal of built-in plugins.
- Modified plugin printer to display built-in status.

Signed-off-by: Jake Abendroth <[email protected]>
- Introduced tests for GetInstalledPluginInfo to validate built-in plugin detection.
- Added tests for plugin removal logic, ensuring built-in plugins cannot be removed.
- Implemented heuristic matching for plugin names in various scenarios.

Signed-off-by: Jake Abendroth <[email protected]>
- Add changelog for issue vmware-tanzu#3210 plugin management enhancements
- Update overview-plugins.md to document new plugin name removal syntax
- Add section explaining built-in vs external plugins
- Document new BuiltIn column in 'velero plugin get' output

Signed-off-by: Jake Abendroth <[email protected]>
…l plugins

- Changed the command paths for the AWS plugin to reflect its status as an external plugin.
- Updated test cases to ensure correct detection of built-in and external plugins.
- Revised documentation to clarify the distinction between built-in and external plugins, including examples.

Signed-off-by: Jake Abendroth <[email protected]>
…removal commands

- Adjusted the output of the 'velero plugin get' command to correctly indicate the built-in status of the AWS and pod plugins.
- Updated examples for the plugin removal command to demonstrate the inability to remove built-in plugins.

Signed-off-by: Jake Abendroth <[email protected]>
@kaovilai
Copy link
Collaborator

might want to rebase. design proposal shouldn't contain .go changes.

@kaovilai
Copy link
Collaborator

We can keep code changes in for now and once design is agreed and if implementation still need enhancement after that we can move implementation out to a follow up pr.

@Lyndon-Li Lyndon-Li requested review from blackpiglet and removed request for ywk253100 November 3, 2025 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants