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

Commit 74bdaf6

Browse files
author
David Chung
authored
Kube support + bootstrapping (#714)
Signed-off-by: David Chung <[email protected]>
1 parent 79c9cbe commit 74bdaf6

File tree

14 files changed

+548
-137
lines changed

14 files changed

+548
-137
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
InfraKit
22
========
3-
3+
[![CircleCI](https://circleci.com/gh/docker/infrakit/tree/master.svg?style=svg&circle-token=50d2063f283f98b7d94746416c979af3102275b5)](https://circleci.com/gh/docker/infrakit/tree/master)
4+
<!--
45
[![Circle CI](https://circleci.com/gh/docker/infrakit.png?style=shield&circle-token=50d2063f283f98b7d94746416c979af3102275b5)](https://circleci.com/gh/docker/infrakit)
6+
-->
57
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/infrakit)](https://goreportcard.com/report/github.com/docker/infrakit)
68
<!--
79
[![codecov.io](https://codecov.io/github/docker/infrakit/coverage.svg?branch=master&token=z08ZKeIJfA)](https://codecov.io/github/docker/infrakit?branch=master)

cmd/infrakit/util/init/init.go

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
package init
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
"time"
8+
9+
"github.com/docker/infrakit/pkg/cli"
10+
"github.com/docker/infrakit/pkg/discovery"
11+
"github.com/docker/infrakit/pkg/launch"
12+
logutil "github.com/docker/infrakit/pkg/log"
13+
"github.com/docker/infrakit/pkg/plugin"
14+
group_types "github.com/docker/infrakit/pkg/plugin/group/types"
15+
flavor_rpc "github.com/docker/infrakit/pkg/rpc/flavor"
16+
run "github.com/docker/infrakit/pkg/run/manager"
17+
group_kind "github.com/docker/infrakit/pkg/run/v0/group"
18+
manager_kind "github.com/docker/infrakit/pkg/run/v0/manager"
19+
"github.com/docker/infrakit/pkg/spi/group"
20+
"github.com/docker/infrakit/pkg/spi/instance"
21+
"github.com/docker/infrakit/pkg/types"
22+
"github.com/spf13/cobra"
23+
)
24+
25+
var log = logutil.New("module", "util/init")
26+
27+
func startPlugins(plugins func() discovery.Plugins, services *cli.Services,
28+
configURL string, starts []string) (*run.Manager, error) {
29+
30+
parsedRules := []launch.Rule{}
31+
32+
if configURL != "" {
33+
buff, err := services.ProcessTemplate(configURL)
34+
if err != nil {
35+
return nil, err
36+
}
37+
view, err := services.ToJSON([]byte(buff))
38+
if err != nil {
39+
return nil, err
40+
}
41+
configs := types.AnyBytes(view)
42+
err = configs.Decode(&parsedRules)
43+
if err != nil {
44+
return nil, err
45+
}
46+
}
47+
48+
pluginManager, err := run.ManagePlugins(parsedRules, plugins, true, 5*time.Second)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
for _, arg := range starts {
54+
55+
p := strings.Split(arg, "=")
56+
execName := "inproc" // default is to use inprocess goroutine for running plugins
57+
if len(p) > 1 {
58+
execName = p[1]
59+
}
60+
61+
// the format is kind[:{plugin_name}][={os|inproc}]
62+
pp := strings.Split(p[0], ":")
63+
kind := pp[0]
64+
name := plugin.Name(kind)
65+
66+
// This is some special case for the legacy setup (pre v0.6)
67+
switch kind {
68+
case manager_kind.Kind:
69+
name = plugin.Name(manager_kind.LookupName)
70+
case group_kind.Kind:
71+
name = plugin.Name(group_kind.LookupName)
72+
}
73+
// customized by user as override
74+
if len(pp) > 1 {
75+
name = plugin.Name(pp[1])
76+
}
77+
78+
log.Info("Launching", "kind", kind, "name", name)
79+
err = pluginManager.Launch(execName, kind, name, nil)
80+
if err != nil {
81+
log.Warn("failed to launch", "exec", execName, "kind", kind, "name", name)
82+
}
83+
}
84+
return pluginManager, nil
85+
}
86+
87+
// Command returns the cobra command
88+
func Command(plugins func() discovery.Plugins) *cobra.Command {
89+
90+
services := cli.NewServices(plugins)
91+
92+
cmd := &cobra.Command{
93+
Use: "init <groups template URL | - >",
94+
Short: "Generates the init script",
95+
}
96+
97+
cmd.Flags().AddFlagSet(services.ProcessTemplateFlags)
98+
groupID := cmd.Flags().String("group-id", "", "Group ID")
99+
sequence := cmd.Flags().Uint("sequence", 0, "Sequence in the group")
100+
101+
configURL := cmd.Flags().String("config-url", "", "URL for the startup configs")
102+
starts := cmd.Flags().StringSlice("start", []string{}, "start spec for plugin just like infrakit plugin start")
103+
104+
debug := cmd.Flags().Bool("debug", false, "True to debug with lots of traces")
105+
106+
cmd.RunE = func(c *cobra.Command, args []string) error {
107+
108+
if len(args) != 1 {
109+
cmd.Usage()
110+
os.Exit(1)
111+
}
112+
113+
if !*debug {
114+
logutil.Configure(&logutil.Options{
115+
Level: 3,
116+
Stdout: false,
117+
Format: "term",
118+
CallFunc: true,
119+
})
120+
}
121+
122+
pluginManager, err := startPlugins(plugins, services, *configURL, *starts)
123+
if err != nil {
124+
return err
125+
}
126+
defer func() {
127+
pluginManager.TerminateAll()
128+
pluginManager.WaitForAllShutdown()
129+
pluginManager.Stop()
130+
}()
131+
132+
pluginManager.WaitStarting()
133+
134+
input, err := services.ReadFromStdinIfElse(
135+
func() bool { return args[0] == "-" },
136+
func() (string, error) { return services.ProcessTemplate(args[0]) },
137+
services.ToJSON,
138+
)
139+
if err != nil {
140+
return err
141+
}
142+
143+
// TODO - update the schema -- this matches the current Plugin/Properties schema
144+
type spec struct {
145+
Plugin plugin.Name
146+
Properties struct {
147+
ID group.ID
148+
Properties group_types.Spec
149+
}
150+
}
151+
152+
specs := []spec{}
153+
err = types.AnyString(input).Decode(&specs)
154+
if err != nil {
155+
return err
156+
}
157+
158+
var groupSpec *group_types.Spec
159+
for _, s := range specs {
160+
if string(s.Properties.ID) == *groupID {
161+
copy := s.Properties.Properties
162+
groupSpec = &copy
163+
break
164+
}
165+
}
166+
167+
if groupSpec == nil {
168+
return fmt.Errorf("no such group: %v", *groupID)
169+
}
170+
171+
// Get the flavor properties and use that to call the prepare of the Flavor to generate the init
172+
endpoint, err := plugins().Find(groupSpec.Flavor.Plugin)
173+
if err != nil {
174+
return err
175+
}
176+
177+
flavorPlugin, err := flavor_rpc.NewClient(groupSpec.Flavor.Plugin, endpoint.Address)
178+
if err != nil {
179+
return err
180+
}
181+
182+
cli.MustNotNil(flavorPlugin, "flavor plugin not found", "name", groupSpec.Flavor.Plugin.String())
183+
184+
instanceSpec := instance.Spec{}
185+
if lidLen := len(groupSpec.Allocation.LogicalIDs); lidLen > 0 {
186+
187+
if int(*sequence) >= lidLen {
188+
return fmt.Errorf("out of bound sequence index: %v in %v", *sequence, groupSpec.Allocation.LogicalIDs)
189+
}
190+
191+
lid := instance.LogicalID(groupSpec.Allocation.LogicalIDs[*sequence])
192+
instanceSpec.LogicalID = &lid
193+
}
194+
195+
instanceSpec, err = flavorPlugin.Prepare(groupSpec.Flavor.Properties, instanceSpec,
196+
groupSpec.Allocation,
197+
group_types.Index{Group: group.ID(*groupID), Sequence: *sequence})
198+
199+
if err != nil {
200+
return err
201+
}
202+
203+
// Here the Init may contain template vars since in the evaluation of the manager / worker
204+
// init templates, we do not propapage the vars set in the command line here.
205+
// So we need to evaluate the entire Init as a template again.
206+
// TODO - this is really better addressed via some formal globally available var store/section
207+
// that is always available to the templates at the schema / document level.
208+
applied, err := services.ProcessTemplate("str://" + instanceSpec.Init)
209+
if err != nil {
210+
return err
211+
}
212+
213+
fmt.Print(applied)
214+
215+
return nil
216+
}
217+
218+
return cmd
219+
}

cmd/infrakit/util/util.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package util
22

33
import (
44
"github.com/docker/infrakit/cmd/infrakit/base"
5+
init_cmd "github.com/docker/infrakit/cmd/infrakit/util/init"
56
"github.com/docker/infrakit/cmd/infrakit/util/mux"
67
"github.com/docker/infrakit/pkg/discovery"
78
"github.com/docker/infrakit/pkg/log"
@@ -24,6 +25,7 @@ func Command(plugins func() discovery.Plugins) *cobra.Command {
2425

2526
util.AddCommand(
2627
mux.Command(plugins),
28+
init_cmd.Command(plugins),
2729
fileServerCommand(plugins),
2830
trackCommand(plugins),
2931
)

dockerfiles/Dockerfile.bundle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ RUN apk add --update wget ca-certificates openssl libvirt-dev openssh
55
RUN mkdir -p /infrakit/plugins /infrakit/configs /infrakit/logs /infrakit/cli /infrakit/instance/terraform
66

77
VOLUME /infrakit
8-
8+
WORKDIR /infrakit
99
ENV INFRAKIT_HOME /infrakit
1010

1111
# Defined in pkg/discovery

pkg/cli/services.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func NewServices(plugins func() discovery.Plugins) *Services {
5757
}
5858

5959
// ProcessTemplateFunc is the function that processes the template at url and returns view or error.
60-
type ProcessTemplateFunc func(url string) (rendered string, err error)
60+
type ProcessTemplateFunc func(url string, ctx ...interface{}) (rendered string, err error)
6161

6262
// ToJSONFunc converts the input buffer to json format
6363
type ToJSONFunc func(in []byte) (json []byte, err error)
@@ -157,7 +157,7 @@ func templateProcessor(plugins func() discovery.Plugins) (*pflag.FlagSet, ToJSON
157157

158158
},
159159
// ProcessTemplateFunc
160-
func(url string) (view string, err error) {
160+
func(url string, ctx ...interface{}) (view string, err error) {
161161

162162
if !strings.Contains(url, "://") {
163163
p := url
@@ -199,7 +199,11 @@ func templateProcessor(plugins func() discovery.Plugins) (*pflag.FlagSet, ToJSON
199199

200200
configureTemplate(engine, plugins)
201201

202-
view, err = engine.Render(nil)
202+
contextObject := (interface{})(nil)
203+
if len(ctx) == 1 {
204+
contextObject = ctx[0]
205+
}
206+
view, err = engine.Render(contextObject)
203207
if err != nil {
204208
return
205209
}

0 commit comments

Comments
 (0)