Setup plugin ids and dependencies
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
6bbed2c125
commit
94e7f8e943
@ -2,6 +2,7 @@ package containerd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -19,6 +20,7 @@ import (
|
|||||||
versionservice "github.com/containerd/containerd/api/services/version"
|
versionservice "github.com/containerd/containerd/api/services/version"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
"github.com/containerd/containerd/remotes/docker"
|
"github.com/containerd/containerd/remotes/docker"
|
||||||
contentservice "github.com/containerd/containerd/services/content"
|
contentservice "github.com/containerd/containerd/services/content"
|
||||||
@ -83,7 +85,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
|
|||||||
}
|
}
|
||||||
return &Client{
|
return &Client{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
runtime: runtime.GOOS,
|
runtime: fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,6 @@ func loadConfig(path string) error {
|
|||||||
// config specifies the containerd configuration file in the TOML format.
|
// config specifies the containerd configuration file in the TOML format.
|
||||||
// It contains fields to configure various subsystems and containerd as a whole.
|
// It contains fields to configure various subsystems and containerd as a whole.
|
||||||
type config struct {
|
type config struct {
|
||||||
// State is the path to a directory where containerd will store runtime state
|
|
||||||
State string `toml:"state"`
|
|
||||||
// Root is the path to a directory where containerd will store persistent data
|
// Root is the path to a directory where containerd will store persistent data
|
||||||
Root string `toml:"root"`
|
Root string `toml:"root"`
|
||||||
// GRPC configuration settings
|
// GRPC configuration settings
|
||||||
|
@ -2,8 +2,7 @@ package main
|
|||||||
|
|
||||||
func defaultConfig() *config {
|
func defaultConfig() *config {
|
||||||
return &config{
|
return &config{
|
||||||
Root: "/var/lib/containerd",
|
Root: "/var/lib/containerd",
|
||||||
State: "/run/containerd",
|
|
||||||
GRPC: grpcConfig{
|
GRPC: grpcConfig{
|
||||||
Address: "/run/containerd/containerd.sock",
|
Address: "/run/containerd/containerd.sock",
|
||||||
},
|
},
|
||||||
@ -11,7 +10,7 @@ func defaultConfig() *config {
|
|||||||
Level: "info",
|
Level: "info",
|
||||||
Address: "/run/containerd/debug.sock",
|
Address: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
Snapshotter: "overlay",
|
Snapshotter: "io.containerd.snapshotter.v1.overlayfs",
|
||||||
Differ: "base",
|
Differ: "io.containerd.differ.v1.base-diff",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ package main
|
|||||||
|
|
||||||
func defaultConfig() *config {
|
func defaultConfig() *config {
|
||||||
return &config{
|
return &config{
|
||||||
Root: "/var/lib/containerd",
|
Root: "/var/lib/containerd",
|
||||||
State: "/run/containerd",
|
|
||||||
GRPC: grpcConfig{
|
GRPC: grpcConfig{
|
||||||
Address: "/run/containerd/containerd.sock",
|
Address: "/run/containerd/containerd.sock",
|
||||||
},
|
},
|
||||||
@ -13,7 +12,7 @@ func defaultConfig() *config {
|
|||||||
Level: "info",
|
Level: "info",
|
||||||
Address: "/run/containerd/debug.sock",
|
Address: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
Snapshotter: "naive",
|
Snapshotter: "io.containerd.snapshotter.v1.naive",
|
||||||
Differ: "base",
|
Differ: "io.containerd.differ.v1.base-diff",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,7 @@ import (
|
|||||||
|
|
||||||
func defaultConfig() *config {
|
func defaultConfig() *config {
|
||||||
return &config{
|
return &config{
|
||||||
Root: filepath.Join(os.Getenv("programfiles"), "containerd", "root"),
|
Root: filepath.Join(os.Getenv("programfiles"), "containerd", "root"),
|
||||||
State: filepath.Join(os.Getenv("programfiles"), "containerd", "state"),
|
|
||||||
GRPC: grpcConfig{
|
GRPC: grpcConfig{
|
||||||
Address: `\\.\pipe\containerd-containerd`,
|
Address: `\\.\pipe\containerd-containerd`,
|
||||||
},
|
},
|
||||||
@ -16,7 +15,7 @@ func defaultConfig() *config {
|
|||||||
Level: "info",
|
Level: "info",
|
||||||
Address: `\\.\pipe\containerd-debug`,
|
Address: `\\.\pipe\containerd-debug`,
|
||||||
},
|
},
|
||||||
Snapshotter: "windows",
|
Snapshotter: "io.containerd.snapshotter.v1.windows",
|
||||||
Differ: "base",
|
Differ: "io.containerd.differ.v1.base-diff",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/snapshot"
|
|
||||||
"github.com/containerd/containerd/sys"
|
"github.com/containerd/containerd/sys"
|
||||||
"github.com/containerd/containerd/version"
|
"github.com/containerd/containerd/version"
|
||||||
metrics "github.com/docker/go-metrics"
|
metrics "github.com/docker/go-metrics"
|
||||||
@ -105,41 +104,42 @@ func main() {
|
|||||||
if err := plugin.Load(filepath.Join(conf.Root, "plugins")); err != nil {
|
if err := plugin.Load(filepath.Join(conf.Root, "plugins")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
registerContentStore()
|
||||||
|
registerMetaDB()
|
||||||
// start debug and metrics APIs
|
// start debug and metrics APIs
|
||||||
if err := serveDebugAPI(); err != nil {
|
if err := serveDebugAPI(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
monitor, err := loadMonitor()
|
|
||||||
if err != nil {
|
var (
|
||||||
return err
|
services []plugin.Service
|
||||||
}
|
plugins = make(map[plugin.PluginType][]interface{})
|
||||||
runtimes, err := loadRuntimes(monitor)
|
)
|
||||||
if err != nil {
|
for _, init := range plugin.Graph() {
|
||||||
return err
|
id := init.URI()
|
||||||
}
|
log.G(global).WithField("type", init.Type).Infof("loading plugin %q...", id)
|
||||||
store, err := resolveContentStore()
|
if !shouldLoad(init) {
|
||||||
if err != nil {
|
continue
|
||||||
return err
|
}
|
||||||
}
|
ic := plugin.NewContext(plugins)
|
||||||
meta, err := resolveMetaDB(context)
|
ic.Root = filepath.Join(conf.Root, id)
|
||||||
if err != nil {
|
ic.Context = log.WithModule(global, id)
|
||||||
return err
|
if init.Config != nil {
|
||||||
}
|
if err := loadPluginConfig(init.ID, init.Config, ic); err != nil {
|
||||||
defer meta.Close()
|
return err
|
||||||
snapshotter, err := loadSnapshotter(store)
|
}
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
|
p, err := init.Init(ic)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
plugins[init.Type] = append(plugins[init.Type], p)
|
||||||
|
if s, ok := p.(plugin.Service); ok {
|
||||||
|
services = append(services, s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
differ, err := loadDiffer(snapshotter, store)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
services, err := loadServices(runtimes, store, snapshotter, meta, differ)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// start the GRPC api with the execution service registered
|
// start the GRPC api with the execution service registered
|
||||||
server := newGRPCServer()
|
server := newGRPCServer()
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
@ -159,7 +159,6 @@ func main() {
|
|||||||
log.G(global).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
|
log.G(global).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
|
||||||
return handleSignals(signals, server)
|
return handleSignals(signals, server)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -184,10 +183,6 @@ func before(context *cli.Context) error {
|
|||||||
name: "root",
|
name: "root",
|
||||||
d: &conf.Root,
|
d: &conf.Root,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "state",
|
|
||||||
d: &conf.State,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "address",
|
name: "address",
|
||||||
d: &conf.GRPC.Address,
|
d: &conf.GRPC.Address,
|
||||||
@ -254,139 +249,27 @@ func serveDebugAPI() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveContentStore() (content.Store, error) {
|
func registerContentStore() {
|
||||||
cp := filepath.Join(conf.Root, "content")
|
plugin.Register(&plugin.Registration{
|
||||||
return content.NewStore(cp)
|
Type: plugin.ContentPlugin,
|
||||||
|
ID: "content",
|
||||||
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
return content.NewStore(ic.Root)
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveMetaDB(ctx *cli.Context) (*bolt.DB, error) {
|
func registerMetaDB() {
|
||||||
path := filepath.Join(conf.Root, "meta.db")
|
plugin.Register(&plugin.Registration{
|
||||||
|
Type: plugin.MetadataPlugin,
|
||||||
db, err := bolt.Open(path, 0644, nil)
|
ID: "bolt",
|
||||||
if err != nil {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return nil, err
|
if err := os.MkdirAll(ic.Root, 0700); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
return db, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadRuntimes(monitor plugin.TaskMonitor) (map[string]plugin.Runtime, error) {
|
|
||||||
o := make(map[string]plugin.Runtime)
|
|
||||||
for name, rr := range plugin.Registrations() {
|
|
||||||
if rr.Type != plugin.RuntimePlugin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.G(global).Infof("loading runtime plugin %q...", name)
|
|
||||||
ic := &plugin.InitContext{
|
|
||||||
Root: conf.Root,
|
|
||||||
State: conf.State,
|
|
||||||
Context: log.WithModule(global, fmt.Sprintf("runtime-%s", name)),
|
|
||||||
Monitor: monitor,
|
|
||||||
}
|
|
||||||
if rr.Config != nil {
|
|
||||||
if err := conf.decodePlugin(name, rr.Config); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ic.Config = rr.Config
|
return bolt.Open(filepath.Join(ic.Root, "meta.db"), 0644, nil)
|
||||||
}
|
},
|
||||||
vr, err := rr.Init(ic)
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
o[name] = vr.(plugin.Runtime)
|
|
||||||
}
|
|
||||||
return o, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadMonitor() (plugin.TaskMonitor, error) {
|
|
||||||
var monitors []plugin.TaskMonitor
|
|
||||||
for name, m := range plugin.Registrations() {
|
|
||||||
if m.Type != plugin.TaskMonitorPlugin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.G(global).Infof("loading monitor plugin %q...", name)
|
|
||||||
ic := &plugin.InitContext{
|
|
||||||
Root: conf.Root,
|
|
||||||
State: conf.State,
|
|
||||||
Context: log.WithModule(global, fmt.Sprintf("monitor-%s", name)),
|
|
||||||
}
|
|
||||||
mm, err := m.Init(ic)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
monitors = append(monitors, mm.(plugin.TaskMonitor))
|
|
||||||
}
|
|
||||||
if len(monitors) == 0 {
|
|
||||||
return plugin.NewNoopMonitor(), nil
|
|
||||||
}
|
|
||||||
return plugin.NewMultiTaskMonitor(monitors...), 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,
|
|
||||||
Content: 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 loadDiffer(snapshotter snapshot.Snapshotter, store content.Store) (plugin.Differ, error) {
|
|
||||||
for name, sr := range plugin.Registrations() {
|
|
||||||
if sr.Type != plugin.DiffPlugin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
moduleName := fmt.Sprintf("diff-%s", conf.Differ)
|
|
||||||
if name != moduleName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
log.G(global).Infof("loading differ plugin %q...", name)
|
|
||||||
ic := &plugin.InitContext{
|
|
||||||
Root: conf.Root,
|
|
||||||
State: conf.State,
|
|
||||||
Content: store,
|
|
||||||
Snapshotter: snapshotter,
|
|
||||||
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.(plugin.Differ), nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("differ not loaded: %v", conf.Differ)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGRPCServer() *grpc.Server {
|
func newGRPCServer() *grpc.Server {
|
||||||
@ -397,40 +280,6 @@ func newGRPCServer() *grpc.Server {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadServices(runtimes map[string]plugin.Runtime,
|
|
||||||
store content.Store, sn snapshot.Snapshotter,
|
|
||||||
meta *bolt.DB, differ plugin.Differ) ([]plugin.Service, error) {
|
|
||||||
var o []plugin.Service
|
|
||||||
for name, sr := range plugin.Registrations() {
|
|
||||||
if sr.Type != plugin.GRPCPlugin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.G(global).Infof("loading grpc service plugin %q...", name)
|
|
||||||
ic := &plugin.InitContext{
|
|
||||||
Root: conf.Root,
|
|
||||||
State: conf.State,
|
|
||||||
Context: log.WithModule(global, fmt.Sprintf("service-%s", name)),
|
|
||||||
Runtimes: runtimes,
|
|
||||||
Content: store,
|
|
||||||
Meta: meta,
|
|
||||||
Snapshotter: sn,
|
|
||||||
Differ: differ,
|
|
||||||
}
|
|
||||||
if sr.Config != nil {
|
|
||||||
if err := conf.decodePlugin(name, sr.Config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ic.Config = sr.Config
|
|
||||||
}
|
|
||||||
vs, err := sr.Init(ic)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
o = append(o, vs.(plugin.Service))
|
|
||||||
}
|
|
||||||
return o, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveGRPC(server *grpc.Server) error {
|
func serveGRPC(server *grpc.Server) error {
|
||||||
path := conf.GRPC.Address
|
path := conf.GRPC.Address
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@ -494,3 +343,23 @@ func dumpStacks() {
|
|||||||
buf = buf[:stackSize]
|
buf = buf[:stackSize]
|
||||||
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadPluginConfig(name string, c interface{}, ic *plugin.InitContext) error {
|
||||||
|
if err := conf.decodePlugin(name, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ic.Config = c
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldLoad(r *plugin.Registration) bool {
|
||||||
|
// only load certain plugins based on the config values
|
||||||
|
switch r.Type {
|
||||||
|
case plugin.SnapshotPlugin:
|
||||||
|
return r.URI() == conf.Snapshotter
|
||||||
|
case plugin.DiffPlugin:
|
||||||
|
return r.URI() == conf.Differ
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,13 +12,14 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const defaultConfigPath = "/etc/containerd/config.toml"
|
||||||
defaultConfigPath = "/etc/containerd/config.toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var handledSignals = []os.Signal{
|
||||||
handledSignals = []os.Signal{unix.SIGTERM, unix.SIGINT, unix.SIGUSR1, unix.SIGCHLD}
|
unix.SIGTERM,
|
||||||
)
|
unix.SIGINT,
|
||||||
|
unix.SIGUSR1,
|
||||||
|
unix.SIGCHLD,
|
||||||
|
}
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(context *cli.Context) error {
|
||||||
if conf.Subreaper {
|
if conf.Subreaper {
|
||||||
@ -33,12 +34,6 @@ func platformInit(context *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(conf.State, 0750); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.Chown(conf.State, conf.GRPC.Uid, conf.GRPC.Gid); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(context *cli.Context) error {
|
||||||
if err := os.MkdirAll(conf.State, 0750); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.Chown(conf.State, conf.GRPC.Uid, conf.GRPC.Gid); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ var runCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "runtime",
|
Name: "runtime",
|
||||||
Usage: "runtime name (linux, windows, vmware-linux)",
|
Usage: "runtime name (io.containerd.runtime.v1.linux, io.containerd.runtime.v1.windows, io.containerd.runtime.v1.com.vmware.linux)",
|
||||||
Value: "linux",
|
Value: "io.containerd.runtime.v1.linux",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "readonly",
|
Name: "readonly",
|
||||||
|
@ -18,10 +18,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("diff-base", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.DiffPlugin,
|
Type: plugin.DiffPlugin,
|
||||||
|
ID: "base-diff",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.ContentPlugin,
|
||||||
|
plugin.SnapshotPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return newBaseDiff(ic.Content, ic.Snapshotter)
|
c, err := ic.Get(plugin.ContentPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s, err := ic.Get(plugin.SnapshotPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newBaseDiff(c.(content.Store), s.(snapshot.Snapshotter))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -32,19 +32,23 @@ import (
|
|||||||
var (
|
var (
|
||||||
ErrTaskNotExists = errors.New("task does not exist")
|
ErrTaskNotExists = errors.New("task does not exist")
|
||||||
ErrTaskAlreadyExists = errors.New("task already exists")
|
ErrTaskAlreadyExists = errors.New("task already exists")
|
||||||
|
pluginID = fmt.Sprintf("%s.%s", plugin.RuntimePlugin, "linux")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
runtimeName = "linux"
|
|
||||||
configFilename = "config.json"
|
configFilename = "config.json"
|
||||||
defaultRuntime = "runc"
|
defaultRuntime = "runc"
|
||||||
defaultShim = "containerd-shim"
|
defaultShim = "containerd-shim"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register(runtimeName, &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.RuntimePlugin,
|
Type: plugin.RuntimePlugin,
|
||||||
|
ID: "linux",
|
||||||
Init: New,
|
Init: New,
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.TaskMonitorPlugin,
|
||||||
|
},
|
||||||
Config: &Config{
|
Config: &Config{
|
||||||
Shim: defaultShim,
|
Shim: defaultShim,
|
||||||
Runtime: defaultRuntime,
|
Runtime: defaultRuntime,
|
||||||
@ -129,25 +133,28 @@ func (l *taskList) delete(ctx context.Context, t *Task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(ic *plugin.InitContext) (interface{}, error) {
|
func New(ic *plugin.InitContext) (interface{}, error) {
|
||||||
path := filepath.Join(ic.State, runtimeName)
|
if err := os.MkdirAll(ic.Root, 0700); err != nil {
|
||||||
if err := os.MkdirAll(path, 0700); err != nil {
|
return nil, err
|
||||||
|
}
|
||||||
|
monitor, err := ic.Get(plugin.TaskMonitorPlugin)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg := ic.Config.(*Config)
|
cfg := ic.Config.(*Config)
|
||||||
c, cancel := context.WithCancel(ic.Context)
|
c, cancel := context.WithCancel(ic.Context)
|
||||||
r := &Runtime{
|
r := &Runtime{
|
||||||
root: path,
|
root: ic.Root,
|
||||||
remote: !cfg.NoShim,
|
remote: !cfg.NoShim,
|
||||||
shim: cfg.Shim,
|
shim: cfg.Shim,
|
||||||
runtime: cfg.Runtime,
|
runtime: cfg.Runtime,
|
||||||
events: make(chan *plugin.Event, 2048),
|
events: make(chan *plugin.Event, 2048),
|
||||||
eventsContext: c,
|
eventsContext: c,
|
||||||
eventsCancel: cancel,
|
eventsCancel: cancel,
|
||||||
monitor: ic.Monitor,
|
monitor: monitor.(plugin.TaskMonitor),
|
||||||
tasks: newTaskList(),
|
tasks: newTaskList(),
|
||||||
}
|
}
|
||||||
// set the events output for a monitor if it generates events
|
// set the events output for a monitor if it generates events
|
||||||
ic.Monitor.Events(r.events)
|
r.monitor.Events(r.events)
|
||||||
tasks, err := r.loadAllTasks(ic.Context)
|
tasks, err := r.loadAllTasks(ic.Context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -157,7 +164,6 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// load all tasks from disk
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +180,10 @@ type Runtime struct {
|
|||||||
tasks *taskList
|
tasks *taskList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Runtime) ID() string {
|
||||||
|
return pluginID
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (t plugin.Task, err error) {
|
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (t plugin.Task, err error) {
|
||||||
namespace, err := namespaces.NamespaceRequired(ctx)
|
namespace, err := namespaces.NamespaceRequired(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -358,7 +368,7 @@ func (r *Runtime) forward(events shim.Shim_EventsClient) {
|
|||||||
}
|
}
|
||||||
r.events <- &plugin.Event{
|
r.events <- &plugin.Event{
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
Runtime: runtimeName,
|
Runtime: r.ID(),
|
||||||
Type: et,
|
Type: et,
|
||||||
Pid: e.Pid,
|
Pid: e.Pid,
|
||||||
ID: e.ID,
|
ID: e.ID,
|
||||||
|
@ -35,7 +35,7 @@ func (c *Task) Info() plugin.TaskInfo {
|
|||||||
return plugin.TaskInfo{
|
return plugin.TaskInfo{
|
||||||
ID: c.containerID,
|
ID: c.containerID,
|
||||||
ContainerID: c.containerID,
|
ContainerID: c.containerID,
|
||||||
Runtime: runtimeName,
|
Runtime: pluginID,
|
||||||
Spec: c.spec,
|
Spec: c.spec,
|
||||||
Namespace: c.namespace,
|
Namespace: c.namespace,
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,10 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
const name = "cgroups"
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register(name, &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.TaskMonitorPlugin,
|
Type: plugin.TaskMonitorPlugin,
|
||||||
|
ID: "cgroups",
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
36
plugin/context.go
Normal file
36
plugin/context.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewContext(plugins map[PluginType][]interface{}) *InitContext {
|
||||||
|
return &InitContext{
|
||||||
|
plugins: plugins,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type InitContext struct {
|
||||||
|
Root string
|
||||||
|
Context context.Context
|
||||||
|
Config interface{}
|
||||||
|
|
||||||
|
plugins map[PluginType][]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InitContext) Get(t PluginType) (interface{}, error) {
|
||||||
|
p := i.plugins[t]
|
||||||
|
if len(p) == 0 {
|
||||||
|
return nil, fmt.Errorf("no plugins registered for %s", t)
|
||||||
|
}
|
||||||
|
return p[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InitContext) GetAll(t PluginType) ([]interface{}, error) {
|
||||||
|
p, ok := i.plugins[t]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("no plugins registered for %s", t)
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
@ -3,7 +3,6 @@ package plugin
|
|||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrUnknownRuntime = errors.New("unknown runtime")
|
|
||||||
ErrContainerExists = errors.New("container with id already exists")
|
ErrContainerExists = errors.New("container with id already exists")
|
||||||
ErrContainerNotExist = errors.New("container does not exist")
|
ErrContainerNotExist = errors.New("container does not exist")
|
||||||
ErrRuntimeNotExist = errors.New("runtime does not exist")
|
ErrRuntimeNotExist = errors.New("runtime does not exist")
|
||||||
|
@ -1,45 +1,42 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
|
||||||
"github.com/containerd/containerd/content"
|
|
||||||
"github.com/containerd/containerd/snapshot"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PluginType int
|
var (
|
||||||
|
ErrNoPluginType = errors.New("plugin: no type")
|
||||||
|
ErrNoPluginID = errors.New("plugin: no id")
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RuntimePlugin PluginType = iota + 1
|
RuntimePlugin PluginType = "io.containerd.runtime.v1"
|
||||||
GRPCPlugin
|
GRPCPlugin PluginType = "io.containerd.grpc.v1"
|
||||||
SnapshotPlugin
|
SnapshotPlugin PluginType = "io.containerd.snapshotter.v1"
|
||||||
TaskMonitorPlugin
|
TaskMonitorPlugin PluginType = "io.containerd.monitor.v1"
|
||||||
DiffPlugin
|
DiffPlugin PluginType = "io.containerd.differ.v1"
|
||||||
|
MetadataPlugin PluginType = "io.containerd.metadata.v1"
|
||||||
|
ContentPlugin PluginType = "io.containerd.content.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Registration struct {
|
type Registration struct {
|
||||||
Type PluginType
|
Type PluginType
|
||||||
Config interface{}
|
ID string
|
||||||
Init func(*InitContext) (interface{}, error)
|
Config interface{}
|
||||||
|
Requires []PluginType
|
||||||
|
Init func(*InitContext) (interface{}, error)
|
||||||
|
|
||||||
|
added bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(@crosbymichael): how do we keep this struct from growing but support dependency injection for loaded plugins?
|
func (r *Registration) URI() string {
|
||||||
type InitContext struct {
|
return fmt.Sprintf("%s.%s", r.Type, r.ID)
|
||||||
Root string
|
|
||||||
State string
|
|
||||||
Runtimes map[string]Runtime
|
|
||||||
Content content.Store
|
|
||||||
Meta *bolt.DB
|
|
||||||
Snapshotter snapshot.Snapshotter
|
|
||||||
Differ Differ
|
|
||||||
Config interface{}
|
|
||||||
Context context.Context
|
|
||||||
Monitor TaskMonitor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
@ -48,10 +45,8 @@ type Service interface {
|
|||||||
|
|
||||||
var register = struct {
|
var register = struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
r map[string]*Registration
|
r []*Registration
|
||||||
}{
|
}{}
|
||||||
r: make(map[string]*Registration),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load loads all plugins at the provided path into containerd
|
// Load loads all plugins at the provided path into containerd
|
||||||
func Load(path string) (err error) {
|
func Load(path string) (err error) {
|
||||||
@ -67,16 +62,39 @@ func Load(path string) (err error) {
|
|||||||
return loadPlugins(path)
|
return loadPlugins(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(name string, r *Registration) error {
|
func Register(r *Registration) {
|
||||||
register.Lock()
|
register.Lock()
|
||||||
defer register.Unlock()
|
defer register.Unlock()
|
||||||
if _, ok := register.r[name]; ok {
|
if r.Type == "" {
|
||||||
return fmt.Errorf("plugin already registered as %q", name)
|
panic(ErrNoPluginType)
|
||||||
}
|
}
|
||||||
register.r[name] = r
|
if r.ID == "" {
|
||||||
return nil
|
panic(ErrNoPluginID)
|
||||||
|
}
|
||||||
|
register.r = append(register.r, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Registrations() map[string]*Registration {
|
func Graph() (ordered []*Registration) {
|
||||||
return register.r
|
for _, r := range register.r {
|
||||||
|
children(r.Requires, &ordered)
|
||||||
|
if !r.added {
|
||||||
|
ordered = append(ordered, r)
|
||||||
|
r.added = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ordered
|
||||||
|
}
|
||||||
|
|
||||||
|
func children(types []PluginType, ordered *[]*Registration) {
|
||||||
|
for _, t := range types {
|
||||||
|
for _, r := range register.r {
|
||||||
|
if r.Type == t {
|
||||||
|
children(r.Requires, ordered)
|
||||||
|
if !r.added {
|
||||||
|
*ordered = append(*ordered, r)
|
||||||
|
r.added = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ type Exit struct {
|
|||||||
// Runtime is responsible for the creation of containers for a certain platform,
|
// Runtime is responsible for the creation of containers for a certain platform,
|
||||||
// arch, or custom usage.
|
// arch, or custom usage.
|
||||||
type Runtime interface {
|
type Runtime interface {
|
||||||
|
// ID of the runtime
|
||||||
|
ID() string
|
||||||
// Create creates a container with the provided id and options
|
// Create creates a container with the provided id and options
|
||||||
Create(ctx context.Context, id string, opts CreateOpts) (Task, error)
|
Create(ctx context.Context, id string, opts CreateOpts) (Task, error)
|
||||||
// Get returns a container
|
// Get returns a container
|
||||||
|
@ -13,10 +13,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("containers-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "containers",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.MetadataPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewService(ic.Meta), nil
|
m, err := ic.Get(plugin.MetadataPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewService(m.(*bolt.DB)), nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,23 @@ var bufPool = sync.Pool{
|
|||||||
var _ api.ContentServer = &Service{}
|
var _ api.ContentServer = &Service{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("content-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "content",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.ContentPlugin,
|
||||||
|
},
|
||||||
Init: NewService,
|
Init: NewService,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(ic *plugin.InitContext) (interface{}, error) {
|
func NewService(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
c, err := ic.Get(plugin.ContentPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &Service{
|
return &Service{
|
||||||
store: ic.Content,
|
store: c.(content.Store),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("diff-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "diff",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.DiffPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
d, err := ic.Get(plugin.DiffPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &service{
|
return &service{
|
||||||
diff: ic.Differ,
|
diff: d.(plugin.Differ),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -35,22 +35,45 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("tasks-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "tasks",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.RuntimePlugin,
|
||||||
|
plugin.MetadataPlugin,
|
||||||
|
plugin.ContentPlugin,
|
||||||
|
},
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ic *plugin.InitContext) (interface{}, error) {
|
func New(ic *plugin.InitContext) (interface{}, error) {
|
||||||
c, err := newCollector(ic.Context, ic.Runtimes)
|
rt, err := ic.GetAll(plugin.RuntimePlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m, err := ic.Get(plugin.MetadataPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ct, err := ic.Get(plugin.ContentPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
runtimes := make(map[string]plugin.Runtime)
|
||||||
|
for _, rr := range rt {
|
||||||
|
r := rr.(plugin.Runtime)
|
||||||
|
runtimes[r.ID()] = r
|
||||||
|
}
|
||||||
|
c, err := newCollector(ic.Context, runtimes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Service{
|
return &Service{
|
||||||
runtimes: ic.Runtimes,
|
runtimes: runtimes,
|
||||||
db: ic.Meta,
|
db: m.(*bolt.DB),
|
||||||
collector: c,
|
collector: c,
|
||||||
store: ic.Content,
|
store: ct.(content.Store),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +484,7 @@ func (s *Service) getTask(ctx context.Context, id string) (plugin.Task, error) {
|
|||||||
func (s *Service) getRuntime(name string) (plugin.Runtime, error) {
|
func (s *Service) getRuntime(name string) (plugin.Runtime, error) {
|
||||||
runtime, ok := s.runtimes[name]
|
runtime, ok := s.runtimes[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, plugin.ErrUnknownRuntime
|
return nil, fmt.Errorf("unknown runtime %q", name)
|
||||||
}
|
}
|
||||||
return runtime, nil
|
return runtime, nil
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,9 @@ type Service struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("healthcheck-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "healthcheck",
|
||||||
Init: NewService,
|
Init: NewService,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("images-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "images",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.MetadataPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewService(ic.Meta), nil
|
m, err := ic.Get(plugin.MetadataPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewService(m.(*bolt.DB)), nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("namespaces-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "namespaces",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.MetadataPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewService(ic.Meta), nil
|
m, err := ic.Get(plugin.MetadataPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewService(m.(*bolt.DB)), nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("snapshots-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "snapshots",
|
||||||
|
Requires: []plugin.PluginType{
|
||||||
|
plugin.SnapshotPlugin,
|
||||||
|
},
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return newService(ic.Snapshotter)
|
s, err := ic.Get(plugin.SnapshotPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newService(s.(snapshot.Snapshotter))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,9 @@ import (
|
|||||||
var _ api.VersionServer = &Service{}
|
var _ api.VersionServer = &Service{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("version-grpc", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
|
ID: "version",
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("snapshot-btrfs", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
|
ID: "btrfs",
|
||||||
Type: plugin.SnapshotPlugin,
|
Type: plugin.SnapshotPlugin,
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
root := filepath.Join(ic.Root, "snapshot", "btrfs")
|
return NewSnapshotter(ic.Root)
|
||||||
return NewSnapshotter(root)
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("snapshot-naive", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.SnapshotPlugin,
|
Type: plugin.SnapshotPlugin,
|
||||||
|
ID: "naive",
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewSnapshotter(filepath.Join(ic.Root, "snapshot", "naive"))
|
return NewSnapshotter(ic.Root)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("snapshot-overlay", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.SnapshotPlugin,
|
Type: plugin.SnapshotPlugin,
|
||||||
|
ID: "overlayfs",
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewSnapshotter(filepath.Join(ic.Root, "snapshot", "overlay"))
|
return NewSnapshotter(ic.Root)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ package windows
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
@ -17,10 +16,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("snapshot-windows", &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.SnapshotPlugin,
|
Type: plugin.SnapshotPlugin,
|
||||||
|
ID: "windows",
|
||||||
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
return NewSnapshotter(filepath.Join(ic.Root, "snapshot", "windows"))
|
return NewSnapshotter(ic.Root)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,15 @@ const (
|
|||||||
var _ = (plugin.Runtime)(&Runtime{})
|
var _ = (plugin.Runtime)(&Runtime{})
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register(runtimeName, &plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
|
ID: "windows",
|
||||||
Type: plugin.RuntimePlugin,
|
Type: plugin.RuntimePlugin,
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ic *plugin.InitContext) (interface{}, error) {
|
func New(ic *plugin.InitContext) (interface{}, error) {
|
||||||
rootDir := filepath.Join(ic.Root, runtimeName)
|
rootDir := filepath.Join(ic.Root)
|
||||||
if err := os.MkdirAll(rootDir, 0755); err != nil {
|
if err := os.MkdirAll(rootDir, 0755); err != nil {
|
||||||
return nil, errors.Wrapf(err, "could not create state directory at %s", rootDir)
|
return nil, errors.Wrapf(err, "could not create state directory at %s", rootDir)
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to delete the old state dir and recreate it
|
// Try to delete the old state dir and recreate it
|
||||||
stateDir := filepath.Join(ic.State, runtimeName)
|
stateDir := filepath.Join(ic.Root, "state")
|
||||||
if err := os.RemoveAll(stateDir); err != nil {
|
if err := os.RemoveAll(stateDir); err != nil {
|
||||||
log.G(c).WithError(err).Warnf("failed to cleanup old state directory at %s", stateDir)
|
log.G(c).WithError(err).Warnf("failed to cleanup old state directory at %s", stateDir)
|
||||||
}
|
}
|
||||||
@ -99,6 +100,10 @@ type RuntimeSpec struct {
|
|||||||
hcs.Configuration
|
hcs.Configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Runtime) ID() string {
|
||||||
|
return fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtimeName)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
|
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
|
||||||
var rtSpec RuntimeSpec
|
var rtSpec RuntimeSpec
|
||||||
if err := json.Unmarshal(opts.Spec, &rtSpec); err != nil {
|
if err := json.Unmarshal(opts.Spec, &rtSpec); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user