fix(preview): fall back to route config when image has no domain label
The preview handler only resolved base route domains from gordon.domain image labels. Most images don't have this label — the route is configured in gordon.toml instead. Now the handler falls back to FindRoutesByImage from the config service, matching how the push CLI resolves domains.
- commit
- 74c9522086607ef96e67a3ad7d09cc9df49fd342
- author
- brice · · 2026-03-18 18:00 UTC
- committer
- brice · · 2026-03-18 22:55 UTC
- parent
- 83b82b4
- signature
- unsigned
3 files · +12 -2
M internal/usecase/auto/dispatcher.go +1 -0
| @@ -17,6 +17,7 @@ type AutoConfigProvider interface { | |||
| 17 | 17 | GetPreviewTagPatterns() []string | |
| 18 | 18 | GetPreviewConfig() domain.PreviewConfig | |
| 19 | 19 | GetAllowedDomains() []string | |
| 20 | + | FindRoutesByImage(ctx context.Context, imageName string) []domain.Route | |
| 20 | 21 | } | |
| 21 | 22 | ||
| 22 | 23 | // ImagePushDispatcher classifies image push events and delegates | |
| @@ -17,6 +17,7 @@ type AutoConfigProvider interface { | |||||
| 17 | GetPreviewTagPatterns() []string | 17 | GetPreviewTagPatterns() []string | ||
| 18 | GetPreviewConfig() domain.PreviewConfig | 18 | GetPreviewConfig() domain.PreviewConfig | ||
| 19 | GetAllowedDomains() []string | 19 | GetAllowedDomains() []string | ||
| 20 | + | FindRoutesByImage(ctx context.Context, imageName string) []domain.Route | |||
| 20 | } | 21 | } | ||
| 21 | 22 | ||||
| 22 | // ImagePushDispatcher classifies image push events and delegates | 23 | // ImagePushDispatcher classifies image push events and delegates | ||
M internal/usecase/auto/dispatcher_test.go +3 -0
| @@ -32,6 +32,9 @@ func (m *mockAutoConfig) IsPreviewEnabled() bool { return m.prev | |||
| 32 | 32 | func (m *mockAutoConfig) GetPreviewTagPatterns() []string { return m.tagPatterns } | |
| 33 | 33 | func (m *mockAutoConfig) GetPreviewConfig() domain.PreviewConfig { return domain.PreviewConfig{} } | |
| 34 | 34 | func (m *mockAutoConfig) GetAllowedDomains() []string { return nil } | |
| 35 | + | func (m *mockAutoConfig) FindRoutesByImage(_ context.Context, _ string) []domain.Route { | |
| 36 | + | return nil | |
| 37 | + | } | |
| 35 | 38 | ||
| 36 | 39 | func TestDispatcher_PreviewTag_DelegatesToPreview(t *testing.T) { | |
| 37 | 40 | route := &mockHandler{} | |
| @@ -32,6 +32,9 @@ func (m *mockAutoConfig) IsPreviewEnabled() bool { return m.prev | |||||
| 32 | func (m *mockAutoConfig) GetPreviewTagPatterns() []string { return m.tagPatterns } | 32 | func (m *mockAutoConfig) GetPreviewTagPatterns() []string { return m.tagPatterns } | ||
| 33 | func (m *mockAutoConfig) GetPreviewConfig() domain.PreviewConfig { return domain.PreviewConfig{} } | 33 | func (m *mockAutoConfig) GetPreviewConfig() domain.PreviewConfig { return domain.PreviewConfig{} } | ||
| 34 | func (m *mockAutoConfig) GetAllowedDomains() []string { return nil } | 34 | func (m *mockAutoConfig) GetAllowedDomains() []string { return nil } | ||
| 35 | + | func (m *mockAutoConfig) FindRoutesByImage(_ context.Context, _ string) []domain.Route { | |||
| 36 | + | return nil | |||
| 37 | + | } | |||
| 35 | 38 | ||||
| 36 | func TestDispatcher_PreviewTag_DelegatesToPreview(t *testing.T) { | 39 | func TestDispatcher_PreviewTag_DelegatesToPreview(t *testing.T) { | ||
| 37 | route := &mockHandler{} | 40 | route := &mockHandler{} | ||
M internal/usecase/auto/preview/handler.go +8 -2
| @@ -62,10 +62,16 @@ func (h *AutoPreviewHandler) Handle(ctx context.Context, event domain.Event) err | |||
| 62 | 62 | previewConfig := h.config.GetPreviewConfig() | |
| 63 | 63 | previewName := ExtractPreviewName(payload.Reference, previewConfig.TagPatterns) | |
| 64 | 64 | ||
| 65 | - | // Resolve base route from labels | |
| 65 | + | // Resolve base route: labels first, then route config fallback | |
| 66 | 66 | domains := collectDomains(labels) | |
| 67 | 67 | if len(domains) == 0 { | |
| 68 | - | log.Debug().Str("image", payload.Name).Msg("no gordon.domain label found, skipping preview handler") | |
| 68 | + | routes := h.config.FindRoutesByImage(ctx, payload.Name) | |
| 69 | + | for _, r := range routes { | |
| 70 | + | domains = append(domains, r.Domain) | |
| 71 | + | } | |
| 72 | + | } | |
| 73 | + | if len(domains) == 0 { | |
| 74 | + | log.Debug().Str("image", payload.Name).Msg("no domain found from labels or routes, skipping preview") | |
| 69 | 75 | return nil | |
| 70 | 76 | } | |
| 71 | 77 | baseRouteDomain := domains[0] | |
| @@ -62,10 +62,16 @@ func (h *AutoPreviewHandler) Handle(ctx context.Context, event domain.Event) err | |||||
| 62 | previewConfig := h.config.GetPreviewConfig() | 62 | previewConfig := h.config.GetPreviewConfig() | ||
| 63 | previewName := ExtractPreviewName(payload.Reference, previewConfig.TagPatterns) | 63 | previewName := ExtractPreviewName(payload.Reference, previewConfig.TagPatterns) | ||
| 64 | 64 | ||||
| 65 | - | // Resolve base route from labels | 65 | + | // Resolve base route: labels first, then route config fallback |
| 66 | domains := collectDomains(labels) | 66 | domains := collectDomains(labels) | ||
| 67 | if len(domains) == 0 { | 67 | if len(domains) == 0 { | ||
| 68 | - | log.Debug().Str("image", payload.Name).Msg("no gordon.domain label found, skipping preview handler") | 68 | + | routes := h.config.FindRoutesByImage(ctx, payload.Name) |
| 69 | + | for _, r := range routes { | |||
| 70 | + | domains = append(domains, r.Domain) | |||
| 71 | + | } | |||
| 72 | + | } | |||
| 73 | + | if len(domains) == 0 { | |||
| 74 | + | log.Debug().Str("image", payload.Name).Msg("no domain found from labels or routes, skipping preview") | |||
| 69 | return nil | 75 | return nil | ||
| 70 | } | 76 | } | ||
| 71 | baseRouteDomain := domains[0] | 77 | baseRouteDomain := domains[0] | ||