client: refactor ListImages to return an error per machine

This commit is contained in:
Pasha Sviderski
2026-06-17 16:32:09 +10:00
parent d36ff67409
commit 7bac40ae3e
3 changed files with 21 additions and 11 deletions
+6
View File
@@ -102,6 +102,12 @@ func list(ctx context.Context, uncli *cli.CLI, opts listOptions) error {
var rows []imageRow
for _, machineImages := range clusterImages {
if err := machineImages.Error(); err != nil {
tui.PrintWarning(fmt.Sprintf("failed to list images on machine '%s': %s",
machineImages.Metadata.MachineName, err))
continue
}
// Get machine name for better readability.
machineName := machineImages.Metadata.MachineName
+10
View File
@@ -1,6 +1,8 @@
package api
import (
"errors"
"github.com/distribution/reference"
"github.com/docker/docker/api/types/image"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -22,6 +24,14 @@ type MachineImages struct {
ContainerdStore bool
}
// Error returns a non-nil error if listing images on this machine failed.
func (mi MachineImages) Error() error {
if mi.Metadata != nil && mi.Metadata.Error != "" {
return errors.New(mi.Metadata.Error)
}
return nil
}
// ImageFilter defines criteria to filter images in ListImages.
type ImageFilter struct {
// Machines filters images to those present on the specified machines (names or IDs).
+5 -11
View File
@@ -87,21 +87,12 @@ func (cli *Client) ListImages(ctx context.Context, filter api.ImageFilter) ([]ap
continue
}
if msg.Metadata.Error != "" {
// Continue processing other messages even if some machines return an error to avoid a partial failure
// of the entire command.
tui.PrintWarning(fmt.Sprintf(
"failed to list images on machine %s: %s", msg.Metadata.MachineName, msg.Metadata.Error,
))
continue
}
mi := api.MachineImages{
Metadata: msg.Metadata,
ContainerdStore: msg.ContainerdStore,
}
if len(msg.Images) > 0 {
if msg.Metadata.Error == "" && len(msg.Images) > 0 {
if err = json.Unmarshal(msg.Images, &mi.Images); err != nil {
return nil, fmt.Errorf("unmarshal images: %w", err)
}
@@ -223,12 +214,15 @@ func (cli *Client) pushImageToMachine(
Machines: []string{machine.Id},
Name: "%invalid-name-to-only-check-store-type%",
})
if err == nil {
err = images[0].Error()
}
if err != nil {
return fmt.Errorf("check Docker image store type on machine '%s': %w", machine.Name, err)
}
// Only support Docker with containerd image store enabled to avoid the confusion of pushing images to containerd
// and then not being able to see and use them in Docker.
// and then not being able to use them in Docker.
if !images[0].ContainerdStore {
pw.Event(progress.NewEvent(pushEventID, progress.Error, "containerd image store required"))
return fmt.Errorf("docker on machine '%s' is not using containerd image store, "+