Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/cli/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func infoCommand(plugins func() discovery.Plugins) *cobra.Command {
return err
}

view, err := renderer.AddDef("plugin", *name).Render(info)
view, err := renderer.Def("plugin", *name, "Plugin name").Render(info)
if err != nil {
return err
}
Expand Down Expand Up @@ -103,7 +103,7 @@ func infoCommand(plugins func() discovery.Plugins) *cobra.Command {
return err
}

view, err := renderer.AddDef("plugin", *name).Render(info)
view, err := renderer.Def("plugin", *name, "Plugin name").Render(info)
if err != nil {
return err
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ func main() {
cmd.AddCommand(infoCommand(f))
cmd.AddCommand(templateCommand(f))
cmd.AddCommand(managerCommand(f))
cmd.AddCommand(pluginCommand(f), instancePluginCommand(f), groupPluginCommand(f), flavorPluginCommand(f))
cmd.AddCommand(metadataCommand(f))
cmd.AddCommand(pluginCommand(f))

cmd.AddCommand(instancePluginCommand(f), groupPluginCommand(f), flavorPluginCommand(f))

err := cmd.Execute()
if err != nil {
Expand Down
219 changes: 219 additions & 0 deletions cmd/cli/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package main

import (
"fmt"
"strconv"

log "github.com/Sirupsen/logrus"
"github.com/docker/infrakit/pkg/discovery"
metadata_plugin "github.com/docker/infrakit/pkg/plugin/metadata"
"github.com/docker/infrakit/pkg/rpc/client"
metadata_rpc "github.com/docker/infrakit/pkg/rpc/metadata"
"github.com/docker/infrakit/pkg/spi/metadata"
"github.com/spf13/cobra"
)

func getPlugin(plugins func() discovery.Plugins, name string) (found metadata.Plugin, err error) {
err = forPlugin(plugins, func(n string, p metadata.Plugin) error {
if n == name {
found = p
}
return nil
})
return
}

func forPlugin(plugins func() discovery.Plugins, do func(string, metadata.Plugin) error) error {
all, err := plugins().List()
if err != nil {
return err
}
for name, endpoint := range all {
rpcClient, err := client.New(endpoint.Address, metadata.InterfaceSpec)
if err != nil {
continue
}
if err := do(name, metadata_rpc.Adapt(rpcClient)); err != nil {
return err
}
}
return nil
}

func listAll(m metadata.Plugin, path metadata.Path) ([]metadata.Path, error) {
if m == nil {
return nil, fmt.Errorf("no plugin")
}
result := []metadata.Path{}
nodes, err := m.List(path)
if err != nil {
return nil, err
}
for _, n := range nodes {
c := path.Join(n)
more, err := listAll(m, c)
if err != nil {
return nil, err
}
if len(more) == 0 {
result = append(result, c)
}
for _, pp := range more {
result = append(result, pp)
}
}
return result, nil
}

func metadataCommand(plugins func() discovery.Plugins) *cobra.Command {

cmd := &cobra.Command{
Use: "metadata",
Short: "Access metadata exposed by infrakit plugins",
}

ls := &cobra.Command{
Use: "ls",
Short: "List all metadata entries",
}

long := ls.Flags().BoolP("long", "l", false, "Print full path")
all := ls.Flags().BoolP("all", "a", false, "Find all under the paths given")

ls.RunE = func(c *cobra.Command, args []string) error {
paths := []string{"."}

// All implies long
if *all {
*long = true
}

if len(args) > 0 {
paths = args
}

for _, p := range paths {

if p == "/" {
// TODO(chungers) -- this is a 'local' infrakit ensemble.
// Absolute paths will come in a multi-cluster / federated model.
return fmt.Errorf("No absolute path")
}

path := metadata_plugin.Path(p)
first := path.Index(0)

targets := []string{} // target plugins to query

// Check all the plugins -- scanning via discovery
if err := forPlugin(plugins,
func(name string, mp metadata.Plugin) error {
if p == "." || (first != nil && name == *first) {
targets = append(targets, name)
}
return nil
}); err != nil {
return err
}

for _, target := range targets {

nodes := []metadata.Path{} // the result set to print

match, err := getPlugin(plugins, target)
if err != nil {
return err
}

if p == "." {
if *all {
allPaths, err := listAll(match, path.Shift(1))
if err != nil {
log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
}
for _, c := range allPaths {
nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
}
} else {
for _, t := range targets {
nodes = append(nodes, metadata_plugin.Path(t))
}
}
} else {
if *all {
allPaths, err := listAll(match, path.Shift(1))
if err != nil {
log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
}
for _, c := range allPaths {
nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
}
} else {
children, err := match.List(path.Shift(1))
if err != nil {
log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
}
for _, c := range children {
nodes = append(nodes, path.Join(c))
}
}
}

if len(targets) > 1 {
fmt.Printf("%s:\n", target)
}
if *long {
fmt.Printf("total %d:\n", len(nodes))
}
for _, l := range nodes {
if *long {
fmt.Println(metadata_plugin.String(l))
} else {
fmt.Println(metadata_plugin.String(l.Rel(path)))
}
}
fmt.Println()
}

}
return nil
}

cat := &cobra.Command{
Use: "cat",
Short: "Get metadata entry by path",
RunE: func(c *cobra.Command, args []string) error {

for _, p := range args {

path := metadata_plugin.Path(p)
first := path.Index(0)
if first != nil {
match, err := getPlugin(plugins, *first)
if err != nil {
return err
}

value, err := match.Get(path.Shift(1))
if err == nil {
if value != nil {
str := value.String()
if s, err := strconv.Unquote(value.String()); err == nil {
str = s
}
fmt.Println(str)
}

} else {
log.Warningln("Cannot metadata cat on plugin", *first, "err=", err)
}
}
}
return nil
},
}

cmd.AddCommand(ls, cat)

return cmd
}
16 changes: 16 additions & 0 deletions cmd/cli/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

log "github.com/Sirupsen/logrus"
"github.com/docker/infrakit/pkg/discovery"
metadata_template "github.com/docker/infrakit/pkg/plugin/metadata/template"
"github.com/docker/infrakit/pkg/template"
"github.com/spf13/cobra"
)
Expand All @@ -24,6 +25,21 @@ func templateCommand(plugins func() discovery.Plugins) *cobra.Command {
if err != nil {
return err
}

// Add functions
engine.WithFunctions(func() []template.Function {
return []template.Function{
{
Name: "metadata",
Description: []string{
"Metadata function takes a path of the form \"plugin_name/path/to/data\"",
"and calls GET on the plugin with the path \"path/to/data\".",
"It's identical to the CLI command infrakit metadata cat ...",
},
Func: metadata_template.MetadataFunc(plugins),
},
}
})
view, err := engine.Render(nil)
if err != nil {
return err
Expand Down
48 changes: 48 additions & 0 deletions examples/flavor/swarm/flavor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"github.com/docker/docker/client"
"github.com/docker/go-connections/tlsconfig"
group_types "github.com/docker/infrakit/pkg/plugin/group/types"
metadata_plugin "github.com/docker/infrakit/pkg/plugin/metadata"
"github.com/docker/infrakit/pkg/spi/flavor"
"github.com/docker/infrakit/pkg/spi/instance"
"github.com/docker/infrakit/pkg/spi/metadata"
"github.com/docker/infrakit/pkg/template"
"github.com/docker/infrakit/pkg/types"
"github.com/docker/infrakit/pkg/util/docker"
Expand Down Expand Up @@ -64,6 +66,52 @@ type baseFlavor struct {
initScript *template.Template
}

// List implements the metadata.Plugin SPI's List method
func (s *baseFlavor) List(path metadata.Path) ([]string, error) {
docker, err := s.getDockerClient(Spec{
Docker: ConnectInfo{
Host: "unix:///var/run/docker.sock", // defaults to local socket
},
})
if err != nil {
return nil, err
}
status, node, err := swarmState(docker)
if err != nil {
return nil, err
}
data := map[string]interface{}{
"local": map[string]interface{}{
"status": status,
"node": node,
},
}
return metadata_plugin.List(path, data), nil
}

// Get implements the metadata.Plugin SPI's List method
func (s *baseFlavor) Get(path metadata.Path) (*types.Any, error) {
docker, err := s.getDockerClient(Spec{
Docker: ConnectInfo{
Host: "unix:///var/run/docker.sock", // defaults to local socket
},
})
if err != nil {
return nil, err
}
status, node, err := swarmState(docker)
if err != nil {
return nil, err
}
data := map[string]interface{}{
"local": map[string]interface{}{
"status": status,
"node": node,
},
}
return metadata_plugin.GetValue(path, data)
}

// Funcs implements the template.FunctionExporter interface that allows the RPC server to expose help on the
// functions it exports
func (s *baseFlavor) Funcs() []template.Function {
Expand Down
32 changes: 26 additions & 6 deletions examples/flavor/swarm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/infrakit/pkg/cli"
"github.com/docker/infrakit/pkg/discovery"
"github.com/docker/infrakit/pkg/plugin/metadata"
flavor_plugin "github.com/docker/infrakit/pkg/rpc/flavor"
"github.com/docker/infrakit/pkg/spi/flavor"
metadata_plugin "github.com/docker/infrakit/pkg/rpc/metadata"
flavor_spi "github.com/docker/infrakit/pkg/spi/flavor"
metadata_spi "github.com/docker/infrakit/pkg/spi/metadata"
"github.com/docker/infrakit/pkg/template"
"github.com/docker/infrakit/pkg/util/docker"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -48,11 +51,28 @@ func main() {
return err
}

cli.RunPlugin(*name, flavor_plugin.PluginServerWithTypes(
map[string]flavor.Plugin{
"manager": NewManagerFlavor(DockerClient, mt),
"worker": NewWorkerFlavor(DockerClient, wt),
}))
managerFlavor := NewManagerFlavor(DockerClient, mt)
workerFlavor := NewWorkerFlavor(DockerClient, wt)

cli.RunPlugin(*name,

// Metadata plugins
metadata_plugin.PluginServer(metadata.NewPluginFromData(map[string]interface{}{
"version": cli.Version,
"revision": cli.Revision,
"implements": flavor_spi.InterfaceSpec,
})).WithTypes(
map[string]metadata_spi.Plugin{
"manager": managerFlavor,
"worker": workerFlavor,
}),

// Flavor plugins
flavor_plugin.PluginServerWithTypes(
map[string]flavor_spi.Plugin{
"manager": managerFlavor,
"worker": workerFlavor,
}))
return nil
}

Expand Down
Loading