Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.

Commit 0e72770

Browse files
nwtDavid Chung
authored andcommitted
Bootstrapping and resources (#357)
Signed-off-by: Noah Treuhaft <[email protected]>
1 parent edad9dd commit 0e72770

File tree

23 files changed

+2225
-2
lines changed

23 files changed

+2225
-2
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ endif
115115
$(call build_binary,infrakit,github.com/docker/infrakit/cmd/cli)
116116
$(call build_binary,infrakit-manager,github.com/docker/infrakit/cmd/manager)
117117
$(call build_binary,infrakit-group-default,github.com/docker/infrakit/cmd/group)
118+
$(call build_binary,infrakit-resource,github.com/docker/infrakit/cmd/resource)
118119
$(call build_binary,infrakit-flavor-combo,github.com/docker/infrakit/examples/flavor/combo)
119120
$(call build_binary,infrakit-flavor-swarm,github.com/docker/infrakit/examples/flavor/swarm)
120121
$(call build_binary,infrakit-flavor-vanilla,github.com/docker/infrakit/examples/flavor/vanilla)

cmd/cli/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func main() {
4747
cmd.AddCommand(eventCommand(f))
4848
cmd.AddCommand(pluginCommand(f))
4949

50-
cmd.AddCommand(instancePluginCommand(f), groupPluginCommand(f), flavorPluginCommand(f))
50+
cmd.AddCommand(instancePluginCommand(f), groupPluginCommand(f), flavorPluginCommand(f), resourcePluginCommand(f))
5151

5252
err := cmd.Execute()
5353
if err != nil {

cmd/cli/resource.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
log "github.com/Sirupsen/logrus"
8+
"github.com/docker/infrakit/pkg/discovery"
9+
"github.com/docker/infrakit/pkg/plugin"
10+
resource_plugin "github.com/docker/infrakit/pkg/rpc/resource"
11+
"github.com/docker/infrakit/pkg/spi/resource"
12+
"github.com/docker/infrakit/pkg/template"
13+
"github.com/docker/infrakit/pkg/types"
14+
"github.com/spf13/cobra"
15+
)
16+
17+
func resourcePluginCommand(plugins func() discovery.Plugins) *cobra.Command {
18+
19+
var resourcePlugin resource.Plugin
20+
21+
cmd := &cobra.Command{
22+
Use: "resource",
23+
Short: "Access resource plugin",
24+
}
25+
name := cmd.PersistentFlags().String("name", "resource", "Name of plugin")
26+
cmd.PersistentPreRunE = func(c *cobra.Command, args []string) error {
27+
if err := upTree(c, func(x *cobra.Command, argv []string) error {
28+
if x.PersistentPreRunE != nil {
29+
return x.PersistentPreRunE(x, argv)
30+
}
31+
return nil
32+
}); err != nil {
33+
return err
34+
}
35+
36+
endpoint, err := plugins().Find(plugin.Name(*name))
37+
if err != nil {
38+
return err
39+
}
40+
41+
p, err := resource_plugin.NewClient(endpoint.Address)
42+
if err != nil {
43+
return err
44+
}
45+
resourcePlugin = p
46+
return nil
47+
}
48+
49+
commit := cobra.Command{
50+
Use: "commit <template URL>",
51+
Short: "commit a resource configuration specified by the URL",
52+
}
53+
commitPretend := commit.Flags().Bool("pretend", false, "Don't actually commit, only explain the commit")
54+
commit.RunE = func(cmd *cobra.Command, args []string) error {
55+
assertNotNil("no plugin", resourcePlugin)
56+
57+
if len(args) != 1 {
58+
cmd.Usage()
59+
os.Exit(1)
60+
}
61+
62+
spec, err := readSpecFromTemplateURL(args[0])
63+
if err != nil {
64+
return err
65+
}
66+
67+
details, err := resourcePlugin.Commit(*spec, *commitPretend)
68+
if err == nil {
69+
if *commitPretend {
70+
fmt.Printf("Committing %s would involve:\n%s\n", spec.ID, details)
71+
} else {
72+
fmt.Printf("Committed %s:\n%s\n", spec.ID, details)
73+
}
74+
}
75+
return err
76+
}
77+
cmd.AddCommand(&commit)
78+
79+
destroy := cobra.Command{
80+
Use: "destroy <template URL>",
81+
Short: "destroy a resource configuration specified by the URL",
82+
}
83+
destroyPretend := destroy.Flags().Bool("pretend", false, "Don't actually destroy, only explain the destroy")
84+
destroy.RunE = func(cmd *cobra.Command, args []string) error {
85+
assertNotNil("no plugin", resourcePlugin)
86+
87+
if len(args) != 1 {
88+
cmd.Usage()
89+
os.Exit(1)
90+
}
91+
92+
spec, err := readSpecFromTemplateURL(args[0])
93+
if err != nil {
94+
return err
95+
}
96+
97+
details, err := resourcePlugin.Destroy(*spec, *destroyPretend)
98+
if err == nil {
99+
if *destroyPretend {
100+
fmt.Printf("Destroying %s would involve:\n%s\n", spec.ID, details)
101+
} else {
102+
fmt.Printf("Destroyed %s:\n%s\n", spec.ID, details)
103+
}
104+
}
105+
return err
106+
}
107+
cmd.AddCommand(&destroy)
108+
109+
describe := cobra.Command{
110+
Use: "describe <template URL>",
111+
Short: "describe a resource configuration specified by the URL",
112+
}
113+
describe.RunE = func(cmd *cobra.Command, args []string) error {
114+
assertNotNil("no plugin", resourcePlugin)
115+
116+
if len(args) != 1 {
117+
cmd.Usage()
118+
os.Exit(1)
119+
}
120+
121+
spec, err := readSpecFromTemplateURL(args[0])
122+
if err != nil {
123+
return err
124+
}
125+
126+
details, err := resourcePlugin.DescribeResources(*spec)
127+
if err == nil {
128+
if len(details) > 0 {
129+
fmt.Println(details)
130+
}
131+
}
132+
return err
133+
}
134+
cmd.AddCommand(&describe)
135+
136+
return cmd
137+
}
138+
139+
func readSpecFromTemplateURL(templateURL string) (*resource.Spec, error) {
140+
log.Infof("Reading template from %v", templateURL)
141+
engine, err := template.NewTemplate(templateURL, template.Options{
142+
SocketDir: discovery.Dir(),
143+
})
144+
if err != nil {
145+
return nil, err
146+
}
147+
148+
engine.WithFunctions(func() []template.Function {
149+
return []template.Function{
150+
{Name: "resource", Func: func(s string) string { return fmt.Sprintf("{{ resource `%s` }}", s) }},
151+
}
152+
})
153+
154+
view, err := engine.Render(nil)
155+
if err != nil {
156+
return nil, err
157+
}
158+
159+
log.Debugln(view)
160+
161+
spec := resource.Spec{}
162+
if err := types.AnyString(view).Decode(&spec); err != nil {
163+
log.Warningln("Error parsing template")
164+
return nil, err
165+
}
166+
167+
return &spec, nil
168+
}

cmd/resource/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
InfraKit Resource Plugin
2+
========================
3+
4+
The Resource plugin works in conjuction with Instance plugins to manage collections of
5+
interdependent, named resources. Dependencies are expressed with the `resource "name"` template
6+
function, the output of which is the ID of the named resource.
7+
8+
## Running
9+
10+
Begin by building plugin [binaries](../../README.md#binaries).
11+
12+
The plugin may be started without any arguments and will default to using unix socket in
13+
`~/.infrakit/plugins` for communications with the CLI and other plugins:
14+
15+
```shell
16+
$ build/infrakit-resource
17+
INFO[0000] Listening at: ~/.infrakit/plugins/resource
18+
```
19+
20+
## Working with the Resource Plugin
21+
22+
Start the resource plugin as show above.
23+
24+
Start the `instance-file` plugin:
25+
```shell
26+
$ mkdir -p instances
27+
$ build/infrakit-instance-file --dir instances
28+
INFO[0000] Listening at: ~/.infrakit/plugins/instance-file
29+
INFO[0000] PID file at ~/.infrakit/plugins/instance-file.pid
30+
```
31+
32+
Save the following in a file named resources.json.
33+
```json
34+
{
35+
"ID": "Fancy Resources",
36+
"Properties": {
37+
"Resources": [
38+
{
39+
"ID": "A",
40+
"Plugin": "instance-file",
41+
"Properties": {}
42+
},
43+
{
44+
"ID": "B",
45+
"Plugin": "instance-file",
46+
"Properties": {
47+
"Note": "Depends on {{ resource `A` }}"
48+
}
49+
}
50+
]
51+
}
52+
}
53+
```
54+
55+
Commit resources.json:
56+
```shell
57+
$ build/infrakit resource commit file:$PWD/resources.json
58+
INFO[0000] Reading template from file:~/resources.json
59+
Committed Fancy Resources:
60+
Provisioned A (instance-9021654729849995625)
61+
Provisioned B (instance-2978607024592968517)
62+
```
63+
64+
Verify the presence of `A`'s ID in `B`:
65+
66+
```shell
67+
$ jq .Spec.Properties.Note instances/instance-2978607024592968517
68+
"Depends on instance-9021654729849995625"
69+
```

cmd/resource/main.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package main
2+
3+
import (
4+
"os"
5+
6+
log "github.com/Sirupsen/logrus"
7+
"github.com/docker/infrakit/pkg/cli"
8+
"github.com/docker/infrakit/pkg/discovery"
9+
"github.com/docker/infrakit/pkg/plugin"
10+
"github.com/docker/infrakit/pkg/plugin/resource"
11+
instance_client "github.com/docker/infrakit/pkg/rpc/instance"
12+
resource_server "github.com/docker/infrakit/pkg/rpc/resource"
13+
"github.com/docker/infrakit/pkg/spi/instance"
14+
"github.com/spf13/cobra"
15+
)
16+
17+
func main() {
18+
19+
cmd := &cobra.Command{
20+
Use: os.Args[0],
21+
Short: "Resource server",
22+
}
23+
name := cmd.Flags().String("name", "resource", "Plugin name to advertise for discovery")
24+
logLevel := cmd.Flags().Int("log", cli.DefaultLogLevel, "Logging level. 0 is least verbose. Max is 5")
25+
26+
cmd.RunE = func(c *cobra.Command, args []string) error {
27+
28+
cli.SetLogLevel(*logLevel)
29+
30+
plugins, err := discovery.NewPluginDiscovery()
31+
if err != nil {
32+
return err
33+
}
34+
35+
instancePluginLookup := func(n plugin.Name) (instance.Plugin, error) {
36+
endpoint, err := plugins.Find(n)
37+
if err != nil {
38+
return nil, err
39+
}
40+
return instance_client.NewClient(n, endpoint.Address)
41+
}
42+
43+
resourcePlugin := resource.NewResourcePlugin(instancePluginLookup)
44+
45+
cli.RunPlugin(*name, resource_server.PluginServer(resourcePlugin))
46+
47+
return nil
48+
}
49+
50+
cmd.AddCommand(cli.VersionCommand())
51+
52+
err := cmd.Execute()
53+
if err != nil {
54+
log.Error(err)
55+
os.Exit(1)
56+
}
57+
}

0 commit comments

Comments
 (0)