github.com/lusis/distribution@v2.0.1+incompatible/registry/storage/signaturestore.go (about) 1 package storage 2 3 import ( 4 "path" 5 "sync" 6 7 "github.com/docker/distribution" 8 "github.com/docker/distribution/context" 9 "github.com/docker/distribution/digest" 10 ) 11 12 type signatureStore struct { 13 *repository 14 } 15 16 var _ distribution.SignatureService = &signatureStore{} 17 18 func (s *signatureStore) Get(dgst digest.Digest) ([][]byte, error) { 19 signaturesPath, err := s.pm.path(manifestSignaturesPathSpec{ 20 name: s.Name(), 21 revision: dgst, 22 }) 23 24 if err != nil { 25 return nil, err 26 } 27 28 // Need to append signature digest algorithm to path to get all items. 29 // Perhaps, this should be in the pathMapper but it feels awkward. This 30 // can be eliminated by implementing listAll on drivers. 31 signaturesPath = path.Join(signaturesPath, "sha256") 32 33 signaturePaths, err := s.driver.List(signaturesPath) 34 if err != nil { 35 return nil, err 36 } 37 38 var wg sync.WaitGroup 39 type result struct { 40 index int 41 signature []byte 42 err error 43 } 44 ch := make(chan result) 45 46 for i, sigPath := range signaturePaths { 47 // Append the link portion 48 sigPath = path.Join(sigPath, "link") 49 50 wg.Add(1) 51 go func(idx int, sigPath string) { 52 defer wg.Done() 53 context.GetLogger(s.ctx). 54 Debugf("fetching signature from %q", sigPath) 55 56 r := result{index: idx} 57 if p, err := s.blobStore.linked(sigPath); err != nil { 58 context.GetLogger(s.ctx). 59 Errorf("error fetching signature from %q: %v", sigPath, err) 60 r.err = err 61 } else { 62 r.signature = p 63 } 64 65 ch <- r 66 }(i, sigPath) 67 } 68 done := make(chan struct{}) 69 go func() { 70 wg.Wait() 71 close(done) 72 }() 73 74 // aggregrate the results 75 signatures := make([][]byte, len(signaturePaths)) 76 loop: 77 for { 78 select { 79 case result := <-ch: 80 signatures[result.index] = result.signature 81 if result.err != nil && err == nil { 82 // only set the first one. 83 err = result.err 84 } 85 case <-done: 86 break loop 87 } 88 } 89 90 return signatures, err 91 } 92 93 func (s *signatureStore) Put(dgst digest.Digest, signatures ...[]byte) error { 94 for _, signature := range signatures { 95 signatureDigest, err := s.blobStore.put(signature) 96 if err != nil { 97 return err 98 } 99 100 signaturePath, err := s.pm.path(manifestSignatureLinkPathSpec{ 101 name: s.Name(), 102 revision: dgst, 103 signature: signatureDigest, 104 }) 105 106 if err != nil { 107 return err 108 } 109 110 if err := s.blobStore.link(signaturePath, signatureDigest); err != nil { 111 return err 112 } 113 } 114 return nil 115 }