Add image verifier transfer service plugin system based on a binary directory

Signed-off-by: Ethan Lowman <ethan.lowman@datadoghq.com>
This commit is contained in:
Ethan Lowman
2023-05-05 15:29:33 -04:00
parent 5c37d3827b
commit ac1d556b92
24 changed files with 1412 additions and 9 deletions

View File

@@ -30,6 +30,7 @@ import (
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
)
func (ts *localTransferService) pull(ctx context.Context, ir transfer.ImageFetcher, is transfer.ImageStorer, tops *transfer.Config) error {
@@ -54,6 +55,32 @@ func (ts *localTransferService) pull(ctx context.Context, ir transfer.ImageFetch
return fmt.Errorf("schema 1 image manifests are no longer supported: %w", errdefs.ErrInvalidArgument)
}
// Verify image before pulling.
for vfName, vf := range ts.verifiers {
log := log.G(ctx).WithFields(logrus.Fields{
"name": name,
"digest": desc.Digest.String(),
"verifier": vfName,
})
log.Debug("Verifying image pull")
jdg, err := vf.VerifyImage(ctx, name, desc)
if err != nil {
log.WithError(err).Error("No judgement received from verifier")
return fmt.Errorf("blocking pull of %v with digest %v: image verifier %v returned error: %w", name, desc.Digest.String(), vfName, err)
}
log = log.WithFields(logrus.Fields{
"ok": jdg.OK,
"reason": jdg.Reason,
})
if !jdg.OK {
log.Warn("Image verifier blocked pull")
return fmt.Errorf("image verifier %s blocked pull of %v with digest %v for reason: %v", vfName, name, desc.Digest.String(), jdg.Reason)
}
log.Debug("Image verifier allowed pull")
}
// TODO: Handle already exists
if tops.Progress != nil {
tops.Progress(transfer.Progress{

View File

@@ -29,15 +29,17 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/pkg/imageverifier"
"github.com/containerd/containerd/pkg/kmutex"
"github.com/containerd/containerd/pkg/transfer"
"github.com/containerd/containerd/pkg/unpack"
)
type localTransferService struct {
leases leases.Manager
content content.Store
images images.Store
leases leases.Manager
content content.Store
images images.Store
verifiers map[string]imageverifier.ImageVerifier
// limiter for upload
limiterU *semaphore.Weighted
// limiter for download operation
@@ -45,12 +47,13 @@ type localTransferService struct {
config TransferConfig
}
func NewTransferService(lm leases.Manager, cs content.Store, is images.Store, tc *TransferConfig) transfer.Transferrer {
func NewTransferService(lm leases.Manager, cs content.Store, is images.Store, vfs map[string]imageverifier.ImageVerifier, tc *TransferConfig) transfer.Transferrer {
ts := &localTransferService{
leases: lm,
content: cs,
images: is,
config: *tc,
leases: lm,
content: cs,
images: is,
verifiers: vfs,
config: *tc,
}
if tc.MaxConcurrentUploadedLayers > 0 {
ts.limiterU = semaphore.NewWeighted(int64(tc.MaxConcurrentUploadedLayers))
@@ -88,6 +91,7 @@ func (ts *localTransferService) Transfer(ctx context.Context, src interface{}, d
case transfer.ImageExportStreamer:
return ts.echo(ctx, s, d, topts)
case transfer.ImageStorer:
// TODO: verify imports with ImageVerifiers?
return ts.importStream(ctx, s, d, topts)
}
}