Merge pull request #611 from dmcgowan/snapshot-plugins
Add snapshot plugin type
This commit is contained in:
commit
2fb3b73b95
6 changed files with 91 additions and 15 deletions
|
@ -5,4 +5,6 @@ import (
|
||||||
_ "github.com/docker/containerd/linux"
|
_ "github.com/docker/containerd/linux"
|
||||||
_ "github.com/docker/containerd/services/content"
|
_ "github.com/docker/containerd/services/content"
|
||||||
_ "github.com/docker/containerd/services/execution"
|
_ "github.com/docker/containerd/services/execution"
|
||||||
|
_ "github.com/docker/containerd/snapshot/btrfs"
|
||||||
|
_ "github.com/docker/containerd/snapshot/overlay"
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ func defaultConfig() *config {
|
||||||
Level: "info",
|
Level: "info",
|
||||||
Socket: "/run/containerd/debug.sock",
|
Socket: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
|
Snapshotter: "overlay",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@ type config struct {
|
||||||
Debug debug `toml:"debug"`
|
Debug debug `toml:"debug"`
|
||||||
// Metrics and monitoring settings
|
// Metrics and monitoring settings
|
||||||
Metrics metricsConfig `toml:"metrics"`
|
Metrics metricsConfig `toml:"metrics"`
|
||||||
|
// Snapshotter specifies which snapshot driver to use
|
||||||
|
Snapshotter string `toml:"snapshotter"`
|
||||||
// Plugins provides plugin specific configuration for the initialization of a plugin
|
// Plugins provides plugin specific configuration for the initialization of a plugin
|
||||||
Plugins map[string]toml.Primitive `toml:"plugins"`
|
Plugins map[string]toml.Primitive `toml:"plugins"`
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/docker/containerd/content"
|
"github.com/docker/containerd/content"
|
||||||
"github.com/docker/containerd/log"
|
"github.com/docker/containerd/log"
|
||||||
"github.com/docker/containerd/plugin"
|
"github.com/docker/containerd/plugin"
|
||||||
|
"github.com/docker/containerd/snapshot"
|
||||||
"github.com/docker/containerd/utils"
|
"github.com/docker/containerd/utils"
|
||||||
metrics "github.com/docker/go-metrics"
|
metrics "github.com/docker/go-metrics"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -101,7 +102,11 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
services, err := loadServices(runtimes, store)
|
snapshotter, err := loadSnapshotter(store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
services, err := loadServices(runtimes, store, snapshotter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -248,12 +253,45 @@ func loadRuntimes() (map[string]containerd.Runtime, error) {
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadSnapshotter(store *content.Store) (snapshot.Snapshotter, error) {
|
||||||
|
for name, sr := range plugin.Registrations() {
|
||||||
|
if sr.Type != plugin.SnapshotPlugin {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
moduleName := fmt.Sprintf("snapshot-%s", conf.Snapshotter)
|
||||||
|
if name != moduleName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.G(global).Infof("loading snapshot plugin %q...", name)
|
||||||
|
ic := &plugin.InitContext{
|
||||||
|
Root: conf.Root,
|
||||||
|
State: conf.State,
|
||||||
|
Store: store,
|
||||||
|
Context: log.WithModule(global, moduleName),
|
||||||
|
}
|
||||||
|
if sr.Config != nil {
|
||||||
|
if err := conf.decodePlugin(name, sr.Config); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ic.Config = sr.Config
|
||||||
|
}
|
||||||
|
sn, err := sr.Init(ic)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sn.(snapshot.Snapshotter), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("snapshotter not loaded: %v", conf.Snapshotter)
|
||||||
|
}
|
||||||
|
|
||||||
func newGRPCServer() *grpc.Server {
|
func newGRPCServer() *grpc.Server {
|
||||||
s := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
|
s := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadServices(runtimes map[string]containerd.Runtime, store *content.Store) ([]plugin.Service, error) {
|
func loadServices(runtimes map[string]containerd.Runtime, store *content.Store, sn snapshot.Snapshotter) ([]plugin.Service, error) {
|
||||||
var o []plugin.Service
|
var o []plugin.Service
|
||||||
for name, sr := range plugin.Registrations() {
|
for name, sr := range plugin.Registrations() {
|
||||||
if sr.Type != plugin.GRPCPlugin {
|
if sr.Type != plugin.GRPCPlugin {
|
||||||
|
@ -261,11 +299,12 @@ func loadServices(runtimes map[string]containerd.Runtime, store *content.Store)
|
||||||
}
|
}
|
||||||
log.G(global).Infof("loading grpc service plugin %q...", name)
|
log.G(global).Infof("loading grpc service plugin %q...", name)
|
||||||
ic := &plugin.InitContext{
|
ic := &plugin.InitContext{
|
||||||
Root: conf.Root,
|
Root: conf.Root,
|
||||||
State: conf.State,
|
State: conf.State,
|
||||||
Context: log.WithModule(global, fmt.Sprintf("service-%s", name)),
|
Context: log.WithModule(global, fmt.Sprintf("service-%s", name)),
|
||||||
Runtimes: runtimes,
|
Runtimes: runtimes,
|
||||||
Store: store,
|
Store: store,
|
||||||
|
Snapshotter: sn,
|
||||||
}
|
}
|
||||||
if sr.Config != nil {
|
if sr.Config != nil {
|
||||||
if err := conf.decodePlugin(name, sr.Config); err != nil {
|
if err := conf.decodePlugin(name, sr.Config); err != nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/containerd"
|
"github.com/docker/containerd"
|
||||||
"github.com/docker/containerd/content"
|
"github.com/docker/containerd/content"
|
||||||
|
"github.com/docker/containerd/snapshot"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
@ -16,6 +17,7 @@ type PluginType int
|
||||||
const (
|
const (
|
||||||
RuntimePlugin PluginType = iota + 1
|
RuntimePlugin PluginType = iota + 1
|
||||||
GRPCPlugin
|
GRPCPlugin
|
||||||
|
SnapshotPlugin
|
||||||
)
|
)
|
||||||
|
|
||||||
type Registration struct {
|
type Registration struct {
|
||||||
|
@ -25,12 +27,13 @@ type Registration struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type InitContext struct {
|
type InitContext struct {
|
||||||
Root string
|
Root string
|
||||||
State string
|
State string
|
||||||
Runtimes map[string]containerd.Runtime
|
Runtimes map[string]containerd.Runtime
|
||||||
Store *content.Store
|
Store *content.Store
|
||||||
Config interface{}
|
Snapshotter snapshot.Snapshotter
|
||||||
Context context.Context
|
Config interface{}
|
||||||
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
|
|
@ -10,17 +10,36 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/containerd"
|
"github.com/docker/containerd"
|
||||||
|
"github.com/docker/containerd/plugin"
|
||||||
"github.com/docker/containerd/snapshot"
|
"github.com/docker/containerd/snapshot"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stevvooe/go-btrfs"
|
"github.com/stevvooe/go-btrfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type btrfsConfig struct {
|
||||||
|
Device string `toml:"device"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugin.Register("snapshot-btrfs", &plugin.Registration{
|
||||||
|
Type: plugin.SnapshotPlugin,
|
||||||
|
Config: &btrfsConfig{},
|
||||||
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
conf := ic.Config.(*btrfsConfig)
|
||||||
|
if conf.Device == "" {
|
||||||
|
return nil, errors.Errorf("btrfs requires \"device\" configuration")
|
||||||
|
}
|
||||||
|
return NewSnapshotter(conf.Device, filepath.Join(ic.Root, "snapshot", "btrfs"))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type Snapshotter struct {
|
type Snapshotter struct {
|
||||||
device string // maybe we can resolve it with path?
|
device string // maybe we can resolve it with path?
|
||||||
root string // root provides paths for internal storage.
|
root string // root provides paths for internal storage.
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSnapshotter(device, root string) (*Snapshotter, error) {
|
func NewSnapshotter(device, root string) (snapshot.Snapshotter, error) {
|
||||||
var (
|
var (
|
||||||
active = filepath.Join(root, "active")
|
active = filepath.Join(root, "active")
|
||||||
snapshots = filepath.Join(root, "snapshots")
|
snapshots = filepath.Join(root, "snapshots")
|
||||||
|
|
|
@ -10,17 +10,27 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/docker/containerd"
|
"github.com/docker/containerd"
|
||||||
|
"github.com/docker/containerd/plugin"
|
||||||
"github.com/docker/containerd/snapshot"
|
"github.com/docker/containerd/snapshot"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugin.Register("snapshot-overlay", &plugin.Registration{
|
||||||
|
Type: plugin.SnapshotPlugin,
|
||||||
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
return NewSnapshotter(filepath.Join(ic.Root, "snapshot", "overlay"))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type Snapshotter struct {
|
type Snapshotter struct {
|
||||||
root string
|
root string
|
||||||
links *cache
|
links *cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSnapshotter(root string) (*Snapshotter, error) {
|
func NewSnapshotter(root string) (snapshot.Snapshotter, error) {
|
||||||
if err := os.MkdirAll(root, 0700); err != nil {
|
if err := os.MkdirAll(root, 0700); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue