...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package name
16
17 import (
18
19 _ "crypto/sha256"
20 "strings"
21
22 "github.com/opencontainers/go-digest"
23 )
24
25 const digestDelim = "@"
26
27
28 type Digest struct {
29 Repository
30 digest string
31 original string
32 }
33
34
35 var _ Reference = (*Digest)(nil)
36
37
38 func (d Digest) Context() Repository {
39 return d.Repository
40 }
41
42
43 func (d Digest) Identifier() string {
44 return d.DigestStr()
45 }
46
47
48 func (d Digest) DigestStr() string {
49 return d.digest
50 }
51
52
53 func (d Digest) Name() string {
54 return d.Repository.Name() + digestDelim + d.DigestStr()
55 }
56
57
58 func (d Digest) String() string {
59 return d.original
60 }
61
62
63 func NewDigest(name string, opts ...Option) (Digest, error) {
64
65 parts := strings.Split(name, digestDelim)
66 if len(parts) != 2 {
67 return Digest{}, newErrBadName("a digest must contain exactly one '@' separator (e.g. registry/repository@digest) saw: %s", name)
68 }
69 base := parts[0]
70 dig := parts[1]
71 prefix := digest.Canonical.String() + ":"
72 if !strings.HasPrefix(dig, prefix) {
73 return Digest{}, newErrBadName("unsupported digest algorithm: %s", dig)
74 }
75 hex := strings.TrimPrefix(dig, prefix)
76 if err := digest.Canonical.Validate(hex); err != nil {
77 return Digest{}, err
78 }
79
80 tag, err := NewTag(base, opts...)
81 if err == nil {
82 base = tag.Repository.Name()
83 }
84
85 repo, err := NewRepository(base, opts...)
86 if err != nil {
87 return Digest{}, err
88 }
89 return Digest{
90 Repository: repo,
91 digest: dig,
92 original: name,
93 }, nil
94 }
95
View as plain text