Update metadata plugin initialization
Updates metadata plugin to require content and snapshotter plugins be loaded and initializes with those plugins, keeping the metadata database structure static after initialization. Service plugins now only require metadata plugin access snapshotter or content stores through metadata, which was already required behavior of the services. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
parent
2ab70f21ac
commit
8d892a651b
@ -25,19 +25,14 @@ func init() {
|
||||
Type: plugin.DiffPlugin,
|
||||
ID: "walking",
|
||||
Requires: []plugin.Type{
|
||||
plugin.ContentPlugin,
|
||||
plugin.MetadataPlugin,
|
||||
},
|
||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
c, err := ic.Get(plugin.ContentPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
md, err := ic.Get(plugin.MetadataPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewWalkingDiff(metadata.NewContentStore(md.(*metadata.DB), c.(content.Store)))
|
||||
return NewWalkingDiff(md.(*metadata.DB).ContentStore())
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -17,9 +17,14 @@ func WithTransactionContext(ctx context.Context, tx *bolt.Tx) context.Context {
|
||||
return context.WithValue(ctx, transactionKey{}, tx)
|
||||
}
|
||||
|
||||
type transactor interface {
|
||||
View(fn func(*bolt.Tx) error) error
|
||||
Update(fn func(*bolt.Tx) error) error
|
||||
}
|
||||
|
||||
// view gets a bolt db transaction either from the context
|
||||
// or starts a new one with the provided bolt database.
|
||||
func view(ctx context.Context, db *DB, fn func(*bolt.Tx) error) error {
|
||||
func view(ctx context.Context, db transactor, fn func(*bolt.Tx) error) error {
|
||||
tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx)
|
||||
if !ok {
|
||||
return db.View(fn)
|
||||
@ -29,7 +34,7 @@ func view(ctx context.Context, db *DB, fn func(*bolt.Tx) error) error {
|
||||
|
||||
// update gets a writable bolt db transaction either from the context
|
||||
// or starts a new one with the provided bolt database.
|
||||
func update(ctx context.Context, db *DB, fn func(*bolt.Tx) error) error {
|
||||
func update(ctx context.Context, db transactor, fn func(*bolt.Tx) error) error {
|
||||
tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx)
|
||||
if !ok {
|
||||
return db.Update(fn)
|
||||
|
@ -19,23 +19,16 @@ import (
|
||||
|
||||
type contentStore struct {
|
||||
content.Store
|
||||
db *DB
|
||||
db transactor
|
||||
}
|
||||
|
||||
// NewContentStore returns a namespaced content store using an existing
|
||||
// newContentStore returns a namespaced content store using an existing
|
||||
// content store interface.
|
||||
func NewContentStore(db *DB, cs content.Store) content.Store {
|
||||
db.storeL.Lock()
|
||||
defer db.storeL.Unlock()
|
||||
|
||||
if db.cs == nil {
|
||||
db.cs = &contentStore{
|
||||
Store: cs,
|
||||
db: db,
|
||||
}
|
||||
func newContentStore(db transactor, cs content.Store) content.Store {
|
||||
return &contentStore{
|
||||
Store: cs,
|
||||
db: db,
|
||||
}
|
||||
return db.cs
|
||||
|
||||
}
|
||||
|
||||
func (cs *contentStore) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
|
||||
@ -360,7 +353,7 @@ type namespacedWriter struct {
|
||||
content.Writer
|
||||
ref string
|
||||
namespace string
|
||||
db *DB
|
||||
db transactor
|
||||
}
|
||||
|
||||
func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
|
@ -23,7 +23,7 @@ func createContentStore(ctx context.Context, root string) (content.Store, func()
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return NewContentStore(NewDB(db), cs), func() error {
|
||||
return NewDB(db, cs, nil).ContentStore(), func() error {
|
||||
return db.Close()
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,26 +1,40 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/snapshot"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
db *bolt.DB
|
||||
|
||||
storeL sync.Mutex
|
||||
ss map[string]*snapshotter
|
||||
cs *contentStore
|
||||
ss map[string]snapshot.Snapshotter
|
||||
cs content.Store
|
||||
}
|
||||
|
||||
func NewDB(db *bolt.DB) *DB {
|
||||
func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB {
|
||||
return &DB{
|
||||
db: db,
|
||||
ss: map[string]*snapshotter{},
|
||||
ss: ss,
|
||||
cs: cs,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *DB) ContentStore() content.Store {
|
||||
if m.cs == nil {
|
||||
return nil
|
||||
}
|
||||
return newContentStore(m, m.cs)
|
||||
}
|
||||
|
||||
func (m *DB) Snapshotter(name string) snapshot.Snapshotter {
|
||||
sn, ok := m.ss[name]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return newSnapshotter(m, name, sn)
|
||||
}
|
||||
|
||||
func (m *DB) View(fn func(*bolt.Tx) error) error {
|
||||
return m.db.View(fn)
|
||||
}
|
||||
|
@ -19,26 +19,17 @@ import (
|
||||
type snapshotter struct {
|
||||
snapshot.Snapshotter
|
||||
name string
|
||||
db *DB
|
||||
db transactor
|
||||
}
|
||||
|
||||
// NewSnapshotter returns a new Snapshotter which namespaces the given snapshot
|
||||
// using the provided name and metadata store.
|
||||
func NewSnapshotter(db *DB, name string, sn snapshot.Snapshotter) snapshot.Snapshotter {
|
||||
db.storeL.Lock()
|
||||
defer db.storeL.Unlock()
|
||||
|
||||
ss, ok := db.ss[name]
|
||||
if !ok {
|
||||
ss = &snapshotter{
|
||||
Snapshotter: sn,
|
||||
name: name,
|
||||
db: db,
|
||||
}
|
||||
db.ss[name] = ss
|
||||
// newSnapshotter returns a new Snapshotter which namespaces the given snapshot
|
||||
// using the provided name and database.
|
||||
func newSnapshotter(db transactor, name string, sn snapshot.Snapshotter) snapshot.Snapshotter {
|
||||
return &snapshotter{
|
||||
Snapshotter: sn,
|
||||
name: name,
|
||||
db: db,
|
||||
}
|
||||
|
||||
return ss
|
||||
}
|
||||
|
||||
func createKey(id uint64, namespace, key string) string {
|
||||
@ -466,11 +457,7 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := bkt.DeleteBucket([]byte(key)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return bkt.DeleteBucket([]byte(key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/containerd/containerd/testutil"
|
||||
)
|
||||
|
||||
func newSnapshotter(ctx context.Context, root string) (snapshot.Snapshotter, func() error, error) {
|
||||
func newTestSnapshotter(ctx context.Context, root string) (snapshot.Snapshotter, func() error, error) {
|
||||
naiveRoot := filepath.Join(root, "naive")
|
||||
if err := os.Mkdir(naiveRoot, 0770); err != nil {
|
||||
return nil, nil, err
|
||||
@ -28,7 +28,7 @@ func newSnapshotter(ctx context.Context, root string) (snapshot.Snapshotter, fun
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sn := NewSnapshotter(NewDB(db), "naive", snapshotter)
|
||||
sn := NewDB(db, nil, map[string]snapshot.Snapshotter{"naive": snapshotter}).Snapshotter("naive")
|
||||
|
||||
return sn, func() error {
|
||||
return db.Close()
|
||||
@ -38,5 +38,5 @@ func newSnapshotter(ctx context.Context, root string) (snapshot.Snapshotter, fun
|
||||
func TestMetadata(t *testing.T) {
|
||||
// Snapshot tests require mounting, still requires root
|
||||
testutil.RequiresRoot(t)
|
||||
testsuite.SnapshotterSuite(t, "Metadata", newSnapshotter)
|
||||
testsuite.SnapshotterSuite(t, "Metadata", newTestSnapshotter)
|
||||
}
|
||||
|
@ -12,19 +12,21 @@ import (
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
containers "github.com/containerd/containerd/api/services/containers/v1"
|
||||
content "github.com/containerd/containerd/api/services/content/v1"
|
||||
contentapi "github.com/containerd/containerd/api/services/content/v1"
|
||||
diff "github.com/containerd/containerd/api/services/diff/v1"
|
||||
eventsapi "github.com/containerd/containerd/api/services/events/v1"
|
||||
images "github.com/containerd/containerd/api/services/images/v1"
|
||||
namespaces "github.com/containerd/containerd/api/services/namespaces/v1"
|
||||
snapshot "github.com/containerd/containerd/api/services/snapshot/v1"
|
||||
snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1"
|
||||
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||
version "github.com/containerd/containerd/api/services/version/v1"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/content/local"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/metadata"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshot"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"golang.org/x/net/context"
|
||||
@ -176,15 +178,34 @@ func loadPlugins(config *Config) ([]*plugin.Registration, error) {
|
||||
plugin.Register(&plugin.Registration{
|
||||
Type: plugin.MetadataPlugin,
|
||||
ID: "bolt",
|
||||
Requires: []plugin.Type{
|
||||
plugin.ContentPlugin,
|
||||
plugin.SnapshotPlugin,
|
||||
},
|
||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
if err := os.MkdirAll(ic.Root, 0711); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs, err := ic.Get(plugin.ContentPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawSnapshotters, err := ic.GetAll(plugin.SnapshotPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snapshotters := make(map[string]snapshot.Snapshotter)
|
||||
for name, sn := range rawSnapshotters {
|
||||
snapshotters[name] = sn.(snapshot.Snapshotter)
|
||||
}
|
||||
|
||||
db, err := bolt.Open(filepath.Join(ic.Root, "meta.db"), 0644, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return metadata.NewDB(db), nil
|
||||
return metadata.NewDB(db, cs.(content.Store), snapshotters), nil
|
||||
},
|
||||
})
|
||||
|
||||
@ -204,7 +225,7 @@ func interceptor(
|
||||
ctx = log.WithModule(ctx, "tasks")
|
||||
case containers.ContainersServer:
|
||||
ctx = log.WithModule(ctx, "containers")
|
||||
case content.ContentServer:
|
||||
case contentapi.ContentServer:
|
||||
ctx = log.WithModule(ctx, "content")
|
||||
case images.ImagesServer:
|
||||
ctx = log.WithModule(ctx, "images")
|
||||
@ -212,7 +233,7 @@ func interceptor(
|
||||
// No need to change the context
|
||||
case version.VersionServer:
|
||||
ctx = log.WithModule(ctx, "version")
|
||||
case snapshot.SnapshotsServer:
|
||||
case snapshotapi.SnapshotsServer:
|
||||
ctx = log.WithModule(ctx, "snapshot")
|
||||
case diff.DiffServer:
|
||||
ctx = log.WithModule(ctx, "diff")
|
||||
|
@ -39,7 +39,6 @@ func init() {
|
||||
Type: plugin.GRPCPlugin,
|
||||
ID: "content",
|
||||
Requires: []plugin.Type{
|
||||
plugin.ContentPlugin,
|
||||
plugin.MetadataPlugin,
|
||||
},
|
||||
Init: NewService,
|
||||
@ -47,19 +46,13 @@ func init() {
|
||||
}
|
||||
|
||||
func NewService(ic *plugin.InitContext) (interface{}, error) {
|
||||
c, err := ic.Get(plugin.ContentPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := ic.Get(plugin.MetadataPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs := metadata.NewContentStore(m.(*metadata.DB), c.(content.Store))
|
||||
|
||||
return &Service{
|
||||
store: cs,
|
||||
store: m.(*metadata.DB).ContentStore(),
|
||||
publisher: ic.Events,
|
||||
}, nil
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshot"
|
||||
protoempty "github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@ -24,7 +23,6 @@ func init() {
|
||||
Type: plugin.GRPCPlugin,
|
||||
ID: "snapshots",
|
||||
Requires: []plugin.Type{
|
||||
plugin.SnapshotPlugin,
|
||||
plugin.MetadataPlugin,
|
||||
},
|
||||
Init: newService,
|
||||
@ -34,31 +32,19 @@ func init() {
|
||||
var empty = &protoempty.Empty{}
|
||||
|
||||
type service struct {
|
||||
snapshotters map[string]snapshot.Snapshotter
|
||||
publisher events.Publisher
|
||||
db *metadata.DB
|
||||
publisher events.Publisher
|
||||
}
|
||||
|
||||
func newService(ic *plugin.InitContext) (interface{}, error) {
|
||||
rawSnapshotters, err := ic.GetAll(plugin.SnapshotPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
md, err := ic.Get(plugin.MetadataPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snapshotters := make(map[string]snapshot.Snapshotter)
|
||||
for name, sn := range rawSnapshotters {
|
||||
snapshotters[name] = metadata.NewSnapshotter(md.(*metadata.DB), name, sn.(snapshot.Snapshotter))
|
||||
}
|
||||
|
||||
if len(snapshotters) == 0 {
|
||||
return nil, errors.Errorf("failed to create snapshotter service: no snapshotters loaded")
|
||||
}
|
||||
|
||||
return &service{
|
||||
snapshotters: snapshotters,
|
||||
publisher: ic.Events,
|
||||
db: md.(*metadata.DB),
|
||||
publisher: ic.Events,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -67,8 +53,8 @@ func (s *service) getSnapshotter(name string) (snapshot.Snapshotter, error) {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "snapshotter argument missing")
|
||||
}
|
||||
|
||||
sn, ok := s.snapshotters[name]
|
||||
if !ok {
|
||||
sn := s.db.Snapshotter(name)
|
||||
if sn == nil {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "snapshotter not loaded: %s", name)
|
||||
}
|
||||
return sn, nil
|
||||
|
@ -44,7 +44,6 @@ func init() {
|
||||
Requires: []plugin.Type{
|
||||
plugin.RuntimePlugin,
|
||||
plugin.MetadataPlugin,
|
||||
plugin.ContentPlugin,
|
||||
},
|
||||
Init: New,
|
||||
})
|
||||
@ -59,11 +58,7 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ct, err := ic.Get(plugin.ContentPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs := metadata.NewContentStore(m.(*metadata.DB), ct.(content.Store))
|
||||
cs := m.(*metadata.DB).ContentStore()
|
||||
runtimes := make(map[string]runtime.Runtime)
|
||||
for _, rr := range rt {
|
||||
r := rr.(runtime.Runtime)
|
||||
|
Loading…
Reference in New Issue
Block a user