From d05f5f5fa71d5d0c5d94654f3f822dcba523d606 Mon Sep 17 00:00:00 2001 From: Risky Feryansyah <36788585+RiskyFeryansyahP@users.noreply.github.com> Date: Tue, 13 Sep 2022 20:38:13 +0700 Subject: [PATCH] pull: improve output for services with both image+build (#9829) When an image pull fails but the service has a `build` section, it will be built, so it's not an unrecoverable error. It's now logged as a warning - in situations where the image will _never_ exist in a registry, `pull_policy: never` can & should be used, which will prevent the error and avoid unnecessary pull attempts. Signed-off-by: Risky Feryansyah Pribadi --- pkg/compose/pull.go | 12 ++++++++++++ pkg/progress/event.go | 2 ++ pkg/progress/tty.go | 5 ++++- pkg/progress/tty_test.go | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index fbeacacec..88cfefbf6 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -181,6 +181,18 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser RegistryAuth: base64.URLEncoding.EncodeToString(buf), Platform: service.Platform, }) + + // check if has error and the service has a build section + // then the status should be warning instead of error + if err != nil && service.Build != nil { + w.Event(progress.Event{ + ID: service.Name, + Status: progress.Warning, + Text: "Warning", + }) + return "", WrapCategorisedComposeError(err, PullFailure) + } + if err != nil { w.Event(progress.Event{ ID: service.Name, diff --git a/pkg/progress/event.go b/pkg/progress/event.go index 0ead54dd4..8603410e9 100644 --- a/pkg/progress/event.go +++ b/pkg/progress/event.go @@ -28,6 +28,8 @@ const ( Done // Error means that the current task has errored Error + // Warning means that the current task has warning + Warning ) // Event represents a progress event. diff --git a/pkg/progress/tty.go b/pkg/progress/tty.go index 09338fb83..8729571ae 100644 --- a/pkg/progress/tty.go +++ b/pkg/progress/tty.go @@ -75,7 +75,7 @@ func (w *ttyWriter) Event(e Event) { if _, ok := w.events[e.ID]; ok { last := w.events[e.ID] switch e.Status { - case Done, Error: + case Done, Error, Warning: if last.Status != e.Status { last.stop() } @@ -222,6 +222,9 @@ func lineText(event Event, pad string, terminalWidth, statusPadding int, color b if event.Status == Error { color = aec.RedF } + if event.Status == Warning { + color = aec.YellowF + } return aec.Apply(o, color) } diff --git a/pkg/progress/tty_test.go b/pkg/progress/tty_test.go index f9b4071d1..e9e0c7e2d 100644 --- a/pkg/progress/tty_test.go +++ b/pkg/progress/tty_test.go @@ -54,6 +54,10 @@ func TestLineText(t *testing.T) { ev.Status = Error out = lineText(ev, "", 50, lineWidth, true) assert.Equal(t, out, "\x1b[31m . id Text Status 0.0s\n\x1b[0m") + + ev.Status = Warning + out = lineText(ev, "", 50, lineWidth, true) + assert.Equal(t, out, "\x1b[33m . id Text Status 0.0s\n\x1b[0m") } func TestLineTextSingleEvent(t *testing.T) { @@ -103,3 +107,32 @@ func TestErrorEvent(t *testing.T) { assert.Assert(t, ok) assert.Assert(t, event.endTime.After(time.Now().Add(-10*time.Second))) } + +func TestWarningEvent(t *testing.T) { + w := &ttyWriter{ + events: map[string]Event{}, + mtx: &sync.Mutex{}, + } + e := Event{ + ID: "id", + Text: "Text", + Status: Working, + StatusText: "Working", + startTime: time.Now(), + spinner: &spinner{ + chars: []string{"."}, + }, + } + // Fire "Working" event and check end time isn't touched + w.Event(e) + event, ok := w.events[e.ID] + assert.Assert(t, ok) + assert.Assert(t, event.endTime.Equal(time.Time{})) + + // Fire "Warning" event and check end time is set + e.Status = Warning + w.Event(e) + event, ok = w.events[e.ID] + assert.Assert(t, ok) + assert.Assert(t, event.endTime.After(time.Now().Add(-10*time.Second))) +}