fix(agent/agentcontainers): handle race between docker ps and docker inspect (#17447)

Fixes https://github.com/coder/internal/issues/586#event-17291038671
This commit is contained in:
Cian Johnston
2025-04-17 13:50:51 +01:00
committed by GitHub
parent b3aba6dab7
commit 6a79965948
2 changed files with 20 additions and 14 deletions
+17 -14
View File
@@ -24,19 +24,6 @@ import (
"github.com/coder/coder/v2/codersdk"
)
// DockerCLILister is a ContainerLister that lists containers using the docker CLI
type DockerCLILister struct {
execer agentexec.Execer
}
var _ Lister = &DockerCLILister{}
func NewDocker(execer agentexec.Execer) Lister {
return &DockerCLILister{
execer: agentexec.DefaultExecer,
}
}
// DockerEnvInfoer is an implementation of agentssh.EnvInfoer that returns
// information about a container.
type DockerEnvInfoer struct {
@@ -241,6 +228,19 @@ func run(ctx context.Context, execer agentexec.Execer, cmd string, args ...strin
return stdout, stderr, err
}
// DockerCLILister is a ContainerLister that lists containers using the docker CLI
type DockerCLILister struct {
execer agentexec.Execer
}
var _ Lister = &DockerCLILister{}
func NewDocker(execer agentexec.Execer) Lister {
return &DockerCLILister{
execer: agentexec.DefaultExecer,
}
}
func (dcl *DockerCLILister) List(ctx context.Context) (codersdk.WorkspaceAgentListContainersResponse, error) {
var stdoutBuf, stderrBuf bytes.Buffer
// List all container IDs, one per line, with no truncation
@@ -319,9 +319,12 @@ func runDockerInspect(ctx context.Context, execer agentexec.Execer, ids ...strin
stdout = bytes.TrimSpace(stdoutBuf.Bytes())
stderr = bytes.TrimSpace(stderrBuf.Bytes())
if err != nil {
if bytes.Contains(stderr, []byte("No such object:")) {
// This can happen if a container is deleted between the time we check for its existence and the time we inspect it.
return stdout, stderr, nil
}
return stdout, stderr, err
}
return stdout, stderr, nil
}
@@ -229,6 +229,9 @@ func TestDockerDevcontainerCLI(t *testing.T) {
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
t.Skip("skipping Docker test; set CODER_TEST_USE_DOCKER=1 to run")
}
if _, err := exec.LookPath("devcontainer"); err != nil {
t.Fatal("this test requires the devcontainer CLI: npm install -g @devcontainers/cli")
}
// Connect to Docker.
pool, err := dockertest.NewPool("")