mirror of https://github.com/docker/docs.git
pass checksum to GetOrCreateSnapshot. One timestamp test now obsolete as we always regenerate a timestamp when regenerating a snapshot, other test has one error change because we now look for an explicit checksum, hence writing incorrect data to DB for the snapshot results in a rather than a
Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
parent
3e5d6d1f31
commit
ae133606ad
|
@ -49,10 +49,10 @@ func GetOrCreateSnapshotKey(gun string, store storage.KeyStore, crypto signed.Cr
|
|||
// the expiry time and version. Note that this function does not write generated
|
||||
// snapshots to the underlying data store, and will either return the latest snapshot time
|
||||
// or nil as the time modified
|
||||
func GetOrCreateSnapshot(gun string, store storage.MetaStore, cryptoService signed.CryptoService) (
|
||||
func GetOrCreateSnapshot(gun, checksum string, store storage.MetaStore, cryptoService signed.CryptoService) (
|
||||
*time.Time, []byte, error) {
|
||||
|
||||
lastModified, currentJSON, err := store.GetCurrent(gun, data.CanonicalSnapshotRole)
|
||||
lastModified, currentJSON, err := store.GetChecksum(gun, data.CanonicalSnapshotRole, checksum)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package snapshot
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -141,7 +143,10 @@ func TestGetSnapshotNoPreviousSnapshot(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.NoError(t, store.SetKey("gun", data.CanonicalSnapshotRole, key.Algorithm(), key.Public()))
|
||||
|
||||
_, _, err = GetOrCreateSnapshot("gun", store, crypto)
|
||||
hashBytes := sha256.Sum256(snapshotJSON)
|
||||
hashHex := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
_, _, err = GetOrCreateSnapshot("gun", hashHex, store, crypto)
|
||||
require.Error(t, err, "GetSnapshot should have failed")
|
||||
if snapshotJSON == nil {
|
||||
require.IsType(t, storage.ErrNotFound{}, err)
|
||||
|
@ -164,8 +169,11 @@ func TestGetSnapshotReturnsPreviousSnapshotIfUnexpired(t *testing.T) {
|
|||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapshotJSON}))
|
||||
|
||||
hashBytes := sha256.Sum256(snapshotJSON)
|
||||
hashHex := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
// test when db is missing the role data (no root)
|
||||
_, gottenSnapshot, err := GetOrCreateSnapshot("gun", store, crypto)
|
||||
_, gottenSnapshot, err := GetOrCreateSnapshot("gun", hashHex, store, crypto)
|
||||
require.NoError(t, err, "GetSnapshot should not have failed")
|
||||
require.True(t, bytes.Equal(snapshotJSON, gottenSnapshot))
|
||||
}
|
||||
|
@ -191,7 +199,10 @@ func TestGetSnapshotOldSnapshotExpired(t *testing.T) {
|
|||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapshotJSON}))
|
||||
|
||||
_, gottenSnapshot, err := GetOrCreateSnapshot("gun", store, crypto)
|
||||
hashBytes := sha256.Sum256(snapshotJSON)
|
||||
hashHex := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
_, gottenSnapshot, err := GetOrCreateSnapshot("gun", hashHex, store, crypto)
|
||||
require.NoError(t, err, "GetSnapshot errored")
|
||||
|
||||
require.False(t, bytes.Equal(snapshotJSON, gottenSnapshot),
|
||||
|
@ -225,7 +236,10 @@ func TestCannotMakeNewSnapshotIfNoRoot(t *testing.T) {
|
|||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 1, Data: snapshotJSON}))
|
||||
|
||||
_, _, err := GetOrCreateSnapshot("gun", store, crypto)
|
||||
hashBytes := sha256.Sum256(snapshotJSON)
|
||||
hashHex := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
_, _, err := GetOrCreateSnapshot("gun", hashHex, store, crypto)
|
||||
require.Error(t, err, "GetSnapshot errored")
|
||||
|
||||
if rootJSON == nil { // missing metadata
|
||||
|
@ -257,8 +271,11 @@ func TestCreateSnapshotNoKeyInCrypto(t *testing.T) {
|
|||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapshotJSON}))
|
||||
|
||||
hashBytes := sha256.Sum256(snapshotJSON)
|
||||
hashHex := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
// pass it a new cryptoservice without the key
|
||||
_, _, err = GetOrCreateSnapshot("gun", store, signed.NewEd25519())
|
||||
_, _, err = GetOrCreateSnapshot("gun", hashHex, store, signed.NewEd25519())
|
||||
require.Error(t, err)
|
||||
require.IsType(t, signed.ErrInsufficientSignatures{}, err)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package timestamp
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go/canonical/json"
|
||||
"github.com/docker/notary"
|
||||
"github.com/docker/notary/tuf"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
|
@ -68,8 +70,16 @@ func GetOrCreateTimestamp(gun string, store storage.MetaStore, cryptoService sig
|
|||
logrus.Error("Failed to unmarshal existing timestamp")
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
snapshotTime, snapshot, err := snapshot.GetOrCreateSnapshot(gun, store, cryptoService)
|
||||
snapChecksums, err := prev.GetSnapshot()
|
||||
if err != nil || snapChecksums == nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
snapshotSha256Bytes, ok := snapChecksums.Hashes[notary.SHA256]
|
||||
if !ok {
|
||||
return nil, nil, data.ErrMissingMeta{Role: data.CanonicalSnapshotRole}
|
||||
}
|
||||
snapshotSha256Hex := hex.EncodeToString(snapshotSha256Bytes[:])
|
||||
snapshotTime, snapshot, err := snapshot.GetOrCreateSnapshot(gun, snapshotSha256Hex, store, cryptoService)
|
||||
if err != nil {
|
||||
logrus.Debug("Previous timestamp, but no valid snapshot for GUN ", gun)
|
||||
return nil, nil, err
|
||||
|
|
|
@ -150,42 +150,6 @@ func TestGetTimestampOldTimestampExpired(t *testing.T) {
|
|||
require.True(t, signedMeta.Signed.Expires.After(time.Now()))
|
||||
}
|
||||
|
||||
// In practice this might happen if the snapshot is expired, for instance, and
|
||||
// is re-signed.
|
||||
func TestGetTimestampIfNewSnapshot(t *testing.T) {
|
||||
store := storage.NewMemStorage()
|
||||
repo, crypto, err := testutils.EmptyRepo("gun")
|
||||
|
||||
rootJSON, err := json.Marshal(repo.Root)
|
||||
require.NoError(t, err)
|
||||
timestampJSON, err := json.Marshal(repo.Timestamp)
|
||||
require.NoError(t, err)
|
||||
snapJSON, err := json.Marshal(repo.Snapshot)
|
||||
require.NoError(t, err)
|
||||
|
||||
// set all the metadata
|
||||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON}))
|
||||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapJSON}))
|
||||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 0, Data: timestampJSON}))
|
||||
|
||||
c1, ts1, err := GetOrCreateTimestamp("gun", store, crypto)
|
||||
require.Nil(t, err, "GetTimestamp errored")
|
||||
|
||||
// update the snapshot to a new version
|
||||
repo.Snapshot.Signed.Version++
|
||||
snapJSON, err = json.Marshal(repo.Snapshot)
|
||||
require.NoError(t, err)
|
||||
store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snapJSON})
|
||||
|
||||
c2, ts2, err := GetOrCreateTimestamp("gun", store, crypto)
|
||||
require.NoError(t, err, "GetTimestamp errored")
|
||||
require.NotEqual(t, ts1, ts2, "Timestamp was not regenerated when snapshot changed")
|
||||
require.True(t, c1.Before(*c2), "Timestamp modification time incorrect")
|
||||
}
|
||||
|
||||
// If the root or snapshot is missing or corrupt, no timestamp can be generated
|
||||
func TestCannotMakeNewTimestampIfNoRootOrSnapshot(t *testing.T) {
|
||||
repo, crypto, err := testutils.EmptyRepo("gun")
|
||||
|
@ -203,14 +167,30 @@ func TestCannotMakeNewTimestampIfNoRootOrSnapshot(t *testing.T) {
|
|||
timestampJSON, err := json.Marshal(repo.Timestamp)
|
||||
require.NoError(t, err)
|
||||
|
||||
invalids := []map[string][]byte{
|
||||
{data.CanonicalRootRole: rootJSON, data.CanonicalSnapshotRole: []byte("invalid JSON")},
|
||||
{data.CanonicalRootRole: []byte("invalid JSON"), data.CanonicalSnapshotRole: snapJSON},
|
||||
{data.CanonicalRootRole: rootJSON},
|
||||
{data.CanonicalSnapshotRole: snapJSON},
|
||||
invalids := []struct {
|
||||
test map[string][]byte
|
||||
err error
|
||||
}{
|
||||
{
|
||||
test: map[string][]byte{data.CanonicalRootRole: rootJSON, data.CanonicalSnapshotRole: []byte("invalid JSON")},
|
||||
err: storage.ErrNotFound{},
|
||||
},
|
||||
{
|
||||
test: map[string][]byte{data.CanonicalRootRole: []byte("invalid JSON"), data.CanonicalSnapshotRole: snapJSON},
|
||||
err: &json.SyntaxError{},
|
||||
},
|
||||
{
|
||||
test: map[string][]byte{data.CanonicalRootRole: rootJSON},
|
||||
err: storage.ErrNotFound{},
|
||||
},
|
||||
{
|
||||
test: map[string][]byte{data.CanonicalSnapshotRole: snapJSON},
|
||||
err: storage.ErrNotFound{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, dataToSet := range invalids {
|
||||
for _, test := range invalids {
|
||||
dataToSet := test.test
|
||||
store := storage.NewMemStorage()
|
||||
for roleName, jsonBytes := range dataToSet {
|
||||
require.NoError(t, store.UpdateCurrent("gun",
|
||||
|
@ -221,12 +201,7 @@ func TestCannotMakeNewTimestampIfNoRootOrSnapshot(t *testing.T) {
|
|||
|
||||
_, _, err := GetOrCreateTimestamp("gun", store, crypto)
|
||||
require.Error(t, err, "GetTimestamp errored")
|
||||
|
||||
if len(dataToSet) == 1 { // missing metadata
|
||||
require.IsType(t, storage.ErrNotFound{}, err)
|
||||
} else {
|
||||
require.IsType(t, &json.SyntaxError{}, err)
|
||||
}
|
||||
require.IsType(t, test.err, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue