Skip to content

Commit 053ebde

Browse files
committed
Show note if instance is running in the background
1 parent 298adb6 commit 053ebde

4 files changed

Lines changed: 114 additions & 3 deletions

File tree

cmd/logout.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77

88
"github.com/localstack/lstk/internal/api"
99
"github.com/localstack/lstk/internal/auth"
10+
"github.com/localstack/lstk/internal/container"
1011
"github.com/localstack/lstk/internal/env"
1112
"github.com/localstack/lstk/internal/output"
13+
"github.com/localstack/lstk/internal/runtime"
1214
"github.com/localstack/lstk/internal/ui"
1315
"github.com/spf13/cobra"
1416
)
@@ -21,7 +23,11 @@ func newLogoutCmd(cfg *env.Env) *cobra.Command {
2123
RunE: func(cmd *cobra.Command, args []string) error {
2224
platformClient := api.NewPlatformClient(cfg.APIEndpoint)
2325
if isInteractiveMode(cfg) {
24-
return ui.RunLogout(cmd.Context(), platformClient, cfg.AuthToken, cfg.ForceFileKeyring)
26+
var rt runtime.Runtime
27+
if dockerRuntime, err := runtime.NewDockerRuntime(); err == nil {
28+
rt = dockerRuntime
29+
}
30+
return ui.RunLogout(cmd.Context(), rt, platformClient, cfg.AuthToken, cfg.ForceFileKeyring)
2531
}
2632

2733
sink := output.NewPlainSink(os.Stdout)
@@ -36,6 +42,12 @@ func newLogoutCmd(cfg *env.Env) *cobra.Command {
3642
}
3743
return fmt.Errorf("failed to logout: %w", err)
3844
}
45+
46+
if rt, err := runtime.NewDockerRuntime(); err == nil {
47+
if running, err := container.AnyRunning(cmd.Context(), rt); err == nil && running {
48+
output.EmitNote(sink, "LocalStack is still running in the background")
49+
}
50+
}
3951
return nil
4052
},
4153
}

internal/container/running.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package container
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/localstack/lstk/internal/config"
8+
"github.com/localstack/lstk/internal/runtime"
9+
)
10+
11+
func AnyRunning(ctx context.Context, rt runtime.Runtime) (bool, error) {
12+
cfg, err := config.Get()
13+
if err != nil {
14+
return false, fmt.Errorf("failed to get config: %w", err)
15+
}
16+
17+
for _, c := range cfg.Containers {
18+
running, err := rt.IsRunning(ctx, c.Name())
19+
if err != nil {
20+
return false, fmt.Errorf("checking %s running: %w", c.Name(), err)
21+
}
22+
if running {
23+
return true, nil
24+
}
25+
}
26+
27+
return false, nil
28+
}

internal/container/running_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package container
2+
3+
import (
4+
"context"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/localstack/lstk/internal/config"
10+
"github.com/localstack/lstk/internal/runtime"
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
"go.uber.org/mock/gomock"
14+
)
15+
16+
func TestAnyRunning_ReturnsTrueWhenConfiguredContainerIsRunning(t *testing.T) {
17+
initTestConfig(t, `
18+
[[containers]]
19+
type = "aws"
20+
tag = "latest"
21+
port = "4566"
22+
`)
23+
24+
ctrl := gomock.NewController(t)
25+
mockRT := runtime.NewMockRuntime(ctrl)
26+
mockRT.EXPECT().IsRunning(gomock.Any(), "localstack-aws").Return(true, nil)
27+
28+
running, err := AnyRunning(context.Background(), mockRT)
29+
30+
require.NoError(t, err)
31+
assert.True(t, running)
32+
}
33+
34+
func TestAnyRunning_ReturnsFalseWhenConfiguredContainerIsNotRunning(t *testing.T) {
35+
initTestConfig(t, `
36+
[[containers]]
37+
type = "aws"
38+
tag = "latest"
39+
port = "4566"
40+
`)
41+
42+
ctrl := gomock.NewController(t)
43+
mockRT := runtime.NewMockRuntime(ctrl)
44+
mockRT.EXPECT().IsRunning(gomock.Any(), "localstack-aws").Return(false, nil)
45+
46+
running, err := AnyRunning(context.Background(), mockRT)
47+
48+
require.NoError(t, err)
49+
assert.False(t, running)
50+
}
51+
52+
func initTestConfig(t *testing.T, content string) {
53+
t.Helper()
54+
55+
dir := t.TempDir()
56+
path := filepath.Join(dir, "config.toml")
57+
err := os.WriteFile(path, []byte(content), 0o600)
58+
require.NoError(t, err)
59+
require.NoError(t, config.InitFromPath(path))
60+
t.Cleanup(func() {
61+
require.NoError(t, config.InitFromPath(path))
62+
})
63+
}

internal/ui/run_logout.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
tea "github.com/charmbracelet/bubbletea"
99
"github.com/localstack/lstk/internal/api"
1010
"github.com/localstack/lstk/internal/auth"
11+
"github.com/localstack/lstk/internal/container"
1112
"github.com/localstack/lstk/internal/output"
13+
"github.com/localstack/lstk/internal/runtime"
1214
)
1315

14-
func RunLogout(parentCtx context.Context, platformClient api.PlatformAPI, authToken string, forceFileKeyring bool) error {
16+
func RunLogout(parentCtx context.Context, rt runtime.Runtime, platformClient api.PlatformAPI, authToken string, forceFileKeyring bool) error {
1517
_, cancel := context.WithCancel(parentCtx)
1618
defer cancel()
1719

@@ -28,8 +30,14 @@ func RunLogout(parentCtx context.Context, platformClient api.PlatformAPI, authTo
2830
return
2931
}
3032

31-
a := auth.New(output.NewTUISink(programSender{p: p}), platformClient, tokenStorage, authToken, "", false)
33+
sink := output.NewTUISink(programSender{p: p})
34+
a := auth.New(sink, platformClient, tokenStorage, authToken, "", false)
3235
err = a.Logout()
36+
if err == nil && rt != nil {
37+
if running, runningErr := container.AnyRunning(parentCtx, rt); runningErr == nil && running {
38+
output.EmitNote(sink, "LocalStack is still running in the background")
39+
}
40+
}
3341

3442
runErrCh <- err
3543
if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, auth.ErrNotLoggedIn) {

0 commit comments

Comments
 (0)