Merge pull request #3055 from ehotinger/ehotinger/flow-opts

Allow opts to flow to the backend snapshotter during snapshot creation.
This commit is contained in:
Michael Crosby 2019-06-19 14:54:36 -04:00 committed by GitHub
commit 8bb521318a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 7 deletions

View File

@ -34,6 +34,10 @@ import (
bolt "go.etcd.io/bbolt"
)
const (
inheritedLabelsPrefix = "containerd.io/snapshot/"
)
type snapshotter struct {
snapshots.Snapshotter
name string
@ -338,12 +342,14 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re
return err
}
inheritedOpt := snapshots.WithLabels(filterInheritedLabels(base.Labels))
// TODO: Consider doing this outside of transaction to lessen
// metadata lock time
if readonly {
m, err = s.Snapshotter.View(ctx, bkey, bparent)
m, err = s.Snapshotter.View(ctx, bkey, bparent, inheritedOpt)
} else {
m, err = s.Snapshotter.Prepare(ctx, bkey, bparent)
m, err = s.Snapshotter.Prepare(ctx, bkey, bparent, inheritedOpt)
}
return err
}); err != nil {
@ -445,9 +451,11 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
return err
}
inheritedOpt := snapshots.WithLabels(filterInheritedLabels(base.Labels))
// TODO: Consider doing this outside of transaction to lessen
// metadata lock time
return s.Snapshotter.Commit(ctx, nameKey, bkey)
return s.Snapshotter.Commit(ctx, nameKey, bkey, inheritedOpt)
})
}
@ -761,3 +769,19 @@ func (s *snapshotter) pruneBranch(ctx context.Context, node *treeNode) error {
func (s *snapshotter) Close() error {
return s.Snapshotter.Close()
}
// filterInheritedLabels filters the provided labels by removing any key which doesn't have
// a prefix of "containerd.io/snapshot/".
func filterInheritedLabels(labels map[string]string) map[string]string {
if labels == nil {
return nil
}
filtered := make(map[string]string)
for k, v := range labels {
if strings.HasPrefix(k, inheritedLabelsPrefix) {
filtered[k] = v
}
}
return filtered
}

View File

@ -20,6 +20,7 @@ import (
"context"
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
@ -63,3 +64,41 @@ func TestMetadata(t *testing.T) {
testutil.RequiresRoot(t)
testsuite.SnapshotterSuite(t, "Metadata", newTestSnapshotter)
}
func TestFilterInheritedLabels(t *testing.T) {
tests := []struct {
labels map[string]string
expected map[string]string
}{
{
nil,
nil,
},
{
map[string]string{},
map[string]string{},
},
{
map[string]string{"": ""},
map[string]string{},
},
{
map[string]string{"foo": "bar"},
map[string]string{},
},
{
map[string]string{inheritedLabelsPrefix + "foo": "bar"},
map[string]string{inheritedLabelsPrefix + "foo": "bar"},
},
{
map[string]string{inheritedLabelsPrefix + "foo": "bar", "qux": "qaz"},
map[string]string{inheritedLabelsPrefix + "foo": "bar"},
},
}
for _, test := range tests {
if actual := filterInheritedLabels(test.labels); !reflect.DeepEqual(actual, test.expected) {
t.Fatalf("expected %v but got %v", test.expected, actual)
}
}
}

View File

@ -86,10 +86,15 @@ func (k *Kind) UnmarshalJSON(b []byte) error {
// Info provides information about a particular snapshot.
// JSON marshallability is supported for interactive with tools like ctr,
type Info struct {
Kind Kind // active or committed snapshot
Name string // name or key of snapshot
Parent string `json:",omitempty"` // name of parent snapshot
Labels map[string]string `json:",omitempty"` // Labels for snapshot
Kind Kind // active or committed snapshot
Name string // name or key of snapshot
Parent string `json:",omitempty"` // name of parent snapshot
// Labels for a snapshot.
//
// Note: only labels prefixed with `containerd.io/snapshot/` will be inherited by the
// snapshotter's `Prepare`, `View`, or `Commit` calls.
Labels map[string]string `json:",omitempty"`
Created time.Time `json:",omitempty"` // Created time
Updated time.Time `json:",omitempty"` // Last update time
}