From 4bad5c11100d07427106642ce38010ca989cf735 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Thu, 25 Jul 2024 09:07:41 +1000 Subject: [PATCH] fix: allow for postgres image to be specified Also change the default to 15.4 to match production fixes #2111 --- backend/controller/pubsub/integration_test.go | 4 +-- cmd/ftl/cmd_dev.go | 2 +- cmd/ftl/cmd_schema_import.go | 2 +- cmd/ftl/cmd_serve.go | 9 +++--- docker-compose.yml | 2 +- internal/container/container.go | 29 +++++++++++++------ 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/backend/controller/pubsub/integration_test.go b/backend/controller/pubsub/integration_test.go index bd6893ac17..df80003233 100644 --- a/backend/controller/pubsub/integration_test.go +++ b/backend/controller/pubsub/integration_test.go @@ -65,13 +65,13 @@ func TestConsumptionDelay(t *testing.T) { SELECT created_at, ROW_NUMBER() OVER (ORDER BY created_at) AS row_num FROM ( select * from topic_events order by created_at - ) + ) AS sub_event_times ), async_call_times AS ( SELECT created_at, ROW_NUMBER() OVER (ORDER BY created_at) AS row_num FROM ( select * from async_calls ac order by created_at - ) + ) AS sub_async_calls ) SELECT COUNT(*) FROM event_times diff --git a/cmd/ftl/cmd_dev.go b/cmd/ftl/cmd_dev.go index e596d84fa3..79427253b6 100644 --- a/cmd/ftl/cmd_dev.go +++ b/cmd/ftl/cmd_dev.go @@ -47,7 +47,7 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error } if d.InitDB { - dsn, err := d.ServeCmd.setupDB(ctx) + dsn, err := d.ServeCmd.setupDB(ctx, d.ServeCmd.DatabaseImage) if err != nil { return fmt.Errorf("failed to setup database: %w", err) } diff --git a/cmd/ftl/cmd_schema_import.go b/cmd/ftl/cmd_schema_import.go index 3ce698fc36..917967b46e 100644 --- a/cmd/ftl/cmd_schema_import.go +++ b/cmd/ftl/cmd_schema_import.go @@ -136,7 +136,7 @@ func query(ctx context.Context, prompt string) error { func (s *schemaImportCmd) setup(ctx context.Context) error { logger := log.FromContext(ctx) - exists, err := container.DoesExist(ctx, ollamaContainerName) + exists, err := container.DoesExist(ctx, ollamaContainerName, optional.None[string]()) if err != nil { return err } diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 001de80f35..1f985915fe 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -44,6 +44,7 @@ type serveCmd struct { Stop bool `help:"Stop the running FTL instance. Can be used with --background to restart the server" default:"false"` StartupTimeout time.Duration `help:"Timeout for the server to start up." default:"1m"` ObservabilityConfig observability.Config `embed:"" prefix:"o11y-"` + DatabaseImage string `help:"The container image to start for the database" default:"postgres:15.4" env:"FTL_DATABASE_IMAGE" hidden:""` controller.CommonConfig } @@ -87,7 +88,7 @@ func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, ini logger.Infof("Starting FTL with %d controller(s)", s.Controllers) // Bring up the DB and DAL. - dsn, err := s.setupDB(ctx) + dsn, err := s.setupDB(ctx, s.DatabaseImage) if err != nil { return err } @@ -299,13 +300,13 @@ func isServeRunning(logger *log.Logger) (bool, error) { return true, nil } -func (s *serveCmd) setupDB(ctx context.Context) (string, error) { +func (s *serveCmd) setupDB(ctx context.Context, image string) (string, error) { logger := log.FromContext(ctx) recreate := s.Recreate port := s.DBPort - exists, err := container.DoesExist(ctx, ftlContainerName) + exists, err := container.DoesExist(ctx, ftlContainerName, optional.Some(image)) if err != nil { return "", err } @@ -320,7 +321,7 @@ func (s *serveCmd) setupDB(ctx context.Context) (string, error) { return "", fmt.Errorf("failed to close listener: %w", err) } - err = container.RunDB(ctx, ftlContainerName, s.DBPort) + err = container.RunDB(ctx, ftlContainerName, s.DBPort, image) if err != nil { return "", err } diff --git a/docker-compose.yml b/docker-compose.yml index 0d84b9d0ce..0854ce9ac6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: db: - image: postgres + image: postgres:15.4 command: postgres user: postgres # For local debugging diff --git a/internal/container/container.go b/internal/container/container.go index 1956cd4a69..4bb5a82da8 100644 --- a/internal/container/container.go +++ b/internal/container/container.go @@ -24,8 +24,9 @@ var dockerClient = once.Once(func(ctx context.Context) (*client.Client, error) { return client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) }) -func DoesExist(ctx context.Context, name string) (bool, error) { +func DoesExist(ctx context.Context, name string, image optional.Option[string]) (bool, error) { cli, err := dockerClient.Get(ctx) + logger := log.FromContext(ctx) if err != nil { return false, err } @@ -37,8 +38,20 @@ func DoesExist(ctx context.Context, name string) (bool, error) { if err != nil { return false, fmt.Errorf("failed to list containers: %w", err) } - - return len(containers) > 0, nil + if len(containers) == 0 { + return false, nil + } + imageName, ok := image.Get() + if !ok { + return true, nil + } + for _, c := range containers { + if c.Image != imageName { + logger.Infof("possible database version mismatch, expecting to use container image %s for container with name %s, bit it was already running with image %s", image, name, c.Image) + break + } + } + return true, nil } // Pull pulls the given image. @@ -105,28 +118,26 @@ func Run(ctx context.Context, image, name string, hostPort, containerPort int, v } // RunDB runs a new detached postgres container with the given name and exposed port. -func RunDB(ctx context.Context, name string, port int) error { +func RunDB(ctx context.Context, name string, port int, image string) error { cli, err := dockerClient.Get(ctx) if err != nil { return err } - const containerName = "postgres" - - exists, err := DoesExist(ctx, containerName) + exists, err := DoesExist(ctx, name, optional.Some(image)) if err != nil { return err } if !exists { - err = Pull(ctx, "postgres:latest") + err = Pull(ctx, image) if err != nil { return err } } config := container.Config{ - Image: "postgres:latest", + Image: image, Env: []string{"POSTGRES_PASSWORD=secret"}, User: "postgres", Cmd: []string{"postgres"},