Skip to content

Commit d2c7cf5

Browse files
committed
refactor: improve logs & context handling
1 parent 6c095e2 commit d2c7cf5

19 files changed

Lines changed: 250 additions & 116 deletions

File tree

e2e/tests/build/build.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ var _ = DevSpaceDescribe("build", func() {
5757
framework.ExpectNoError(err)
5858

5959
// create devspace docker client to access docker APIs
60-
devspaceDockerClient, err := docker.NewClient(log)
60+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
6161
framework.ExpectNoError(err)
6262

6363
dockerClient := devspaceDockerClient.DockerAPIClient()
@@ -93,7 +93,7 @@ var _ = DevSpaceDescribe("build", func() {
9393
framework.ExpectNoError(err)
9494

9595
// create devspace docker client to access docker APIs
96-
devspaceDockerClient, err := docker.NewClient(log)
96+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
9797
framework.ExpectNoError(err)
9898

9999
dockerClient := devspaceDockerClient.DockerAPIClient()
@@ -143,7 +143,7 @@ var _ = DevSpaceDescribe("build", func() {
143143
framework.ExpectNoError(err)
144144

145145
// create devspace docker client to access docker APIs
146-
devspaceDockerClient, err := docker.NewClient(log)
146+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
147147
framework.ExpectNoError(err)
148148

149149
dockerClient := devspaceDockerClient.DockerAPIClient()
@@ -177,7 +177,7 @@ var _ = DevSpaceDescribe("build", func() {
177177
framework.ExpectNoError(err)
178178

179179
// create devspace docker client to access docker APIs
180-
devspaceDockerClient, err := docker.NewClient(log)
180+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
181181
framework.ExpectNoError(err)
182182

183183
dockerClient := devspaceDockerClient.DockerAPIClient()
@@ -241,7 +241,7 @@ var _ = DevSpaceDescribe("build", func() {
241241
framework.ExpectNoError(err)
242242

243243
// create devspace docker client to access docker APIs
244-
devspaceDockerClient, err := docker.NewClient(log)
244+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
245245
framework.ExpectNoError(err)
246246

247247
dockerClient := devspaceDockerClient.DockerAPIClient()
@@ -305,7 +305,7 @@ var _ = DevSpaceDescribe("build", func() {
305305
framework.ExpectNoError(err)
306306

307307
// create devspace docker client to access docker APIs
308-
devspaceDockerClient, err := docker.NewClient(log)
308+
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
309309
framework.ExpectNoError(err)
310310

311311
dockerClient := devspaceDockerClient.DockerAPIClient()

pkg/devspace/configure/image.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
const dockerHubHostname = "hub.docker.com"
2525

2626
// AddImage adds an image to the provided config
27-
func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string, languageHandler *generator.LanguageHandler) error {
27+
func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string) error {
2828
var (
2929
useDockerHub = "Use " + dockerHubHostname
3030
useGithubRegistry = "Use GitHub image registry"

pkg/devspace/devpod/devpod.go

Lines changed: 111 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ package devpod
33
import (
44
"context"
55
"fmt"
6+
"github.com/mgutz/ansi"
67
"io"
8+
kerrors "k8s.io/apimachinery/pkg/api/errors"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/util/wait"
711
"net/http"
812
"os"
913
syncpkg "sync"
@@ -64,13 +68,14 @@ func newDevPod() *devPod {
6468

6569
func (d *devPod) Start(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, options Options) error {
6670
d.m.Lock()
67-
defer d.m.Unlock()
68-
6971
if d.cancel != nil {
72+
d.m.Unlock()
7073
return errors.Errorf("dev pod is already running, please stop it before starting")
7174
}
75+
7276
d.cancelCtx, d.cancel = context.WithCancel(ctx.Context)
7377
ctx = ctx.WithContext(d.cancelCtx)
78+
d.m.Unlock()
7479

7580
// log devpod to console if debug
7681
if ctx.Log.GetLevel() == logrus.DebugLevel {
@@ -83,8 +88,7 @@ func (d *devPod) Start(ctx *devspacecontext.Context, devPodConfig *latest.DevPod
8388
// start the dev pod
8489
err := d.startWithRetry(ctx, devPodConfig, options)
8590
if err != nil {
86-
d.cancel()
87-
<-d.done
91+
d.Stop()
8892
return err
8993
}
9094

@@ -104,57 +108,70 @@ func (d *devPod) Done() <-chan struct{} {
104108

105109
func (d *devPod) Stop() {
106110
d.m.Lock()
107-
defer d.m.Lock()
108-
109111
if d.cancel != nil {
110112
d.cancel()
111-
<-d.done
112113
}
114+
d.m.Unlock()
115+
<-d.done
113116
}
114117

115118
func (d *devPod) startWithRetry(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, options Options) error {
116119
t := &tomb.Tomb{}
117120

118121
go func(ctx *devspacecontext.Context) {
122+
// wait for parent context cancel
123+
// or that the DevPod is done
119124
select {
120125
case <-ctx.Context.Done():
126+
case <-t.Dead():
127+
}
128+
129+
if ctx.IsDone() {
121130
<-t.Dead()
122131
close(d.done)
123132
return
124-
case <-t.Dead():
125-
if ctx.IsDone() {
126-
close(d.done)
127-
return
128-
}
129-
130-
// try restarting the dev pod if it has stopped because of
131-
// a lost connection
132-
if _, ok := t.Err().(DevPodLostConnection); ok {
133-
for {
134-
err := d.startWithRetry(ctx, devPodConfig, options)
135-
if err != nil {
136-
if ctx.IsDone() {
137-
return
138-
}
133+
}
139134

140-
ctx.Log.Infof("Restart dev %s because of: %v", devPodConfig.Name, err)
141-
select {
142-
case <-ctx.Context.Done():
143-
return
144-
case <-time.After(time.Second * 10):
145-
continue
146-
}
135+
// check if pod was terminated
136+
d.m.Lock()
137+
selectedPod := d.selectedPod
138+
d.selectedPod = nil
139+
d.m.Unlock()
140+
141+
// check if we need to restart
142+
if selectedPod != nil {
143+
shouldTerminate := false
144+
err := wait.PollImmediateUntil(time.Second, func() (bool, error) {
145+
pod, err := ctx.KubeClient.KubeClient().CoreV1().Pods(selectedPod.Pod.Namespace).Get(ctx.Context, selectedPod.Pod.Name, metav1.GetOptions{})
146+
if err != nil {
147+
if kerrors.IsNotFound(err) {
148+
d.restart(ctx, devPodConfig, options)
149+
return true, nil
147150
}
148151

149-
return
152+
// this case means there might be problems with internet
153+
ctx.Log.Debugf("error trying to retrieve pod: %v", err)
154+
return false, nil
155+
} else if pod.DeletionTimestamp != nil {
156+
d.restart(ctx, devPodConfig, options)
157+
return true, nil
150158
}
151-
} else {
152-
d.m.Lock()
153-
d.err = t.Err()
154-
d.m.Unlock()
155-
close(d.done)
159+
160+
shouldTerminate = true
161+
return true, nil
162+
}, ctx.Context.Done())
163+
if err != nil && err != context.Canceled {
164+
ctx.Log.Errorf("error restarting dev: %v", err)
165+
}
166+
if !shouldTerminate {
167+
return
156168
}
157169
}
170+
171+
d.m.Lock()
172+
d.err = t.Err()
173+
d.m.Unlock()
174+
close(d.done)
158175
}(ctx)
159176

160177
// Create a new tomb and run it
@@ -170,6 +187,27 @@ func (d *devPod) startWithRetry(ctx *devspacecontext.Context, devPodConfig *late
170187
return nil
171188
}
172189

190+
func (d *devPod) restart(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, options Options) {
191+
for {
192+
err := d.startWithRetry(ctx, devPodConfig, options)
193+
if err != nil {
194+
if ctx.IsDone() {
195+
return
196+
}
197+
198+
ctx.Log.Infof("Restart dev %s because of: %v", devPodConfig.Name, err)
199+
select {
200+
case <-ctx.Context.Done():
201+
return
202+
case <-time.After(time.Second * 10):
203+
continue
204+
}
205+
}
206+
207+
return
208+
}
209+
}
210+
173211
func (d *devPod) start(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, opts Options, parent *tomb.Tomb) error {
174212
// check first if we need to replace the pod
175213
if !opts.DisablePodReplace && needPodReplace(devPodConfig) {
@@ -204,14 +242,20 @@ func (d *devPod) start(ctx *devspacecontext.Context, devPodConfig *latest.DevPod
204242
WithWaitingStrategy(targetselector.NewUntilNewestRunningWaitingStrategy(time.Millisecond * 500)).
205243
WithSkipInitContainers(true)
206244
var err error
207-
d.selectedPod, err = targetselector.NewTargetSelector(options).SelectSingleContainer(ctx.Context, ctx.KubeClient, ctx.Log)
245+
selectedPod, err := targetselector.NewTargetSelector(options).SelectSingleContainer(ctx.Context, ctx.KubeClient, ctx.Log)
208246
if err != nil {
209247
return errors.Wrap(err, "waiting for pod to become ready")
210248
}
211-
ctx.Log.Debugf("Selected pod:container %s:%s", d.selectedPod.Pod.Name, d.selectedPod.Container.Name)
249+
ctx.Log.Infof("Selected %s (%s)", ansi.Color(fmt.Sprintf("%s:%s", selectedPod.Pod.Name, selectedPod.Container.Name), "yellow+b"), ansi.Color("pod:container", "white+b"))
250+
251+
// set selected pod
252+
d.m.Lock()
253+
d.selectedPod = selectedPod
254+
d.m.Unlock()
212255

213256
// Run dev.open configs
214257
if !opts.DisableOpen {
258+
ctx := ctx.WithLogger(ctx.Log.WithPrefixColor("open ", "yellow+b"))
215259
for _, openConfig := range devPodConfig.Open {
216260
if openConfig.URL != "" {
217261
url := openConfig.URL
@@ -239,34 +283,35 @@ func (d *devPod) start(ctx *devspacecontext.Context, devPodConfig *latest.DevPod
239283
}
240284

241285
// start sync and port forwarding
242-
err = d.startServices(ctx, devPodConfig, newTargetSelector(d.selectedPod.Pod.Name, d.selectedPod.Pod.Namespace, d.selectedPod.Container.Name, parent), opts, parent)
286+
err = d.startServices(ctx, devPodConfig, newTargetSelector(selectedPod.Pod.Name, selectedPod.Pod.Namespace, selectedPod.Container.Name, parent), opts, parent)
243287
if err != nil {
244288
return err
245289
}
246290

247291
// start logs
248292
terminalDevContainer := d.getTerminalDevContainer(devPodConfig)
249293
if terminalDevContainer != nil {
250-
return d.startTerminal(ctx, terminalDevContainer, opts, parent)
294+
return d.startTerminal(ctx, terminalDevContainer, opts, selectedPod, parent)
251295
}
252296

253297
// start attach if defined
254298
attachDevContainer := d.getAttachDevContainer(devPodConfig)
255299
if attachDevContainer != nil {
256-
return d.startAttach(ctx, attachDevContainer, opts, parent)
300+
return d.startAttach(ctx, attachDevContainer, opts, selectedPod, parent)
257301
}
258302

259-
return d.startLogs(ctx, devPodConfig, parent)
303+
return d.startLogs(ctx, devPodConfig, selectedPod, parent)
260304
}
261305

262-
func (d *devPod) startLogs(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, parent *tomb.Tomb) error {
306+
func (d *devPod) startLogs(ctx *devspacecontext.Context, devPodConfig *latest.DevPod, selectedPod *selector.SelectedPodContainer, parent *tomb.Tomb) error {
307+
ctx = ctx.WithLogger(ctx.Log.WithPrefixColor("logs ", "yellow+b"))
263308
loader.EachDevContainer(devPodConfig, func(devContainer *latest.DevContainer) bool {
264309
if devContainer.Logs == nil || (devContainer.Logs.Enabled != nil && !*devContainer.Logs.Enabled) {
265310
return true
266311
}
267312

268313
parent.Go(func() error {
269-
return logs.StartLogs(ctx, devContainer, newTargetSelector(d.selectedPod.Pod.Name, d.selectedPod.Pod.Namespace, d.selectedPod.Container.Name, parent))
314+
return logs.StartLogs(ctx, devContainer, newTargetSelector(selectedPod.Pod.Name, selectedPod.Pod.Namespace, selectedPod.Container.Name, parent))
270315
})
271316

272317
return true
@@ -303,7 +348,7 @@ func (d *devPod) getTerminalDevContainer(devPodConfig *latest.DevPod) *latest.De
303348
return devContainer
304349
}
305350

306-
func (d *devPod) startAttach(ctx *devspacecontext.Context, devContainer *latest.DevContainer, opts Options, parent *tomb.Tomb) error {
351+
func (d *devPod) startAttach(ctx *devspacecontext.Context, devContainer *latest.DevContainer, opts Options, selectedPod *selector.SelectedPodContainer, parent *tomb.Tomb) error {
307352
parent.Go(func() error {
308353
id, err := logpkg.AcquireGlobalSilence()
309354
if err != nil {
@@ -312,10 +357,11 @@ func (d *devPod) startAttach(ctx *devspacecontext.Context, devContainer *latest.
312357
defer logpkg.ReleaseGlobalSilence(id)
313358

314359
// make sure the global log is silent
360+
ctx = ctx.WithLogger(ctx.Log.WithPrefixColor("attach ", "yellow+b"))
315361
err = attach.StartAttach(
316362
ctx,
317363
devContainer,
318-
newTargetSelector(d.selectedPod.Pod.Name, d.selectedPod.Pod.Namespace, d.selectedPod.Container.Name, parent),
364+
newTargetSelector(selectedPod.Pod.Name, selectedPod.Pod.Namespace, selectedPod.Container.Name, parent),
319365
DefaultTerminalStdout,
320366
DefaultTerminalStderr,
321367
DefaultTerminalStdin,
@@ -325,6 +371,11 @@ func (d *devPod) startAttach(ctx *devspacecontext.Context, devContainer *latest.
325371
return errors.Wrap(err, "error in attach")
326372
}
327373

374+
// if context is done we just return
375+
if ctx.IsDone() {
376+
return nil
377+
}
378+
328379
// kill ourselves here
329380
if !opts.ContinueOnTerminalExit && opts.KillApplication != nil {
330381
go opts.KillApplication()
@@ -337,7 +388,7 @@ func (d *devPod) startAttach(ctx *devspacecontext.Context, devContainer *latest.
337388
return nil
338389
}
339390

340-
func (d *devPod) startTerminal(ctx *devspacecontext.Context, devContainer *latest.DevContainer, opts Options, parent *tomb.Tomb) error {
391+
func (d *devPod) startTerminal(ctx *devspacecontext.Context, devContainer *latest.DevContainer, opts Options, selectedPod *selector.SelectedPodContainer, parent *tomb.Tomb) error {
341392
parent.Go(func() error {
342393
id, err := logpkg.AcquireGlobalSilence()
343394
if err != nil {
@@ -346,10 +397,11 @@ func (d *devPod) startTerminal(ctx *devspacecontext.Context, devContainer *lates
346397
defer logpkg.ReleaseGlobalSilence(id)
347398

348399
// make sure the global log is silent
400+
ctx = ctx.WithLogger(ctx.Log.WithPrefixColor("term ", "yellow+b"))
349401
err = terminal.StartTerminal(
350402
ctx,
351403
devContainer,
352-
newTargetSelector(d.selectedPod.Pod.Name, d.selectedPod.Pod.Namespace, d.selectedPod.Container.Name, parent),
404+
newTargetSelector(selectedPod.Pod.Name, selectedPod.Pod.Namespace, selectedPod.Container.Name, parent),
353405
DefaultTerminalStdout,
354406
DefaultTerminalStderr,
355407
DefaultTerminalStdin,
@@ -359,6 +411,11 @@ func (d *devPod) startTerminal(ctx *devspacecontext.Context, devContainer *lates
359411
return errors.Wrap(err, "error in terminal forwarding")
360412
}
361413

414+
// if context is done we just return
415+
if ctx.IsDone() {
416+
return nil
417+
}
418+
362419
// kill ourselves here
363420
if !opts.ContinueOnTerminalExit && opts.KillApplication != nil {
364421
go opts.KillApplication()
@@ -383,10 +440,9 @@ func (d *devPod) startServices(ctx *devspacecontext.Context, devPod *latest.DevP
383440
return nil
384441
}
385442

443+
// add prefix
444+
ctx := ctx.WithLogger(ctx.Log.WithPrefixColor("sync ", "yellow+b"))
386445
err := sync.StartSync(ctx, devPod, selector, parent)
387-
if err != nil {
388-
fmt.Println(err)
389-
}
390446
return err
391447
})
392448

@@ -396,16 +452,21 @@ func (d *devPod) startServices(ctx *devspacecontext.Context, devPod *latest.DevP
396452
return nil
397453
}
398454

455+
ctx := ctx.WithLogger(ctx.Log.WithPrefixColor("ports ", "yellow+b"))
399456
return portforwarding.StartPortForwarding(ctx, devPod, selector, parent)
400457
})
401458

402459
// Start SSH
403460
sshDone := parent.NotifyGo(func() error {
461+
// add ssh prefix
462+
ctx := ctx.WithLogger(ctx.Log.WithPrefixColor("ssh ", "yellow+b"))
404463
return ssh.StartSSH(ctx, devPod, selector, parent)
405464
})
406465

407466
// Start Reverse Commands
408467
reverseCommandsDone := parent.NotifyGo(func() error {
468+
// add proxy prefix
469+
ctx := ctx.WithLogger(ctx.Log.WithPrefixColor("proxy ", "yellow+b"))
409470
return proxycommands.StartProxyCommands(ctx, devPod, selector, parent)
410471
})
411472

0 commit comments

Comments
 (0)