(ctx context.Context, opts ...content.WriterOpt)
| 371 | } |
| 372 | |
| 373 | func (cs *contentStore) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) { |
| 374 | var wOpts content.WriterOpts |
| 375 | for _, opt := range opts { |
| 376 | if err := opt(&wOpts); err != nil { |
| 377 | return nil, err |
| 378 | } |
| 379 | } |
| 380 | // TODO(AkihiroSuda): we could create a random string or one calculated based on the context |
| 381 | // https://github.com/containerd/containerd/issues/2129#issuecomment-380255019 |
| 382 | if wOpts.Ref == "" { |
| 383 | return nil, fmt.Errorf("ref must not be empty: %w", errdefs.ErrInvalidArgument) |
| 384 | } |
| 385 | ns, err := namespaces.NamespaceRequired(ctx) |
| 386 | if err != nil { |
| 387 | return nil, err |
| 388 | } |
| 389 | |
| 390 | cs.l.RLock() |
| 391 | defer cs.l.RUnlock() |
| 392 | |
| 393 | var ( |
| 394 | w content.Writer |
| 395 | exists bool |
| 396 | bref string |
| 397 | ) |
| 398 | if err := update(ctx, cs.db, func(tx *bolt.Tx) error { |
| 399 | var shared bool |
| 400 | if wOpts.Desc.Digest != "" { |
| 401 | cbkt := getBlobBucket(tx, ns, wOpts.Desc.Digest) |
| 402 | if cbkt != nil { |
| 403 | // Add content to lease to prevent other reference removals |
| 404 | // from effecting this object during a provided lease |
| 405 | if err := addContentLease(ctx, tx, wOpts.Desc.Digest); err != nil { |
| 406 | return fmt.Errorf("unable to lease content: %w", err) |
| 407 | } |
| 408 | // Return error outside of transaction to ensure |
| 409 | // commit succeeds with the lease. |
| 410 | exists = true |
| 411 | return nil |
| 412 | } |
| 413 | |
| 414 | if cs.shared || isSharedContent(tx, wOpts.Desc.Digest) { |
| 415 | if st, err := cs.Store.Info(ctx, wOpts.Desc.Digest); err == nil { |
| 416 | // Ensure the expected size is the same, it is likely |
| 417 | // an error if the size is mismatched but the caller |
| 418 | // must resolve this on commit |
| 419 | if wOpts.Desc.Size == 0 || wOpts.Desc.Size == st.Size { |
| 420 | shared = true |
| 421 | wOpts.Desc.Size = st.Size |
| 422 | } |
| 423 | } |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | bkt, err := createIngestBucket(tx, ns, wOpts.Ref) |
| 428 | if err != nil { |
| 429 | return err |
| 430 | } |
nothing calls this directly
no test coverage detected