From a03f47b3ddb48149c428aae07f418aac310e0368 Mon Sep 17 00:00:00 2001 From: David Moore <4121492+davemooreuws@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:27:13 +1100 Subject: [PATCH] fix: handle db connection string host for nitric run (#827) --- cmd/run.go | 1 + cmd/start.go | 1 + pkg/cloud/cloud.go | 21 ++++++++++++++++- pkg/cloud/sql/sql.go | 27 +++++++++++++-------- pkg/dashboard/dashboard.go | 7 +++++- pkg/project/dockerhost/dockerhost.go | 35 ++++++++++++++++++++++++++++ pkg/project/migrations.go | 10 ++------ 7 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 pkg/project/dockerhost/dockerhost.go diff --git a/cmd/run.go b/cmd/run.go index e82513b50..8df668dee 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -102,6 +102,7 @@ var runCmd = &cobra.Command{ LogWriter: logWriter, LocalConfig: proj.LocalConfig, MigrationRunner: project.BuildAndRunMigrations, + LocalCloudMode: cloud.LocalCloudModeRun, }) tui.CheckErr(err) runView.Send(local.LocalCloudStartStatusMsg{Status: local.Done}) diff --git a/cmd/start.go b/cmd/start.go index 16ac3bd49..b1d6c781b 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -182,6 +182,7 @@ var startCmd = &cobra.Command{ LogWriter: logWriter, LocalConfig: proj.LocalConfig, MigrationRunner: project.BuildAndRunMigrations, + LocalCloudMode: cloud.LocalCloudModeStart, }) tui.CheckErr(err) runView.Send(local.LocalCloudStartStatusMsg{Status: local.Done}) diff --git a/pkg/cloud/cloud.go b/pkg/cloud/cloud.go index 9efe39347..90163fa1c 100644 --- a/pkg/cloud/cloud.go +++ b/pkg/cloud/cloud.go @@ -39,6 +39,7 @@ import ( "github.com/nitrictech/cli/pkg/cloud/websockets" "github.com/nitrictech/cli/pkg/grpcx" "github.com/nitrictech/cli/pkg/netx" + "github.com/nitrictech/cli/pkg/project/dockerhost" "github.com/nitrictech/cli/pkg/project/localconfig" "github.com/nitrictech/nitric/core/pkg/logger" "github.com/nitrictech/nitric/core/pkg/server" @@ -229,11 +230,22 @@ func (lc *LocalCloud) AddService(serviceName string) (int, error) { return ports[0], nil } +// LocalCloudMode type run or start +type LocalCloudMode string + +const ( + // LocalCloudModeRun - run mode + LocalCloudModeRun LocalCloudMode = "run" + // LocalCloudModeStart - start mode + LocalCloudModeStart LocalCloudMode = "start" +) + type LocalCloudOptions struct { TLSCredentials *gateway.TLSCredentials LogWriter io.Writer LocalConfig localconfig.LocalConfiguration MigrationRunner sql.MigrationRunner + LocalCloudMode LocalCloudMode } func New(projectName string, opts LocalCloudOptions) (*LocalCloud, error) { @@ -291,7 +303,14 @@ func New(projectName string, opts LocalCloudOptions) (*LocalCloud, error) { return nil, err } - localDatabaseService, err := sql.NewLocalSqlServer(projectName, localResources, opts.MigrationRunner) + connectionStringHost := "localhost" + + // Use the host.docker.internal address for connection strings with local cloud run mode + if opts.LocalCloudMode == LocalCloudModeRun { + connectionStringHost = dockerhost.GetInternalDockerHost() + } + + localDatabaseService, err := sql.NewLocalSqlServer(projectName, localResources, opts.MigrationRunner, connectionStringHost) if err != nil { return nil, err } diff --git a/pkg/cloud/sql/sql.go b/pkg/cloud/sql/sql.go index 97251adbd..65effa557 100644 --- a/pkg/cloud/sql/sql.go +++ b/pkg/cloud/sql/sql.go @@ -69,10 +69,11 @@ type ( ) type LocalSqlServer struct { - projectName string - containerId string - port int - State State + projectName string + containerId string + connectionStringHost string + port int + State State sqlpb.UnimplementedSqlServer migrationRunner MigrationRunner @@ -120,7 +121,7 @@ func (l *LocalSqlServer) ensureDatabaseExists(databaseName string) (string, erro } // Return the connection string of the new database - return fmt.Sprintf("postgresql://postgres:localsecret@localhost:%d/%s?sslmode=disable", l.port, databaseName), nil + return fmt.Sprintf("postgresql://postgres:localsecret@%s:%d/%s?sslmode=disable", l.connectionStringHost, l.port, databaseName), nil } func (l *LocalSqlServer) start() error { @@ -338,12 +339,18 @@ func (l *LocalSqlServer) RegisterDatabases(lrs resources.LocalResourcesState) { l.Publish(l.State) } -func NewLocalSqlServer(projectName string, localResources *resources.LocalResourcesService, migrationRunner MigrationRunner) (*LocalSqlServer, error) { +func NewLocalSqlServer(projectName string, localResources *resources.LocalResourcesService, migrationRunner MigrationRunner, connectionStringHost string) (*LocalSqlServer, error) { + if connectionStringHost == "" { + // default to localhost + connectionStringHost = "localhost" + } + localSql := &LocalSqlServer{ - projectName: projectName, - State: make(State), - bus: EventBus.New(), - migrationRunner: migrationRunner, + projectName: projectName, + State: make(State), + bus: EventBus.New(), + migrationRunner: migrationRunner, + connectionStringHost: connectionStringHost, } err := localSql.start() diff --git a/pkg/dashboard/dashboard.go b/pkg/dashboard/dashboard.go index e13b378dd..f79f5c3a1 100644 --- a/pkg/dashboard/dashboard.go +++ b/pkg/dashboard/dashboard.go @@ -39,6 +39,7 @@ import ( "github.com/nitrictech/cli/pkg/cloud" "github.com/nitrictech/cli/pkg/collector" "github.com/nitrictech/cli/pkg/netx" + "github.com/nitrictech/cli/pkg/project/dockerhost" resourcespb "github.com/nitrictech/nitric/core/pkg/proto/resources/v1" websocketspb "github.com/nitrictech/nitric/core/pkg/proto/websockets/v1" @@ -603,12 +604,16 @@ func (d *Dashboard) updateSqlDatabases(state sql.State) { sqlDatabases := []*SQLDatabaseSpec{} for dbName, db := range state { + // connection strings should always use localhost for dashboard + strToReplace := dockerhost.GetInternalDockerHost() + connectionString := strings.Replace(db.ConnectionString, strToReplace, "localhost", 1) + sqlDatabases = append(sqlDatabases, &SQLDatabaseSpec{ BaseResourceSpec: &BaseResourceSpec{ Name: dbName, RequestingServices: db.ResourceRegister.RequestingServices, }, - ConnectionString: db.ConnectionString, + ConnectionString: connectionString, Status: db.Status, MigrationsPath: db.ResourceRegister.Resource.Migrations.GetMigrationsPath(), }) diff --git a/pkg/project/dockerhost/dockerhost.go b/pkg/project/dockerhost/dockerhost.go new file mode 100644 index 000000000..554944e5f --- /dev/null +++ b/pkg/project/dockerhost/dockerhost.go @@ -0,0 +1,35 @@ +// Copyright Nitric Pty Ltd. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dockerhost + +import ( + goruntime "runtime" + + "github.com/nitrictech/nitric/core/pkg/env" +) + +func GetInternalDockerHost() string { + dockerHost := "host.docker.internal" + + if goruntime.GOOS == "linux" { + host := env.GetEnv("NITRIC_DOCKER_HOST", "172.17.0.1") + + return host.String() + } + + return dockerHost +} diff --git a/pkg/project/migrations.go b/pkg/project/migrations.go index 62d953fad..d1c447ac6 100644 --- a/pkg/project/migrations.go +++ b/pkg/project/migrations.go @@ -31,8 +31,8 @@ import ( "github.com/nitrictech/cli/pkg/cloud/sql" "github.com/nitrictech/cli/pkg/collector" "github.com/nitrictech/cli/pkg/docker" + "github.com/nitrictech/cli/pkg/project/dockerhost" "github.com/nitrictech/cli/pkg/project/runtime" - "github.com/nitrictech/nitric/core/pkg/env" "github.com/nitrictech/nitric/core/pkg/logger" resourcespb "github.com/nitrictech/nitric/core/pkg/proto/resources/v1" ) @@ -196,13 +196,7 @@ func RunMigration(databaseName string, connectionString string) error { imageName := migrationImageName(databaseName) // Update connection string for docker host... - dockerHost := "host.docker.internal" - - if goruntime.GOOS == "linux" { - host := env.GetEnv("NITRIC_DOCKER_HOST", "172.17.0.1") - - dockerHost = host.String() - } + dockerHost := dockerhost.GetInternalDockerHost() dockerConnectionString := strings.Replace(connectionString, "localhost", dockerHost, 1)