forked from notaryproject/notary
-
Notifications
You must be signed in to change notification settings - Fork 0
/
memorystore.go
137 lines (122 loc) · 3.55 KB
/
memorystore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package storage
import (
"crypto/sha256"
"encoding/json"
"fmt"
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/tuf/data"
"github.com/theupdateframework/notary/tuf/utils"
)
// NewMemoryStore returns a MetadataStore that operates entirely in memory.
// Very useful for testing
func NewMemoryStore(seed map[data.RoleName][]byte) *MemoryStore {
var (
consistent = make(map[string][]byte)
initial = make(map[string][]byte)
)
// add all seed meta to consistent
for name, d := range seed {
checksum := sha256.Sum256(d)
path := utils.ConsistentName(name.String(), checksum[:])
initial[name.String()] = d
consistent[path] = d
}
return &MemoryStore{
data: initial,
consistent: consistent,
}
}
// MemoryStore implements a mock RemoteStore entirely in memory.
// For testing purposes only.
type MemoryStore struct {
data map[string][]byte
consistent map[string][]byte
}
// GetSized returns up to size bytes of data references by name.
// If size is "NoSizeLimit", this corresponds to "infinite," but we cut off at a
// predefined threshold "notary.MaxDownloadSize", as we will always know the
// size for everything but a timestamp and sometimes a root,
// neither of which should be exceptionally large
func (m MemoryStore) GetSized(name string, size int64) ([]byte, error) {
d, ok := m.data[name]
if ok {
if size == NoSizeLimit {
size = notary.MaxDownloadSize
}
if int64(len(d)) < size {
return d, nil
}
return d[:size], nil
}
d, ok = m.consistent[name]
if ok {
if int64(len(d)) < size {
return d, nil
}
return d[:size], nil
}
return nil, ErrMetaNotFound{Resource: name}
}
// Get returns the data associated with name
func (m MemoryStore) Get(name string) ([]byte, error) {
if d, ok := m.data[name]; ok {
return d, nil
}
if d, ok := m.consistent[name]; ok {
return d, nil
}
return nil, ErrMetaNotFound{Resource: name}
}
// Set sets the metadata value for the given name
func (m *MemoryStore) Set(name string, meta []byte) error {
m.data[name] = meta
parsedMeta := &data.SignedMeta{}
err := json.Unmarshal(meta, parsedMeta)
if err == nil {
// no parse error means this is metadata and not a key, so store by version
version := parsedMeta.Signed.Version
versionedName := fmt.Sprintf("%d.%s", version, name)
m.data[versionedName] = meta
}
checksum := sha256.Sum256(meta)
path := utils.ConsistentName(name, checksum[:])
m.consistent[path] = meta
return nil
}
// SetMulti sets multiple pieces of metadata for multiple names
// in a single operation.
func (m *MemoryStore) SetMulti(metas map[string][]byte) error {
for role, blob := range metas {
m.Set(role, blob)
}
return nil
}
// Remove removes the metadata for a single role - if the metadata doesn't
// exist, no error is returned
func (m *MemoryStore) Remove(name string) error {
if meta, ok := m.data[name]; ok {
checksum := sha256.Sum256(meta)
path := utils.ConsistentName(name, checksum[:])
delete(m.data, name)
delete(m.consistent, path)
}
return nil
}
// RemoveAll clears the existing memory store by setting this store as new empty one
func (m *MemoryStore) RemoveAll() error {
*m = *NewMemoryStore(nil)
return nil
}
// Location provides a human readable name for the storage location
func (m MemoryStore) Location() string {
return "memory"
}
// ListFiles returns a list of all files. The names returned should be
// usable with Get directly, with no modification.
func (m *MemoryStore) ListFiles() []string {
names := make([]string, 0, len(m.data))
for n := range m.data {
names = append(names, n)
}
return names
}