Add Tarsum Calculation during v2 Pull operation

While the v2 pull operation is writing the body of the layer blob to disk
it now computes the tarsum checksum of the archive before extracting it to
the backend storage driver. If the checksum does not match that from the
image manifest an error is raised.

Also adds more debug logging to the pull operation and fixes existing test
cases which were failing. Adds a reverse lookup constructor to the tarsum
package so that you can get a tarsum object using a checksum label.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
This commit is contained in:
Josh Hawn 2014-12-23 13:40:06 -08:00 committed by Derek McGowan
parent a3bca489d0
commit 328a6bbf4e
2 changed files with 51 additions and 5 deletions

View file

@ -3,8 +3,11 @@ package tarsum
import ( import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"crypto"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors"
"fmt"
"hash" "hash"
"io" "io"
"strings" "strings"
@ -39,6 +42,30 @@ func NewTarSumHash(r io.Reader, dc bool, v Version, tHash THash) (TarSum, error)
return ts, err return ts, err
} }
// Create a new TarSum using the provided TarSum version+hash label.
func NewTarSumForLabel(r io.Reader, disableCompression bool, label string) (TarSum, error) {
parts := strings.SplitN(label, "+", 2)
if len(parts) != 2 {
return nil, errors.New("tarsum label string should be of the form: {tarsum_version}+{hash_name}")
}
versionName, hashName := parts[0], parts[1]
version, ok := tarSumVersionsByName[versionName]
if !ok {
return nil, fmt.Errorf("unknown TarSum version name: %q", versionName)
}
hashConfig, ok := standardHashConfigs[hashName]
if !ok {
return nil, fmt.Errorf("unknown TarSum hash name: %q", hashName)
}
tHash := NewTHash(hashConfig.name, hashConfig.hash.New)
return NewTarSumHash(r, disableCompression, version, tHash)
}
// TarSum is the generic interface for calculating fixed time // TarSum is the generic interface for calculating fixed time
// checksums of a tar archive // checksums of a tar archive
type TarSum interface { type TarSum interface {
@ -89,6 +116,18 @@ func NewTHash(name string, h func() hash.Hash) THash {
return simpleTHash{n: name, h: h} return simpleTHash{n: name, h: h}
} }
type tHashConfig struct {
name string
hash crypto.Hash
}
var (
standardHashConfigs = map[string]tHashConfig{
"sha256": {name: "sha256", hash: crypto.SHA256},
"sha512": {name: "sha512", hash: crypto.SHA512},
}
)
// TarSum default is "sha256" // TarSum default is "sha256"
var DefaultTHash = NewTHash("sha256", sha256.New) var DefaultTHash = NewTHash("sha256", sha256.New)

View file

@ -31,11 +31,18 @@ func GetVersions() []Version {
return v return v
} }
var tarSumVersions = map[Version]string{ var (
Version0: "tarsum", tarSumVersions = map[Version]string{
Version1: "tarsum.v1", Version0: "tarsum",
VersionDev: "tarsum.dev", Version1: "tarsum.v1",
} VersionDev: "tarsum.dev",
}
tarSumVersionsByName = map[string]Version{
"tarsum": Version0,
"tarsum.v1": Version1,
"tarsum.dev": VersionDev,
}
)
func (tsv Version) String() string { func (tsv Version) String() string {
return tarSumVersions[tsv] return tarSumVersions[tsv]