Skip to content

Commit 5920a42

Browse files
committed
Start API server only once
Signed-off-by: David Gageot <[email protected]>
1 parent 734e5e3 commit 5920a42

File tree

13 files changed

+136
-164
lines changed

13 files changed

+136
-164
lines changed

cmd/skaffold/app/cmd/cmd.go

+55-32
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/color"
2727
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
2828
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
29+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
30+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/server"
2931
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/update"
3032
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
3133
"github.com/pkg/errors"
@@ -44,47 +46,68 @@ var (
4446

4547
func NewSkaffoldCommand(out, err io.Writer) *cobra.Command {
4648
updateMsg := make(chan string)
49+
var shutdownAPIServer func() error
4750

4851
rootCmd := &cobra.Command{
4952
Use: "skaffold",
5053
Short: "A tool that facilitates continuous development for Kubernetes applications.",
5154
SilenceErrors: true,
52-
}
53-
54-
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
55-
opts.Command = cmd.Use
55+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
56+
cmd.Root().SilenceUsage = true
5657

57-
if err := SetUpLogs(err, v); err != nil {
58-
return err
59-
}
58+
opts.Command = cmd.Use
6059

61-
if forceColors {
62-
color.ForceColors()
63-
}
60+
// Setup colors
61+
if forceColors {
62+
color.ForceColors()
63+
}
64+
color.OverwriteDefault(color.Color(defaultColor))
6465

65-
rootCmd.SilenceUsage = true
66-
logrus.Infof("Skaffold %+v", version.Get())
67-
color.OverwriteDefault(color.Color(defaultColor))
66+
// Setup logs
67+
if err := setUpLogs(err, v); err != nil {
68+
return err
69+
}
6870

69-
if quietFlag {
70-
logrus.Debugf("Update check is disabled because of quiet mode")
71-
} else {
72-
go func() {
73-
if err := updateCheck(updateMsg); err != nil {
74-
logrus.Infof("update check failed: %s", err)
75-
}
76-
}()
77-
}
71+
// Start API Server
72+
if cmd.Use == "dev" {
73+
// TODO(dgageot): api server is always started in dev mode, right now.
74+
// It should instead default to true.
75+
opts.EnableRPC = true
76+
}
77+
shutdown, err := server.Initialize(opts)
78+
if err != nil {
79+
return errors.Wrap(err, "initializing api server")
80+
}
81+
shutdownAPIServer = shutdown
82+
83+
// Print version
84+
version := version.Get()
85+
logrus.Infof("Skaffold %+v", version)
86+
event.LogSkaffoldMetadata(version)
87+
88+
if quietFlag {
89+
logrus.Debugf("Update check is disabled because of quiet mode")
90+
} else {
91+
go func() {
92+
if err := updateCheck(updateMsg); err != nil {
93+
logrus.Infof("update check failed: %s", err)
94+
}
95+
}()
96+
}
7897

79-
return nil
80-
}
98+
return nil
99+
},
100+
PersistentPostRun: func(cmd *cobra.Command, args []string) {
101+
select {
102+
case msg := <-updateMsg:
103+
fmt.Fprintf(out, "%s\n", msg)
104+
default:
105+
}
81106

82-
rootCmd.PersistentPostRun = func(cmd *cobra.Command, args []string) {
83-
select {
84-
case msg := <-updateMsg:
85-
fmt.Fprintf(out, "%s\n", msg)
86-
default:
87-
}
107+
if shutdownAPIServer != nil {
108+
shutdownAPIServer()
109+
}
110+
},
88111
}
89112

90113
SetUpFlags()
@@ -158,9 +181,9 @@ func FlagToEnvVarName(f *pflag.Flag) string {
158181
return fmt.Sprintf("SKAFFOLD_%s", strings.Replace(strings.ToUpper(f.Name), "-", "_", -1))
159182
}
160183

