Remove project network on compose down

Signed-off-by: Guillame Tardif <guillaume.tardif@gmail.com>
This commit is contained in:
Guillame Tardif 2020-11-27 16:15:13 +01:00
parent 9b140930a7
commit 8b60c76684
4 changed files with 85 additions and 28 deletions

View File

@ -143,6 +143,25 @@ func (s *composeService) Down(ctx context.Context, projectName string) error {
return nil
})
}
err = eg.Wait()
if err != nil {
return err
}
networks, err := s.apiClient.NetworkList(ctx, moby.NetworkListOptions{
Filters: filters.NewArgs(
projectFilter(projectName),
),
})
if err != nil {
return err
}
for _, network := range networks {
networkID := network.ID
networkName := network.Name
eg.Go(func() error {
return s.ensureNetworkDown(ctx, networkID, networkName)
})
}
return eg.Wait()
}
@ -593,6 +612,32 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi
return nil
}
func (s *composeService) ensureNetworkDown(ctx context.Context, networkID string, networkName string) error {
w := progress.ContextWriter(ctx)
w.Event(progress.Event{
ID: fmt.Sprintf("Network %q", networkName),
Status: progress.Working,
StatusText: "Delete",
})
if err := s.apiClient.NetworkRemove(ctx, networkID); err != nil {
msg := fmt.Sprintf("failed to create network %s", networkID)
w.Event(progress.Event{
ID: fmt.Sprintf("Network %q", networkName),
Status: progress.Error,
StatusText: "Error: " + msg,
})
return errors.Wrapf(err, msg)
}
w.Event(progress.Event{
ID: fmt.Sprintf("Network %q", networkName),
Status: progress.Done,
StatusText: "Deleted",
})
return nil
}
func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeConfig) error {
// TODO could identify volume by label vs name
_, err := s.apiClient.VolumeInspect(ctx, volume.Name)

View File

@ -35,12 +35,11 @@ func TestLocalBackendComposeUp(t *testing.T) {
const projectName = "compose-e2e-demo"
networkList := c.RunDockerCmd("--context", "default", "network", "ls")
t.Run("up", func(t *testing.T) {
c.RunDockerCmd("compose", "up", "-f", "../../tests/composefiles/demo_multi_port.yaml", "--project-name", projectName)
})
t.Cleanup(func() {
_ = c.RunDockerCmd("compose", "down", "--project-name", projectName)
})
t.Run("check running project", func(t *testing.T) {
res := c.RunDockerCmd("compose", "ps", "-p", projectName)
@ -49,6 +48,9 @@ func TestLocalBackendComposeUp(t *testing.T) {
endpoint := "http://localhost:80"
output := HTTPGetWithRetry(t, endpoint+"/words/noun", http.StatusOK, 2*time.Second, 20*time.Second)
assert.Assert(t, strings.Contains(output, `"word":`))
res = c.RunDockerCmd("--context", "default", "network", "ls")
assert.Equal(t, len(Lines(res.Stdout())), len(Lines(networkList.Stdout()))+1)
})
t.Run("check compose labels", func(t *testing.T) {
@ -67,4 +69,13 @@ func TestLocalBackendComposeUp(t *testing.T) {
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.project": `})
res.Assert(t, icmd.Expected{Out: `"com.docker.compose.version": `})
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerCmd("compose", "down", "--project-name", projectName)
})
t.Run("check compose labels", func(t *testing.T) {
networksAfterDown := c.RunDockerCmd("--context", "default", "network", "ls")
assert.Equal(t, networkList.Stdout(), networksAfterDown.Stdout())
})
}

View File

@ -206,7 +206,7 @@ func TestRunVolume(t *testing.T) {
t.Cleanup(func() {
c.RunDockerCmd("volume", "rm", volumeID)
res := c.RunDockerCmd("volume", "ls")
lines := lines(res.Stdout())
lines := Lines(res.Stdout())
assert.Equal(t, len(lines), 1)
})
@ -217,13 +217,13 @@ func TestRunVolume(t *testing.T) {
t.Run("list volumes", func(t *testing.T) {
res := c.RunDockerCmd("volume", "ls", "--quiet")
l := lines(res.Stdout())
l := Lines(res.Stdout())
assert.Equal(t, len(l), 2)
assert.Equal(t, l[0], volumeID)
assert.Equal(t, l[1], volumeID2)
res = c.RunDockerCmd("volume", "ls")
l = lines(res.Stdout())
l = Lines(res.Stdout())
assert.Equal(t, len(l), 3)
firstAccount := l[1]
fields := strings.Fields(firstAccount)
@ -251,7 +251,7 @@ func TestRunVolume(t *testing.T) {
t.Run("delete only fileshare", func(t *testing.T) {
c.RunDockerCmd("volume", "rm", volumeID2)
res := c.RunDockerCmd("volume", "ls")
lines := lines(res.Stdout())
lines := Lines(res.Stdout())
assert.Equal(t, len(lines), 2)
assert.Assert(t, !strings.Contains(res.Stdout(), fileshareName2), "second fileshare still visible after rm")
})
@ -288,7 +288,7 @@ func TestRunVolume(t *testing.T) {
t.Run("ps", func(t *testing.T) {
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
l := out[len(out)-1]
assert.Assert(t, strings.Contains(l, container), "Looking for %q in line: %s", container, l)
assert.Assert(t, strings.Contains(l, "nginx"))
@ -379,10 +379,6 @@ func TestRunVolume(t *testing.T) {
})
}
func lines(output string) []string {
return strings.Split(strings.TrimSpace(output), "\n")
}
func TestContainerRunAttached(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)
_, groupID, location := setupTestResourceGroup(t, c)
@ -472,11 +468,11 @@ func TestContainerRunAttached(t *testing.T) {
t.Run("ps stopped container with --all", func(t *testing.T) {
res := c.RunDockerCmd("ps", container)
out := lines(res.Stdout())
out := Lines(res.Stdout())
assert.Assert(t, is.Len(out, 1))
res = c.RunDockerCmd("ps", "--all", container)
out = lines(res.Stdout())
out = Lines(res.Stdout())
assert.Assert(t, is.Len(out, 2))
})
@ -497,14 +493,14 @@ func TestContainerRunAttached(t *testing.T) {
res := c.RunDockerCmd("prune")
assert.Equal(t, "Deleted resources:\nTotal CPUs reclaimed: 0.00, total memory reclaimed: 0.00 GB\n", res.Stdout())
res = c.RunDockerCmd("ps")
l := lines(res.Stdout())
l := Lines(res.Stdout())
assert.Equal(t, 2, len(l))
res = c.RunDockerCmd("prune", "--force")
assert.Equal(t, "Deleted resources:\n"+container+"\nTotal CPUs reclaimed: 0.10, total memory reclaimed: 0.10 GB\n", res.Stdout())
res = c.RunDockerCmd("ps", "--all")
l = lines(res.Stdout())
l = Lines(res.Stdout())
assert.Equal(t, 1, len(l))
})
}
@ -539,7 +535,7 @@ func TestUpSecretsResources(t *testing.T) {
t.Run("compose up", func(t *testing.T) {
c.RunDockerCmd("compose", "up", "-f", composefilePath, "--project-name", composeProjectName)
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
// Check 2 containers running
assert.Assert(t, is.Len(out, 3))
})
@ -547,7 +543,7 @@ func TestUpSecretsResources(t *testing.T) {
t.Cleanup(func() {
c.RunDockerCmd("compose", "down", "--project-name", composeProjectName)
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
assert.Equal(t, len(out), 1)
})
@ -689,7 +685,7 @@ func TestUpUpdate(t *testing.T) {
t.Run("check deployed compose app", func(t *testing.T) {
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
// Check three containers are running
assert.Assert(t, is.Len(out, 4))
webRunning := false
@ -729,11 +725,11 @@ func TestUpUpdate(t *testing.T) {
t.Run("compose ps", func(t *testing.T) {
res := c.RunDockerCmd("compose", "ps", "--project-name", composeProjectName, "--quiet")
l := lines(res.Stdout())
l := Lines(res.Stdout())
assert.Assert(t, is.Len(l, 3))
res = c.RunDockerCmd("compose", "ps", "--project-name", composeProjectName)
l = lines(res.Stdout())
l = Lines(res.Stdout())
assert.Assert(t, is.Len(l, 4))
var wordsDisplayed, webDisplayed, dbDisplayed bool
for _, line := range l {
@ -757,10 +753,10 @@ func TestUpUpdate(t *testing.T) {
t.Run("compose ls", func(t *testing.T) {
res := c.RunDockerCmd("compose", "ls", "--quiet")
l := lines(res.Stdout())
l := Lines(res.Stdout())
assert.Assert(t, is.Len(l, 1))
res = c.RunDockerCmd("compose", "ls")
l = lines(res.Stdout())
l = Lines(res.Stdout())
assert.Equal(t, 2, len(l))
fields := strings.Fields(l[1])
@ -777,7 +773,7 @@ func TestUpUpdate(t *testing.T) {
t.Run("update", func(t *testing.T) {
c.RunDockerCmd("compose", "up", "-f", multiPortComposefile, "--project-name", composeProjectName)
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
// Check three containers are running
assert.Assert(t, is.Len(out, 4))
@ -812,7 +808,7 @@ func TestUpUpdate(t *testing.T) {
t.Run("down", func(t *testing.T) {
c.RunDockerCmd("compose", "down", "--project-name", composeProjectName)
res := c.RunDockerCmd("ps")
out := lines(res.Stdout())
out := Lines(res.Stdout())
assert.Equal(t, len(out), 1)
})
}
@ -835,7 +831,7 @@ func TestRunEnvVars(t *testing.T) {
cmd.Env = append(cmd.Env, "MYSQL_USER=user1")
res := icmd.RunCmd(cmd)
res.Assert(t, icmd.Success)
out := lines(res.Stdout())
out := Lines(res.Stdout())
container := strings.TrimSpace(out[len(out)-1])
res = c.RunDockerCmd("inspect", container)
@ -882,7 +878,7 @@ func setupTestResourceGroup(t *testing.T, c *E2eCLI) (string, string, string) {
createAciContextAndUseIt(t, c, sID, rg, location)
// Check nothing is running
res := c.RunDockerCmd("ps")
assert.Assert(t, is.Len(lines(res.Stdout()), 1))
assert.Assert(t, is.Len(Lines(res.Stdout()), 1))
return sID, rg, location
}
@ -945,7 +941,7 @@ func uploadFile(t *testing.T, cred azfile.SharedKeyCredential, baseURL, fileName
}
func getContainerName(stdout string) string {
out := lines(stdout)
out := Lines(stdout)
return strings.TrimSpace(out[len(out)-1])
}

View File

@ -192,6 +192,11 @@ func GoldenFile(name string) string {
return name + ".golden"
}
//Lines split output into lines
func Lines(output string) []string {
return strings.Split(strings.TrimSpace(output), "\n")
}
// HTTPGetWithRetry performs an HTTP GET on an `endpoint`, using retryDelay also as a request timeout.
// In the case of an error or the response status is not the expeted one, it retries the same request,
// returning the response body as a string (empty if we could not reach it)