Explorar o código

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 <[email protected]>
Risky Feryansyah %!s(int64=3) %!d(string=hai) anos
pai
achega
d05f5f5fa7
Modificáronse 4 ficheiros con 51 adicións e 1 borrados
  1. 12 0
      pkg/compose/pull.go
  2. 2 0
      pkg/progress/event.go
  3. 4 1
      pkg/progress/tty.go
  4. 33 0
      pkg/progress/tty_test.go

+ 12 - 0
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,

+ 2 - 0
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.

+ 4 - 1
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)
 	}
 

+ 33 - 0
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)))
+}