Skip to content

Commit cb71ed1

Browse files
refactoring
1 parent 8ecc55a commit cb71ed1

2 files changed

Lines changed: 41 additions & 25 deletions

File tree

internal/container/start.go

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ func Start(ctx context.Context, rt runtime.Runtime, sink output.Sink, platformCl
5454
}
5555
}
5656

57-
// Check state before proceeding: skip already-running containers, reject port conflicts.
5857
containers, cfg.Containers, err = selectContainersToStart(ctx, rt, sink, containers, cfg.Containers)
5958
if err != nil {
6059
return err
@@ -63,50 +62,65 @@ func Start(ctx context.Context, rt runtime.Runtime, sink output.Sink, platformCl
6362
return nil
6463
}
6564

66-
// Pull all images first
67-
for _, config := range containers {
65+
// TODO validate license for tag "latest" without resolving the actual image version,
66+
// and avoid pulling all images first
67+
if err := pullImages(ctx, rt, sink, containers); err != nil {
68+
return err
69+
}
70+
71+
if err := validateLicenses(ctx, rt, sink, platformClient, containers, cfg.Containers, token); err != nil {
72+
return err
73+
}
74+
75+
return startContainers(ctx, rt, sink, containers)
76+
}
77+
78+
func pullImages(ctx context.Context, rt runtime.Runtime, sink output.Sink, containers []runtime.ContainerConfig) error {
79+
for _, c := range containers {
6880
// Remove any existing stopped container with the same name
69-
if err := rt.Remove(ctx, config.Name); err != nil && !errdefs.IsNotFound(err) {
70-
return fmt.Errorf("failed to remove existing container %s: %w", config.Name, err)
81+
if err := rt.Remove(ctx, c.Name); err != nil && !errdefs.IsNotFound(err) {
82+
return fmt.Errorf("failed to remove existing container %s: %w", c.Name, err)
7183
}
7284

73-
output.EmitStatus(sink, "pulling", config.Image, "")
85+
output.EmitStatus(sink, "pulling", c.Image, "")
7486
progress := make(chan runtime.PullProgress)
7587
go func() {
7688
for p := range progress {
77-
output.EmitProgress(sink, config.Image, p.LayerID, p.Status, p.Current, p.Total)
89+
output.EmitProgress(sink, c.Image, p.LayerID, p.Status, p.Current, p.Total)
7890
}
7991
}()
80-
if err := rt.PullImage(ctx, config.Image, progress); err != nil {
81-
return fmt.Errorf("failed to pull image %s: %w", config.Image, err)
92+
if err := rt.PullImage(ctx, c.Image, progress); err != nil {
93+
return fmt.Errorf("failed to pull image %s: %w", c.Image, err)
8294
}
8395
}
96+
return nil
97+
}
8498

85-
// TODO validate license for tag "latest" without resolving the actual image version,
86-
// and avoid pulling all images first
87-
for i, c := range cfg.Containers {
99+
func validateLicenses(ctx context.Context, rt runtime.Runtime, sink output.Sink, platformClient api.PlatformAPI, containers []runtime.ContainerConfig, cfgContainers []config.ContainerConfig, token string) error {
100+
for i, c := range cfgContainers {
88101
if err := validateLicense(ctx, rt, sink, platformClient, containers[i], &c, token); err != nil {
89102
return err
90103
}
91104
}
105+
return nil
106+
}
92107

93-
// Start containers
94-
for _, config := range containers {
95-
output.EmitStatus(sink, "starting", config.Name, "")
96-
containerID, err := rt.Start(ctx, config)
108+
func startContainers(ctx context.Context, rt runtime.Runtime, sink output.Sink, containers []runtime.ContainerConfig) error {
109+
for _, c := range containers {
110+
output.EmitStatus(sink, "starting", c.Name, "")
111+
containerID, err := rt.Start(ctx, c)
97112
if err != nil {
98-
return fmt.Errorf("failed to start %s: %w", config.Name, err)
113+
return fmt.Errorf("failed to start %s: %w", c.Name, err)
99114
}
100115

101-
output.EmitStatus(sink, "waiting", config.Name, "")
102-
healthURL := fmt.Sprintf("http://localhost:%s%s", config.Port, config.HealthPath)
103-
if err := awaitStartup(ctx, rt, sink, containerID, config.Name, healthURL); err != nil {
116+
output.EmitStatus(sink, "waiting", c.Name, "")
117+
healthURL := fmt.Sprintf("http://localhost:%s%s", c.Port, c.HealthPath)
118+
if err := awaitStartup(ctx, rt, sink, containerID, c.Name, healthURL); err != nil {
104119
return err
105120
}
106121

107-
output.EmitStatus(sink, "ready", config.Name, fmt.Sprintf("containerId: %s", containerID[:12]))
122+
output.EmitStatus(sink, "ready", c.Name, fmt.Sprintf("containerId: %s", containerID[:12]))
108123
}
109-
110124
return nil
111125
}
112126

@@ -140,7 +154,10 @@ func checkPortAvailable(port string) error {
140154
if err != nil {
141155
return nil
142156
}
143-
conn.Close()
157+
err = conn.Close()
158+
if err != nil {
159+
return nil
160+
}
144161
return fmt.Errorf("port %s already in use", port)
145162
}
146163

test/integration/start_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/stretchr/testify/require"
1414
)
1515

16-
1716
func TestStartCommandSucceedsWithValidToken(t *testing.T) {
1817
requireDocker(t)
1918
authToken := os.Getenv("LOCALSTACK_AUTH_TOKEN")
@@ -120,7 +119,7 @@ func TestStartCommandFailsWhenPortInUse(t *testing.T) {
120119

121120
ln, err := net.Listen("tcp", ":4566")
122121
require.NoError(t, err, "failed to bind port 4566 for test")
123-
defer ln.Close()
122+
defer func() { _ = ln.Close() }()
124123

125124
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
126125
defer cancel()

0 commit comments

Comments
 (0)