Remove the git clone container's anonymous volume with it (closes #215) #217
@@ -657,10 +657,11 @@ func (c *Client) performClone(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The git image declares a volume, so Docker gives each clone container
|
// The git image declares a volume, so Docker gives each clone container
|
||||||
// an anonymous volume; remove it with the container.
|
// an anonymous volume; remove it with the container. The removal must
|
||||||
|
// still run when the deploy is cancelled.
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = c.docker.ContainerRemove(
|
_ = c.docker.ContainerRemove(
|
||||||
ctx,
|
context.WithoutCancel(ctx),
|
||||||
gitContainerID.String(),
|
gitContainerID.String(),
|
||||||
container.RemoveOptions{Force: true, RemoveVolumes: true},
|
container.RemoveOptions{Force: true, RemoveVolumes: true},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package docker //nolint:testpackage // tests unexported regexps and Client struct
|
package docker //nolint:testpackage // tests unexported regexps and Client struct
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -160,14 +161,27 @@ func TestCloneRepoRejectsInjection(t *testing.T) {
|
|||||||
|
|
||||||
// TestPerformCloneRemovesContainerVolumes runs a clone against a fake Docker
|
// TestPerformCloneRemovesContainerVolumes runs a clone against a fake Docker
|
||||||
// API and checks that the clone container is removed together with its
|
// API and checks that the clone container is removed together with its
|
||||||
// anonymous volumes, whether the clone succeeds or fails.
|
// anonymous volumes, whether the clone succeeds, fails, or is cancelled.
|
||||||
func TestPerformCloneRemovesContainerVolumes(t *testing.T) {
|
func TestPerformCloneRemovesContainerVolumes(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
for _, exitCode := range []int{0, 1} {
|
tests := []struct {
|
||||||
t.Run(fmt.Sprintf("exit code %d", exitCode), func(t *testing.T) {
|
name string
|
||||||
|
exitCode int
|
||||||
|
cancel bool
|
||||||
|
}{
|
||||||
|
{name: "succeeds", exitCode: 0},
|
||||||
|
{name: "fails", exitCode: 1},
|
||||||
|
{name: "cancelled", cancel: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(t.Context())
|
||||||
|
t.Cleanup(cancel)
|
||||||
|
|
||||||
removeQuery := make(chan url.Values, 1)
|
removeQuery := make(chan url.Values, 1)
|
||||||
|
|
||||||
srv := httptest.NewServer(http.HandlerFunc(
|
srv := httptest.NewServer(http.HandlerFunc(
|
||||||
@@ -179,8 +193,12 @@ func TestPerformCloneRemovesContainerVolumes(t *testing.T) {
|
|||||||
removeQuery <- r.URL.Query()
|
removeQuery <- r.URL.Query()
|
||||||
case strings.HasSuffix(r.URL.Path, "/containers/create"):
|
case strings.HasSuffix(r.URL.Path, "/containers/create"):
|
||||||
_, _ = w.Write([]byte(`{"Id":"gitcontainer"}`))
|
_, _ = w.Write([]byte(`{"Id":"gitcontainer"}`))
|
||||||
|
case strings.HasSuffix(r.URL.Path, "/wait") && tt.cancel:
|
||||||
|
// Cancel the deploy while the clone is running.
|
||||||
|
cancel()
|
||||||
|
<-r.Context().Done()
|
||||||
case strings.HasSuffix(r.URL.Path, "/wait"):
|
case strings.HasSuffix(r.URL.Path, "/wait"):
|
||||||
_, _ = fmt.Fprintf(w, `{"StatusCode":%d}`, exitCode)
|
_, _ = fmt.Fprintf(w, `{"StatusCode":%d}`, tt.exitCode)
|
||||||
default:
|
default:
|
||||||
_, _ = w.Write([]byte(`{}`))
|
_, _ = w.Write([]byte(`{}`))
|
||||||
}
|
}
|
||||||
@@ -208,7 +226,7 @@ func TestPerformCloneRemovesContainerVolumes(t *testing.T) {
|
|||||||
hostKeyFile: filepath.Join(dir, "deploy_key"),
|
hostKeyFile: filepath.Join(dir, "deploy_key"),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = c.performClone(t.Context(), cfg)
|
_, _ = c.performClone(ctx, cfg)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case query := <-removeQuery:
|
case query := <-removeQuery:
|
||||||
|
|||||||
Reference in New Issue
Block a user