MCPcopy
hub / github.com/google/go-containerregistry / commitSubjectReferrers

Method commitSubjectReferrers

pkg/v1/remote/write.go:508–583  ·  view source on GitHub ↗

commitSubjectReferrers is responsible for updating the fallback tag manifest to track descriptors referring to a subject for registries that don't yet support the Referrers API. TODO: use conditional requests to avoid race conditions

(ctx context.Context, sub name.Digest, add v1.Descriptor)

Source from the content-addressed store, hash-verified

506// commitSubjectReferrers is responsible for updating the fallback tag manifest to track descriptors referring to a subject for registries that don't yet support the Referrers API.
507// TODO: use conditional requests to avoid race conditions
508func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, add v1.Descriptor) error {
509 // Check if the registry supports Referrers API.
510 // TODO: This should be done once per registry, not once per subject.
511 u := w.url(fmt.Sprintf("/v2/%s/referrers/%s", w.repo.RepositoryStr(), sub.DigestStr()))
512 req, err := http.NewRequest(http.MethodGet, u.String(), nil)
513 if err != nil {
514 return err
515 }
516 req.Header.Set("Accept", string(types.OCIImageIndex))
517 resp, err := w.client.Do(req.WithContext(ctx))
518 if err != nil {
519 return err
520 }
521 defer resp.Body.Close()
522
523 if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {
524 return err
525 }
526 if resp.StatusCode == http.StatusOK {
527 // The registry supports Referrers API. The registry is responsible for updating the referrers list.
528 return nil
529 }
530
531 // The registry doesn't support Referrers API, we need to update the manifest tagged with the fallback tag.
532 // Make the request to GET the current manifest.
533 t := fallbackTag(sub)
534 u = w.url(fmt.Sprintf("/v2/%s/manifests/%s", w.repo.RepositoryStr(), t.Identifier()))
535 req, err = http.NewRequest(http.MethodGet, u.String(), nil)
536 if err != nil {
537 return err
538 }
539 req.Header.Set("Accept", string(types.OCIImageIndex))
540 resp, err = w.client.Do(req.WithContext(ctx))
541 if err != nil {
542 return err
543 }
544 defer resp.Body.Close()
545
546 var im v1.IndexManifest
547 if err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {
548 return err
549 } else if resp.StatusCode == http.StatusNotFound {
550 // Not found just means there are no attachments. Start with an empty index.
551 im = v1.IndexManifest{
552 SchemaVersion: 2,
553 MediaType: types.OCIImageIndex,
554 Manifests: []v1.Descriptor{add},
555 }
556 } else {
557 if err := json.NewDecoder(resp.Body).Decode(&im); err != nil {
558 return err
559 }
560 if im.SchemaVersion != 2 {
561 return fmt.Errorf("fallback tag manifest is not a schema version 2: %d", im.SchemaVersion)
562 }
563 if im.MediaType != types.OCIImageIndex {
564 return fmt.Errorf("fallback tag manifest is not an OCI image index: %s", im.MediaType)
565 }

Callers 1

commitManifestMethod · 0.95

Calls 11

urlMethod · 0.95
commitManifestMethod · 0.95
CheckErrorFunction · 0.92
fallbackTagFunction · 0.85
RepositoryStrMethod · 0.80
DigestStrMethod · 0.80
StringMethod · 0.65
CloseMethod · 0.65
IdentifierMethod · 0.65
SetMethod · 0.45
DoMethod · 0.45

Tested by

no test coverage detected