diff --git a/pkg/fanal/image/daemon.go b/pkg/fanal/image/daemon.go index a5e4b3c5a6b6..f6eb303e4125 100644 --- a/pkg/fanal/image/daemon.go +++ b/pkg/fanal/image/daemon.go @@ -32,8 +32,8 @@ func tryPodmanDaemon(_ context.Context, imageName string, _ name.Reference, _ ty }, cleanup, nil } -func tryContainerdDaemon(ctx context.Context, imageName string, _ name.Reference, _ types.ImageOptions) (types.Image, func(), error) { - img, cleanup, err := daemon.ContainerdImage(ctx, imageName) +func tryContainerdDaemon(ctx context.Context, imageName string, _ name.Reference, opts types.ImageOptions) (types.Image, func(), error) { + img, cleanup, err := daemon.ContainerdImage(ctx, imageName, opts) if err != nil { return nil, cleanup, err } diff --git a/pkg/fanal/image/daemon/containerd.go b/pkg/fanal/image/daemon/containerd.go index c019c3b6c6fd..66220adeda34 100644 --- a/pkg/fanal/image/daemon/containerd.go +++ b/pkg/fanal/image/daemon/containerd.go @@ -24,6 +24,8 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/samber/lo" "golang.org/x/xerrors" + + "github.com/aquasecurity/trivy/pkg/fanal/types" ) const ( @@ -50,14 +52,21 @@ func (n familiarNamed) String() string { return string(n) } -func imageWriter(client *containerd.Client, img containerd.Image) imageSave { +func imageWriter(client *containerd.Client, img containerd.Image, platform types.Platform) imageSave { return func(ctx context.Context, ref []string) (io.ReadCloser, error) { if len(ref) < 1 { return nil, xerrors.New("no image reference") } imgOpts := archive.WithImage(client.ImageService(), ref[0]) manifestOpts := archive.WithManifest(img.Target()) - platOpts := archive.WithPlatform(platforms.DefaultStrict()) + + var platformMatchComparer platforms.MatchComparer + if platform.Platform == nil { + platformMatchComparer = platforms.DefaultStrict() + } else { + platformMatchComparer = img.Platform() + } + platOpts := archive.WithPlatform(platformMatchComparer) pr, pw := io.Pipe() go func() { pw.CloseWithError(archive.Export(ctx, client.ContentStore(), pw, imgOpts, manifestOpts, platOpts)) @@ -67,7 +76,7 @@ func imageWriter(client *containerd.Client, img containerd.Image) imageSave { } // ContainerdImage implements v1.Image -func ContainerdImage(ctx context.Context, imageName string) (Image, func(), error) { +func ContainerdImage(ctx context.Context, imageName string, opts types.ImageOptions) (Image, func(), error) { cleanup := func() {} addr := os.Getenv("CONTAINERD_ADDRESS") @@ -85,7 +94,17 @@ func ContainerdImage(ctx context.Context, imageName string) (Image, func(), erro return nil, cleanup, err } - client, err := containerd.New(addr) + options := []containerd.ClientOpt{} + if opts.RegistryOptions.Platform.Platform != nil { + ociPlatform, err := platforms.Parse(opts.RegistryOptions.Platform.String()) + if err != nil { + return nil, cleanup, err + } + + options = append(options, containerd.WithDefaultPlatform(platforms.OnlyStrict(ociPlatform))) + } + + client, err := containerd.New(addr, options...) if err != nil { return nil, cleanup, xerrors.Errorf("failed to initialize a containerd client: %w", err) } @@ -125,7 +144,7 @@ func ContainerdImage(ctx context.Context, imageName string) (Image, func(), erro } return &image{ - opener: imageOpener(ctx, ref.String(), f, imageWriter(client, img)), + opener: imageOpener(ctx, ref.String(), f, imageWriter(client, img, opts.RegistryOptions.Platform)), inspect: insp, history: history, }, cleanup, nil