Skip to content

Commit da187c3

Browse files
CopilotJeffreyCA
andcommitted
Fix lint errors and improve containerd compatibility for pack CLI
Co-authored-by: JeffreyCA <9157833+JeffreyCA@users.noreply.github.com>
1 parent 35963ef commit da187c3

4 files changed

Lines changed: 80 additions & 13 deletions

File tree

cli/azd/.vscode/cspell-azd-dictionary.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ buildargs
6767
BUILDID
6868
BUILDNUMBER
6969
buildpacks
70+
BUILDKIT
7071
byoi
7172
cflags
7273
circleci
@@ -77,6 +78,8 @@ conditionalize
7778
consolesize
7879
containerapp
7980
containerapps
81+
containerd
82+
Containerd
8083
contoso
8184
createdby
8285
csharpapp

cli/azd/pkg/project/framework_service_docker.go

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,37 @@ func (p *dockerProject) packBuild(
553553
previewer,
554554
isContainerdEnabled)
555555
p.console.StopPreviewer(ctx, false)
556+
557+
// If build fails and it looks like a containerd issue, try again with containerd workarounds
558+
if err != nil {
559+
if strings.Contains(err.Error(), "failed to write image") && strings.Contains(err.Error(), "No such image") {
560+
p.console.Message(ctx, "Detected potential containerd compatibility issue, retrying with workarounds...")
561+
562+
// Start previewer again for retry
563+
previewer = p.console.ShowPreviewer(ctx,
564+
&input.ShowPreviewerOptions{
565+
Prefix: " ",
566+
MaxLineCount: 8,
567+
Title: "Docker (pack) Output - Retry",
568+
})
569+
570+
// Force containerd compatibility mode
571+
retryErr := packCli.BuildWithContainerdSupport(
572+
ctx,
573+
buildContext,
574+
builder,
575+
imageName,
576+
environ,
577+
previewer,
578+
true) // Force containerd compatibility
579+
p.console.StopPreviewer(ctx, false)
580+
581+
if retryErr == nil {
582+
err = nil // Success on retry
583+
}
584+
}
585+
}
586+
556587
if err != nil {
557588
span.EndWithStatus(err)
558589

@@ -568,10 +599,10 @@ func (p *dockerProject) packBuild(
568599
}
569600

570601
// Provide better error message for containerd-related issues
571-
if isContainerdEnabled && strings.Contains(err.Error(), "failed to write image") {
602+
if strings.Contains(err.Error(), "failed to write image") && strings.Contains(err.Error(), "No such image") {
572603
return nil, &internal.ErrorWithSuggestion{
573604
Err: err,
574-
Suggestion: "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, which may cause compatibility issues with pack CLI. " +
575606
"Consider disabling 'Use containerd for pulling and storing images' in Docker Desktop settings, " +
576607
"or try running the command again as this may be a transient issue.",
577608
}

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,30 @@ 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
287288
result, err := d.executeCommand(ctx, "", "system", "info", "--format", "{{.Driver}}")
288289
if err != nil {
289290
return false, fmt.Errorf("checking docker driver: %w", err)
290291
}
291292

292-
// Check for containerd driver in the output
293293
driver := strings.TrimSpace(result.Stdout)
294-
return driver == "containerd" || strings.Contains(driver, "containerd"), nil
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
295311
}
296312

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

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

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -627,19 +627,36 @@ func Test_IsContainerdEnabled(t *testing.T) {
627627
mockContext := mocks.NewMockContext(context.Background())
628628
docker := NewCli(mockContext.CommandRunner)
629629

630+
callCount := 0
630631
mockContext.CommandRunner.When(func(args exec.RunArgs, command string) bool {
631632
return strings.Contains(command, "docker system info")
632633
}).RespondFn(func(args exec.RunArgs) (exec.RunResult, error) {
633634
require.Equal(t, "docker", args.Cmd)
634-
require.Equal(t, []string{
635-
"system", "info", "--format", "{{.Driver}}",
636-
}, args.Args)
637-
638-
return exec.RunResult{
639-
Stdout: "overlay2",
640-
Stderr: "",
641-
ExitCode: 0,
642-
}, nil
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")
643660
})
644661

645662
isContainerd, err := docker.IsContainerdEnabled(context.Background())

0 commit comments

Comments
 (0)