-
Notifications
You must be signed in to change notification settings - Fork 141
Unified workload manager #2487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Unified workload manager #2487
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2487 +/- ##
==========================================
+ Coverage 55.36% 55.82% +0.45%
==========================================
Files 307 309 +2
Lines 29375 29580 +205
==========================================
+ Hits 16264 16512 +248
+ Misses 11669 11617 -52
- Partials 1442 1451 +9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
dmjb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking this as "request changes" until we figure out how to split up this interface.
|
|
||
| // Default to 8080 if no port is specified (matches GetProxyPort behavior) | ||
| // This is needed for HTTP-based transports (SSE, streamable-http) which require a target port | ||
| return 8080 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This particular change could go in a dedicated PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| k8sClient, err := client.New(cfg, client.Options{Scheme: scheme}) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to create Kubernetes client: %w", err) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we already have pkg/container/kubernetes/client.go. We should probably move that to a dedicated common package so we could reuse it around. Let me do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, here it is #2560
| // NewManager creates a new container manager instance. | ||
| // NewManager creates a new CLI workload manager. | ||
| // Returns Manager interface (existing behavior, unchanged). | ||
| // IMPORTANT: This function only works in CLI mode. For Kubernetes, use k8s.NewManagerFromContext() directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so this is kept here so you wouldn't need to make that many changes in the codebae from the CLI point of view. Right? Wouldn't this be an issue for the proxyrunner which assumes it'll be running on k8s, wouldn't we need to change that? It used to be the case that it would try to do the right thing depending on whether it was running on k8s or not. Why not keep that functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that’s correct. We can create a separate PR to update the references, I’d prefer not to include too many of those changes here since this PR has already grown quite large.
Also, it would make more sense to move the CLI manager into the cli package.
As for proxyrunner, the NewManagerFromRuntime function uses the Kubernetes runtime, and the status manager then checks the environment to determine whether it’s running on Kubernetes and picks the appropriate status manager accordingly.
Does that address your concern?
Summary
This PR implements separate workload management interfaces for CLI (Docker/Podman) and Kubernetes environments, following the same architectural pattern established by
groups.Manager. This enables platform-specific optimizations while maintaining consistent patterns across ToolHive's workload management system.Motivation
Following the successful unification of group management, we now extend this pattern to workload management with platform-specific interfaces. This enables:
k8s.Workload(withMCPServerPhase) while CLI workloads usecore.Workload(withWorkloadStatus)Implementation
Separate Manager Interfaces
CLI Manager (
workloads.Manager)core.Workloaddomain modelGetLogs,GetProxyLogs)Kubernetes Manager (
k8s.Manager)k8s.Workloaddomain model (withMCPServerPhase)kubectl logsdirectly)Platform-Specific Domain Models
core.Workload(CLI)runtime.WorkloadStatusenum (Running, Stopped, etc.)k8s.Workload(Kubernetes)mcpv1alpha1.MCPServerPhaseenum (Running, Pending, Failed, etc.)GroupRef)Separate Backend Discoverers
CLI Discoverer (
cliBackendDiscoverer)workloads.Managerinterfaceruntime.WorkloadStatusto vmcp health statusKubernetes Discoverer (
k8sBackendDiscoverer)k8s.Managerinterfacemcpv1alpha1.MCPServerPhaseto vmcp health statusFactory Functions
CLI Manager
Kubernetes Manager
Runtime Detection
workloads.NewManager()detects Kubernetes runtime and returns errork8s.NewManagerFromContext()for KubernetesKey Features
Group Integration
ListWorkloadsInGroupandMoveToGroupGroupReffieldgroups.ManagerUnified Backend Discovery
NewCLIBackendDiscovererfor CLI workloadsNewK8SBackendDiscovererfor Kubernetes workloadsBackendDiscovererinterfaceComprehensive Testing
cli_manager_test.goandk8s_test.goFiles Added
CLI Manager:
pkg/workloads/cli_manager.go- CLI implementationpkg/workloads/cli_manager_test.go- CLI tests (2214 lines)Kubernetes Manager:
pkg/workloads/k8s/manager.go- Kubernetes interface definitionpkg/workloads/k8s/k8s.go- Kubernetes implementationpkg/workloads/k8s/workload.go- Kubernetes domain modelpkg/workloads/k8s/k8s_test.go- Kubernetes tests (758 lines)pkg/workloads/k8s/mocks/mock_manager.go- Generated mocksDiscoverers:
pkg/vmcp/aggregator/cli_discoverer.go- CLI backend discovererpkg/vmcp/aggregator/k8s_discoverer.go- Kubernetes backend discovererpkg/vmcp/aggregator/cli_discoverer_test.go- CLI discoverer testspkg/vmcp/aggregator/k8s_discoverer_test.go- Kubernetes discoverer testsFiles Modified
pkg/workloads/manager.go- Factory functions for CLI manager (returns error in Kubernetes)pkg/workloads/manager_test.go- Factory function testscmd/vmcp/app/commands.go- Runtime-based discoverer selectionBenefits
Testing
Design Decisions
Why Separate Interfaces?
WorkloadStatus, Kubernetes usesMCPServerPhaseWhy No GetLogs/GetProxyLogs in K8s Manager?
kubectl logsdirectly, which is more flexibleRelated
groups.Manager(separate CLI and CRD managers)Example Usage
CLI Mode:
Kubernetes Mode:
vmcp Discovery (Automatic Selection):