diff --git a/src/pkg/cli/compose/fixup.go b/src/pkg/cli/compose/fixup.go index 84291a029..8e4e639c7 100644 --- a/src/pkg/cli/compose/fixup.go +++ b/src/pkg/cli/compose/fixup.go @@ -241,6 +241,14 @@ func fixupPostgresService(svccfg *composeTypes.ServiceConfig, provider client.Pr } term.Debugf("service %q: adding postgres host port %d", svccfg.Name, port) svccfg.Ports = []composeTypes.ServicePortConfig{{Target: port, Mode: Mode_HOST, Protocol: Protocol_TCP}} + } else { + for i, port := range svccfg.Ports { + if port.Mode == Mode_INGRESS || port.Mode == "" { + svccfg.Ports[i].Mode = Mode_HOST + svccfg.Ports[i].Published = "" // ignore published port in host mode + svccfg.Ports[i].AppProtocol = "" // ignore app protocol in host mode + } + } } return nil } @@ -303,6 +311,14 @@ func fixupRedisService(svccfg *composeTypes.ServiceConfig, provider client.Provi } term.Debugf("service %q: adding redis host port %d", svccfg.Name, port) svccfg.Ports = []composeTypes.ServicePortConfig{{Target: port, Mode: Mode_HOST, Protocol: Protocol_TCP}} + } else { + for i, port := range svccfg.Ports { + if port.Mode == Mode_INGRESS || port.Mode == "" { + svccfg.Ports[i].Mode = Mode_HOST + svccfg.Ports[i].Published = "" // ignore published port in host mode + svccfg.Ports[i].AppProtocol = "" // ignore app protocol in host mode + } + } } return nil } diff --git a/src/pkg/cli/compose/validation_test.go b/src/pkg/cli/compose/validation_test.go index 929e50b94..413e75a58 100644 --- a/src/pkg/cli/compose/validation_test.go +++ b/src/pkg/cli/compose/validation_test.go @@ -46,6 +46,11 @@ func TestValidationAndConvert(t *testing.T) { t.Fatal(err) } + if err := FixupServices(context.Background(), mockClient, project, UploadModeIgnore); err != nil { + t.Logf("Service conversion failed: %v", err) + logs.WriteString(err.Error() + "\n") + } + if err := ValidateProjectConfig(context.Background(), project, listConfigNamesFunc); err != nil { t.Logf("Project config validation failed: %v", err) logs.WriteString(err.Error() + "\n") @@ -56,11 +61,6 @@ func TestValidationAndConvert(t *testing.T) { logs.WriteString(err.Error() + "\n") } - if err := FixupServices(context.Background(), mockClient, project, UploadModeIgnore); err != nil { - t.Logf("Service conversion failed: %v", err) - logs.WriteString(err.Error() + "\n") - } - // The order of the services is not guaranteed, so we sort the logs before comparing logLines := strings.SplitAfter(logs.String(), "\n") slices.Sort(logLines) diff --git a/src/pkg/cli/composeUp.go b/src/pkg/cli/composeUp.go index 48a3d4cca..7060b258f 100644 --- a/src/pkg/cli/composeUp.go +++ b/src/pkg/cli/composeUp.go @@ -47,10 +47,6 @@ func ComposeUp(ctx context.Context, project *compose.Project, fabric client.Fabr } } - if err := compose.ValidateProject(project); err != nil { - return nil, project, &ComposeError{err} - } - // Create a new project with only the necessary resources. // Do not modify the original project, because the caller needs it for debugging. fixedProject := project.WithoutUnnecessaryResources() @@ -59,6 +55,10 @@ func ComposeUp(ctx context.Context, project *compose.Project, fabric client.Fabr return nil, project, err } + if err := compose.ValidateProject(project); err != nil { + return nil, project, &ComposeError{err} + } + bytes, err := fixedProject.MarshalYAML() if err != nil { return nil, project, err diff --git a/src/testdata/models/compose.yaml.warnings b/src/testdata/models/compose.yaml.warnings index a782b8fa4..8e624a3c4 100644 --- a/src/testdata/models/compose.yaml.warnings +++ b/src/testdata/models/compose.yaml.warnings @@ -1,2 +1,4 @@ + ! service "ai_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "my_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "withendpoint": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/ports/compose.yaml.warnings b/src/testdata/ports/compose.yaml.warnings index 8b30e60f7..679d6aa54 100644 --- a/src/testdata/ports/compose.yaml.warnings +++ b/src/testdata/ports/compose.yaml.warnings @@ -13,7 +13,5 @@ ! service "short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "short-published": ingress port without healthcheck defaults to GET / HTTP/1.1 ! service "short-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "short-udp": ingress port without healthcheck defaults to GET / HTTP/1.1 ! service "short-udp": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "short-udp-published": ingress port without healthcheck defaults to GET / HTTP/1.1 ! service "short-udp-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/postgres/compose.yaml b/src/testdata/postgres/compose.yaml index 7e1f277b4..f6d700614 100644 --- a/src/testdata/postgres/compose.yaml +++ b/src/testdata/postgres/compose.yaml @@ -14,6 +14,12 @@ services: - target: 5432 mode: host + short-ports: + image: postgres + x-defang-postgres: + ports: + - 5432:5432 + no-ext: image: postgres ports: @@ -29,3 +35,4 @@ services: x-defang-postgres: environment: - PGPORT=5433 + diff --git a/src/testdata/postgres/compose.yaml.fixup b/src/testdata/postgres/compose.yaml.fixup index 09db6a768..fafe954e2 100644 --- a/src/testdata/postgres/compose.yaml.fixup +++ b/src/testdata/postgres/compose.yaml.fixup @@ -47,6 +47,21 @@ } ] }, + "short-ports": { + "command": null, + "entrypoint": null, + "image": "postgres", + "networks": { + "default": null + }, + "ports": [ + { + "mode": "host", + "target": 5432, + "protocol": "tcp" + } + ] + }, "with-ext": { "command": null, "entrypoint": null, diff --git a/src/testdata/postgres/compose.yaml.golden b/src/testdata/postgres/compose.yaml.golden index ea3fc363e..0aedfc0ef 100644 --- a/src/testdata/postgres/compose.yaml.golden +++ b/src/testdata/postgres/compose.yaml.golden @@ -20,6 +20,16 @@ services: networks: default: null x-defang-postgres: null + short-ports: + image: postgres + networks: + default: null + ports: + - mode: ingress + target: 5432 + published: "5432" + protocol: tcp + x-defang-postgres: null with-ext: image: postgres networks: diff --git a/src/testdata/postgres/compose.yaml.warnings b/src/testdata/postgres/compose.yaml.warnings index 1add04c8d..9d2228cac 100644 --- a/src/testdata/postgres/compose.yaml.warnings +++ b/src/testdata/postgres/compose.yaml.warnings @@ -2,6 +2,7 @@ ! service "no-ext": stateful service will lose data on restart; use a managed service instead ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "wrong-image": managed Postgres service should use a postgres image ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/redis/compose.yaml b/src/testdata/redis/compose.yaml index 89a86a189..251d67730 100644 --- a/src/testdata/redis/compose.yaml +++ b/src/testdata/redis/compose.yaml @@ -13,6 +13,12 @@ services: - target: 6379 mode: host + short-ports: + image: redis + x-defang-redis: + ports: + - 6379:6379 + no-ext: image: redis ports: diff --git a/src/testdata/redis/compose.yaml.fixup b/src/testdata/redis/compose.yaml.fixup index b16d5c3f8..c962800cf 100644 --- a/src/testdata/redis/compose.yaml.fixup +++ b/src/testdata/redis/compose.yaml.fixup @@ -47,6 +47,21 @@ } ] }, + "short-ports": { + "command": null, + "entrypoint": null, + "image": "redis", + "networks": { + "default": null + }, + "ports": [ + { + "mode": "host", + "target": 6379, + "protocol": "tcp" + } + ] + }, "with-ext": { "command": null, "entrypoint": null, diff --git a/src/testdata/redis/compose.yaml.golden b/src/testdata/redis/compose.yaml.golden index fe7d0914a..c264924d2 100644 --- a/src/testdata/redis/compose.yaml.golden +++ b/src/testdata/redis/compose.yaml.golden @@ -21,6 +21,16 @@ services: networks: default: null x-defang-redis: null + short-ports: + image: redis + networks: + default: null + ports: + - mode: ingress + target: 6379 + published: "6379" + protocol: tcp + x-defang-redis: null with-ext: image: redis networks: diff --git a/src/testdata/redis/compose.yaml.warnings b/src/testdata/redis/compose.yaml.warnings index 86d1f02b4..9b4797685 100644 --- a/src/testdata/redis/compose.yaml.warnings +++ b/src/testdata/redis/compose.yaml.warnings @@ -2,6 +2,7 @@ ! service "no-ext": stateful service will lose data on restart; use a managed service instead ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "wrong-image": managed Redis service should use a redis image ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors