plugins: experimental support for new plugin management

This patch introduces a new experimental engine-level plugin management
with a new API and command line. Plugins can be distributed via a Docker
registry, and their lifecycle is managed by the engine.
This makes plugins a first-class construct.

For more background, have a look at issue #20363.

Documentation is in a separate commit. If you want to understand how the
new plugin system works, you can start by reading the documentation.

Note: backwards compatibility with existing plugins is maintained,
albeit they won't benefit from the advantages of the new system.

Signed-off-by: Tibor Vass <tibor@docker.com>
Signed-off-by: Anusha Ragunathan <anusha@docker.com>
This commit is contained in:
Tibor Vass 2016-05-16 11:50:55 -04:00
parent 789aee497c
commit 59c8eda724
8 changed files with 48 additions and 30 deletions

View file

@ -203,18 +203,17 @@ func TestResponseModifierOverride(t *testing.T) {
// createTestPlugin creates a new sample authorization plugin
func createTestPlugin(t *testing.T) *authorizationPlugin {
plugin := &plugins.Plugin{Name: "authz"}
pwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
plugin.Client, err = plugins.NewClient("unix:///"+path.Join(pwd, pluginAddress), tlsconfig.Options{InsecureSkipVerify: true})
client, err := plugins.NewClient("unix:///"+path.Join(pwd, pluginAddress), &tlsconfig.Options{InsecureSkipVerify: true})
if err != nil {
t.Fatalf("Failed to create client %v", err)
}
return &authorizationPlugin{name: "plugin", plugin: plugin}
return &authorizationPlugin{name: "plugin", plugin: client}
}
// AuthZPluginTestServer is a simple server that implements the authZ plugin interface

View file

@ -35,7 +35,7 @@ func NewPlugins(names []string) []Plugin {
// authorizationPlugin is an internal adapter to docker plugin system
type authorizationPlugin struct {
plugin *plugins.Plugin
plugin *plugins.Client
name string
once sync.Once
}
@ -54,7 +54,7 @@ func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error)
}
authRes := &Response{}
if err := a.plugin.Client.Call(AuthZApiRequest, authReq, authRes); err != nil {
if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil {
return nil, err
}
@ -67,7 +67,7 @@ func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error)
}
authRes := &Response{}
if err := a.plugin.Client.Call(AuthZApiResponse, authReq, authRes); err != nil {
if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil {
return nil, err
}
@ -80,7 +80,12 @@ func (a *authorizationPlugin) initPlugin() error {
var err error
a.once.Do(func() {
if a.plugin == nil {
a.plugin, err = plugins.Get(a.name, AuthZApiImplements)
plugin, e := plugins.Get(a.name, AuthZApiImplements)
if e != nil {
err = e
return
}
a.plugin = plugin.Client()
}
})
return err