Skip to content

Commit d3b96f4

Browse files
author
Aaron Lehmann
committed
Add retry on image push 5xx errors
Some registries can be flaky and return intermittent 5xx errors. This change allows those errors to be retried, similarly to network-level errors. Note that this needs the upstream containerd fix containerd/containerd#5276 to work reliably. This was tested with a registry that was modified to return 504 on every other manifest PUT. Without the change, exports to the registry fail every other attempt. With the change and the related containerd change, exports to the registry always succeed. Signed-off-by: Aaron Lehmann <[email protected]>
1 parent 4e69662 commit d3b96f4

4 files changed

Lines changed: 12 additions & 2 deletions

File tree

util/contentutil/copy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func CopyChain(ctx context.Context, ingester content.Ingester, provider content.
6565
handlers := []images.Handler{
6666
images.ChildrenHandler(provider),
6767
filterHandler,
68-
retryhandler.New(remotes.FetchHandler(ingester, &localFetcher{provider}), nil),
68+
retryhandler.New(remotes.FetchHandler(ingester, &localFetcher{provider}), func(_ []byte) {}),
6969
}
7070

7171
if err := images.Dispatch(ctx, images.Handlers(handlers...), nil, desc); err != nil {

util/imageutil/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, cache Co
101101
children := childrenConfigHandler(cache, platform)
102102

103103
handlers := []images.Handler{
104-
retryhandler.New(remotes.FetchHandler(cache, fetcher), nil),
104+
retryhandler.New(remotes.FetchHandler(cache, fetcher), func(_ []byte) {}),
105105
children,
106106
}
107107
if err := images.Dispatch(ctx, images.Handlers(handlers...), nil, desc); err != nil {

util/progress/logs/logs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ func (sw *streamWriter) Close() error {
133133
func LoggerFromContext(ctx context.Context) func([]byte) {
134134
return func(dt []byte) {
135135
pw, _, _ := progress.FromContext(ctx)
136+
defer pw.Close()
136137
pw.Write(identity.NewID(), client.VertexLog{
137138
Stream: stderr,
138139
Data: []byte(dt),

util/resolver/retryhandler/retry.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/containerd/containerd/images"
13+
remoteserrors "github.com/containerd/containerd/remotes/errors"
1314
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1415
"github.com/pkg/errors"
1516
)
@@ -48,6 +49,14 @@ func New(f images.HandlerFunc, logger func([]byte)) images.HandlerFunc {
4849
}
4950

5051
func retryError(err error) bool {
52+
// Retry on 5xx errors
53+
var errUnexpectedStatus remoteserrors.ErrUnexpectedStatus
54+
if errors.As(err, &errUnexpectedStatus) &&
55+
errUnexpectedStatus.StatusCode >= 500 &&
56+
errUnexpectedStatus.StatusCode <= 599 {
57+
return true
58+
}
59+
5160
if errors.Is(err, io.EOF) || errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.EPIPE) {
5261
return true
5362
}

0 commit comments

Comments
 (0)