Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion internal/generate/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generate
import (
"context"
"fmt"
"maps"
"sort"
"strings"

Expand All @@ -11,6 +12,7 @@ import (
"github.com/goccy/go-yaml"

"github.com/open-source-cloud/devstack/internal/config"
"github.com/open-source-cloud/devstack/internal/proxy"
"github.com/open-source-cloud/devstack/internal/template"
)

Expand Down Expand Up @@ -92,7 +94,12 @@ func buildProjectService(res *graphResolver, m *config.Model, project, service s
}

out["networks"] = map[string]any{"default": nil, SharedNetwork: nil}
out["labels"] = b.labels(map[string]string{LabelProject: project, LabelService: service})
svcLabels := map[string]string{LabelProject: project, LabelService: service}
// spec 05 — when a reverse proxy is configured, emit the caddy-docker-proxy
// route labels onto the service so adding/removing it reloads Caddy with no
// central-config edit. No-op (nil) when the proxy is disabled.
maps.Copy(svcLabels, proxy.LabelsForService(m, project, service))
out["labels"] = b.labels(svcLabels)

if exp := exposeList(svc.Ports); len(exp) > 0 {
out["expose"] = exp
Expand Down
35 changes: 35 additions & 0 deletions internal/generate/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,38 @@ services:
t.Errorf("compose should reference the cache dependency:\n%s", compose)
}
}

// TestProxyLabelsEmitted verifies the caddy-docker-proxy labels are merged onto
// a routed service when the workspace declares a proxy (spec 05 / N5).
func TestProxyLabelsEmitted(t *testing.T) {
root := t.TempDir()
write := func(rel, body string) {
p := filepath.Join(root, rel)
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(p, []byte(body), 0o644); err != nil {
t.Fatal(err)
}
}
write("workspace.yaml", "apiVersion: devstack/v1\nkind: Workspace\nname: shop\nnetwork: { proxy: { engine: caddy, httpsLocal: true } }\nprojects:\n - { name: api, path: api }\n")
write("api/devstack.yaml", "apiVersion: devstack/v1\nkind: Project\nname: api\nservices:\n web: { template: node.vite, ports: { http: 8080 } }\n")
m, err := config.LoadAt(root)
if err != nil {
t.Fatalf("load: %v", err)
}
g, err := New(m, template.NewFSSource(templates.FS), WithEnv(map[string]string{}))
if err != nil {
t.Fatalf("New: %v", err)
}
st, err := g.GenerateProject("api")
if err != nil {
t.Fatalf("GenerateProject: %v", err)
}
compose := string(st.Compose)
for _, want := range []string{"caddy: web.api.localhost", "caddy.reverse_proxy", "caddy.tls: internal"} {
if !strings.Contains(compose, want) {
t.Errorf("compose missing proxy label %q:\n%s", want, compose)
}
}
}
22 changes: 22 additions & 0 deletions internal/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,28 @@ func HostFor(service, project string) string {
return service + "." + project + "." + LocalDomain
}

// LabelsForService returns the Caddy labels a generated project service should
// carry when the proxy is enabled and the service exposes a port; nil otherwise.
// This is the single seam generate uses to emit routing (no central config).
func LabelsForService(m *config.Model, project, service string) map[string]string {
if !Enabled(m) {
return nil
}
p, ok := m.Projects[project]
if !ok {
return nil
}
port := primaryPort(p.Services[service].Ports)
if port == 0 {
return nil
}
return CaddyLabels(Route{
Project: project, Service: service,
Host: HostFor(service, project), Port: port,
TLS: m.Workspace.Network.Proxy.HTTPSLocal,
})
}

// CaddyLabels renders the caddy-docker-proxy labels for a route. These are merged
// onto the project service in the generated compose so caddy reloads on the
// Docker event with no central-config edit (spec 05).
Expand Down
Loading