Repository: moby/moby
File: builder/builder-next/exporter/wrapper.go (Go)

Code before:

	return &imageExporterInstanceWrapper{
		ExporterInstance: inst,
		callbacks:        e.callbacks,
	}, nil
}

type imageExporterInstanceWrapper struct {
	exporter.ExporterInstance
	callbacks BuildkitCallbacks
}

func (i *imageExporterInstanceWrapper) Export(ctx context.Context, src *exporter.Source, inlineCache exptypes.InlineCache, sessionID string) (map[string]string, exporter.DescriptorReference, error) {
	out, ref, err := i.ExporterInstance.Export(ctx, src, inlineCache, sessionID)
	if err != nil {
		return out, ref, err
	}

	desc := ref.Descriptor()
	imageID := out[exptypes.ExporterImageDigestKey]
	if i.callbacks.Exported != nil {
		i.callbacks.Exported(ctx, imageID, desc)
	}

	if i.callbacks.Named != nil {
		for _, name := range strings.Split(out["image.name"], ",") {
			ref, err := reference.ParseNormalizedNamed(name)
			if err != nil {
				// Shouldn't happen, but log if it does and continue.
				log.G(ctx).WithFields(log.Fields{
					"name":  name,
					"error": err,
				}).Warn("image named with invalid reference produced by buildkit")
				continue
			}

			if namedTagged, ok := reference.TagNameOnly(ref).(reference.NamedTagged); ok {
				i.callbacks.Named(ctx, namedTagged, desc)
			}
		}
	}

	return out, ref, nil
}


Review comment (suggestion):
Can you also check that this key exists and is non-empty?

We also recently added a constant to buildkit for this because we noticed this wasn't working properly. The constant was added in https://github.com/moby/buildkit/pull/5862. If it's possible to use that, it would be preferred. Otherwise a note that the exported constant should be used when buildkit is updated.

Code after:

	return &imageExporterInstanceWrapper{
		ExporterInstance: inst,
		callbacks:        e.callbacks,
	}, nil
}

type imageExporterInstanceWrapper struct {
	exporter.ExporterInstance
	callbacks BuildkitCallbacks
}

func (i *imageExporterInstanceWrapper) Export(ctx context.Context, src *exporter.Source, inlineCache exptypes.InlineCache, sessionID string) (map[string]string, exporter.DescriptorReference, error) {
	out, ref, err := i.ExporterInstance.Export(ctx, src, inlineCache, sessionID)
	if err != nil {
		return out, ref, err
	}

	desc := ref.Descriptor()
	imageID := out[exptypes.ExporterImageDigestKey]
	if i.callbacks.Exported != nil {
		i.callbacks.Exported(ctx, imageID, desc)
	}

	if i.callbacks.Named != nil {
		i.processNamedCallback(ctx, out, desc)
	}

	return out, ref, nil
}

func (i *imageExporterInstanceWrapper) processNamedCallback(ctx context.Context, out map[string]string, desc ocispec.Descriptor) {
	// TODO(vvoland): Change to exptypes.ExporterImageNameKey when BuildKit v0.21 is vendored.
	imageName := out["image.name"]
	if imageName == "" {
		log.G(ctx).Warn("image named with empty image.name produced by buildkit")
		return
	}

	for _, name := range strings.Split(imageName, ",") {
		ref, err := reference.ParseNormalizedNamed(name)
		if err != nil {
			// Shouldn't happen, but log if it does and continue.
			log.G(ctx).WithFields(log.Fields{
				"name":  name,
				"error": err,
			}).Warn("image named with invalid reference produced by buildkit")
			continue
		}

		if namedTagged, ok := reference.TagNameOnly(ref).(reference.NamedTagged); ok {