mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-10-31 21:26:11 +00:00 
			
		
		
		
	Replace riddler with code that constructs config.json directly
Generated largely from the specified config; small parts taken from `docker image inspect`, such as the command line. Renamed some of the yaml keys to match the OCI spec rather than Docker Compose as we decided they are more readable, no more underscores. Add some extra functionality - tmpfs specification - fully general mount specification - no new privileges can be specified now For nostalgic reasons, using engine-api to talk to the docker cli as we only need an old API version, and it is nice and easy to vendor... Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
		
							
								
								
									
										139
									
								
								vendor/github.com/docker/distribution/digest/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/github.com/docker/distribution/digest/digest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| package digest | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"hash" | ||||
| 	"io" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// DigestSha256EmptyTar is the canonical sha256 digest of empty data | ||||
| 	DigestSha256EmptyTar = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" | ||||
| ) | ||||
|  | ||||
| // Digest allows simple protection of hex formatted digest strings, prefixed | ||||
| // by their algorithm. Strings of type Digest have some guarantee of being in | ||||
| // the correct format and it provides quick access to the components of a | ||||
| // digest string. | ||||
| // | ||||
| // The following is an example of the contents of Digest types: | ||||
| // | ||||
| // 	sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc | ||||
| // | ||||
| // This allows to abstract the digest behind this type and work only in those | ||||
| // terms. | ||||
| type Digest string | ||||
|  | ||||
| // NewDigest returns a Digest from alg and a hash.Hash object. | ||||
| func NewDigest(alg Algorithm, h hash.Hash) Digest { | ||||
| 	return NewDigestFromBytes(alg, h.Sum(nil)) | ||||
| } | ||||
|  | ||||
| // NewDigestFromBytes returns a new digest from the byte contents of p. | ||||
| // Typically, this can come from hash.Hash.Sum(...) or xxx.SumXXX(...) | ||||
| // functions. This is also useful for rebuilding digests from binary | ||||
| // serializations. | ||||
| func NewDigestFromBytes(alg Algorithm, p []byte) Digest { | ||||
| 	return Digest(fmt.Sprintf("%s:%x", alg, p)) | ||||
| } | ||||
|  | ||||
| // NewDigestFromHex returns a Digest from alg and a the hex encoded digest. | ||||
| func NewDigestFromHex(alg, hex string) Digest { | ||||
| 	return Digest(fmt.Sprintf("%s:%s", alg, hex)) | ||||
| } | ||||
|  | ||||
| // DigestRegexp matches valid digest types. | ||||
| var DigestRegexp = regexp.MustCompile(`[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+`) | ||||
|  | ||||
| // DigestRegexpAnchored matches valid digest types, anchored to the start and end of the match. | ||||
| var DigestRegexpAnchored = regexp.MustCompile(`^` + DigestRegexp.String() + `$`) | ||||
|  | ||||
| var ( | ||||
| 	// ErrDigestInvalidFormat returned when digest format invalid. | ||||
| 	ErrDigestInvalidFormat = fmt.Errorf("invalid checksum digest format") | ||||
|  | ||||
| 	// ErrDigestInvalidLength returned when digest has invalid length. | ||||
| 	ErrDigestInvalidLength = fmt.Errorf("invalid checksum digest length") | ||||
|  | ||||
| 	// ErrDigestUnsupported returned when the digest algorithm is unsupported. | ||||
| 	ErrDigestUnsupported = fmt.Errorf("unsupported digest algorithm") | ||||
| ) | ||||
|  | ||||
| // ParseDigest parses s and returns the validated digest object. An error will | ||||
| // be returned if the format is invalid. | ||||
| func ParseDigest(s string) (Digest, error) { | ||||
| 	d := Digest(s) | ||||
|  | ||||
| 	return d, d.Validate() | ||||
| } | ||||
|  | ||||
| // FromReader returns the most valid digest for the underlying content using | ||||
| // the canonical digest algorithm. | ||||
| func FromReader(rd io.Reader) (Digest, error) { | ||||
| 	return Canonical.FromReader(rd) | ||||
| } | ||||
|  | ||||
| // FromBytes digests the input and returns a Digest. | ||||
| func FromBytes(p []byte) Digest { | ||||
| 	return Canonical.FromBytes(p) | ||||
| } | ||||
|  | ||||
| // Validate checks that the contents of d is a valid digest, returning an | ||||
| // error if not. | ||||
| func (d Digest) Validate() error { | ||||
| 	s := string(d) | ||||
|  | ||||
| 	if !DigestRegexpAnchored.MatchString(s) { | ||||
| 		return ErrDigestInvalidFormat | ||||
| 	} | ||||
|  | ||||
| 	i := strings.Index(s, ":") | ||||
| 	if i < 0 { | ||||
| 		return ErrDigestInvalidFormat | ||||
| 	} | ||||
|  | ||||
| 	// case: "sha256:" with no hex. | ||||
| 	if i+1 == len(s) { | ||||
| 		return ErrDigestInvalidFormat | ||||
| 	} | ||||
|  | ||||
| 	switch algorithm := Algorithm(s[:i]); algorithm { | ||||
| 	case SHA256, SHA384, SHA512: | ||||
| 		if algorithm.Size()*2 != len(s[i+1:]) { | ||||
| 			return ErrDigestInvalidLength | ||||
| 		} | ||||
| 		break | ||||
| 	default: | ||||
| 		return ErrDigestUnsupported | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Algorithm returns the algorithm portion of the digest. This will panic if | ||||
| // the underlying digest is not in a valid format. | ||||
| func (d Digest) Algorithm() Algorithm { | ||||
| 	return Algorithm(d[:d.sepIndex()]) | ||||
| } | ||||
|  | ||||
| // Hex returns the hex digest portion of the digest. This will panic if the | ||||
| // underlying digest is not in a valid format. | ||||
| func (d Digest) Hex() string { | ||||
| 	return string(d[d.sepIndex()+1:]) | ||||
| } | ||||
|  | ||||
| func (d Digest) String() string { | ||||
| 	return string(d) | ||||
| } | ||||
|  | ||||
| func (d Digest) sepIndex() int { | ||||
| 	i := strings.Index(string(d), ":") | ||||
|  | ||||
| 	if i < 0 { | ||||
| 		panic("could not find ':' in digest: " + d) | ||||
| 	} | ||||
|  | ||||
| 	return i | ||||
| } | ||||
							
								
								
									
										155
									
								
								vendor/github.com/docker/distribution/digest/digester.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								vendor/github.com/docker/distribution/digest/digester.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| package digest | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"fmt" | ||||
| 	"hash" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // Algorithm identifies and implementation of a digester by an identifier. | ||||
| // Note the that this defines both the hash algorithm used and the string | ||||
| // encoding. | ||||
| type Algorithm string | ||||
|  | ||||
| // supported digest types | ||||
| const ( | ||||
| 	SHA256 Algorithm = "sha256" // sha256 with hex encoding | ||||
| 	SHA384 Algorithm = "sha384" // sha384 with hex encoding | ||||
| 	SHA512 Algorithm = "sha512" // sha512 with hex encoding | ||||
|  | ||||
| 	// Canonical is the primary digest algorithm used with the distribution | ||||
| 	// project. Other digests may be used but this one is the primary storage | ||||
| 	// digest. | ||||
| 	Canonical = SHA256 | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// TODO(stevvooe): Follow the pattern of the standard crypto package for | ||||
| 	// registration of digests. Effectively, we are a registerable set and | ||||
| 	// common symbol access. | ||||
|  | ||||
| 	// algorithms maps values to hash.Hash implementations. Other algorithms | ||||
| 	// may be available but they cannot be calculated by the digest package. | ||||
| 	algorithms = map[Algorithm]crypto.Hash{ | ||||
| 		SHA256: crypto.SHA256, | ||||
| 		SHA384: crypto.SHA384, | ||||
| 		SHA512: crypto.SHA512, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // Available returns true if the digest type is available for use. If this | ||||
| // returns false, New and Hash will return nil. | ||||
| func (a Algorithm) Available() bool { | ||||
| 	h, ok := algorithms[a] | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// check availability of the hash, as well | ||||
| 	return h.Available() | ||||
| } | ||||
|  | ||||
| func (a Algorithm) String() string { | ||||
| 	return string(a) | ||||
| } | ||||
|  | ||||
| // Size returns number of bytes returned by the hash. | ||||
| func (a Algorithm) Size() int { | ||||
| 	h, ok := algorithms[a] | ||||
| 	if !ok { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	return h.Size() | ||||
| } | ||||
|  | ||||
| // Set implemented to allow use of Algorithm as a command line flag. | ||||
| func (a *Algorithm) Set(value string) error { | ||||
| 	if value == "" { | ||||
| 		*a = Canonical | ||||
| 	} else { | ||||
| 		// just do a type conversion, support is queried with Available. | ||||
| 		*a = Algorithm(value) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // New returns a new digester for the specified algorithm. If the algorithm | ||||
| // does not have a digester implementation, nil will be returned. This can be | ||||
| // checked by calling Available before calling New. | ||||
| func (a Algorithm) New() Digester { | ||||
| 	return &digester{ | ||||
| 		alg:  a, | ||||
| 		hash: a.Hash(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Hash returns a new hash as used by the algorithm. If not available, the | ||||
| // method will panic. Check Algorithm.Available() before calling. | ||||
| func (a Algorithm) Hash() hash.Hash { | ||||
| 	if !a.Available() { | ||||
| 		// NOTE(stevvooe): A missing hash is usually a programming error that | ||||
| 		// must be resolved at compile time. We don't import in the digest | ||||
| 		// package to allow users to choose their hash implementation (such as | ||||
| 		// when using stevvooe/resumable or a hardware accelerated package). | ||||
| 		// | ||||
| 		// Applications that may want to resolve the hash at runtime should | ||||
| 		// call Algorithm.Available before call Algorithm.Hash(). | ||||
| 		panic(fmt.Sprintf("%v not available (make sure it is imported)", a)) | ||||
| 	} | ||||
|  | ||||
| 	return algorithms[a].New() | ||||
| } | ||||
|  | ||||
| // FromReader returns the digest of the reader using the algorithm. | ||||
| func (a Algorithm) FromReader(rd io.Reader) (Digest, error) { | ||||
| 	digester := a.New() | ||||
|  | ||||
| 	if _, err := io.Copy(digester.Hash(), rd); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return digester.Digest(), nil | ||||
| } | ||||
|  | ||||
| // FromBytes digests the input and returns a Digest. | ||||
| func (a Algorithm) FromBytes(p []byte) Digest { | ||||
| 	digester := a.New() | ||||
|  | ||||
| 	if _, err := digester.Hash().Write(p); err != nil { | ||||
| 		// Writes to a Hash should never fail. None of the existing | ||||
| 		// hash implementations in the stdlib or hashes vendored | ||||
| 		// here can return errors from Write. Having a panic in this | ||||
| 		// condition instead of having FromBytes return an error value | ||||
| 		// avoids unnecessary error handling paths in all callers. | ||||
| 		panic("write to hash function returned error: " + err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return digester.Digest() | ||||
| } | ||||
|  | ||||
| // TODO(stevvooe): Allow resolution of verifiers using the digest type and | ||||
| // this registration system. | ||||
|  | ||||
| // Digester calculates the digest of written data. Writes should go directly | ||||
| // to the return value of Hash, while calling Digest will return the current | ||||
| // value of the digest. | ||||
| type Digester interface { | ||||
| 	Hash() hash.Hash // provides direct access to underlying hash instance. | ||||
| 	Digest() Digest | ||||
| } | ||||
|  | ||||
| // digester provides a simple digester definition that embeds a hasher. | ||||
| type digester struct { | ||||
| 	alg  Algorithm | ||||
| 	hash hash.Hash | ||||
| } | ||||
|  | ||||
| func (d *digester) Hash() hash.Hash { | ||||
| 	return d.hash | ||||
| } | ||||
|  | ||||
| func (d *digester) Digest() Digest { | ||||
| 	return NewDigest(d.alg, d.hash) | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/github.com/docker/distribution/digest/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/docker/distribution/digest/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // Package digest provides a generalized type to opaquely represent message | ||||
| // digests and their operations within the registry. The Digest type is | ||||
| // designed to serve as a flexible identifier in a content-addressable system. | ||||
| // More importantly, it provides tools and wrappers to work with | ||||
| // hash.Hash-based digests with little effort. | ||||
| // | ||||
| // Basics | ||||
| // | ||||
| // The format of a digest is simply a string with two parts, dubbed the | ||||
| // "algorithm" and the "digest", separated by a colon: | ||||
| // | ||||
| // 	<algorithm>:<digest> | ||||
| // | ||||
| // An example of a sha256 digest representation follows: | ||||
| // | ||||
| // 	sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc | ||||
| // | ||||
| // In this case, the string "sha256" is the algorithm and the hex bytes are | ||||
| // the "digest". | ||||
| // | ||||
| // Because the Digest type is simply a string, once a valid Digest is | ||||
| // obtained, comparisons are cheap, quick and simple to express with the | ||||
| // standard equality operator. | ||||
| // | ||||
| // Verification | ||||
| // | ||||
| // The main benefit of using the Digest type is simple verification against a | ||||
| // given digest. The Verifier interface, modeled after the stdlib hash.Hash | ||||
| // interface, provides a common write sink for digest verification. After | ||||
| // writing is complete, calling the Verifier.Verified method will indicate | ||||
| // whether or not the stream of bytes matches the target digest. | ||||
| // | ||||
| // Missing Features | ||||
| // | ||||
| // In addition to the above, we intend to add the following features to this | ||||
| // package: | ||||
| // | ||||
| // 1. A Digester type that supports write sink digest calculation. | ||||
| // | ||||
| // 2. Suspend and resume of ongoing digest calculations to support efficient digest verification in the registry. | ||||
| // | ||||
| package digest | ||||
							
								
								
									
										245
									
								
								vendor/github.com/docker/distribution/digest/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								vendor/github.com/docker/distribution/digest/set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | ||||
| package digest | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ErrDigestNotFound is used when a matching digest | ||||
| 	// could not be found in a set. | ||||
| 	ErrDigestNotFound = errors.New("digest not found") | ||||
|  | ||||
| 	// ErrDigestAmbiguous is used when multiple digests | ||||
| 	// are found in a set. None of the matching digests | ||||
| 	// should be considered valid matches. | ||||
| 	ErrDigestAmbiguous = errors.New("ambiguous digest string") | ||||
| ) | ||||
|  | ||||
| // Set is used to hold a unique set of digests which | ||||
| // may be easily referenced by easily  referenced by a string | ||||
| // representation of the digest as well as short representation. | ||||
| // The uniqueness of the short representation is based on other | ||||
| // digests in the set. If digests are omitted from this set, | ||||
| // collisions in a larger set may not be detected, therefore it | ||||
| // is important to always do short representation lookups on | ||||
| // the complete set of digests. To mitigate collisions, an | ||||
| // appropriately long short code should be used. | ||||
| type Set struct { | ||||
| 	mutex   sync.RWMutex | ||||
| 	entries digestEntries | ||||
| } | ||||
|  | ||||
| // NewSet creates an empty set of digests | ||||
| // which may have digests added. | ||||
| func NewSet() *Set { | ||||
| 	return &Set{ | ||||
| 		entries: digestEntries{}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // checkShortMatch checks whether two digests match as either whole | ||||
| // values or short values. This function does not test equality, | ||||
| // rather whether the second value could match against the first | ||||
| // value. | ||||
| func checkShortMatch(alg Algorithm, hex, shortAlg, shortHex string) bool { | ||||
| 	if len(hex) == len(shortHex) { | ||||
| 		if hex != shortHex { | ||||
| 			return false | ||||
| 		} | ||||
| 		if len(shortAlg) > 0 && string(alg) != shortAlg { | ||||
| 			return false | ||||
| 		} | ||||
| 	} else if !strings.HasPrefix(hex, shortHex) { | ||||
| 		return false | ||||
| 	} else if len(shortAlg) > 0 && string(alg) != shortAlg { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Lookup looks for a digest matching the given string representation. | ||||
| // If no digests could be found ErrDigestNotFound will be returned | ||||
| // with an empty digest value. If multiple matches are found | ||||
| // ErrDigestAmbiguous will be returned with an empty digest value. | ||||
| func (dst *Set) Lookup(d string) (Digest, error) { | ||||
| 	dst.mutex.RLock() | ||||
| 	defer dst.mutex.RUnlock() | ||||
| 	if len(dst.entries) == 0 { | ||||
| 		return "", ErrDigestNotFound | ||||
| 	} | ||||
| 	var ( | ||||
| 		searchFunc func(int) bool | ||||
| 		alg        Algorithm | ||||
| 		hex        string | ||||
| 	) | ||||
| 	dgst, err := ParseDigest(d) | ||||
| 	if err == ErrDigestInvalidFormat { | ||||
| 		hex = d | ||||
| 		searchFunc = func(i int) bool { | ||||
| 			return dst.entries[i].val >= d | ||||
| 		} | ||||
| 	} else { | ||||
| 		hex = dgst.Hex() | ||||
| 		alg = dgst.Algorithm() | ||||
| 		searchFunc = func(i int) bool { | ||||
| 			if dst.entries[i].val == hex { | ||||
| 				return dst.entries[i].alg >= alg | ||||
| 			} | ||||
| 			return dst.entries[i].val >= hex | ||||
| 		} | ||||
| 	} | ||||
| 	idx := sort.Search(len(dst.entries), searchFunc) | ||||
| 	if idx == len(dst.entries) || !checkShortMatch(dst.entries[idx].alg, dst.entries[idx].val, string(alg), hex) { | ||||
| 		return "", ErrDigestNotFound | ||||
| 	} | ||||
| 	if dst.entries[idx].alg == alg && dst.entries[idx].val == hex { | ||||
| 		return dst.entries[idx].digest, nil | ||||
| 	} | ||||
| 	if idx+1 < len(dst.entries) && checkShortMatch(dst.entries[idx+1].alg, dst.entries[idx+1].val, string(alg), hex) { | ||||
| 		return "", ErrDigestAmbiguous | ||||
| 	} | ||||
|  | ||||
| 	return dst.entries[idx].digest, nil | ||||
| } | ||||
|  | ||||
| // Add adds the given digest to the set. An error will be returned | ||||
| // if the given digest is invalid. If the digest already exists in the | ||||
| // set, this operation will be a no-op. | ||||
| func (dst *Set) Add(d Digest) error { | ||||
| 	if err := d.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	dst.mutex.Lock() | ||||
| 	defer dst.mutex.Unlock() | ||||
| 	entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d} | ||||
| 	searchFunc := func(i int) bool { | ||||
| 		if dst.entries[i].val == entry.val { | ||||
| 			return dst.entries[i].alg >= entry.alg | ||||
| 		} | ||||
| 		return dst.entries[i].val >= entry.val | ||||
| 	} | ||||
| 	idx := sort.Search(len(dst.entries), searchFunc) | ||||
| 	if idx == len(dst.entries) { | ||||
| 		dst.entries = append(dst.entries, entry) | ||||
| 		return nil | ||||
| 	} else if dst.entries[idx].digest == d { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	entries := append(dst.entries, nil) | ||||
| 	copy(entries[idx+1:], entries[idx:len(entries)-1]) | ||||
| 	entries[idx] = entry | ||||
| 	dst.entries = entries | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Remove removes the given digest from the set. An err will be | ||||
| // returned if the given digest is invalid. If the digest does | ||||
| // not exist in the set, this operation will be a no-op. | ||||
| func (dst *Set) Remove(d Digest) error { | ||||
| 	if err := d.Validate(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	dst.mutex.Lock() | ||||
| 	defer dst.mutex.Unlock() | ||||
| 	entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d} | ||||
| 	searchFunc := func(i int) bool { | ||||
| 		if dst.entries[i].val == entry.val { | ||||
| 			return dst.entries[i].alg >= entry.alg | ||||
| 		} | ||||
| 		return dst.entries[i].val >= entry.val | ||||
| 	} | ||||
| 	idx := sort.Search(len(dst.entries), searchFunc) | ||||
| 	// Not found if idx is after or value at idx is not digest | ||||
| 	if idx == len(dst.entries) || dst.entries[idx].digest != d { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	entries := dst.entries | ||||
| 	copy(entries[idx:], entries[idx+1:]) | ||||
| 	entries = entries[:len(entries)-1] | ||||
| 	dst.entries = entries | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // All returns all the digests in the set | ||||
| func (dst *Set) All() []Digest { | ||||
| 	dst.mutex.RLock() | ||||
| 	defer dst.mutex.RUnlock() | ||||
| 	retValues := make([]Digest, len(dst.entries)) | ||||
| 	for i := range dst.entries { | ||||
| 		retValues[i] = dst.entries[i].digest | ||||
| 	} | ||||
|  | ||||
| 	return retValues | ||||
| } | ||||
|  | ||||
| // ShortCodeTable returns a map of Digest to unique short codes. The | ||||
| // length represents the minimum value, the maximum length may be the | ||||
| // entire value of digest if uniqueness cannot be achieved without the | ||||
| // full value. This function will attempt to make short codes as short | ||||
| // as possible to be unique. | ||||
| func ShortCodeTable(dst *Set, length int) map[Digest]string { | ||||
| 	dst.mutex.RLock() | ||||
| 	defer dst.mutex.RUnlock() | ||||
| 	m := make(map[Digest]string, len(dst.entries)) | ||||
| 	l := length | ||||
| 	resetIdx := 0 | ||||
| 	for i := 0; i < len(dst.entries); i++ { | ||||
| 		var short string | ||||
| 		extended := true | ||||
| 		for extended { | ||||
| 			extended = false | ||||
| 			if len(dst.entries[i].val) <= l { | ||||
| 				short = dst.entries[i].digest.String() | ||||
| 			} else { | ||||
| 				short = dst.entries[i].val[:l] | ||||
| 				for j := i + 1; j < len(dst.entries); j++ { | ||||
| 					if checkShortMatch(dst.entries[j].alg, dst.entries[j].val, "", short) { | ||||
| 						if j > resetIdx { | ||||
| 							resetIdx = j | ||||
| 						} | ||||
| 						extended = true | ||||
| 					} else { | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 				if extended { | ||||
| 					l++ | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		m[dst.entries[i].digest] = short | ||||
| 		if i >= resetIdx { | ||||
| 			l = length | ||||
| 		} | ||||
| 	} | ||||
| 	return m | ||||
| } | ||||
|  | ||||
| type digestEntry struct { | ||||
| 	alg    Algorithm | ||||
| 	val    string | ||||
| 	digest Digest | ||||
| } | ||||
|  | ||||
| type digestEntries []*digestEntry | ||||
|  | ||||
| func (d digestEntries) Len() int { | ||||
| 	return len(d) | ||||
| } | ||||
|  | ||||
| func (d digestEntries) Less(i, j int) bool { | ||||
| 	if d[i].val != d[j].val { | ||||
| 		return d[i].val < d[j].val | ||||
| 	} | ||||
| 	return d[i].alg < d[j].alg | ||||
| } | ||||
|  | ||||
| func (d digestEntries) Swap(i, j int) { | ||||
| 	d[i], d[j] = d[j], d[i] | ||||
| } | ||||
							
								
								
									
										44
									
								
								vendor/github.com/docker/distribution/digest/verifiers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/docker/distribution/digest/verifiers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| package digest | ||||
|  | ||||
| import ( | ||||
| 	"hash" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // Verifier presents a general verification interface to be used with message | ||||
| // digests and other byte stream verifications. Users instantiate a Verifier | ||||
| // from one of the various methods, write the data under test to it then check | ||||
| // the result with the Verified method. | ||||
| type Verifier interface { | ||||
| 	io.Writer | ||||
|  | ||||
| 	// Verified will return true if the content written to Verifier matches | ||||
| 	// the digest. | ||||
| 	Verified() bool | ||||
| } | ||||
|  | ||||
| // NewDigestVerifier returns a verifier that compares the written bytes | ||||
| // against a passed in digest. | ||||
| func NewDigestVerifier(d Digest) (Verifier, error) { | ||||
| 	if err := d.Validate(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return hashVerifier{ | ||||
| 		hash:   d.Algorithm().Hash(), | ||||
| 		digest: d, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| type hashVerifier struct { | ||||
| 	digest Digest | ||||
| 	hash   hash.Hash | ||||
| } | ||||
|  | ||||
| func (hv hashVerifier) Write(p []byte) (n int, err error) { | ||||
| 	return hv.hash.Write(p) | ||||
| } | ||||
|  | ||||
| func (hv hashVerifier) Verified() bool { | ||||
| 	return hv.digest == NewDigest(hv.digest.Algorithm(), hv.hash) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user