59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package contentutil
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/containerd/containerd/content"
|
|
"github.com/containerd/containerd/errdefs"
|
|
"github.com/containerd/containerd/remotes"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func FromPusher(p remotes.Pusher) content.Ingester {
|
|
return &pushingIngester{
|
|
p: p,
|
|
}
|
|
}
|
|
|
|
type pushingIngester struct {
|
|
p remotes.Pusher
|
|
}
|
|
|
|
// Writer implements content.Ingester. desc.MediaType must be set for manifest blobs.
|
|
func (i *pushingIngester) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
|
|
var wOpts content.WriterOpts
|
|
for _, opt := range opts {
|
|
if err := opt(&wOpts); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if wOpts.Ref == "" {
|
|
return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty")
|
|
}
|
|
// pusher requires desc.MediaType to determine the PUT URL, especially for manifest blobs.
|
|
contentWriter, err := i.p.Push(ctx, wOpts.Desc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &writer{
|
|
Writer: contentWriter,
|
|
contentWriterRef: wOpts.Ref,
|
|
}, nil
|
|
}
|
|
|
|
type writer struct {
|
|
content.Writer // returned from pusher.Push
|
|
contentWriterRef string // ref passed for Writer()
|
|
}
|
|
|
|
func (w *writer) Status() (content.Status, error) {
|
|
st, err := w.Writer.Status()
|
|
if err != nil {
|
|
return st, err
|
|
}
|
|
if w.contentWriterRef != "" {
|
|
st.Ref = w.contentWriterRef
|
|
}
|
|
return st, nil
|
|
}
|