diff --git a/go.mod b/go.mod index 9de7643f6..e45b0f6a7 100644 --- a/go.mod +++ b/go.mod @@ -32,8 +32,8 @@ require ( github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/moby/buildkit v0.29.1-0.20260408185135-a243ce438aee github.com/moby/go-archive v0.2.0 - github.com/moby/moby/api v1.54.1 - github.com/moby/moby/client v0.4.0 + github.com/moby/moby/api v1.54.2 + github.com/moby/moby/client v0.4.1 github.com/moby/policy-helpers v0.0.0-20260324161837-b7c0b994300b github.com/moby/sys/atomicwriter v0.1.0 github.com/moby/sys/mountinfo v0.7.2 diff --git a/go.sum b/go.sum index dcbf85522..950936278 100644 --- a/go.sum +++ b/go.sum @@ -428,10 +428,10 @@ github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8 github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4= -github.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= -github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw= -github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U= github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/policy-helpers v0.0.0-20260324161837-b7c0b994300b h1:lvBBM2ACrsG5/O1G1caEwlh0XeqA89IQK3xq0Sh/5NI= diff --git a/vendor/github.com/moby/moby/client/internal/json-stream.go b/vendor/github.com/moby/moby/client/internal/json-stream.go index 07d07bd7e..d86b99da2 100644 --- a/vendor/github.com/moby/moby/client/internal/json-stream.go +++ b/vendor/github.com/moby/moby/client/internal/json-stream.go @@ -12,8 +12,9 @@ const rs = 0x1E type DecoderFn func(v any) error -// NewJSONStreamDecoder builds adequate DecoderFn to read json records formatted with specified content-type -func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn { +// NewJSONStreamDecoder builds a DecoderFn to read a stream of JSON records +// formatted with the specified content-type. +func NewJSONStreamDecoder(r io.Reader, contentType types.MediaType) DecoderFn { switch contentType { case types.MediaTypeJSONSequence: return json.NewDecoder(NewRSFilterReader(r)).Decode @@ -24,27 +25,38 @@ func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn { } } -// RSFilterReader wraps an io.Reader and filters out ASCII RS characters -type RSFilterReader struct { +type rsFilterReader struct { reader io.Reader - buffer []byte } -// NewRSFilterReader creates a new RSFilterReader that filters out RS characters -func NewRSFilterReader(r io.Reader) *RSFilterReader { - return &RSFilterReader{ - reader: r, - buffer: make([]byte, 4096), // Internal buffer for reading chunks - } +// NewRSFilterReader creates an [io.Reader] that filters out ASCII Record Separators (RS). +func NewRSFilterReader(r io.Reader) io.Reader { + return &rsFilterReader{reader: r} } -// Read implements the io.Reader interface, filtering out RS characters -func (r *RSFilterReader) Read(p []byte) (n int, err error) { +func (r *rsFilterReader) Read(p []byte) (int, error) { if len(p) == 0 { return 0, nil } - n, err = r.reader.Read(p) - filtered := slices.DeleteFunc(p[:n], func(b byte) bool { return b == rs }) - return len(filtered), err + for { + n, err := r.reader.Read(p) + if n == 0 { + return 0, err + } + + filtered := slices.DeleteFunc(p[:n], func(b byte) bool { return b == rs }) + n = len(filtered) + if err != nil { + if err == io.EOF && n > 0 { + return n, nil + } + return n, err + } + if n == 0 { + // Avoid returning (0, nil) after consuming input; keep reading until data or an error (e.g., EOF). + continue + } + return n, nil + } } diff --git a/vendor/github.com/moby/moby/client/internal/jsonmessages.go b/vendor/github.com/moby/moby/client/internal/jsonmessages.go index 31262fd8e..05210d0dc 100644 --- a/vendor/github.com/moby/moby/client/internal/jsonmessages.go +++ b/vendor/github.com/moby/moby/client/internal/jsonmessages.go @@ -8,6 +8,8 @@ import ( "iter" "sync" + "github.com/containerd/errdefs/pkg/errhttp" + "github.com/moby/moby/api/types/jsonstream" ) @@ -44,41 +46,90 @@ func (r Stream) Close() error { var _ io.ReadCloser = Stream{} -// JSONMessages decodes the response stream as a sequence of JSONMessages. -// if stream ends or context is cancelled, the underlying [io.Reader] is closed. +// JSONMessages decodes the response stream as a sequence of [jsonstream.Message]. +// The underlying [io.Reader] is closed when the stream ends or if the context +// is cancelled. func (r Stream) JSONMessages(ctx context.Context) iter.Seq2[jsonstream.Message, error] { stop := context.AfterFunc(ctx, func() { _ = r.Close() }) - dec := json.NewDecoder(r) return func(yield func(jsonstream.Message, error) bool) { defer func() { stop() // unregister AfterFunc - r.Close() + _ = r.Close() }() + + dec := json.NewDecoder(r) for { var jm jsonstream.Message - err := dec.Decode(&jm) - if errors.Is(err, io.EOF) { - break - } - if ctx.Err() != nil { - yield(jm, ctx.Err()) + if err := dec.Decode(&jm); err != nil { + if errors.Is(err, io.EOF) { + return + } + if err := ctx.Err(); err != nil { + // Do not return decoding errors if the context was + // cancelled, because the decoding errors may be due + // to the context being cancelled. + yield(jsonstream.Message{}, err) + return + } + yield(jsonstream.Message{}, err) return } - if !yield(jm, err) { + if !yield(jm, nil) { return } } } } -// Wait waits for operation to complete and detects errors reported as JSONMessage +// Wait consumes the stream until completion. +// +// It returns nil if the operation completes successfully. Errors are +// returned if the context is canceled, a decoding/transport failure +// occurs, or a JSON message reports an error ([jsonstream.Message.Error]). func (r Stream) Wait(ctx context.Context) error { - for _, err := range r.JSONMessages(ctx) { + for jm, err := range r.JSONMessages(ctx) { if err != nil { + // decode, transport and context cancellation errors. return err } + if jm.Error != nil { + // push/pull failures. + return httpErrorFromStatusCode(jm.Error, jm.Error.Code) + } } return nil } + +type httpError struct { + err error + errdef error +} + +func (e *httpError) Error() string { + return e.err.Error() +} + +func (e *httpError) Unwrap() error { + return e.err +} + +func (e *httpError) Is(target error) bool { + return errors.Is(e.errdef, target) +} + +// httpErrorFromStatusCode creates an errdef error, based on the provided HTTP status-code +// +// TODO(thaJeztah): unify with the implementation in client and move to an internal package +// see https://github.com/moby/moby/blob/client/v0.4.0/client/errors.go#L76-L114 +func httpErrorFromStatusCode(err error, statusCode int) error { + if err == nil { + return nil + } + + return &httpError{ + err: err, + errdef: errhttp.ToNative(statusCode), + } +} diff --git a/vendor/github.com/moby/moby/client/system_disk_usage.go b/vendor/github.com/moby/moby/client/system_disk_usage.go index c5df1e1b1..3f54bfd34 100644 --- a/vendor/github.com/moby/moby/client/system_disk_usage.go +++ b/vendor/github.com/moby/moby/client/system_disk_usage.go @@ -244,12 +244,15 @@ func imageDiskUsageFromLegacyAPI(du *legacyDiskUsage) ImagesDiskUsage { Items: du.Images, } - for _, i := range idu.Items { - if i.Containers > 0 { + for _, img := range idu.Items { + switch { + case img.Containers < 0: + // No container-count information available; skip (assume it's in use). + case img.Containers > 0: idu.ActiveCount++ - } else if i.Size != -1 && i.SharedSize != -1 { - // Only count reclaimable size if we have size information - idu.Reclaimable += (i.Size - i.SharedSize) + case img.Containers == 0 && img.Size != -1 && img.SharedSize != -1: + reclaimable := img.Size - img.SharedSize + idu.Reclaimable += reclaimable } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 77e389264..4f40c92e3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -756,7 +756,7 @@ github.com/moby/go-archive/tarheader # github.com/moby/locker v1.0.1 ## explicit; go 1.13 github.com/moby/locker -# github.com/moby/moby/api v1.54.1 +# github.com/moby/moby/api v1.54.2 ## explicit; go 1.24 github.com/moby/moby/api/pkg/authconfig github.com/moby/moby/api/pkg/stdcopy @@ -777,7 +777,7 @@ github.com/moby/moby/api/types/storage github.com/moby/moby/api/types/swarm github.com/moby/moby/api/types/system github.com/moby/moby/api/types/volume -# github.com/moby/moby/client v0.4.0 +# github.com/moby/moby/client v0.4.1 ## explicit; go 1.24 github.com/moby/moby/client github.com/moby/moby/client/internal