mirror of
https://github.com/linuxkit/linuxkit.git
synced 2026-01-17 10:49:22 +00:00
- The tools directory ideally should not contain source code - Removes double vendoring of packagages - Makes it easer to hook the build into the top-level Makefile Eventually, the plugin should be moved to the infrakit repo. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
135 lines
3.5 KiB
Go
135 lines
3.5 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"github.com/docker/infrakit/pkg/plugin"
|
|
"github.com/docker/infrakit/pkg/spi"
|
|
"github.com/docker/infrakit/pkg/template"
|
|
)
|
|
|
|
// TypedFunctionExporter is an interface implemented by plugins that supports multiple types in a single RPC endpoint.
|
|
// Each typed plugin can export some functions and this interface provides metadata about them.
|
|
type TypedFunctionExporter interface {
|
|
|
|
// Types returns a list of types in this plugin
|
|
Types() []string
|
|
|
|
// FuncsByType returns the template functions exported by each typed plugin
|
|
FuncsByType(string) []template.Function
|
|
}
|
|
|
|
// PluginInfo is the service object for the RPC metadata service
|
|
type PluginInfo struct {
|
|
vendor spi.Vendor
|
|
reflectors []*reflector
|
|
receiver interface{}
|
|
}
|
|
|
|
// NewPluginInfo returns an instance of the metadata service
|
|
func NewPluginInfo(receiver interface{}) (*PluginInfo, error) {
|
|
m := &PluginInfo{
|
|
reflectors: []*reflector{},
|
|
receiver: receiver,
|
|
}
|
|
if v, is := receiver.(spi.Vendor); is {
|
|
m.vendor = v
|
|
}
|
|
return m, m.Register(receiver)
|
|
}
|
|
|
|
// Register registers an rpc-capable object for introspection and metadata service
|
|
func (m *PluginInfo) Register(receiver interface{}) error {
|
|
r := &reflector{target: receiver}
|
|
m.reflectors = append(m.reflectors, r)
|
|
return nil
|
|
}
|
|
|
|
// ShowAPI responds by returning information about the plugin.
|
|
func (m *PluginInfo) ShowAPI(resp http.ResponseWriter, req *http.Request) {
|
|
meta := m.getInfo()
|
|
buff, err := json.Marshal(meta)
|
|
if err != nil {
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
resp.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
resp.Write(buff)
|
|
return
|
|
}
|
|
|
|
// ShowTemplateFunctions responds by returning information about template functions the plugin expopses.
|
|
func (m *PluginInfo) ShowTemplateFunctions(resp http.ResponseWriter, req *http.Request) {
|
|
result := map[string][]template.Function{}
|
|
exporter, is := m.receiver.(template.FunctionExporter)
|
|
if is {
|
|
base := template.UpdateDocumentation(exporter.Funcs())
|
|
if len(base) > 0 {
|
|
result["base"] = base
|
|
}
|
|
}
|
|
|
|
texporter, is := m.receiver.(TypedFunctionExporter)
|
|
if is {
|
|
for _, t := range texporter.Types() {
|
|
typed := template.UpdateDocumentation(texporter.FuncsByType(t))
|
|
if len(typed) > 0 {
|
|
result[t] = typed
|
|
}
|
|
}
|
|
}
|
|
|
|
if t, err := template.NewTemplate("str://", template.Options{}); err == nil {
|
|
builtin := template.UpdateDocumentation(t.DefaultFuncs())
|
|
if len(builtin) > 0 {
|
|
result["builtin"] = builtin
|
|
}
|
|
}
|
|
|
|
buff, err := json.MarshalIndent(result, "", " ")
|
|
if err != nil {
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
resp.Write([]byte(err.Error()))
|
|
return
|
|
}
|
|
resp.Write(buff)
|
|
return
|
|
}
|
|
|
|
func (m *PluginInfo) getInfo() *plugin.Info {
|
|
meta := &plugin.Info{}
|
|
myImplements := []spi.InterfaceSpec{}
|
|
myInterfaces := []plugin.InterfaceDescription{}
|
|
|
|
for _, r := range m.reflectors {
|
|
|
|
iface := r.Interface()
|
|
myImplements = append(myImplements, iface)
|
|
|
|
descriptions := []plugin.MethodDescription{}
|
|
for _, method := range r.pluginMethods() {
|
|
|
|
desc := r.toDescription(method)
|
|
descriptions = append(descriptions, desc)
|
|
|
|
// sets the example properties which are the custom types for the plugin
|
|
r.setExampleProperties(desc.Request.Params)
|
|
}
|
|
|
|
myInterfaces = append(myInterfaces,
|
|
plugin.InterfaceDescription{
|
|
InterfaceSpec: iface,
|
|
Methods: descriptions,
|
|
})
|
|
}
|
|
|
|
if m.vendor != nil {
|
|
meta.Vendor = m.vendor.VendorInfo()
|
|
}
|
|
|
|
meta.Implements = myImplements
|
|
meta.Interfaces = myInterfaces
|
|
return meta
|
|
}
|