Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Avoid race between stop/kill and wait #773

Merged
merged 3 commits into from
Jan 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions e2e/run_volume_test.go
Original file line number Diff line number Diff line change
@@ -124,8 +124,6 @@ func runVolume(t *testing.T, vmName, runtime, networkPlugin string) {
}

func TestVolumeWithDockerAndDockerBridge(t *testing.T) {
// TODO: https://github.com/weaveworks/ignite/issues/658
t.Skip("SKIPPING\nThis test fails to stop the VM within docker\nTODO: https://github.com/weaveworks/ignite/issues/658")
runVolume(
t,
"e2e-test-volume-docker-and-docker-bridge",
20 changes: 17 additions & 3 deletions pkg/runtime/docker/client.go
Original file line number Diff line number Diff line change
@@ -175,21 +175,35 @@ func (dc *dockerClient) RunContainer(image meta.OCIImageRef, config *runtime.Con
}

func (dc *dockerClient) StopContainer(container string, timeout *time.Duration) error {
// Start waiting before we do the stop, to avoid race
errC, readyC := make(chan error), make(chan struct{})
go func() {
errC <- dc.waitForContainer(container, cont.WaitConditionNotRunning, &readyC)
}()
<-readyC // wait until removal detection has started

if err := dc.client.ContainerStop(context.Background(), container, timeout); err != nil {
return err
}

// Wait for the container to be stopped
return dc.waitForContainer(container, cont.WaitConditionNotRunning, nil)
return <-errC
}

func (dc *dockerClient) KillContainer(container, signal string) error {
// Start waiting before we do the kill, to avoid race
errC, readyC := make(chan error), make(chan struct{})
go func() {
errC <- dc.waitForContainer(container, cont.WaitConditionNotRunning, &readyC)
}()
<-readyC // wait until removal detection has started

if err := dc.client.ContainerKill(context.Background(), container, signal); err != nil {
return err
}

// Wait for the container to be killed
return dc.waitForContainer(container, cont.WaitConditionNotRunning, nil)
return <-errC
}

func (dc *dockerClient) RemoveContainer(container string) error {
@@ -245,7 +259,7 @@ func (dc *dockerClient) waitForContainer(container string, condition cont.WaitCo
return fmt.Errorf("failed to wait for container %q: %s", container, result.Error.Message)
}
case err := <-errC:
return err
return fmt.Errorf("error waiting for container %q: %w", container, err)
}

return nil