diff --git a/internal/container/start.go b/internal/container/start.go index b157e938..e3b84b1e 100644 --- a/internal/container/start.go +++ b/internal/container/start.go @@ -542,7 +542,8 @@ func awaitStartup(ctx context.Context, rt runtime.Runtime, sink output.Sink, con func filterHostEnv(envList []string) []string { var out []string for _, e := range envList { - if strings.HasPrefix(e, "CI=") || (strings.HasPrefix(e, "LOCALSTACK_") && !strings.HasPrefix(e, "LOCALSTACK_AUTH_TOKEN=")) { + if strings.HasPrefix(e, "CI=") || + (strings.HasPrefix(e, "LOCALSTACK_") && !strings.HasPrefix(e, "LOCALSTACK_AUTH_TOKEN=")) { out = append(out, e) } } diff --git a/internal/container/start_test.go b/internal/container/start_test.go index e0325b77..27b672ef 100644 --- a/internal/container/start_test.go +++ b/internal/container/start_test.go @@ -156,6 +156,7 @@ func TestFilterHostEnv(t *testing.T) { "LOCALSTACK_DISABLE_EVENTS=1", "LOCALSTACK_API_ENDPOINT=https://example.test", "LOCALSTACK_AUTH_TOKEN=host-token", + "LOCALSTACK_PERSISTENCE=1", "PATH=/usr/bin", "HOME=/home/user", "CI_PIPELINE=foo", @@ -166,10 +167,10 @@ func TestFilterHostEnv(t *testing.T) { assert.Contains(t, got, "CI=true") assert.Contains(t, got, "LOCALSTACK_DISABLE_EVENTS=1") assert.Contains(t, got, "LOCALSTACK_API_ENDPOINT=https://example.test") + assert.Contains(t, got, "LOCALSTACK_PERSISTENCE=1") assert.NotContains(t, got, "LOCALSTACK_AUTH_TOKEN=host-token", "host LOCALSTACK_AUTH_TOKEN must be filtered so it cannot overwrite the lstk-resolved token") assert.NotContains(t, got, "PATH=/usr/bin") assert.NotContains(t, got, "HOME=/home/user") assert.NotContains(t, got, "CI_PIPELINE=foo", "only exact CI= must be forwarded, not CI_*") } - diff --git a/test/integration/env/env.go b/test/integration/env/env.go index 2dbf67f0..f47876be 100644 --- a/test/integration/env/env.go +++ b/test/integration/env/env.go @@ -17,6 +17,7 @@ const ( AnalyticsEndpoint Key = "LSTK_ANALYTICS_ENDPOINT" DisableEvents Key = "LOCALSTACK_DISABLE_EVENTS" Home Key = "HOME" + Persistence Key = "LOCALSTACK_PERSISTENCE" ) func Get(key Key) string { diff --git a/test/integration/start_test.go b/test/integration/start_test.go index 8cf2fe08..5638963c 100644 --- a/test/integration/start_test.go +++ b/test/integration/start_test.go @@ -343,6 +343,67 @@ func TestStartCommandPassesCIAndLocalStackEnvVars(t *testing.T) { assert.NotEmpty(t, envVars["LOCALSTACK_AUTH_TOKEN"]) } +func TestStartCommandForwardsPersistenceEnvFromHost(t *testing.T) { + requireDocker(t) + _ = env.Require(t, env.AuthToken) + + cleanup() + t.Cleanup(cleanup) + + mockServer := createMockLicenseServer(true) + defer mockServer.Close() + + ctx := testContext(t) + _, stderr, err := runLstk(t, ctx, "", env.With(env.APIEndpoint, mockServer.URL). + With(env.Persistence, "1"), + "start") + require.NoError(t, err, "lstk start failed: %s", stderr) + requireExitCode(t, 0, err) + + inspect, err := dockerClient.ContainerInspect(ctx, containerName) + require.NoError(t, err, "failed to inspect container") + require.True(t, inspect.State.Running) + + envVars := containerEnvToMap(inspect.Config.Env) + assert.Equal(t, "1", envVars["LOCALSTACK_PERSISTENCE"]) +} + +func TestStartCommandSetsPersistenceEnvFromConfig(t *testing.T) { + requireDocker(t) + _ = env.Require(t, env.AuthToken) + + cleanup() + t.Cleanup(cleanup) + + mockServer := createMockLicenseServer(true) + defer mockServer.Close() + + configContent := ` +[env.persistence] +PERSISTENCE = "1" + +[[containers]] +type = "aws" +tag = "latest" +port = "4566" +env = ["persistence"] +` + configFile := filepath.Join(t.TempDir(), "config.toml") + require.NoError(t, os.WriteFile(configFile, []byte(configContent), 0644)) + + ctx := testContext(t) + _, stderr, err := runLstk(t, ctx, "", env.With(env.APIEndpoint, mockServer.URL), "--config", configFile, "start") + require.NoError(t, err, "lstk start failed: %s", stderr) + requireExitCode(t, 0, err) + + inspect, err := dockerClient.ContainerInspect(ctx, containerName) + require.NoError(t, err, "failed to inspect container") + require.True(t, inspect.State.Running) + + envVars := containerEnvToMap(inspect.Config.Env) + assert.Equal(t, "1", envVars["PERSISTENCE"]) +} + // hasBindTarget checks if any bind mount targets the given container path. func hasBindTarget(binds []string, containerPath string) bool { for _, b := range binds {