From 387f1db769dc897dff0871dcfb93f4d850026206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Titsworth-Morin?= Date: Fri, 22 May 2026 10:31:35 +0000 Subject: [PATCH 1/3] feat(compose): add 'compose lint' command with enriched error messages --- src/cmd/cli/command/compose.go | 48 +++++++++++++++++++ src/cmd/cli/command/compose_test.go | 46 ++++++++++++++++++ .../testdata/lint-invalid/compose.yaml | 4 ++ src/pkg/cli/compose/fixup.go | 2 +- src/pkg/cli/compose/validation.go | 16 +++---- .../ambiguous-strings/compose.yaml.warnings | 4 +- src/testdata/base-image/compose.yaml.warnings | 6 +-- .../build-image/compose.yaml.warnings | 2 +- src/testdata/build/compose.yaml.warnings | 6 +-- .../bun-in-compose/compose.yaml.warnings | 4 +- .../bun-in-dockerfile/compose.yaml.warnings | 4 +- .../compose-go-warn/compose.yaml.warnings | 4 +- .../configdetection/compose.yaml.warnings | 2 +- .../configoverride/compose.yaml.warnings | 2 +- src/testdata/debugproj/compose.yaml.warnings | 4 +- src/testdata/dependson/compose.yaml.warnings | 6 +-- .../compose.yaml.warnings | 4 +- src/testdata/emptyenv/compose.yaml.warnings | 2 +- src/testdata/extends/compose.yaml.warnings | 16 +++---- src/testdata/fixupenv/compose.yaml.warnings | 18 +++---- src/testdata/gpu/compose.yaml.warnings | 2 +- .../healthcheck/compose.yaml.warnings | 12 ++--- src/testdata/heroku/compose.yaml.warnings | 10 ++-- .../interpolate/compose.yaml.warnings | 2 +- src/testdata/llm/compose.yaml.warnings | 10 ++-- src/testdata/longname/compose.yaml.warnings | 2 +- src/testdata/models/compose.yaml.warnings | 10 ++-- src/testdata/mongo/compose.yaml.warnings | 34 ++++++------- src/testdata/networks/compose.yaml.warnings | 14 +++--- src/testdata/platforms/compose.yaml.warnings | 2 +- src/testdata/ports/compose.yaml.warnings | 24 +++++----- src/testdata/postgres/compose.yaml.warnings | 14 +++--- src/testdata/profiles/compose.yaml.warnings | 4 +- src/testdata/provider/compose.yaml.warnings | 4 +- src/testdata/railpack/compose.yaml.warnings | 6 +-- src/testdata/redis/compose.yaml.warnings | 16 +++---- src/testdata/replicas/compose.yaml.warnings | 8 ++-- src/testdata/sanity/compose.yaml.warnings | 2 +- src/testdata/secretname/compose.yaml.warnings | 2 +- src/testdata/toomany/compose.yaml.warnings | 2 +- .../toomany/docker-compose.yml.warnings | 2 +- 41 files changed, 240 insertions(+), 142 deletions(-) create mode 100644 src/cmd/cli/command/testdata/lint-invalid/compose.yaml diff --git a/src/cmd/cli/command/compose.go b/src/cmd/cli/command/compose.go index 53d7167de..e963e494d 100644 --- a/src/cmd/cli/command/compose.go +++ b/src/cmd/cli/command/compose.go @@ -553,6 +553,53 @@ func makeComposeConfigCmd() *cobra.Command { } } +func makeComposeLintCmd() *cobra.Command { + return &cobra.Command{ + Use: "lint", + Args: cobra.NoArgs, + Short: "Validate a Compose file without deploying", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + sessionx, err := newCommandSessionWithOpts(cmd, commandSessionOpts{ + CheckAccountInfo: false, + }) + if err != nil { + term.Warn("unable to load stack:", err, "- using offline validation") + sessionx = &session.Session{ + Loader: newLoaderForCommand(cmd), + Provider: client.NewPlaygroundProvider(global.Client, stacks.DefaultBeta), + Stack: &stacks.Parameters{Name: stacks.DefaultBeta, Provider: client.ProviderDefang}, + } + } + + project, loadErr := sessionx.Loader.LoadProject(ctx) + if loadErr != nil { + return handleInvalidComposeFileErr(ctx, loadErr) + } + + if err := compose.ValidateServiceDockerfiles(project); err != nil { + return fmt.Errorf("compose file has errors:\n%w", err) + } + + if err := compose.FixupServices(ctx, sessionx.Provider, project, compose.UploadModeIgnore); err != nil { + return fmt.Errorf("compose file has errors:\n%w", err) + } + + if err := compose.ValidateProject(project, modes.ModeUnspecified); err != nil { + return fmt.Errorf("compose file has errors:\n%w", err) + } + + if term.HadWarnings() { + term.Info("Compose file is valid with warnings") + } else { + term.Info("Compose file is valid") + } + return nil + }, + } +} + func makeComposePsCmd() *cobra.Command { getServicesCmd := &cobra.Command{ Use: "ps", @@ -763,6 +810,7 @@ services: composeCmd.PersistentFlags().StringVar(&byoc.DefangPulumiBackend, "pulumi-backend", "", `specify an alternate Pulumi backend URL or "pulumi-cloud"`) composeCmd.AddCommand(makeComposeUpCmd()) composeCmd.AddCommand(makeComposeConfigCmd()) + composeCmd.AddCommand(makeComposeLintCmd()) composeCmd.AddCommand(makeComposeDownCmd()) composeCmd.AddCommand(makeComposePsCmd()) composeCmd.AddCommand(makeLogsCmd()) diff --git a/src/cmd/cli/command/compose_test.go b/src/cmd/cli/command/compose_test.go index ccd324664..3d74f2540 100644 --- a/src/cmd/cli/command/compose_test.go +++ b/src/cmd/cli/command/compose_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "os" + "strings" "testing" "connectrpc.com/connect" @@ -79,3 +80,48 @@ func TestComposeConfig(t *testing.T) { } }) } + +func TestComposeLint(t *testing.T) { + global.Client = unauthedMockFabricClient{} + t.Cleanup(func() { + global.Client = nil + }) + + defaultTerm := term.DefaultTerm + t.Cleanup(func() { + term.DefaultTerm = defaultTerm + }) + + t.Run("Valid", func(t *testing.T) { + t.Chdir("testdata/without-stack") + var stdout, stderr bytes.Buffer + term.DefaultTerm = term.NewTerm(os.Stdin, &stdout, &stderr) + + cmd := makeComposeLintCmd() + err := cmd.Execute() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if !strings.Contains(stdout.String(), "Compose file is valid") { + t.Fatalf("expected valid lint output, got stdout %q stderr %q", stdout.String(), stderr.String()) + } + }) + + t.Run("Invalid", func(t *testing.T) { + t.Chdir("testdata/lint-invalid") + var stdout, stderr bytes.Buffer + term.DefaultTerm = term.NewTerm(os.Stdin, &stdout, &stderr) + + cmd := makeComposeLintCmd() + err := cmd.Execute() + if err == nil { + t.Fatal("expected lint error") + } + if !strings.Contains(err.Error(), "compose file has errors:") { + t.Fatalf("expected error heading, got error %q stdout %q stderr %q", err.Error(), stdout.String(), stderr.String()) + } + if !strings.Contains(err.Error(), "unsupported compose directive: hostname; use 'domainname' instead") { + t.Fatalf("expected remediation hint, got error %q", err.Error()) + } + }) +} diff --git a/src/cmd/cli/command/testdata/lint-invalid/compose.yaml b/src/cmd/cli/command/testdata/lint-invalid/compose.yaml new file mode 100644 index 000000000..82ca2ad72 --- /dev/null +++ b/src/cmd/cli/command/testdata/lint-invalid/compose.yaml @@ -0,0 +1,4 @@ +services: + web: + image: nginx:latest + hostname: web diff --git a/src/pkg/cli/compose/fixup.go b/src/pkg/cli/compose/fixup.go index ee667de68..6d6880789 100644 --- a/src/pkg/cli/compose/fixup.go +++ b/src/pkg/cli/compose/fixup.go @@ -550,7 +550,7 @@ func GetImageRepo(image string) string { func fixupPort(port composeTypes.ServicePortConfig) composeTypes.ServicePortConfig { switch port.Mode { case "": - term.Warnf("port %d: no 'mode' was specified; defaulting to 'ingress' (add 'mode: ingress' to silence)", port.Target) + term.Warnf("port %d: no 'mode' was specified; defaulting to 'ingress'; add 'mode: ingress' for public or 'mode: host' for internal", port.Target) fallthrough case Mode_INGRESS: // This code is unnecessarily complex because compose-go silently converts short `ports:` syntax to ingress+tcp diff --git a/src/pkg/cli/compose/validation.go b/src/pkg/cli/compose/validation.go index b8f4e35ce..dff29f61e 100644 --- a/src/pkg/cli/compose/validation.go +++ b/src/pkg/cli/compose/validation.go @@ -71,7 +71,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P term.Debugf("service %q: unsupported compose directive: container_name", svccfg.Name) } if svccfg.Hostname != "" { - return fmt.Errorf("service %q: unsupported compose directive: hostname; consider using 'domainname' instead", svccfg.Name) + return fmt.Errorf("service %q: unsupported compose directive: hostname; use 'domainname' instead", svccfg.Name) } if len(svccfg.DNSSearch) != 0 { return fmt.Errorf("service %q: unsupported compose directive: dns_search", svccfg.Name) @@ -89,7 +89,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P return fmt.Errorf("service %q: unsupported compose directive: device_cgroup_rules", svccfg.Name) } if len(svccfg.Entrypoint) > 0 { - return fmt.Errorf("service %q: unsupported compose directive: entrypoint", svccfg.Name) + return fmt.Errorf("service %q: unsupported compose directive: entrypoint; move logic to Dockerfile ENTRYPOINT or use 'command'", svccfg.Name) } if len(svccfg.GroupAdd) > 0 { return fmt.Errorf("service %q: unsupported compose directive: group_add", svccfg.Name) @@ -122,7 +122,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P } } if len(svccfg.Volumes) > 0 { - term.Warnf("service %q: unsupported compose directive: volumes", svccfg.Name) // TODO: add support for volumes + term.Warnf("service %q: unsupported compose directive: volumes; for databases, consider x-defang-postgres/redis/mongodb for managed storage", svccfg.Name) // TODO: add support for volumes } if len(svccfg.VolumesFrom) > 0 { term.Warnf("service %q: unsupported compose directive: volumes_from", svccfg.Name) // TODO: add support for volumes_from @@ -177,7 +177,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P return fmt.Errorf("service %q: unsupported compose directive: build privileged", svccfg.Name) } if svccfg.Build.DockerfileInline != "" { - return fmt.Errorf("service %q: unsupported compose directive: build dockerfile_inline", svccfg.Name) + return fmt.Errorf("service %q: unsupported compose directive: build dockerfile_inline; move inline content to a Dockerfile", svccfg.Name) } if svccfg.Build.AdditionalContexts != nil { return fmt.Errorf("service %q: unsupported compose directive: build additional_contexts", svccfg.Name) @@ -226,7 +226,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P // Show a warning when we have ingress ports but no explicit healthcheck for _, port := range svccfg.Ports { if port.Mode == Mode_INGRESS { - term.Warnf("service %q: ingress port %d without healthcheck; defaults to GET / HTTP/1.1", svccfg.Name, port.Target) + term.Warnf("service %q: ingress port %d without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:%d/\"]", svccfg.Name, port.Target, port.Target) break } } @@ -269,7 +269,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P return fmt.Errorf("service %q: unsupported compose directive: deploy rollback_config", svccfg.Name) } if svccfg.Deploy.RestartPolicy != nil { - return fmt.Errorf("service %q: unsupported compose directive: deploy restart_policy", svccfg.Name) + return fmt.Errorf("service %q: unsupported compose directive: deploy restart_policy; use service-level 'restart' field instead", svccfg.Name) } if svccfg.Deploy.EndpointMode != "" { return fmt.Errorf("service %q: unsupported compose directive: deploy endpoint_mode", svccfg.Name) @@ -297,7 +297,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P if reservations == nil || reservations.MemoryBytes == 0 { // Don't show this warning for managed pseudo-services like CDN if svccfg.Extensions["x-defang-static-files"] == nil { - term.Warnf("service %q: missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors", svccfg.Name) + term.Warnf("service %q: missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M", svccfg.Name) } } @@ -351,7 +351,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P } if !managedRedis && !managedPostgres && !managedMongodb && isStatefulImage(svccfg.Image) { - term.Warnf("service %q: stateful service will lose data on restart; use a managed service instead", svccfg.Name) + term.Warnf("service %q: stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true", svccfg.Name) } for k := range svccfg.Extensions { diff --git a/src/testdata/ambiguous-strings/compose.yaml.warnings b/src/testdata/ambiguous-strings/compose.yaml.warnings index b5c8d7028..2d0444912 100644 --- a/src/testdata/ambiguous-strings/compose.yaml.warnings +++ b/src/testdata/ambiguous-strings/compose.yaml.warnings @@ -1,3 +1,3 @@ ! project name "ambiguous-strings" is longer than 16 characters, you may run into issues with resource name length - ! service "a": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "b": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "a": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "b": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/base-image/compose.yaml.warnings b/src/testdata/base-image/compose.yaml.warnings index 462f4b19e..6f708edcf 100644 --- a/src/testdata/base-image/compose.yaml.warnings +++ b/src/testdata/base-image/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "mutiple-images": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "no-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "one-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mutiple-images": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "one-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/build-image/compose.yaml.warnings b/src/testdata/build-image/compose.yaml.warnings index 31b49007b..b25ed33c3 100644 --- a/src/testdata/build-image/compose.yaml.warnings +++ b/src/testdata/build-image/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "app": 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; suggest deploy.resources.reservations.memory: 512M ! service "app": using published image instead of rebuilding; pass --build to build and publish a new image diff --git a/src/testdata/build/compose.yaml.warnings b/src/testdata/build/compose.yaml.warnings index c1edb4dfb..ea6854289 100644 --- a/src/testdata/build/compose.yaml.warnings +++ b/src/testdata/build/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "build1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "build2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "normalized": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "build1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "build2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "normalized": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/bun-in-compose/compose.yaml.warnings b/src/testdata/bun-in-compose/compose.yaml.warnings index fa20f93f0..85bc3e902 100644 --- a/src/testdata/bun-in-compose/compose.yaml.warnings +++ b/src/testdata/bun-in-compose/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/bun-in-dockerfile/compose.yaml.warnings b/src/testdata/bun-in-dockerfile/compose.yaml.warnings index fa20f93f0..85bc3e902 100644 --- a/src/testdata/bun-in-dockerfile/compose.yaml.warnings +++ b/src/testdata/bun-in-dockerfile/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/compose-go-warn/compose.yaml.warnings b/src/testdata/compose-go-warn/compose.yaml.warnings index eadbc08fd..076e92bf7 100644 --- a/src/testdata/compose-go-warn/compose.yaml.warnings +++ b/src/testdata/compose-go-warn/compose.yaml.warnings @@ -1,4 +1,4 @@ ! "yes" for boolean is not supported by YAML 1.2, please use `true` ! project name "compose-go-warning" is longer than 16 characters, you may run into issues with resource name length - ! service "echo": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 - ! service "echo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "echo": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] + ! service "echo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/configdetection/compose.yaml.warnings b/src/testdata/configdetection/compose.yaml.warnings index b34af22b6..24e8bbb77 100644 --- a/src/testdata/configdetection/compose.yaml.warnings +++ b/src/testdata/configdetection/compose.yaml.warnings @@ -3,4 +3,4 @@ ! service "configdetection": environment "GH_PAT" may contain sensitive information; consider using 'defang config set GH_PAT' to securely store this value ! service "configdetection": environment "HIGH_ENTROPY_STRING" may contain sensitive information; consider using 'defang config set HIGH_ENTROPY_STRING' to securely store this value ! service "configdetection": environment "MY_URL" may contain sensitive information; consider using 'defang config set MY_URL' to securely store this value - ! service "configdetection": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "configdetection": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/configoverride/compose.yaml.warnings b/src/testdata/configoverride/compose.yaml.warnings index 16597ca8e..0842eddaa 100644 --- a/src/testdata/configoverride/compose.yaml.warnings +++ b/src/testdata/configoverride/compose.yaml.warnings @@ -1,2 +1,2 @@ ! service "service1": environment variable(s) ["VAR1"] overridden by config - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/debugproj/compose.yaml.warnings b/src/testdata/debugproj/compose.yaml.warnings index d6ec97128..676d878b3 100644 --- a/src/testdata/debugproj/compose.yaml.warnings +++ b/src/testdata/debugproj/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "failing": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "ok": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "failing": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "ok": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/dependson/compose.yaml.warnings b/src/testdata/dependson/compose.yaml.warnings index 8e40937c4..8750db6c8 100644 --- a/src/testdata/dependson/compose.yaml.warnings +++ b/src/testdata/dependson/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service3": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service3": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/dockerfile-validation-errors/compose.yaml.warnings b/src/testdata/dockerfile-validation-errors/compose.yaml.warnings index fc05bf453..e40f2bcf7 100644 --- a/src/testdata/dockerfile-validation-errors/compose.yaml.warnings +++ b/src/testdata/dockerfile-validation-errors/compose.yaml.warnings @@ -1,4 +1,4 @@ ! project name "dockerfile-validation-errors" is longer than 16 characters, you may run into issues with resource name length - ! service "invalid-dockerfile": ingress port 8080 without healthcheck; defaults to GET / HTTP/1.1 - ! service "invalid-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "invalid-dockerfile": ingress port 8080 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:8080/"] + ! service "invalid-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "invalid-dockerfile": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/emptyenv/compose.yaml.warnings b/src/testdata/emptyenv/compose.yaml.warnings index 471b371f0..8f91ab660 100644 --- a/src/testdata/emptyenv/compose.yaml.warnings +++ b/src/testdata/emptyenv/compose.yaml.warnings @@ -1 +1 @@ - ! service "emptyenv": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "emptyenv": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/extends/compose.yaml.warnings b/src/testdata/extends/compose.yaml.warnings index 49caffe11..d77c6d3ff 100644 --- a/src/testdata/extends/compose.yaml.warnings +++ b/src/testdata/extends/compose.yaml.warnings @@ -1,9 +1,9 @@ - ! service "array-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "array-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "array-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "array-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "map-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "map-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "map-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "map-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "array-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "array-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "array-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "array-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "map-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "map-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "map-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "map-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M Error: missing configs ["EMPTY_VALUE" "NEW_VALUE" "NO_VALUE" "WITH_VALUE"] (https://s.defang.io/config) diff --git a/src/testdata/fixupenv/compose.yaml.warnings b/src/testdata/fixupenv/compose.yaml.warnings index fdc14b599..36fa24e1b 100644 --- a/src/testdata/fixupenv/compose.yaml.warnings +++ b/src/testdata/fixupenv/compose.yaml.warnings @@ -1,11 +1,11 @@ - ! service "Mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "fixup-args": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "ingress-service": ingress port 5432 without healthcheck; defaults to GET / HTTP/1.1 - ! service "ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "refer-self-build-arg": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "Mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "fixup-args": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "ingress-service": ingress port 5432 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5432/"] + ! service "ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "refer-self-build-arg": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "refer-self-build-arg": service name is longer than 16 characters, you may run into issues with resource name length - ! service "refer-self-env": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1 - ! service "refer-self-env": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "ui": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "use-ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "refer-self-env": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5678/"] + ! service "refer-self-env": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "ui": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "use-ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "use-ingress-service": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/gpu/compose.yaml.warnings b/src/testdata/gpu/compose.yaml.warnings index 2a9093506..30d69debd 100644 --- a/src/testdata/gpu/compose.yaml.warnings +++ b/src/testdata/gpu/compose.yaml.warnings @@ -1 +1 @@ - ! service "mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/healthcheck/compose.yaml.warnings b/src/testdata/healthcheck/compose.yaml.warnings index b3891096b..1156cb582 100644 --- a/src/testdata/healthcheck/compose.yaml.warnings +++ b/src/testdata/healthcheck/compose.yaml.warnings @@ -1,6 +1,6 @@ - ! service "cmd-shell": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "curl": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "flask1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "flask2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "none": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "wget": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "cmd-shell": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "curl": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "flask1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "flask2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "none": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "wget": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/heroku/compose.yaml.warnings b/src/testdata/heroku/compose.yaml.warnings index a7033feb3..f7ab3e438 100644 --- a/src/testdata/heroku/compose.yaml.warnings +++ b/src/testdata/heroku/compose.yaml.warnings @@ -1,6 +1,6 @@ ! service "app": environment "DATABASE_URL" may contain sensitive information; consider using 'defang config set DATABASE_URL' to securely store this value - ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "postgres": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "postgres": stateful service will lose data on restart; use a managed service instead - ! service "redis": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "redis": stateful service will lose data on restart; use a managed service instead + ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "postgres": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "postgres": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true + ! service "redis": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "redis": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true diff --git a/src/testdata/interpolate/compose.yaml.warnings b/src/testdata/interpolate/compose.yaml.warnings index 032a498b4..ed95a3cba 100644 --- a/src/testdata/interpolate/compose.yaml.warnings +++ b/src/testdata/interpolate/compose.yaml.warnings @@ -1,4 +1,4 @@ ! Environment variable "NODE_ENV" is ignored; add it to `.env` if needed ! Environment variable "NODE_ENV" is ignored; add it to `.env` or it may be resolved from config during deployment - ! service "interpolate": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "interpolate": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M Error: missing configs ["NODE_ENV" "POSTGRES_PASSWORD" "def"] (https://s.defang.io/config) diff --git a/src/testdata/llm/compose.yaml.warnings b/src/testdata/llm/compose.yaml.warnings index 19ca180be..fd0bfa2b6 100644 --- a/src/testdata/llm/compose.yaml.warnings +++ b/src/testdata/llm/compose.yaml.warnings @@ -1,7 +1,7 @@ - ! service "alt-repo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "gateway-with-ports": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1 - ! service "gateway-with-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "alt-repo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "gateway-with-ports": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5678/"] + ! service "gateway-with-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "gateway-with-ports": service name is longer than 16 characters, you may run into issues with resource name length - ! service "gateway-without-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "gateway-without-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "gateway-without-ports": service name is longer than 16 characters, you may run into issues with resource name length - ! service "llm": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "llm": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/longname/compose.yaml.warnings b/src/testdata/longname/compose.yaml.warnings index 4fa655ecb..e28f4b011 100644 --- a/src/testdata/longname/compose.yaml.warnings +++ b/src/testdata/longname/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/models/compose.yaml.warnings b/src/testdata/models/compose.yaml.warnings index 83f7405d9..434888da2 100644 --- a/src/testdata/models/compose.yaml.warnings +++ b/src/testdata/models/compose.yaml.warnings @@ -1,7 +1,7 @@ ! service "ai_model": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! service "ai_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "modellist": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "modelmap": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "ai_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "modellist": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "modelmap": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "my_model": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! 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 + ! service "my_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "withendpoint": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/mongo/compose.yaml.warnings b/src/testdata/mongo/compose.yaml.warnings index b1afad3c7..b489ae5da 100644 --- a/src/testdata/mongo/compose.yaml.warnings +++ b/src/testdata/mongo/compose.yaml.warnings @@ -1,20 +1,20 @@ - ! service "mongo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "mongo-express": environment "ME_CONFIG_MONGODB_URL" may contain sensitive information; consider using 'defang config set ME_CONFIG_MONGODB_URL' to securely store this value - ! service "mongo-express": ingress port 8081 without healthcheck; defaults to GET / HTTP/1.1 - ! service "mongo-express": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1234": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1235": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1236": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1236": stateful service will lose data on restart; use a managed service instead - ! service "mongo-port1237": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1238": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port1239": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port27018": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-port27019": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-unmanaged": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "mongo-unmanaged": stateful service will lose data on restart; use a managed service instead + ! service "mongo-express": ingress port 8081 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:8081/"] + ! service "mongo-express": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1234": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1235": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1236": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1236": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true + ! service "mongo-port1237": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1238": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1239": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port27018": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port27019": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-unmanaged": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-unmanaged": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true ! service "mongo-wrong-image": managed MongoDB service should use a mongo image - ! service "mongo-wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "mongo-wrong-image": service name is longer than 16 characters, you may run into issues with resource name length - ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "short-ports": stateful service will lose data on restart; use a managed service instead + ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-ports": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true diff --git a/src/testdata/networks/compose.yaml.warnings b/src/testdata/networks/compose.yaml.warnings index 9363fd3f3..33d8b5d83 100644 --- a/src/testdata/networks/compose.yaml.warnings +++ b/src/testdata/networks/compose.yaml.warnings @@ -1,8 +1,8 @@ - ! service "service-default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-internal": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-invalid": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-multi": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-private": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-public": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "service-public-list": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-internal": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-invalid": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-multi": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-private": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-public": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-public-list": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "service-public-list": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/platforms/compose.yaml.warnings b/src/testdata/platforms/compose.yaml.warnings index f3a73cc0f..b615ed7c3 100644 --- a/src/testdata/platforms/compose.yaml.warnings +++ b/src/testdata/platforms/compose.yaml.warnings @@ -1 +1 @@ - ! service "intel2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "intel2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/ports/compose.yaml.warnings b/src/testdata/ports/compose.yaml.warnings index 96b6dde94..e309c9ea1 100644 --- a/src/testdata/ports/compose.yaml.warnings +++ b/src/testdata/ports/compose.yaml.warnings @@ -3,16 +3,16 @@ ! port 84: UDP ports default to 'host' mode (add 'mode: host' to silence) ! port 85: 'published' should be equal to 'target'; ignoring 'published: 8085' ! port 85: UDP ports default to 'host' mode (add 'mode: host' to silence) - ! service "grpc": ingress port 9000 without healthcheck; defaults to GET / HTTP/1.1 - ! service "grpc": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "long": ingress port 82 without healthcheck; defaults to GET / HTTP/1.1 - ! service "long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "long-published": ingress port 83 without healthcheck; defaults to GET / HTTP/1.1 - ! service "long-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "short": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 - ! 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 81 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": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "short-udp-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "grpc": ingress port 9000 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:9000/"] + ! service "grpc": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "long": ingress port 82 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:82/"] + ! service "long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "long-published": ingress port 83 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:83/"] + ! service "long-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] + ! service "short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-published": ingress port 81 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:81/"] + ! service "short-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-udp": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-udp-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "short-udp-published": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/postgres/compose.yaml.warnings b/src/testdata/postgres/compose.yaml.warnings index 35121a7b1..c873d93e9 100644 --- a/src/testdata/postgres/compose.yaml.warnings +++ b/src/testdata/postgres/compose.yaml.warnings @@ -1,9 +1,9 @@ - ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! 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 "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ext": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true + ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "no-ports-override": service name is longer than 16 characters, you may run into issues with resource name length - ! 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 "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! 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 + ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/profiles/compose.yaml.warnings b/src/testdata/profiles/compose.yaml.warnings index e9c53d678..c70790d50 100644 --- a/src/testdata/profiles/compose.yaml.warnings +++ b/src/testdata/profiles/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "always": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "defangonly": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "always": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "defangonly": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/provider/compose.yaml.warnings b/src/testdata/provider/compose.yaml.warnings index 95bc4b9ba..431948a0e 100644 --- a/src/testdata/provider/compose.yaml.warnings +++ b/src/testdata/provider/compose.yaml.warnings @@ -1,4 +1,4 @@ ! service "ai_runner": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! service "ai_runner": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "ai_runner": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "chat": environment "OPENAI_API_KEY" may contain sensitive information; consider using 'defang config set OPENAI_API_KEY' to securely store this value - ! service "chat": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "chat": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/railpack/compose.yaml.warnings b/src/testdata/railpack/compose.yaml.warnings index afda8ef94..03104486a 100644 --- a/src/testdata/railpack/compose.yaml.warnings +++ b/src/testdata/railpack/compose.yaml.warnings @@ -1,4 +1,4 @@ - ! service "railpack-long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "railpack-short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "railpackwithdockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "railpack-long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "railpack-short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "railpackwithdockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "railpackwithdockerfile": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/redis/compose.yaml.warnings b/src/testdata/redis/compose.yaml.warnings index 78024026c..a5b568d94 100644 --- a/src/testdata/redis/compose.yaml.warnings +++ b/src/testdata/redis/compose.yaml.warnings @@ -1,10 +1,10 @@ - ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! 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 "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ext": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true + ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "no-ports-override": service name is longer than 16 characters, you may run into issues with resource name length - ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "valkey-service": 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 "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "valkey-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "wrong-image": managed Redis service should use a redis or valkey image - ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/replicas/compose.yaml.warnings b/src/testdata/replicas/compose.yaml.warnings index a60e6d4a6..9823bf2fe 100644 --- a/src/testdata/replicas/compose.yaml.warnings +++ b/src/testdata/replicas/compose.yaml.warnings @@ -1,7 +1,7 @@ - ! service "autoscaled": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "autoscaled": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "default": high-availability mode requires at least 2 replicas or x-defang-autoscaling - ! service "default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M ! service "deploy": high-availability mode requires at least 2 replicas or x-defang-autoscaling ! service "managed": high-availability mode requires at least 2 replicas or x-defang-autoscaling - ! service "managed": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors - ! service "replicated": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "managed": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "replicated": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/sanity/compose.yaml.warnings b/src/testdata/sanity/compose.yaml.warnings index 6be379d55..e4bbc2d11 100644 --- a/src/testdata/sanity/compose.yaml.warnings +++ b/src/testdata/sanity/compose.yaml.warnings @@ -1 +1 @@ - ! service "nginx": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 + ! service "nginx": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] diff --git a/src/testdata/secretname/compose.yaml.warnings b/src/testdata/secretname/compose.yaml.warnings index 2ebf82e23..2b7fe5702 100644 --- a/src/testdata/secretname/compose.yaml.warnings +++ b/src/testdata/secretname/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "app": 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; suggest deploy.resources.reservations.memory: 512M ! service "app": secrets will be exposed as environment variables, not files (use 'environment' instead) diff --git a/src/testdata/toomany/compose.yaml.warnings b/src/testdata/toomany/compose.yaml.warnings index 7c3f3ebde..52f58dab0 100644 --- a/src/testdata/toomany/compose.yaml.warnings +++ b/src/testdata/toomany/compose.yaml.warnings @@ -1 +1 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M diff --git a/src/testdata/toomany/docker-compose.yml.warnings b/src/testdata/toomany/docker-compose.yml.warnings index 7c3f3ebde..52f58dab0 100644 --- a/src/testdata/toomany/docker-compose.yml.warnings +++ b/src/testdata/toomany/docker-compose.yml.warnings @@ -1 +1 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M From 2a901ad0f4a5c15cf16b888671646937275c17c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Titsworth-Morin?= Date: Fri, 22 May 2026 11:14:25 +0000 Subject: [PATCH 2/3] fix: make compose lint truly offline, remove value suggestions from hints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove FixupServices dependency — lint now runs ValidateProject and ValidateServiceDockerfiles directly without needing a provider - Aggregate all validation errors instead of early-returning on first phase - Remove "suggest 512M" from memory reservation warning — we don't know what the user's service needs - Revert healthcheck warning to original (no curl suggestion — image may not have curl) - Revert golden files that only had memory/healthcheck hint changes Co-Authored-By: Claude Opus 4.6 --- src/cmd/cli/command/compose.go | 30 +++++++------------ src/cmd/cli/command/compose_test.go | 5 ---- src/pkg/cli/compose/validation.go | 4 +-- .../ambiguous-strings/compose.yaml.warnings | 4 +-- src/testdata/base-image/compose.yaml.warnings | 6 ++-- .../build-image/compose.yaml.warnings | 2 +- src/testdata/build/compose.yaml.warnings | 6 ++-- .../bun-in-compose/compose.yaml.warnings | 4 +-- .../bun-in-dockerfile/compose.yaml.warnings | 4 +-- .../compose-go-warn/compose.yaml.warnings | 4 +-- .../configdetection/compose.yaml.warnings | 2 +- .../configoverride/compose.yaml.warnings | 2 +- src/testdata/debugproj/compose.yaml.warnings | 4 +-- src/testdata/dependson/compose.yaml.warnings | 6 ++-- .../compose.yaml.warnings | 4 +-- src/testdata/emptyenv/compose.yaml.warnings | 2 +- src/testdata/extends/compose.yaml.warnings | 16 +++++----- src/testdata/fixupenv/compose.yaml.warnings | 18 +++++------ src/testdata/gpu/compose.yaml.warnings | 2 +- .../healthcheck/compose.yaml.warnings | 12 ++++---- src/testdata/heroku/compose.yaml.warnings | 6 ++-- .../interpolate/compose.yaml.warnings | 2 +- src/testdata/llm/compose.yaml.warnings | 10 +++---- src/testdata/longname/compose.yaml.warnings | 2 +- src/testdata/models/compose.yaml.warnings | 10 +++---- src/testdata/mongo/compose.yaml.warnings | 28 ++++++++--------- src/testdata/networks/compose.yaml.warnings | 14 ++++----- src/testdata/platforms/compose.yaml.warnings | 2 +- src/testdata/ports/compose.yaml.warnings | 24 +++++++-------- src/testdata/postgres/compose.yaml.warnings | 12 ++++---- src/testdata/profiles/compose.yaml.warnings | 4 +-- src/testdata/provider/compose.yaml.warnings | 4 +-- src/testdata/railpack/compose.yaml.warnings | 6 ++-- src/testdata/redis/compose.yaml.warnings | 14 ++++----- src/testdata/replicas/compose.yaml.warnings | 8 ++--- src/testdata/sanity/compose.yaml.warnings | 2 +- src/testdata/secretname/compose.yaml.warnings | 2 +- src/testdata/toomany/compose.yaml.warnings | 2 +- .../toomany/docker-compose.yml.warnings | 2 +- 39 files changed, 138 insertions(+), 153 deletions(-) diff --git a/src/cmd/cli/command/compose.go b/src/cmd/cli/command/compose.go index e963e494d..59a1e7c93 100644 --- a/src/cmd/cli/command/compose.go +++ b/src/cmd/cli/command/compose.go @@ -559,35 +559,25 @@ func makeComposeLintCmd() *cobra.Command { Args: cobra.NoArgs, Short: "Validate a Compose file without deploying", RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() + loader := newLoaderForCommand(cmd) - sessionx, err := newCommandSessionWithOpts(cmd, commandSessionOpts{ - CheckAccountInfo: false, - }) - if err != nil { - term.Warn("unable to load stack:", err, "- using offline validation") - sessionx = &session.Session{ - Loader: newLoaderForCommand(cmd), - Provider: client.NewPlaygroundProvider(global.Client, stacks.DefaultBeta), - Stack: &stacks.Parameters{Name: stacks.DefaultBeta, Provider: client.ProviderDefang}, - } - } - - project, loadErr := sessionx.Loader.LoadProject(ctx) + project, loadErr := loader.LoadProject(cmd.Context()) if loadErr != nil { - return handleInvalidComposeFileErr(ctx, loadErr) + return handleInvalidComposeFileErr(cmd.Context(), loadErr) } + var errs []error + if err := compose.ValidateServiceDockerfiles(project); err != nil { - return fmt.Errorf("compose file has errors:\n%w", err) + errs = append(errs, err) } - if err := compose.FixupServices(ctx, sessionx.Provider, project, compose.UploadModeIgnore); err != nil { - return fmt.Errorf("compose file has errors:\n%w", err) + if err := compose.ValidateProject(project, modes.ModeUnspecified); err != nil { + errs = append(errs, err) } - if err := compose.ValidateProject(project, modes.ModeUnspecified); err != nil { - return fmt.Errorf("compose file has errors:\n%w", err) + if len(errs) > 0 { + return fmt.Errorf("compose file has errors:\n%w", errors.Join(errs...)) } if term.HadWarnings() { diff --git a/src/cmd/cli/command/compose_test.go b/src/cmd/cli/command/compose_test.go index 3d74f2540..538d9b3d7 100644 --- a/src/cmd/cli/command/compose_test.go +++ b/src/cmd/cli/command/compose_test.go @@ -82,11 +82,6 @@ func TestComposeConfig(t *testing.T) { } func TestComposeLint(t *testing.T) { - global.Client = unauthedMockFabricClient{} - t.Cleanup(func() { - global.Client = nil - }) - defaultTerm := term.DefaultTerm t.Cleanup(func() { term.DefaultTerm = defaultTerm diff --git a/src/pkg/cli/compose/validation.go b/src/pkg/cli/compose/validation.go index dff29f61e..9a51764ee 100644 --- a/src/pkg/cli/compose/validation.go +++ b/src/pkg/cli/compose/validation.go @@ -226,7 +226,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P // Show a warning when we have ingress ports but no explicit healthcheck for _, port := range svccfg.Ports { if port.Mode == Mode_INGRESS { - term.Warnf("service %q: ingress port %d without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:%d/\"]", svccfg.Name, port.Target, port.Target) + term.Warnf("service %q: ingress port %d without healthcheck; defaults to GET / HTTP/1.1", svccfg.Name, port.Target) break } } @@ -297,7 +297,7 @@ func validateService(svccfg *composeTypes.ServiceConfig, project *composeTypes.P if reservations == nil || reservations.MemoryBytes == 0 { // Don't show this warning for managed pseudo-services like CDN if svccfg.Extensions["x-defang-static-files"] == nil { - term.Warnf("service %q: missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M", svccfg.Name) + term.Warnf("service %q: missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors", svccfg.Name) } } diff --git a/src/testdata/ambiguous-strings/compose.yaml.warnings b/src/testdata/ambiguous-strings/compose.yaml.warnings index 2d0444912..b5c8d7028 100644 --- a/src/testdata/ambiguous-strings/compose.yaml.warnings +++ b/src/testdata/ambiguous-strings/compose.yaml.warnings @@ -1,3 +1,3 @@ ! project name "ambiguous-strings" is longer than 16 characters, you may run into issues with resource name length - ! service "a": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "b": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "a": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "b": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/base-image/compose.yaml.warnings b/src/testdata/base-image/compose.yaml.warnings index 6f708edcf..462f4b19e 100644 --- a/src/testdata/base-image/compose.yaml.warnings +++ b/src/testdata/base-image/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "mutiple-images": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "no-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "one-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mutiple-images": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "no-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "one-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/build-image/compose.yaml.warnings b/src/testdata/build-image/compose.yaml.warnings index b25ed33c3..31b49007b 100644 --- a/src/testdata/build-image/compose.yaml.warnings +++ b/src/testdata/build-image/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "app": using published image instead of rebuilding; pass --build to build and publish a new image diff --git a/src/testdata/build/compose.yaml.warnings b/src/testdata/build/compose.yaml.warnings index ea6854289..c1edb4dfb 100644 --- a/src/testdata/build/compose.yaml.warnings +++ b/src/testdata/build/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "build1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "build2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "normalized": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "build1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "build2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "normalized": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/bun-in-compose/compose.yaml.warnings b/src/testdata/bun-in-compose/compose.yaml.warnings index 85bc3e902..fa20f93f0 100644 --- a/src/testdata/bun-in-compose/compose.yaml.warnings +++ b/src/testdata/bun-in-compose/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/bun-in-dockerfile/compose.yaml.warnings b/src/testdata/bun-in-dockerfile/compose.yaml.warnings index 85bc3e902..fa20f93f0 100644 --- a/src/testdata/bun-in-dockerfile/compose.yaml.warnings +++ b/src/testdata/bun-in-dockerfile/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "bun": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "server": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/compose-go-warn/compose.yaml.warnings b/src/testdata/compose-go-warn/compose.yaml.warnings index 076e92bf7..eadbc08fd 100644 --- a/src/testdata/compose-go-warn/compose.yaml.warnings +++ b/src/testdata/compose-go-warn/compose.yaml.warnings @@ -1,4 +1,4 @@ ! "yes" for boolean is not supported by YAML 1.2, please use `true` ! project name "compose-go-warning" is longer than 16 characters, you may run into issues with resource name length - ! service "echo": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] - ! service "echo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "echo": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 + ! service "echo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/configdetection/compose.yaml.warnings b/src/testdata/configdetection/compose.yaml.warnings index 24e8bbb77..b34af22b6 100644 --- a/src/testdata/configdetection/compose.yaml.warnings +++ b/src/testdata/configdetection/compose.yaml.warnings @@ -3,4 +3,4 @@ ! service "configdetection": environment "GH_PAT" may contain sensitive information; consider using 'defang config set GH_PAT' to securely store this value ! service "configdetection": environment "HIGH_ENTROPY_STRING" may contain sensitive information; consider using 'defang config set HIGH_ENTROPY_STRING' to securely store this value ! service "configdetection": environment "MY_URL" may contain sensitive information; consider using 'defang config set MY_URL' to securely store this value - ! service "configdetection": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "configdetection": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/configoverride/compose.yaml.warnings b/src/testdata/configoverride/compose.yaml.warnings index 0842eddaa..16597ca8e 100644 --- a/src/testdata/configoverride/compose.yaml.warnings +++ b/src/testdata/configoverride/compose.yaml.warnings @@ -1,2 +1,2 @@ ! service "service1": environment variable(s) ["VAR1"] overridden by config - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/debugproj/compose.yaml.warnings b/src/testdata/debugproj/compose.yaml.warnings index 676d878b3..d6ec97128 100644 --- a/src/testdata/debugproj/compose.yaml.warnings +++ b/src/testdata/debugproj/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "failing": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "ok": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "failing": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "ok": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/dependson/compose.yaml.warnings b/src/testdata/dependson/compose.yaml.warnings index 8750db6c8..8e40937c4 100644 --- a/src/testdata/dependson/compose.yaml.warnings +++ b/src/testdata/dependson/compose.yaml.warnings @@ -1,3 +1,3 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service3": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service3": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/dockerfile-validation-errors/compose.yaml.warnings b/src/testdata/dockerfile-validation-errors/compose.yaml.warnings index e40f2bcf7..fc05bf453 100644 --- a/src/testdata/dockerfile-validation-errors/compose.yaml.warnings +++ b/src/testdata/dockerfile-validation-errors/compose.yaml.warnings @@ -1,4 +1,4 @@ ! project name "dockerfile-validation-errors" is longer than 16 characters, you may run into issues with resource name length - ! service "invalid-dockerfile": ingress port 8080 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:8080/"] - ! service "invalid-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "invalid-dockerfile": ingress port 8080 without healthcheck; defaults to GET / HTTP/1.1 + ! service "invalid-dockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "invalid-dockerfile": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/emptyenv/compose.yaml.warnings b/src/testdata/emptyenv/compose.yaml.warnings index 8f91ab660..471b371f0 100644 --- a/src/testdata/emptyenv/compose.yaml.warnings +++ b/src/testdata/emptyenv/compose.yaml.warnings @@ -1 +1 @@ - ! service "emptyenv": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "emptyenv": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/extends/compose.yaml.warnings b/src/testdata/extends/compose.yaml.warnings index d77c6d3ff..49caffe11 100644 --- a/src/testdata/extends/compose.yaml.warnings +++ b/src/testdata/extends/compose.yaml.warnings @@ -1,9 +1,9 @@ - ! service "array-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "array-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "array-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "array-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "map-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "map-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "map-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "map-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "array-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "array-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "array-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "array-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "map-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "map-reset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "map-set": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "map-unset": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors Error: missing configs ["EMPTY_VALUE" "NEW_VALUE" "NO_VALUE" "WITH_VALUE"] (https://s.defang.io/config) diff --git a/src/testdata/fixupenv/compose.yaml.warnings b/src/testdata/fixupenv/compose.yaml.warnings index 36fa24e1b..fdc14b599 100644 --- a/src/testdata/fixupenv/compose.yaml.warnings +++ b/src/testdata/fixupenv/compose.yaml.warnings @@ -1,11 +1,11 @@ - ! service "Mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "fixup-args": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "ingress-service": ingress port 5432 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5432/"] - ! service "ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "refer-self-build-arg": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "Mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "fixup-args": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "ingress-service": ingress port 5432 without healthcheck; defaults to GET / HTTP/1.1 + ! service "ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "refer-self-build-arg": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "refer-self-build-arg": service name is longer than 16 characters, you may run into issues with resource name length - ! service "refer-self-env": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5678/"] - ! service "refer-self-env": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "ui": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "use-ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "refer-self-env": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1 + ! service "refer-self-env": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "ui": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "use-ingress-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "use-ingress-service": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/gpu/compose.yaml.warnings b/src/testdata/gpu/compose.yaml.warnings index 30d69debd..2a9093506 100644 --- a/src/testdata/gpu/compose.yaml.warnings +++ b/src/testdata/gpu/compose.yaml.warnings @@ -1 +1 @@ - ! service "mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mistral": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/healthcheck/compose.yaml.warnings b/src/testdata/healthcheck/compose.yaml.warnings index 1156cb582..b3891096b 100644 --- a/src/testdata/healthcheck/compose.yaml.warnings +++ b/src/testdata/healthcheck/compose.yaml.warnings @@ -1,6 +1,6 @@ - ! service "cmd-shell": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "curl": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "flask1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "flask2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "none": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "wget": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "cmd-shell": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "curl": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "flask1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "flask2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "none": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "wget": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/heroku/compose.yaml.warnings b/src/testdata/heroku/compose.yaml.warnings index f7ab3e438..ba87e8faf 100644 --- a/src/testdata/heroku/compose.yaml.warnings +++ b/src/testdata/heroku/compose.yaml.warnings @@ -1,6 +1,6 @@ ! service "app": environment "DATABASE_URL" may contain sensitive information; consider using 'defang config set DATABASE_URL' to securely store this value - ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "postgres": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "postgres": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "postgres": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true - ! service "redis": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "redis": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "redis": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true diff --git a/src/testdata/interpolate/compose.yaml.warnings b/src/testdata/interpolate/compose.yaml.warnings index ed95a3cba..032a498b4 100644 --- a/src/testdata/interpolate/compose.yaml.warnings +++ b/src/testdata/interpolate/compose.yaml.warnings @@ -1,4 +1,4 @@ ! Environment variable "NODE_ENV" is ignored; add it to `.env` if needed ! Environment variable "NODE_ENV" is ignored; add it to `.env` or it may be resolved from config during deployment - ! service "interpolate": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "interpolate": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors Error: missing configs ["NODE_ENV" "POSTGRES_PASSWORD" "def"] (https://s.defang.io/config) diff --git a/src/testdata/llm/compose.yaml.warnings b/src/testdata/llm/compose.yaml.warnings index fd0bfa2b6..19ca180be 100644 --- a/src/testdata/llm/compose.yaml.warnings +++ b/src/testdata/llm/compose.yaml.warnings @@ -1,7 +1,7 @@ - ! service "alt-repo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "gateway-with-ports": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:5678/"] - ! service "gateway-with-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "alt-repo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "gateway-with-ports": ingress port 5678 without healthcheck; defaults to GET / HTTP/1.1 + ! service "gateway-with-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "gateway-with-ports": service name is longer than 16 characters, you may run into issues with resource name length - ! service "gateway-without-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "gateway-without-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "gateway-without-ports": service name is longer than 16 characters, you may run into issues with resource name length - ! service "llm": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "llm": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/longname/compose.yaml.warnings b/src/testdata/longname/compose.yaml.warnings index e28f4b011..4fa655ecb 100644 --- a/src/testdata/longname/compose.yaml.warnings +++ b/src/testdata/longname/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "aVeryLongServiceNameThatIsDefinitelyTooLongThatWillCauseAnError": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/models/compose.yaml.warnings b/src/testdata/models/compose.yaml.warnings index 434888da2..83f7405d9 100644 --- a/src/testdata/models/compose.yaml.warnings +++ b/src/testdata/models/compose.yaml.warnings @@ -1,7 +1,7 @@ ! service "ai_model": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! service "ai_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "modellist": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "modelmap": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "ai_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "modellist": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "modelmap": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "my_model": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! service "my_model": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "withendpoint": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! 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/mongo/compose.yaml.warnings b/src/testdata/mongo/compose.yaml.warnings index b489ae5da..66c8b3a6a 100644 --- a/src/testdata/mongo/compose.yaml.warnings +++ b/src/testdata/mongo/compose.yaml.warnings @@ -1,20 +1,20 @@ - ! service "mongo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "mongo-express": environment "ME_CONFIG_MONGODB_URL" may contain sensitive information; consider using 'defang config set ME_CONFIG_MONGODB_URL' to securely store this value - ! service "mongo-express": ingress port 8081 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:8081/"] - ! service "mongo-express": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port1234": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port1235": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port1236": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-express": ingress port 8081 without healthcheck; defaults to GET / HTTP/1.1 + ! service "mongo-express": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port1234": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port1235": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port1236": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "mongo-port1236": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true - ! service "mongo-port1237": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port1238": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port1239": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port27018": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-port27019": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "mongo-unmanaged": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-port1237": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port1238": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port1239": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port27018": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-port27019": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "mongo-unmanaged": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "mongo-unmanaged": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true ! service "mongo-wrong-image": managed MongoDB service should use a mongo image - ! service "mongo-wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "mongo-wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "mongo-wrong-image": service name is longer than 16 characters, you may run into issues with resource name length - ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "short-ports": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true diff --git a/src/testdata/networks/compose.yaml.warnings b/src/testdata/networks/compose.yaml.warnings index 33d8b5d83..9363fd3f3 100644 --- a/src/testdata/networks/compose.yaml.warnings +++ b/src/testdata/networks/compose.yaml.warnings @@ -1,8 +1,8 @@ - ! service "service-default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-internal": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-invalid": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-multi": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-private": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-public": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "service-public-list": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service-default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-internal": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-invalid": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-multi": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-private": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-public": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "service-public-list": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "service-public-list": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/platforms/compose.yaml.warnings b/src/testdata/platforms/compose.yaml.warnings index b615ed7c3..f3a73cc0f 100644 --- a/src/testdata/platforms/compose.yaml.warnings +++ b/src/testdata/platforms/compose.yaml.warnings @@ -1 +1 @@ - ! service "intel2": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "intel2": 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 e309c9ea1..96b6dde94 100644 --- a/src/testdata/ports/compose.yaml.warnings +++ b/src/testdata/ports/compose.yaml.warnings @@ -3,16 +3,16 @@ ! port 84: UDP ports default to 'host' mode (add 'mode: host' to silence) ! port 85: 'published' should be equal to 'target'; ignoring 'published: 8085' ! port 85: UDP ports default to 'host' mode (add 'mode: host' to silence) - ! service "grpc": ingress port 9000 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:9000/"] - ! service "grpc": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "long": ingress port 82 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:82/"] - ! service "long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "long-published": ingress port 83 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:83/"] - ! service "long-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "short": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] - ! service "short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "short-published": ingress port 81 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:81/"] - ! service "short-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "short-udp": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "short-udp-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "grpc": ingress port 9000 without healthcheck; defaults to GET / HTTP/1.1 + ! service "grpc": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "long": ingress port 82 without healthcheck; defaults to GET / HTTP/1.1 + ! service "long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "long-published": ingress port 83 without healthcheck; defaults to GET / HTTP/1.1 + ! service "long-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "short": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 + ! 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 81 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": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "short-udp-published": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "short-udp-published": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/postgres/compose.yaml.warnings b/src/testdata/postgres/compose.yaml.warnings index c873d93e9..6b6d29131 100644 --- a/src/testdata/postgres/compose.yaml.warnings +++ b/src/testdata/postgres/compose.yaml.warnings @@ -1,9 +1,9 @@ - ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "no-ext": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true - ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! 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 "no-ports-override": service name is longer than 16 characters, you may run into issues with resource name length - ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! 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; suggest deploy.resources.reservations.memory: 512M + ! 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/profiles/compose.yaml.warnings b/src/testdata/profiles/compose.yaml.warnings index c70790d50..e9c53d678 100644 --- a/src/testdata/profiles/compose.yaml.warnings +++ b/src/testdata/profiles/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "always": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "defangonly": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "always": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "defangonly": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/provider/compose.yaml.warnings b/src/testdata/provider/compose.yaml.warnings index 431948a0e..95bc4b9ba 100644 --- a/src/testdata/provider/compose.yaml.warnings +++ b/src/testdata/provider/compose.yaml.warnings @@ -1,4 +1,4 @@ ! service "ai_runner": environment "LITELLM_MASTER_KEY" may contain sensitive information; consider using 'defang config set LITELLM_MASTER_KEY' to securely store this value - ! service "ai_runner": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "ai_runner": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "chat": environment "OPENAI_API_KEY" may contain sensitive information; consider using 'defang config set OPENAI_API_KEY' to securely store this value - ! service "chat": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "chat": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/railpack/compose.yaml.warnings b/src/testdata/railpack/compose.yaml.warnings index 03104486a..afda8ef94 100644 --- a/src/testdata/railpack/compose.yaml.warnings +++ b/src/testdata/railpack/compose.yaml.warnings @@ -1,4 +1,4 @@ - ! service "railpack-long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "railpack-short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "railpackwithdockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "railpack-long": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "railpack-short": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "railpackwithdockerfile": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "railpackwithdockerfile": service name is longer than 16 characters, you may run into issues with resource name length diff --git a/src/testdata/redis/compose.yaml.warnings b/src/testdata/redis/compose.yaml.warnings index a5b568d94..7e641a7f8 100644 --- a/src/testdata/redis/compose.yaml.warnings +++ b/src/testdata/redis/compose.yaml.warnings @@ -1,10 +1,10 @@ - ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "no-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "no-ext": stateful service will lose data on restart; use a managed service instead; consider x-defang-postgres/redis/mongodb: true - ! service "no-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "no-ports-override": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! 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 "no-ports-override": service name is longer than 16 characters, you may run into issues with resource name length - ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "valkey-service": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "with-ext": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "short-ports": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "valkey-service": 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 or valkey image - ! service "wrong-image": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! 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/replicas/compose.yaml.warnings b/src/testdata/replicas/compose.yaml.warnings index 9823bf2fe..a60e6d4a6 100644 --- a/src/testdata/replicas/compose.yaml.warnings +++ b/src/testdata/replicas/compose.yaml.warnings @@ -1,7 +1,7 @@ - ! service "autoscaled": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "autoscaled": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "default": high-availability mode requires at least 2 replicas or x-defang-autoscaling - ! service "default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "default": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "deploy": high-availability mode requires at least 2 replicas or x-defang-autoscaling ! service "managed": high-availability mode requires at least 2 replicas or x-defang-autoscaling - ! service "managed": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M - ! service "replicated": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "managed": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "replicated": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/sanity/compose.yaml.warnings b/src/testdata/sanity/compose.yaml.warnings index e4bbc2d11..6be379d55 100644 --- a/src/testdata/sanity/compose.yaml.warnings +++ b/src/testdata/sanity/compose.yaml.warnings @@ -1 +1 @@ - ! service "nginx": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1; add a healthcheck such as: test: ["CMD", "curl", "-f", "http://localhost:80/"] + ! service "nginx": ingress port 80 without healthcheck; defaults to GET / HTTP/1.1 diff --git a/src/testdata/secretname/compose.yaml.warnings b/src/testdata/secretname/compose.yaml.warnings index 2b7fe5702..2ebf82e23 100644 --- a/src/testdata/secretname/compose.yaml.warnings +++ b/src/testdata/secretname/compose.yaml.warnings @@ -1,2 +1,2 @@ - ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "app": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors ! service "app": secrets will be exposed as environment variables, not files (use 'environment' instead) diff --git a/src/testdata/toomany/compose.yaml.warnings b/src/testdata/toomany/compose.yaml.warnings index 52f58dab0..7c3f3ebde 100644 --- a/src/testdata/toomany/compose.yaml.warnings +++ b/src/testdata/toomany/compose.yaml.warnings @@ -1 +1 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors diff --git a/src/testdata/toomany/docker-compose.yml.warnings b/src/testdata/toomany/docker-compose.yml.warnings index 52f58dab0..7c3f3ebde 100644 --- a/src/testdata/toomany/docker-compose.yml.warnings +++ b/src/testdata/toomany/docker-compose.yml.warnings @@ -1 +1 @@ - ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors; suggest deploy.resources.reservations.memory: 512M + ! service "service1": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors From fd2f17f08fb8c525860de07769d13aa9d00bbb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Titsworth-Morin?= Date: Fri, 22 May 2026 17:10:23 +0000 Subject: [PATCH 3/3] feat(compose): add --fix flag to compose lint Add `defang compose lint --fix` to apply safe mechanical fixes and write the result back to the compose file. Fixes include: - Port mode assignment (ingress/host based on protocol/image) - Limits-to-reservations copy - Restart policy normalization - Unsupported directive removal (dns, devices, etc.) This follows the eslint `--fix` pattern: lint validates, --fix applies deterministic corrections before validating. Co-Authored-By: Claude Opus 4.6 --- src/cmd/cli/command/compose.go | 64 +++++- src/pkg/cli/compose/fix.go | 194 +++++++++++++++++ src/pkg/cli/compose/fix_test.go | 197 ++++++++++++++++++ src/testdata/compose-fix/compose.yaml | 12 ++ src/testdata/compose-fix/compose.yaml.fixup | 36 ++++ src/testdata/compose-fix/compose.yaml.golden | 23 ++ .../compose-fix/compose.yaml.warnings | 3 + 7 files changed, 528 insertions(+), 1 deletion(-) create mode 100644 src/pkg/cli/compose/fix.go create mode 100644 src/pkg/cli/compose/fix_test.go create mode 100644 src/testdata/compose-fix/compose.yaml create mode 100644 src/testdata/compose-fix/compose.yaml.fixup create mode 100644 src/testdata/compose-fix/compose.yaml.golden create mode 100644 src/testdata/compose-fix/compose.yaml.warnings diff --git a/src/cmd/cli/command/compose.go b/src/cmd/cli/command/compose.go index 59a1e7c93..174fab665 100644 --- a/src/cmd/cli/command/compose.go +++ b/src/cmd/cli/command/compose.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "os" "slices" "strings" "time" @@ -554,7 +555,8 @@ func makeComposeConfigCmd() *cobra.Command { } func makeComposeLintCmd() *cobra.Command { - return &cobra.Command{ + var fix bool + cmd := &cobra.Command{ Use: "lint", Args: cobra.NoArgs, Short: "Validate a Compose file without deploying", @@ -566,6 +568,16 @@ func makeComposeLintCmd() *cobra.Command { return handleInvalidComposeFileErr(cmd.Context(), loadErr) } + if fix { + fixes := compose.FixProject(project) + printFixResults(fixes) + if len(fixes) > 0 { + if err := writeFixedCompose(project); err != nil { + return err + } + } + } + var errs []error if err := compose.ValidateServiceDockerfiles(project); err != nil { @@ -588,6 +600,56 @@ func makeComposeLintCmd() *cobra.Command { return nil }, } + cmd.Flags().BoolVar(&fix, "fix", false, "apply safe mechanical fixes to the Compose file") + return cmd +} + +func writeFixedCompose(project *compose.Project) error { + if len(project.ComposeFiles) == 0 { + return fmt.Errorf("no compose file to write to") + } + data, err := compose.MarshalYAML(project) + if err != nil { + return err + } + path := project.ComposeFiles[0] + if err := os.WriteFile(path, data, 0644); err != nil { + return fmt.Errorf("writing %s: %w", path, err) + } + term.Info("Updated", path) + return nil +} + +func printFixResults(fixes []compose.FixResult) { + if len(fixes) == 0 { + term.Info("No fixes needed.") + return + } + term.Println("Fixes applied:") + for _, fix := range fixes { + term.Printf(" service %q: %s\n", fix.Service, describeFixResult(fix)) + } + term.Printf("\n%d fix(es) applied.\n", len(fixes)) +} + +func describeFixResult(fix compose.FixResult) string { + switch fix.Action { + case "removed": + return fmt.Sprintf("removed unsupported directive: %s (%s)", fix.Field, fix.Reason) + case "changed": + if fix.Before != "" { + return fmt.Sprintf("changed %s from %q to %q (%s)", fix.Field, fix.Before, fix.After, fix.Reason) + } + return fmt.Sprintf("changed %s to %q (%s)", fix.Field, fix.After, fix.Reason) + default: + if fix.Field == "mode" { + return fmt.Sprintf("added mode: %s to %s", fix.After, fix.Reason) + } + if fix.Reason != "" { + return fmt.Sprintf("added %s: %s (%s)", fix.Field, fix.After, fix.Reason) + } + return fmt.Sprintf("added %s: %s", fix.Field, fix.After) + } } func makeComposePsCmd() *cobra.Command { diff --git a/src/pkg/cli/compose/fix.go b/src/pkg/cli/compose/fix.go new file mode 100644 index 000000000..b3aaf72bd --- /dev/null +++ b/src/pkg/cli/compose/fix.go @@ -0,0 +1,194 @@ +package compose + +import ( + "fmt" + "sort" + + composeTypes "github.com/compose-spec/compose-go/v2/types" +) + +const defaultRestartPolicy = "unless-stopped" + +type FixResult struct { + Service string + Field string + Action string // "added", "removed", "changed" + Before string + After string + Reason string +} + +func FixProject(project *Project) []FixResult { + if project == nil { + return nil + } + + var results []FixResult + for _, name := range sortedServiceNames(project) { + service := project.Services[name] + results = append(results, fixService(&service)...) + project.Services[name] = service + } + return results +} + +func sortedServiceNames(project *Project) []string { + names := make([]string, 0, len(project.Services)) + for name := range project.Services { + names = append(names, name) + } + sort.Strings(names) + return names +} + +func fixService(service *composeTypes.ServiceConfig) []FixResult { + var results []FixResult + repo := GetImageRepo(service.Image) + isManagedStoreImage := IsPostgresRepo(repo) || IsRedisRepo(repo) || IsMongoRepo(repo) + + results = append(results, fixPorts(service, isManagedStoreImage)...) + results = append(results, fixLimitsToReservations(service)...) + results = append(results, fixRestart(service)...) + results = append(results, fixUnsupportedDirectives(service)...) + + return results +} + +func fixPorts(service *composeTypes.ServiceConfig, isManagedStoreImage bool) []FixResult { + var results []FixResult + for i := range service.Ports { + port := &service.Ports[i] + if port.Mode != "" { + continue + } + + mode := Mode_INGRESS + reason := "" + if port.Protocol == Protocol_UDP { + mode = Mode_HOST + reason = "UDP port" + } else if isManagedStoreImage { + mode = Mode_HOST + reason = "database image" + } + port.Mode = mode + results = append(results, FixResult{ + Service: service.Name, + Field: "mode", + Action: "added", + After: mode, + Reason: portReason(port.Target, reason), + }) + } + return results +} + +func portReason(target uint32, reason string) string { + if reason == "" { + return fmt.Sprintf("port %d", target) + } + return fmt.Sprintf("port %d (%s)", target, reason) +} + +func fixLimitsToReservations(service *composeTypes.ServiceConfig) []FixResult { + if service.Deploy == nil { + return nil + } + if service.Deploy.Resources.Limits == nil || service.Deploy.Resources.Reservations != nil { + return nil + } + limits := *service.Deploy.Resources.Limits + service.Deploy.Resources.Reservations = &limits + return []FixResult{{ + Service: service.Name, + Field: "deploy.resources.reservations", + Action: "added", + After: "copied from deploy.resources.limits", + Reason: "Defang uses reservations for scheduling, not limits", + }} +} + +func fixRestart(service *composeTypes.ServiceConfig) []FixResult { + restart := restartFromDeployPolicy(service) + if restart == "" && isSupportedRestart(service.Restart) { + return nil + } + + before := service.Restart + if restart == "" { + restart = defaultRestartPolicy + } + service.Restart = restart + + reason := "unsupported restart policy" + if service.Deploy != nil && service.Deploy.RestartPolicy != nil { + reason = "deploy.restart_policy is unsupported; converted to service-level restart" + service.Deploy.RestartPolicy = nil + } else if before == "" { + reason = "missing restart policy" + } + + action := "changed" + if before == "" { + action = "added" + } + return []FixResult{{ + Service: service.Name, + Field: "restart", + Action: action, + Before: before, + After: restart, + Reason: reason, + }} +} + +func restartFromDeployPolicy(service *composeTypes.ServiceConfig) string { + if service.Deploy == nil || service.Deploy.RestartPolicy == nil { + return "" + } + switch service.Deploy.RestartPolicy.Condition { + case "", "any": + return "always" + default: + return defaultRestartPolicy + } +} + +func isSupportedRestart(restart string) bool { + return restart == "always" || restart == defaultRestartPolicy +} + +func fixUnsupportedDirectives(service *composeTypes.ServiceConfig) []FixResult { + var results []FixResult + if len(service.DNS) != 0 { + service.DNS = nil + results = append(results, removedDirective(service.Name, "dns")) + } + if len(service.DNSSearch) != 0 { + service.DNSSearch = nil + results = append(results, removedDirective(service.Name, "dns_search")) + } + if len(service.Devices) != 0 { + service.Devices = nil + results = append(results, removedDirective(service.Name, "devices")) + } + if len(service.DeviceCgroupRules) != 0 { + service.DeviceCgroupRules = nil + results = append(results, removedDirective(service.Name, "device_cgroup_rules")) + } + if len(service.GroupAdd) != 0 { + service.GroupAdd = nil + results = append(results, removedDirective(service.Name, "group_add")) + } + return results +} + +func removedDirective(service, field string) FixResult { + return FixResult{ + Service: service, + Field: field, + Action: "removed", + Before: "present", + Reason: "unsupported directive", + } +} diff --git a/src/pkg/cli/compose/fix_test.go b/src/pkg/cli/compose/fix_test.go new file mode 100644 index 000000000..87078a914 --- /dev/null +++ b/src/pkg/cli/compose/fix_test.go @@ -0,0 +1,197 @@ +package compose + +import ( + "reflect" + "testing" + + "github.com/DefangLabs/defang/src/pkg/modes" + composeTypes "github.com/compose-spec/compose-go/v2/types" +) + +func TestFixProject(t *testing.T) { + tests := []struct { + name string + project *Project + want []FixResult + check func(*testing.T, *Project) + }{ + { + name: "web service port mode and restart", + project: &Project{Services: Services{ + "web": { + Name: "web", + Image: "nginx", + Ports: []composeTypes.ServicePortConfig{{Target: 8080}}, + }, + }}, + want: []FixResult{ + {Service: "web", Field: "mode", Action: "added", After: Mode_INGRESS, Reason: "port 8080"}, + {Service: "web", Field: "restart", Action: "added", After: defaultRestartPolicy, Reason: "missing restart policy"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["web"] + if service.Ports[0].Mode != Mode_INGRESS { + t.Fatalf("port mode = %q, want %q", service.Ports[0].Mode, Mode_INGRESS) + } + if service.Restart != defaultRestartPolicy { + t.Fatalf("restart = %q, want %q", service.Restart, defaultRestartPolicy) + } + }, + }, + { + name: "managed postgres defaults to host mode", + project: &Project{Services: Services{ + "db": { + Name: "db", + Image: "postgres:16", + Ports: []composeTypes.ServicePortConfig{{Target: 5432}}, + }, + }}, + want: []FixResult{ + {Service: "db", Field: "mode", Action: "added", After: Mode_HOST, Reason: "port 5432 (database image)"}, + {Service: "db", Field: "restart", Action: "added", After: defaultRestartPolicy, Reason: "missing restart policy"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["db"] + if service.Ports[0].Mode != Mode_HOST { + t.Fatalf("port mode = %q, want %q", service.Ports[0].Mode, Mode_HOST) + } + }, + }, + { + name: "limits copied to reservations", + project: &Project{Services: Services{ + "api": { + Name: "api", + Image: "api", + Restart: defaultRestartPolicy, + Deploy: &composeTypes.DeployConfig{Resources: composeTypes.Resources{ + Limits: &composeTypes.Resource{MemoryBytes: 1024 * MiB}, + }}, + }, + }}, + want: []FixResult{ + {Service: "api", Field: "deploy.resources.reservations", Action: "added", After: "copied from deploy.resources.limits", Reason: "Defang uses reservations for scheduling, not limits"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["api"] + if service.Deploy.Resources.Reservations == nil { + t.Fatal("reservations were not added") + } + if service.Deploy.Resources.Reservations.MemoryBytes != 1024*MiB { + t.Fatalf("memory = %d, want %d", service.Deploy.Resources.Reservations.MemoryBytes, 1024*MiB) + } + }, + }, + { + name: "unsupported directives removed", + project: &Project{Services: Services{ + "worker": { + Name: "worker", + Image: "worker", + Restart: defaultRestartPolicy, + DNS: composeTypes.StringList{"1.1.1.1"}, + DNSSearch: composeTypes.StringList{"example.com"}, + Devices: []composeTypes.DeviceMapping{{Source: "/dev/null", Target: "/dev/null"}}, + DeviceCgroupRules: []string{"c 1:3 mr"}, + GroupAdd: []string{"audio"}, + }, + }}, + want: []FixResult{ + {Service: "worker", Field: "dns", Action: "removed", Before: "present", Reason: "unsupported directive"}, + {Service: "worker", Field: "dns_search", Action: "removed", Before: "present", Reason: "unsupported directive"}, + {Service: "worker", Field: "devices", Action: "removed", Before: "present", Reason: "unsupported directive"}, + {Service: "worker", Field: "device_cgroup_rules", Action: "removed", Before: "present", Reason: "unsupported directive"}, + {Service: "worker", Field: "group_add", Action: "removed", Before: "present", Reason: "unsupported directive"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["worker"] + if len(service.DNS) != 0 || len(service.DNSSearch) != 0 || len(service.Devices) != 0 || len(service.DeviceCgroupRules) != 0 || len(service.GroupAdd) != 0 { + t.Fatal("unsupported directives were not removed") + } + }, + }, + { + name: "deploy restart policy converted to service restart", + project: &Project{Services: Services{ + "api": { + Name: "api", + Image: "api", + Deploy: &composeTypes.DeployConfig{ + RestartPolicy: &composeTypes.RestartPolicy{Condition: "any"}, + }, + }, + }}, + want: []FixResult{ + {Service: "api", Field: "restart", Action: "added", Before: "", After: "always", Reason: "deploy.restart_policy is unsupported; converted to service-level restart"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["api"] + if service.Restart != "always" { + t.Fatalf("restart = %q, want %q", service.Restart, "always") + } + if service.Deploy.RestartPolicy != nil { + t.Fatal("deploy.restart_policy was not removed") + } + }, + }, + { + name: "udp port defaults to host mode", + project: &Project{Services: Services{ + "dns": { + Name: "dns", + Image: "coredns", + Restart: "always", + Ports: []composeTypes.ServicePortConfig{{Target: 53, Protocol: Protocol_UDP}}, + }, + }}, + want: []FixResult{ + {Service: "dns", Field: "mode", Action: "added", After: Mode_HOST, Reason: "port 53 (UDP port)"}, + }, + check: func(t *testing.T, project *Project) { + service := project.Services["dns"] + if service.Ports[0].Mode != Mode_HOST { + t.Fatalf("port mode = %q, want %q", service.Ports[0].Mode, Mode_HOST) + } + }, + }, + { + name: "no fixes needed", + project: &Project{Services: Services{ + "app": { + Name: "app", + Image: "myapp", + Restart: "always", + Ports: []composeTypes.ServicePortConfig{{Target: 80, Mode: Mode_INGRESS}}, + }, + }}, + want: nil, + check: func(t *testing.T, project *Project) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FixProject(tt.project) + if !reflect.DeepEqual(got, tt.want) { + t.Fatalf("FixProject() = %#v, want %#v", got, tt.want) + } + tt.check(t, tt.project) + }) + } +} + +func TestFixProjectOutputValidates(t *testing.T) { + loader := NewLoader(WithPath("../../../testdata/compose-fix/compose.yaml")) + project, err := loader.LoadProject(t.Context()) + if err != nil { + t.Fatalf("LoadProject() failed: %v", err) + } + + if fixes := FixProject(project); len(fixes) == 0 { + t.Fatal("expected fixes") + } + if err := ValidateProject(project, modes.ModeUnspecified); err != nil { + t.Fatalf("ValidateProject() after FixProject() failed: %v", err) + } +} diff --git a/src/testdata/compose-fix/compose.yaml b/src/testdata/compose-fix/compose.yaml new file mode 100644 index 000000000..e24f8632d --- /dev/null +++ b/src/testdata/compose-fix/compose.yaml @@ -0,0 +1,12 @@ +name: compose-fix +services: + web: + image: nginx + ports: + - target: 8080 + dns: + - 1.1.1.1 + db: + image: postgres:16 + ports: + - target: 5432 diff --git a/src/testdata/compose-fix/compose.yaml.fixup b/src/testdata/compose-fix/compose.yaml.fixup new file mode 100644 index 000000000..16f9a6fba --- /dev/null +++ b/src/testdata/compose-fix/compose.yaml.fixup @@ -0,0 +1,36 @@ +{ + "db": { + "command": null, + "entrypoint": null, + "image": "postgres:16", + "networks": { + "default": null + }, + "ports": [ + { + "mode": "host", + "target": 5432, + "protocol": "tcp" + } + ] + }, + "web": { + "command": null, + "dns": [ + "1.1.1.1" + ], + "entrypoint": null, + "image": "nginx", + "networks": { + "default": null + }, + "ports": [ + { + "mode": "ingress", + "target": 8080, + "protocol": "tcp", + "app_protocol": "http" + } + ] + } +} \ No newline at end of file diff --git a/src/testdata/compose-fix/compose.yaml.golden b/src/testdata/compose-fix/compose.yaml.golden new file mode 100644 index 000000000..ea34d6304 --- /dev/null +++ b/src/testdata/compose-fix/compose.yaml.golden @@ -0,0 +1,23 @@ +name: compose-fix +services: + db: + image: postgres:16 + networks: + default: null + ports: + - mode: ingress + target: 5432 + protocol: tcp + web: + dns: + - 1.1.1.1 + image: nginx + networks: + default: null + ports: + - mode: ingress + target: 8080 + protocol: tcp +networks: + default: + name: compose-fix_default diff --git a/src/testdata/compose-fix/compose.yaml.warnings b/src/testdata/compose-fix/compose.yaml.warnings new file mode 100644 index 000000000..d31dc75d6 --- /dev/null +++ b/src/testdata/compose-fix/compose.yaml.warnings @@ -0,0 +1,3 @@ + ! service "db": missing memory reservation; using provider-specific defaults. Specify deploy.resources.reservations.memory to avoid out-of-memory errors + ! service "db": stateful service will lose data on restart; use a managed service instead +Error: service "web": unsupported compose directive: dns