| 151 | } |
| 152 | |
| 153 | func loadImage(ctx context.Context, in io.Reader, namespace, address, snapshotter string, output io.Writer, platMC platforms.MatchComparer, quiet bool) error { |
| 154 | // In addition to passing WithImagePlatform() to client.Import(), we also need to pass WithDefaultPlatform() to NewClient(). |
| 155 | // Otherwise unpacking may fail. |
| 156 | client, ctx, cancel, err := clientutil.NewClient(ctx, namespace, address, containerd.WithDefaultPlatform(platMC)) |
| 157 | if err != nil { |
| 158 | return err |
| 159 | } |
| 160 | defer func() { |
| 161 | cancel() |
| 162 | client.Close() |
| 163 | }() |
| 164 | r := &readCounter{Reader: in} |
| 165 | imgs, err := client.Import(ctx, r, containerd.WithDigestRef(archive.DigestTranslator(snapshotter)), containerd.WithSkipDigestRef(func(name string) bool { return name != "" }), containerd.WithImportPlatform(platMC)) |
| 166 | if err != nil { |
| 167 | if r.N == 0 { |
| 168 | // Avoid confusing "unrecognized image format" |
| 169 | return errors.New("no image was built") |
| 170 | } |
| 171 | if errors.Is(err, images.ErrEmptyWalk) { |
| 172 | err = fmt.Errorf("%w (Hint: set `--platform=PLATFORM` or `--all-platforms`)", err) |
| 173 | } |
| 174 | return err |
| 175 | } |
| 176 | for _, img := range imgs { |
| 177 | image := containerd.NewImageWithPlatform(client, img, platMC) |
| 178 | |
| 179 | // TODO: Show unpack status |
| 180 | if !quiet { |
| 181 | fmt.Fprintf(output, "unpacking %s (%s)...\n", img.Name, img.Target.Digest) |
| 182 | } |
| 183 | err = image.Unpack(ctx, snapshotter) |
| 184 | if err != nil { |
| 185 | return err |
| 186 | } |
| 187 | if quiet { |
| 188 | fmt.Fprintln(output, img.Target.Digest) |
| 189 | } else { |
| 190 | fmt.Fprintf(output, "Loaded image: %s\n", img.Name) |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | return nil |
| 195 | } |
| 196 | |
| 197 | // GetEffectiveSourcePolicyFile returns the effective source policy file path. |
| 198 | // If optionValue is set, it takes precedence. Otherwise, the EXPERIMENTAL_BUILDKIT_SOURCE_POLICY |