Files
buildkit/source/containerimage/identifier.go
Tonis Tiigi 93999f4071 sourcepolicy: normalize parsed source identifiers
Render parsed source identifiers back to their canonical SourceOp form before
source policy evaluation. This lets Git subdir cleanup use the existing source
parser and avoids policy-specific Git parsing.

Add String methods for source identifiers and cover them with unit tests, plus
a client integration regression for canonical Git subdir policy matching.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2026-07-22 11:36:47 +02:00

103 lines
2.5 KiB
Go

package containerimage
import (
"github.com/containerd/containerd/v2/pkg/reference"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/solver/llbsolver/provenance"
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
"github.com/moby/buildkit/source"
srctypes "github.com/moby/buildkit/source/types"
"github.com/moby/buildkit/util/resolver"
digest "github.com/opencontainers/go-digest"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
type ImageIdentifier struct {
Reference reference.Spec
Platform *ocispecs.Platform
ResolveMode resolver.ResolveMode
RecordType client.UsageRecordType
LayerLimit *int
Checksum digest.Digest
}
func NewImageIdentifier(str string) (*ImageIdentifier, error) {
ref, err := reference.Parse(str)
if err != nil {
return nil, errors.WithStack(err)
}
if ref.Object == "" {
return nil, errors.WithStack(reference.ErrObjectRequired)
}
return &ImageIdentifier{Reference: ref}, nil
}
var _ source.Identifier = (*ImageIdentifier)(nil)
func (id *ImageIdentifier) String() string {
return srctypes.DockerImageScheme + "://" + id.Reference.String()
}
func (*ImageIdentifier) Scheme() string {
return srctypes.DockerImageScheme
}
func (id *ImageIdentifier) Capture(c *provenance.Capture, pin string) error {
dgst, err := digest.Parse(pin)
if err != nil {
return errors.Wrapf(err, "failed to parse image digest %s", pin)
}
c.AddImage(provenancetypes.ImageSource{
Ref: id.Reference.String(),
Platform: id.Platform,
Digest: dgst,
})
return nil
}
type OCIIdentifier struct {
Reference reference.Spec
Platform *ocispecs.Platform
SessionID string
StoreID string
LayerLimit *int
}
func NewOCIIdentifier(str string) (*OCIIdentifier, error) {
ref, err := reference.Parse(str)
if err != nil {
return nil, errors.WithStack(err)
}
if ref.Object == "" {
return nil, errors.WithStack(reference.ErrObjectRequired)
}
return &OCIIdentifier{Reference: ref}, nil
}
var _ source.Identifier = (*OCIIdentifier)(nil)
func (id *OCIIdentifier) String() string {
return srctypes.OCIScheme + "://" + id.Reference.String()
}
func (*OCIIdentifier) Scheme() string {
return srctypes.OCIScheme
}
func (id *OCIIdentifier) Capture(c *provenance.Capture, pin string) error {
dgst, err := digest.Parse(pin)
if err != nil {
return errors.Wrapf(err, "failed to parse OCI digest %s", pin)
}
c.AddImage(provenancetypes.ImageSource{
Ref: id.Reference.String(),
Platform: id.Platform,
Digest: dgst,
Local: true,
})
return nil
}