Add route declarations and automatic port allocation to MCP agent
Service definitions can now declare routes per component instead of manual port mappings: [[components.routes]] name = "rest" port = 8443 mode = "l4" The agent allocates free host ports at deploy time and injects $PORT/$PORT_<NAME> env vars into containers. Backward compatible: components with old-style ports= work unchanged. Changes: - Proto: RouteSpec message, routes + env fields on ComponentSpec - Servicedef: RouteDef parsing and validation from TOML - Registry: component_routes table with host_port tracking - Runtime: Env field on ContainerSpec, -e flag in BuildRunArgs - Agent: PortAllocator (random 10000-60000, availability check), deploy wiring for route→port mapping and env injection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,9 @@ func (p *Podman) BuildRunArgs(spec ContainerSpec) []string {
|
||||
for _, vol := range spec.Volumes {
|
||||
args = append(args, "-v", vol)
|
||||
}
|
||||
for _, env := range spec.Env {
|
||||
args = append(args, "-e", env)
|
||||
}
|
||||
|
||||
args = append(args, spec.Image)
|
||||
args = append(args, spec.Cmd...)
|
||||
|
||||
@@ -16,6 +16,7 @@ type ContainerSpec struct {
|
||||
Ports []string // "host:container" port mappings
|
||||
Volumes []string // "host:container" volume mounts
|
||||
Cmd []string // command and arguments
|
||||
Env []string // environment variables (KEY=VALUE)
|
||||
}
|
||||
|
||||
// ContainerInfo describes the observed state of a running or stopped container.
|
||||
|
||||
@@ -76,6 +76,38 @@ func TestBuildRunArgs(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("env vars", func(t *testing.T) {
|
||||
spec := ContainerSpec{
|
||||
Name: "test-app",
|
||||
Image: "img:latest",
|
||||
Env: []string{"PORT=12345", "PORT_GRPC=12346"},
|
||||
}
|
||||
requireEqualArgs(t, p.BuildRunArgs(spec), []string{
|
||||
"run", "-d", "--name", "test-app",
|
||||
"-e", "PORT=12345", "-e", "PORT_GRPC=12346",
|
||||
"img:latest",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("full spec with env", func(t *testing.T) {
|
||||
spec := ContainerSpec{
|
||||
Name: "svc-api",
|
||||
Image: "img:latest",
|
||||
Network: "net",
|
||||
Ports: []string{"127.0.0.1:12345:8443"},
|
||||
Volumes: []string{"/srv:/srv"},
|
||||
Env: []string{"PORT=12345"},
|
||||
}
|
||||
requireEqualArgs(t, p.BuildRunArgs(spec), []string{
|
||||
"run", "-d", "--name", "svc-api",
|
||||
"--network", "net",
|
||||
"-p", "127.0.0.1:12345:8443",
|
||||
"-v", "/srv:/srv",
|
||||
"-e", "PORT=12345",
|
||||
"img:latest",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("cmd after image", func(t *testing.T) {
|
||||
spec := ContainerSpec{
|
||||
Name: "test-app",
|
||||
|
||||
Reference in New Issue
Block a user