mirror of https://github.com/docker/docs.git
cleaning up cache vs filestore
Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
parent
9b604d0a6c
commit
20b60d9cc2
190
Godeps/_workspace/src/github.com/endophage/gotuf/client/client_test.go
generated
vendored
Normal file
190
Godeps/_workspace/src/github.com/endophage/gotuf/client/client_test.go
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
tuf "github.com/endophage/gotuf"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/endophage/gotuf/data"
|
||||
"github.com/endophage/gotuf/keys"
|
||||
"github.com/endophage/gotuf/signed"
|
||||
"github.com/endophage/gotuf/store"
|
||||
)
|
||||
|
||||
func TestRotation(t *testing.T) {
|
||||
kdb := keys.NewDB()
|
||||
signer := signed.NewEd25519()
|
||||
repo := tuf.NewTufRepo(kdb, signer)
|
||||
remote := store.NewMemoryStore(nil, nil)
|
||||
cache := store.NewMemoryStore(nil, nil)
|
||||
|
||||
// Generate initial root key and role and add to key DB
|
||||
rootKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating root key")
|
||||
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating root role")
|
||||
|
||||
kdb.AddKey(rootKey)
|
||||
err = kdb.AddRole(rootRole)
|
||||
assert.NoError(t, err, "Error adding root role to db")
|
||||
|
||||
// Generate new key and role. These will appear in the root.json
|
||||
// but will not be added to the keyDB.
|
||||
replacementKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating replacement root key")
|
||||
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating replacement root role")
|
||||
|
||||
// Generate a new root with the replacement key and role
|
||||
testRoot, err := data.NewRoot(
|
||||
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
|
||||
map[string]*data.RootRole{"root": &replacementRole.RootRole},
|
||||
false,
|
||||
)
|
||||
assert.NoError(t, err, "Failed to create new root")
|
||||
|
||||
// Sign testRoot with both old and new keys
|
||||
signedRoot, err := testRoot.ToSigned()
|
||||
err = signed.Sign(signer, signedRoot, rootKey, replacementKey)
|
||||
assert.NoError(t, err, "Failed to sign root")
|
||||
var origKeySig bool
|
||||
var replKeySig bool
|
||||
for _, sig := range signedRoot.Signatures {
|
||||
if sig.KeyID == rootKey.ID() {
|
||||
origKeySig = true
|
||||
} else if sig.KeyID == replacementKey.ID() {
|
||||
replKeySig = true
|
||||
}
|
||||
}
|
||||
assert.True(t, origKeySig, "Original root key signature not present")
|
||||
assert.True(t, replKeySig, "Replacement root key signature not present")
|
||||
|
||||
client := NewClient(repo, remote, kdb, cache)
|
||||
|
||||
err = client.verifyRoot("root", signedRoot, 0)
|
||||
assert.NoError(t, err, "Failed to verify key rotated root")
|
||||
}
|
||||
|
||||
func TestRotationNewSigMissing(t *testing.T) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
kdb := keys.NewDB()
|
||||
signer := signed.NewEd25519()
|
||||
repo := tuf.NewTufRepo(kdb, signer)
|
||||
remote := store.NewMemoryStore(nil, nil)
|
||||
cache := store.NewMemoryStore(nil, nil)
|
||||
|
||||
// Generate initial root key and role and add to key DB
|
||||
rootKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating root key")
|
||||
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating root role")
|
||||
|
||||
kdb.AddKey(rootKey)
|
||||
err = kdb.AddRole(rootRole)
|
||||
assert.NoError(t, err, "Error adding root role to db")
|
||||
|
||||
// Generate new key and role. These will appear in the root.json
|
||||
// but will not be added to the keyDB.
|
||||
replacementKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating replacement root key")
|
||||
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating replacement root role")
|
||||
|
||||
assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same")
|
||||
|
||||
// Generate a new root with the replacement key and role
|
||||
testRoot, err := data.NewRoot(
|
||||
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
|
||||
map[string]*data.RootRole{"root": &replacementRole.RootRole},
|
||||
false,
|
||||
)
|
||||
assert.NoError(t, err, "Failed to create new root")
|
||||
|
||||
_, ok := testRoot.Signed.Keys[rootKey.ID()]
|
||||
assert.False(t, ok, "Old root key appeared in test root")
|
||||
|
||||
// Sign testRoot with both old and new keys
|
||||
signedRoot, err := testRoot.ToSigned()
|
||||
err = signed.Sign(signer, signedRoot, rootKey)
|
||||
assert.NoError(t, err, "Failed to sign root")
|
||||
var origKeySig bool
|
||||
var replKeySig bool
|
||||
for _, sig := range signedRoot.Signatures {
|
||||
if sig.KeyID == rootKey.ID() {
|
||||
origKeySig = true
|
||||
} else if sig.KeyID == replacementKey.ID() {
|
||||
replKeySig = true
|
||||
}
|
||||
}
|
||||
assert.True(t, origKeySig, "Original root key signature not present")
|
||||
assert.False(t, replKeySig, "Replacement root key signature was present and shouldn't be")
|
||||
|
||||
client := NewClient(repo, remote, kdb, cache)
|
||||
|
||||
err = client.verifyRoot("root", signedRoot, 0)
|
||||
assert.Error(t, err, "Should have errored on verify as replacement signature was missing.")
|
||||
|
||||
}
|
||||
|
||||
func TestRotationOldSigMissing(t *testing.T) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
kdb := keys.NewDB()
|
||||
signer := signed.NewEd25519()
|
||||
repo := tuf.NewTufRepo(kdb, signer)
|
||||
remote := store.NewMemoryStore(nil, nil)
|
||||
cache := store.NewMemoryStore(nil, nil)
|
||||
|
||||
// Generate initial root key and role and add to key DB
|
||||
rootKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating root key")
|
||||
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating root role")
|
||||
|
||||
kdb.AddKey(rootKey)
|
||||
err = kdb.AddRole(rootRole)
|
||||
assert.NoError(t, err, "Error adding root role to db")
|
||||
|
||||
// Generate new key and role. These will appear in the root.json
|
||||
// but will not be added to the keyDB.
|
||||
replacementKey, err := signer.Create("root", data.ED25519Key)
|
||||
assert.NoError(t, err, "Error creating replacement root key")
|
||||
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
|
||||
assert.NoError(t, err, "Error creating replacement root role")
|
||||
|
||||
assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same")
|
||||
|
||||
// Generate a new root with the replacement key and role
|
||||
testRoot, err := data.NewRoot(
|
||||
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
|
||||
map[string]*data.RootRole{"root": &replacementRole.RootRole},
|
||||
false,
|
||||
)
|
||||
assert.NoError(t, err, "Failed to create new root")
|
||||
|
||||
_, ok := testRoot.Signed.Keys[rootKey.ID()]
|
||||
assert.False(t, ok, "Old root key appeared in test root")
|
||||
|
||||
// Sign testRoot with both old and new keys
|
||||
signedRoot, err := testRoot.ToSigned()
|
||||
err = signed.Sign(signer, signedRoot, replacementKey)
|
||||
assert.NoError(t, err, "Failed to sign root")
|
||||
var origKeySig bool
|
||||
var replKeySig bool
|
||||
for _, sig := range signedRoot.Signatures {
|
||||
if sig.KeyID == rootKey.ID() {
|
||||
origKeySig = true
|
||||
} else if sig.KeyID == replacementKey.ID() {
|
||||
replKeySig = true
|
||||
}
|
||||
}
|
||||
assert.False(t, origKeySig, "Original root key signature was present and shouldn't be")
|
||||
assert.True(t, replKeySig, "Replacement root key signature was not present")
|
||||
|
||||
client := NewClient(repo, remote, kdb, cache)
|
||||
|
||||
err = client.verifyRoot("root", signedRoot, 0)
|
||||
assert.Error(t, err, "Should have errored on verify as replacement signature was missing.")
|
||||
|
||||
}
|
|
@ -103,6 +103,17 @@ func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper) (*N
|
|||
KeyStoreManager: keyStoreManager,
|
||||
}
|
||||
|
||||
fileStore, err := store.NewFilesystemStore(
|
||||
nRepo.tufRepoPath,
|
||||
"metadata",
|
||||
"json",
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nRepo.fileStore = fileStore
|
||||
|
||||
return nRepo, nil
|
||||
}
|
||||
|
||||
|
@ -210,16 +221,6 @@ func (r *NotaryRepository) Initialize(uCryptoService *cryptoservice.UnlockedCryp
|
|||
|
||||
r.tufRepo = tuf.NewTufRepo(kdb, r.cryptoService)
|
||||
|
||||
r.fileStore, err = store.NewFilesystemStore(
|
||||
r.tufRepoPath,
|
||||
"metadata",
|
||||
"json",
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := r.tufRepo.InitRepo(false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -421,21 +422,11 @@ func (r *NotaryRepository) Publish(getPass passwordRetriever) error {
|
|||
}
|
||||
|
||||
func (r *NotaryRepository) bootstrapRepo() error {
|
||||
fileStore, err := store.NewFilesystemStore(
|
||||
r.tufRepoPath,
|
||||
"metadata",
|
||||
"json",
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kdb := keys.NewDB()
|
||||
tufRepo := tuf.NewTufRepo(kdb, r.cryptoService)
|
||||
|
||||
logrus.Debugf("Loading trusted collection.")
|
||||
rootJSON, err := fileStore.GetMeta("root", 0)
|
||||
rootJSON, err := r.fileStore.GetMeta("root", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -445,7 +436,7 @@ func (r *NotaryRepository) bootstrapRepo() error {
|
|||
return err
|
||||
}
|
||||
tufRepo.SetRoot(root)
|
||||
targetsJSON, err := fileStore.GetMeta("targets", 0)
|
||||
targetsJSON, err := r.fileStore.GetMeta("targets", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -455,7 +446,7 @@ func (r *NotaryRepository) bootstrapRepo() error {
|
|||
return err
|
||||
}
|
||||
tufRepo.SetTargets("targets", targets)
|
||||
snapshotJSON, err := fileStore.GetMeta("snapshot", 0)
|
||||
snapshotJSON, err := r.fileStore.GetMeta("snapshot", 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -467,7 +458,6 @@ func (r *NotaryRepository) bootstrapRepo() error {
|
|||
tufRepo.SetSnapshot(snapshot)
|
||||
|
||||
r.tufRepo = tufRepo
|
||||
r.fileStore = fileStore
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -506,19 +496,7 @@ func (r *NotaryRepository) snapshot() error {
|
|||
}
|
||||
|
||||
func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
||||
var cache store.MetadataStore
|
||||
cache, err := store.NewFilesystemStore(
|
||||
filepath.Join(r.tufRepoPath, "cache"),
|
||||
"metadata",
|
||||
"json",
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
cache = store.NewMemoryStore(nil, nil)
|
||||
}
|
||||
|
||||
var rootJSON []byte
|
||||
err = nil
|
||||
remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
|
||||
if err == nil {
|
||||
// if remote store successfully set up, try and get root from remote
|
||||
|
@ -528,7 +506,12 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
|||
// if remote store couldn't be setup, or we failed to get a root from it
|
||||
// load the root from cache (offline operation)
|
||||
if err != nil {
|
||||
rootJSON, err = cache.GetMeta("root", maxSize)
|
||||
if err, ok := err.(*store.ErrMetaNotFound); ok {
|
||||
// if the error was MetaNotFound then we successfully contacted
|
||||
// the store and it doesn't know about the repo.
|
||||
return nil, err
|
||||
}
|
||||
rootJSON, err = r.fileStore.GetMeta("root", maxSize)
|
||||
if err != nil {
|
||||
// if cache didn't return a root, we cannot proceed
|
||||
return nil, &store.ErrMetaNotFound{}
|
||||
|
@ -557,6 +540,6 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
|||
r.tufRepo,
|
||||
remote,
|
||||
kdb,
|
||||
cache,
|
||||
r.fileStore,
|
||||
), nil
|
||||
}
|
||||
|
|
|
@ -64,10 +64,10 @@ func (st *MemStorage) GetCurrent(gun, role string) (data []byte, err error) {
|
|||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
space, ok := st.tufMeta[id]
|
||||
if !ok {
|
||||
if !ok || len(space) == 0 {
|
||||
return nil, &ErrNotFound{}
|
||||
}
|
||||
return space[len(st.tufMeta[id])-1].data, nil
|
||||
return space[len(space)-1].data, nil
|
||||
}
|
||||
|
||||
// Delete delets all the metadata for a given GUN
|
||||
|
|
Loading…
Reference in New Issue