161-
func SetUpLogs(out io.Writer, level string) error {
184+
func setUpLogs(out io.Writer, level string) error {
162185
logrus.SetOutput(out)
163-
lvl, err := logrus.ParseLevel(v)
186+
lvl, err := logrus.ParseLevel(level)
164187
if err != nil {
165188
return errors.Wrap(err, "parsing log level")
166189
}

cmd/skaffold/app/cmd/dev.go

-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ func NewCmdDev(out io.Writer) *cobra.Command {
4343
}
4444

4545
func doDev(ctx context.Context, out io.Writer) error {
46-
opts.EnableRPC = true
47-
4846
cleanup := func() {}
4947
if opts.Cleanup {
5048
defer func() {

cmd/skaffold/app/cmd/runner.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ func withRunner(ctx context.Context, action func(runner.Runner, *latest.Skaffold
4242
if err != nil {
4343
return errors.Wrap(err, "creating runner")
4444
}
45-
defer runner.Stop()
4645

4746
err = action(runner, config)
47+
4848
return alwaysSucceedWhenCancelled(ctx, err)
4949
}
5050

pkg/skaffold/build/local/local_test.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,12 @@ func TestLocalRun(t *testing.T) {
222222
fakeWarner := &warnings.Collect{}
223223
t.Override(&warnings.Printf, fakeWarner.Warnf)
224224

225-
cfg := latest.BuildConfig{
225+
event.InitializeState(latest.BuildConfig{
226226
BuildType: latest.BuildType{
227227
LocalBuild: &latest.LocalBuild{},
228228
},
229-
}
230-
event.InitializeState(&runcontext.RunContext{
231-
Cfg: &latest.Pipeline{
232-
Build: cfg,
233-
},
234-
Opts: &config.SkaffoldOptions{},
235229
})
230+
236231
l := Builder{
237232
cfg: &latest.LocalBuild{},
238233
localDocker: docker.NewLocalDaemon(&test.api, nil, false, map[string]bool{}),

pkg/skaffold/build/sequence_test.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ import (
2525
"testing"
2626

2727
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag"
28-
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
2928
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
30-
runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/context"
3129
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
3230
"github.com/GoogleContainerTools/skaffold/testutil"
3331
)
@@ -143,15 +141,9 @@ func (t *concatTagger) doBuild(ctx context.Context, out io.Writer, artifact *lat
143141
}
144142

145143
func initializeEvents() {
146-
cfg := latest.BuildConfig{
144+
event.InitializeState(latest.BuildConfig{
147145
BuildType: latest.BuildType{
148146
LocalBuild: &latest.LocalBuild{},
149147
},
150-
}
151-
event.InitializeState(&runcontext.RunContext{
152-
Cfg: &latest.Pipeline{
153-
Build: cfg,
154-
},
155-
Opts: &config.SkaffoldOptions{},
156148
})
157149
}

pkg/skaffold/deploy/helm_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ func TestHelmDeploy(t *testing.T) {
459459
testutil.Run(t, test.description, func(t *testutil.T) {
460460
t.Override(&util.DefaultExecCommand, test.cmd)
461461

462-
event.InitializeState(test.runContext)
462+
event.InitializeState(test.runContext.Cfg.Build)
463463
err := NewHelmDeployer(test.runContext).Deploy(context.Background(), ioutil.Discard, test.builds, nil)
464464

465465
t.CheckError(test.shouldErr, err)

pkg/skaffold/event/event.go

+12-16
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"fmt"
2222
"sync"
2323

24-
runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/context"
2524
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
2625
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/server/proto"
2726
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
@@ -35,10 +34,7 @@ const (
3534
Failed = "Failed"
3635
)
3736

38-
var (
39-
handler *eventHandler
40-
once sync.Once
41-
)
37+
var handler = &eventHandler{}
4238

4339
type eventHandler struct {
4440
eventLog []proto.LogEntry
@@ -126,12 +122,10 @@ func (ev *eventHandler) forEachEvent(callback func(*proto.LogEntry) error) error
126122
return <-listener.errors
127123
}
128124

129-
func emptyState(build *latest.BuildConfig) proto.State {
125+
func emptyState(build latest.BuildConfig) proto.State {
130126
builds := map[string]string{}
131-
if build != nil {
132-
for _, a := range build.Artifacts {
133-
builds[a.ImageName] = NotStarted
134-
}
127+
for _, a := range build.Artifacts {
128+
builds[a.ImageName] = NotStarted
135129
}
136130

137131
return proto.State{
@@ -146,12 +140,8 @@ func emptyState(build *latest.BuildConfig) proto.State {
146140
}
147141

148142
// InitializeState instantiates the global state of the skaffold runner, as well as the event log.
149-
func InitializeState(runCtx *runcontext.RunContext) {
150-
once.Do(func() {
151-
handler = &eventHandler{
152-
state: emptyState(&runCtx.Cfg.Build),
153-
}
154-
})
143+
func InitializeState(build latest.BuildConfig) {
144+
handler.setState(emptyState(build))
155145
}
156146

157147
// DeployInProgress notifies that a deployment has been started.
@@ -202,6 +192,12 @@ func PortForwarded(localPort, remotePort int32, podName, containerName, namespac
202192
})
203193
}
204194

195+
func (ev *eventHandler) setState(state proto.State) {
196+
ev.stateLock.Lock()
197+
ev.state = state
198+
ev.stateLock.Unlock()
199+
}
200+
205201
func (ev *eventHandler) handleDeployEvent(e *proto.DeployEvent) {
206202
go ev.handle(&proto.Event{
207203
EventType: &proto.Event_DeployEvent{

pkg/skaffold/event/event_test.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestGetLogEvents(t *testing.T) {
5555

5656
func TestGetState(t *testing.T) {
5757
ev := &eventHandler{
58-
state: emptyState(nil),
58+
state: emptyState(latest.BuildConfig{}),
5959
}
6060

6161
ev.stateLock.Lock()
@@ -68,10 +68,10 @@ func TestGetState(t *testing.T) {
6868
}
6969

7070
func TestDeployInProgress(t *testing.T) {
71-
defer func() { handler = nil }()
71+
defer func() { handler = &eventHandler{} }()
7272

7373
handler = &eventHandler{
74-
state: emptyState(nil),
74+
state: emptyState(latest.BuildConfig{}),
7575
}
7676

7777
wait(t, func() bool { return handler.getState().DeployState.Status == NotStarted })
@@ -80,10 +80,10 @@ func TestDeployInProgress(t *testing.T) {
8080
}
8181

8282
func TestDeployFailed(t *testing.T) {
83-
defer func() { handler = nil }()
83+
defer func() { handler = &eventHandler{} }()
8484

8585
handler = &eventHandler{
86-
state: emptyState(nil),
86+
state: emptyState(latest.BuildConfig{}),
8787
}
8888

8989
wait(t, func() bool { return handler.getState().DeployState.Status == NotStarted })
@@ -92,10 +92,10 @@ func TestDeployFailed(t *testing.T) {
9292
}
9393

9494
func TestDeployComplete(t *testing.T) {
95-
defer func() { handler = nil }()
95+
defer func() { handler = &eventHandler{} }()
9696

9797
handler = &eventHandler{
98-
state: emptyState(nil),
98+
state: emptyState(latest.BuildConfig{}),
9999
}
100100

101101
wait(t, func() bool { return handler.getState().DeployState.Status == NotStarted })
@@ -104,10 +104,10 @@ func TestDeployComplete(t *testing.T) {
104104
}
105105

106106
func TestBuildInProgress(t *testing.T) {
107-
defer func() { handler = nil }()
107+
defer func() { handler = &eventHandler{} }()
108108

109109
handler = &eventHandler{
110-
state: emptyState(&latest.BuildConfig{
110+
state: emptyState(latest.BuildConfig{
111111
Artifacts: []*latest.Artifact{{
112112
ImageName: "img",
113113
}},
@@ -120,10 +120,10 @@ func TestBuildInProgress(t *testing.T) {
120120
}
121121

122122
func TestBuildFailed(t *testing.T) {
123-
defer func() { handler = nil }()
123+
defer func() { handler = &eventHandler{} }()
124124

125125
handler = &eventHandler{
126-
state: emptyState(&latest.BuildConfig{
126+
state: emptyState(latest.BuildConfig{
127127
Artifacts: []*latest.Artifact{{
128128
ImageName: "img",
129129
}},
@@ -136,10 +136,10 @@ func TestBuildFailed(t *testing.T) {
136136
}
137137

138138
func TestBuildComplete(t *testing.T) {
139-
defer func() { handler = nil }()
139+
defer func() { handler = &eventHandler{} }()
140140

141141
handler = &eventHandler{
142-
state: emptyState(&latest.BuildConfig{
142+
state: emptyState(latest.BuildConfig{
143143
Artifacts: []*latest.Artifact{{
144144
ImageName: "img",
145145
}},
@@ -152,10 +152,10 @@ func TestBuildComplete(t *testing.T) {
152152
}
153153

154154
func TestPortForwarded(t *testing.T) {
155-
defer func() { handler = nil }()
155+
defer func() { handler = &eventHandler{} }()
156156

157157
handler = &eventHandler{
158-
state: emptyState(nil),
158+
state: emptyState(latest.BuildConfig{}),
159159
}
160160

161161
wait(t, func() bool { return handler.getState().ForwardedPorts["container"] == nil })

pkg/skaffold/kubernetes/portforward/pod_forwarder_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727

2828
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
2929
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes"
30-
runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/context"
3130
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
3231
"github.com/GoogleContainerTools/skaffold/testutil"
3332
v1 "k8s.io/api/core/v1"
@@ -436,7 +435,7 @@ func TestAutomaticPortForwardPod(t *testing.T) {
436435
}
437436
for _, test := range tests {
438437
testutil.Run(t, test.description, func(t *testutil.T) {
439-
event.InitializeState(&runcontext.RunContext{Cfg: &latest.Pipeline{Build: latest.BuildConfig{}}})
438+
event.InitializeState(latest.BuildConfig{})
440439
taken := map[int]struct{}{}
441440

442441
forwardingTimeoutTime = time.Second
@@ -499,7 +498,7 @@ func TestStartPodForwarder(t *testing.T) {
499498

500499
for _, test := range tests {
501500
t.Run(test.description, func(t *testing.T) {
502-
event.InitializeState(&runcontext.RunContext{Cfg: &latest.Pipeline{Build: latest.BuildConfig{}}})
501+
event.InitializeState(latest.BuildConfig{})
503502
client := fakekubeclientset.NewSimpleClientset(&v1.Pod{})
504503
fakeWatcher := watch.NewRaceFreeFake()
505504
client.PrependWatchReactor("*", testutil.SetupFakeWatcher(fakeWatcher))

0 commit comments

Comments
 (0)