Skip to content

Commit fb9b625

Browse files
CopilotJeffreyCA
andcommitted
Simplify containerd detection to use DriverStatus check
Co-authored-by: JeffreyCA <9157833+JeffreyCA@users.noreply.github.com>
1 parent df9b41d commit fb9b625

5 files changed

Lines changed: 30 additions & 61 deletions

File tree

cli/azd/pkg/project/framework_service_docker.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,20 +553,20 @@ func (p *dockerProject) packBuild(
553553
previewer,
554554
isContainerdEnabled)
555555
p.console.StopPreviewer(ctx, false)
556-
556+
557557
// If build fails and it looks like a containerd issue, try again with containerd workarounds
558558
if err != nil {
559559
if strings.Contains(err.Error(), "failed to write image") && strings.Contains(err.Error(), "No such image") {
560560
p.console.Message(ctx, "Detected potential containerd compatibility issue, retrying with workarounds...")
561-
561+
562562
// Start previewer again for retry
563563
previewer = p.console.ShowPreviewer(ctx,
564564
&input.ShowPreviewerOptions{
565565
Prefix: " ",
566566
MaxLineCount: 8,
567567
Title: "Docker (pack) Output - Retry",
568568
})
569-
569+
570570
// Force containerd compatibility mode
571571
retryErr := packCli.BuildWithContainerdSupport(
572572
ctx,
@@ -577,13 +577,13 @@ func (p *dockerProject) packBuild(
577577
previewer,
578578
true) // Force containerd compatibility
579579
p.console.StopPreviewer(ctx, false)
580-
580+
581581
if retryErr == nil {
582582
err = nil // Success on retry
583583
}
584584
}
585585
}
586-
586+
587587
if err != nil {
588588
span.EndWithStatus(err)
589589

@@ -602,7 +602,8 @@ func (p *dockerProject) packBuild(
602602
if strings.Contains(err.Error(), "failed to write image") && strings.Contains(err.Error(), "No such image") {
603603
return nil, &internal.ErrorWithSuggestion{
604604
Err: err,
605-
Suggestion: "This error typically occurs when Docker is configured to use containerd image store, which may cause compatibility issues with pack CLI. " +
605+
Suggestion: "This error typically occurs when Docker is configured to use containerd image store, " +
606+
"which may cause compatibility issues with pack CLI. " +
606607
"Consider disabling 'Use containerd for pulling and storing images' in Docker Desktop settings, " +
607608
"or try running the command again as this may be a transient issue.",
608609
}

cli/azd/pkg/tools/docker/docker.go

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -284,30 +284,15 @@ func (d *Cli) Name() string {
284284

285285
// IsContainerdEnabled checks if Docker is using containerd as the image store
286286
func (d *Cli) IsContainerdEnabled(ctx context.Context) (bool, error) {
287-
// First, try to check for containerd-specific features
288-
result, err := d.executeCommand(ctx, "", "system", "info", "--format", "{{.Driver}}")
287+
result, err := d.executeCommand(ctx, "", "system", "info", "--format", "{{.DriverStatus}}")
289288
if err != nil {
290-
return false, fmt.Errorf("checking docker driver: %w", err)
289+
return false, fmt.Errorf("checking docker driver status: %w", err)
291290
}
292-
293-
driver := strings.TrimSpace(result.Stdout)
294-
295-
// Check for containerd-based storage drivers
296-
if driver == "containerd" || strings.Contains(driver, "containerd") {
297-
return true, nil
298-
}
299-
300-
// Additional check: Look for containerd namespace information which is present when containerd image store is used
301-
result, err = d.executeCommand(ctx, "", "system", "info", "--format", "{{.Containerd}}")
302-
if err == nil && strings.TrimSpace(result.Stdout) != "<no value>" && strings.TrimSpace(result.Stdout) != "" {
303-
// If there's containerd info with namespaces, it's likely using containerd image store
304-
infoResult, infoErr := d.executeCommand(ctx, "", "system", "info", "--format", "{{.Containerd.Namespaces}}")
305-
if infoErr == nil && strings.Contains(strings.TrimSpace(infoResult.Stdout), "moby") {
306-
return true, nil
307-
}
308-
}
309-
310-
return false, nil
291+
292+
driverStatus := strings.TrimSpace(result.Stdout)
293+
294+
// Check for containerd snapshotter which indicates containerd image store is enabled
295+
return strings.Contains(driverStatus, "io.containerd.snapshotter.v1"), nil
311296
}
312297

313298
func (d *Cli) executeCommand(ctx context.Context, cwd string, args ...string) (exec.RunResult, error) {

cli/azd/pkg/tools/docker/docker_test.go

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -607,11 +607,11 @@ func Test_IsContainerdEnabled(t *testing.T) {
607607
}).RespondFn(func(args exec.RunArgs) (exec.RunResult, error) {
608608
require.Equal(t, "docker", args.Cmd)
609609
require.Equal(t, []string{
610-
"system", "info", "--format", "{{.Driver}}",
610+
"system", "info", "--format", "{{.DriverStatus}}",
611611
}, args.Args)
612612

613613
return exec.RunResult{
614-
Stdout: "containerd",
614+
Stdout: "[[driver-type io.containerd.snapshotter.v1]]",
615615
Stderr: "",
616616
ExitCode: 0,
617617
}, nil
@@ -627,36 +627,20 @@ func Test_IsContainerdEnabled(t *testing.T) {
627627
mockContext := mocks.NewMockContext(context.Background())
628628
docker := NewCli(mockContext.CommandRunner)
629629

630-
callCount := 0
631630
mockContext.CommandRunner.When(func(args exec.RunArgs, command string) bool {
632631
return strings.Contains(command, "docker system info")
633632
}).RespondFn(func(args exec.RunArgs) (exec.RunResult, error) {
634633
require.Equal(t, "docker", args.Cmd)
635-
636-
callCount++
637-
if callCount == 1 {
638-
// First call checks driver
639-
require.Equal(t, []string{
640-
"system", "info", "--format", "{{.Driver}}",
641-
}, args.Args)
642-
return exec.RunResult{
643-
Stdout: "overlay2",
644-
Stderr: "",
645-
ExitCode: 0,
646-
}, nil
647-
} else if callCount == 2 {
648-
// Second call checks for containerd info
649-
require.Equal(t, []string{
650-
"system", "info", "--format", "{{.Containerd}}",
651-
}, args.Args)
652-
return exec.RunResult{
653-
Stdout: "<no value>",
654-
Stderr: "",
655-
ExitCode: 0,
656-
}, nil
657-
}
658-
659-
return exec.RunResult{}, errors.New("unexpected call")
634+
require.Equal(t, []string{
635+
"system", "info", "--format", "{{.DriverStatus}}",
636+
}, args.Args)
637+
638+
return exec.RunResult{
639+
Stdout: "[[Backing Filesystem extfs] [Supports d_type true] [Using metacopy false] " +
640+
"[Native Overlay Diff true] [userxattr false]]",
641+
Stderr: "",
642+
ExitCode: 0,
643+
}, nil
660644
})
661645

662646
isContainerd, err := docker.IsContainerdEnabled(context.Background())
@@ -683,6 +667,6 @@ func Test_IsContainerdEnabled(t *testing.T) {
683667

684668
require.Error(t, err)
685669
require.False(t, isContainerd)
686-
require.Contains(t, err.Error(), "checking docker driver")
670+
require.Contains(t, err.Error(), "checking docker driver status")
687671
})
688672
}

cli/azd/pkg/tools/pack/pack.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,13 @@ func (cli *Cli) BuildWithContainerdSupport(
212212

213213
runArgs := exec.NewRunArgs(cli.path, "build", imageName, "--builder", builder, "--path", cwd)
214214
runArgs.Args = append(runArgs.Args, envArgs...)
215-
215+
216216
// When containerd is enabled, set environment variables to improve compatibility
217217
if isContainerdEnabled {
218218
// Force pack to use Docker daemon directly instead of relying on containerd image store
219219
runArgs = runArgs.WithEnv([]string{"DOCKER_BUILDKIT=0"})
220220
}
221-
221+
222222
if progressWriter != nil {
223223
runArgs = runArgs.WithStdOut(progressWriter).WithStdErr(progressWriter)
224224
}

cli/azd/pkg/tools/pack/pack_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ func TestNewPackCliUpgrade(t *testing.T) {
247247
require.Equal(t, "pack cli", string(contents))
248248
}
249249

250-
251250
func Test_PackCli_BuildWithContainerdSupport(t *testing.T) {
252251
tests := []struct {
253252
name string
@@ -287,7 +286,7 @@ func Test_PackCli_BuildWithContainerdSupport(t *testing.T) {
287286
}
288287
}
289288

290-
require.Equal(t, tt.isContainerdEnabled, buildkitDisabled,
289+
require.Equal(t, tt.isContainerdEnabled, buildkitDisabled,
291290
"Expected DOCKER_BUILDKIT=0 environment variable to be %v", tt.isContainerdEnabled)
292291

293292
return exec.RunResult{ExitCode: 0}, nil

0 commit comments

Comments
 (0)