Compare commits

...

1 Commits

Author SHA1 Message Date
renovate[bot]
603f2a5f6b fix(deps): update common, image, and storage deps to 28c83ab
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-01 00:37:54 +00:00
36 changed files with 378 additions and 98 deletions

10
go.mod
View File

@@ -19,9 +19,9 @@ require (
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
go.podman.io/common v0.66.2-0.20260123202709-b5801a635dfa
go.podman.io/image/v5 v5.38.1-0.20260123202709-b5801a635dfa
go.podman.io/storage v1.61.1-0.20260123202709-b5801a635dfa
go.podman.io/common v0.66.2-0.20260130150631-28c83ab6f016
go.podman.io/image/v5 v5.38.1-0.20260130150631-28c83ab6f016
go.podman.io/storage v1.61.1-0.20260130150631-28c83ab6f016
golang.org/x/term v0.39.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -69,8 +69,8 @@ require (
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs/v4 v4.0.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/moby/api v1.52.0 // indirect
github.com/moby/moby/client v0.2.1 // indirect
github.com/moby/moby/api v1.53.0 // indirect
github.com/moby/moby/client v0.2.2 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

20
go.sum
View File

@@ -123,10 +123,10 @@ github.com/mistifyio/go-zfs/v4 v4.0.0 h1:sU0+5dX45tdDK5xNZ3HBi95nxUc48FS92qbIZEv
github.com/mistifyio/go-zfs/v4 v4.0.0/go.mod h1:weotFtXTHvBwhr9Mv96KYnDkTPBOHFUbm9cBmQpesL0=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=
github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=
github.com/moby/moby/api v1.53.0 h1:PihqG1ncw4W+8mZs69jlwGXdaYBeb5brF6BL7mPIS/w=
github.com/moby/moby/api v1.53.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/moby/client v0.2.2 h1:Pt4hRMCAIlyjL3cr8M5TrXCwKzguebPAc2do2ur7dEM=
github.com/moby/moby/client v0.2.2/go.mod h1:2EkIPVNCqR05CMIzL1mfA07t0HvVUUOl85pasRz/GmQ=
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
@@ -233,12 +233,12 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.podman.io/common v0.66.2-0.20260123202709-b5801a635dfa h1:c9Q8zn+AQhrLHaTKL/eghpkD//2SQGn4f5eem/yppy4=
go.podman.io/common v0.66.2-0.20260123202709-b5801a635dfa/go.mod h1:bGauG8nGM+EIHwcCXqhHFCOpdrMZrlap4yrlmNUJs1Y=
go.podman.io/image/v5 v5.38.1-0.20260123202709-b5801a635dfa h1:T/8IVrvcT8N7+1P13Tr1HbAwfa8KQMIMxf2FF9axK8k=
go.podman.io/image/v5 v5.38.1-0.20260123202709-b5801a635dfa/go.mod h1:8wlUZxYaYCtP1IG7eqoy9a4sNULafIV9o4Cj5Jr9Eaw=
go.podman.io/storage v1.61.1-0.20260123202709-b5801a635dfa h1:u/1HgvlgbgV3xngyb8iCSwK55kYI4HwjPVfXCPORJ+s=
go.podman.io/storage v1.61.1-0.20260123202709-b5801a635dfa/go.mod h1:yuLB1ikwsdGrGqSGBWv7fMbOeHupCaMn5iJ1biqxrpI=
go.podman.io/common v0.66.2-0.20260130150631-28c83ab6f016 h1:67MhMHV9Dv484Kc0CldVffhzsNF0Kkacy9xLEmw78XI=
go.podman.io/common v0.66.2-0.20260130150631-28c83ab6f016/go.mod h1:+4bMKfBbfK+qgURkCj6vUtghP5ASjsWyYDI/udLOKxk=
go.podman.io/image/v5 v5.38.1-0.20260130150631-28c83ab6f016 h1:SHPDaE4/lgL/VZYuPkE1hVC4Hclv+gFZpVS3eUFnxgg=
go.podman.io/image/v5 v5.38.1-0.20260130150631-28c83ab6f016/go.mod h1:imQIBRN6114qH01ttrueVkVCHj28jhsiN7Yubh0CzGc=
go.podman.io/storage v1.61.1-0.20260130150631-28c83ab6f016 h1:9/D0XEn1s36LX52GkVfrYA11hOFBCNx/q52CajkEW8A=
go.podman.io/storage v1.61.1-0.20260130150631-28c83ab6f016/go.mod h1:yuLB1ikwsdGrGqSGBWv7fMbOeHupCaMn5iJ1biqxrpI=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View File

@@ -1,7 +1,7 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
@@ -176,13 +176,24 @@
END OF TERMS AND CONDITIONS
Copyright 2013-2018 Docker, Inc.
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -0,0 +1,15 @@
package image
import (
"time"
)
// BuildIdentity contains build reference information if image was created via build.
type BuildIdentity struct {
// Ref is the identifier for the build request. This reference can be used to
// look up the build details in BuildKit history API.
Ref string `json:"Ref,omitempty"`
// CreatedAt is the time when the build ran.
CreatedAt time.Time `json:"CreatedAt,omitempty"`
}

View File

@@ -2,13 +2,12 @@
package image
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// HistoryResponseItem individual image layer information in response to ImageHistory operation
// HistoryResponseItem HistoryResponseItem
//
// individual image layer information in response to ImageHistory operation
//
// swagger:model HistoryResponseItem
type HistoryResponseItem struct {

View File

@@ -0,0 +1,15 @@
package image
// Identity holds information about the identity and origin of the image.
// This is trusted information verified by the daemon and cannot be modified
// by tagging an image to a different name.
type Identity struct {
// Signature contains the properties of verified signatures for the image.
Signature []SignatureIdentity `json:"Signature,omitzero"`
// Pull contains remote location information if image was created via pull.
// If image was pulled via mirror, this contains the original repository location.
// After successful push this images also contains the pushed repository location.
Pull []PullIdentity `json:"Pull,omitzero"`
// Build contains build reference information if image was created via build.
Build []BuildIdentity `json:"Build,omitzero"`
}

View File

@@ -105,4 +105,33 @@ type InspectResponse struct {
// WARNING: This is experimental and may change at any time without any backward
// compatibility.
Manifests []ManifestSummary `json:"Manifests,omitempty"`
// Identity holds information about the identity and origin of the image.
// This is trusted information verified by the daemon and cannot be modified
// by tagging an image to a different name.
Identity *Identity `json:"Identity,omitempty"`
}
// SignatureTimestampType is the type of timestamp used in the signature.
type SignatureTimestampType string
const (
SignatureTimestampTlog SignatureTimestampType = "Tlog"
SignatureTimestampAuthority SignatureTimestampType = "TimestampAuthority"
)
// SignatureType is the type of signature format.
type SignatureType string
const (
SignatureTypeBundleV03 SignatureType = "bundle-v0.3"
SignatureTypeSimpleSigningV1 SignatureType = "simplesigning-v1"
)
// KnownSignerIdentity is an identifier for a special signer identity that is known to the implementation.
type KnownSignerIdentity string
const (
// KnownSignerDHI is the known identity for Docker Hardened Images.
KnownSignerDHI KnownSignerIdentity = "DHI"
)

View File

@@ -0,0 +1,8 @@
package image
// PullIdentity contains remote location information if image was created via pull.
// If image was pulled via mirror, this contains the original repository location.
type PullIdentity struct {
// Repository is the remote repository location the image was pulled from.
Repository string `json:"Repository,omitempty"`
}

View File

@@ -0,0 +1,26 @@
package image
// SignatureIdentity contains the properties of verified signatures for the image.
type SignatureIdentity struct {
// Name is a textual description summarizing the type of signature.
Name string `json:"Name,omitempty"`
// Timestamps contains a list of verified signed timestamps for the signature.
Timestamps []SignatureTimestamp `json:"Timestamps,omitzero"`
// KnownSigner is an identifier for a special signer identity that is known to the implementation.
KnownSigner KnownSignerIdentity `json:"KnownSigner,omitempty"`
// DockerReference is the Docker image reference associated with the signature.
// This is an optional field only present in older hashedrecord signatures.
DockerReference string `json:"DockerReference,omitempty"`
// Signer contains information about the signer certificate used to sign the image.
Signer *SignerIdentity `json:"Signer,omitempty"`
// SignatureType is the type of signature format. E.g. "bundle-v0.3" or "hashedrecord".
SignatureType SignatureType `json:"SignatureType,omitempty"`
// Error contains error information if signature verification failed.
// Other fields will be empty in this case.
Error string `json:"Error,omitempty"`
// Warnings contains any warnings that occurred during signature verification.
// For example, if there was no internet connectivity and cached trust roots were used.
// Warning does not indicate a failed verification but may point to configuration issues.
Warnings []string `json:"Warnings,omitzero"`
}

View File

@@ -0,0 +1,12 @@
package image
import (
"time"
)
// SignatureTimestamp contains information about a verified signed timestamp for an image signature.
type SignatureTimestamp struct {
Type SignatureTimestampType `json:"Type"`
URI string `json:"URI"`
Timestamp time.Time `json:"Timestamp"`
}

View File

@@ -0,0 +1,57 @@
package image
// SignerIdentity contains information about the signer certificate used to sign the image.
// This is [certificate.Summary] with deprecated fields removed and keys in Moby uppercase style.
//
// [certificate.Summary]: https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg/fulcio/certificate#Summary
type SignerIdentity struct {
CertificateIssuer string `json:"CertificateIssuer"`
SubjectAlternativeName string `json:"SubjectAlternativeName"`
// The OIDC issuer. Should match `iss` claim of ID token or, in the case of
// a federated login like Dex it should match the issuer URL of the
// upstream issuer. The issuer is not set the extensions are invalid and
// will fail to render.
Issuer string `json:"Issuer,omitempty"` // OID 1.3.6.1.4.1.57264.1.8 and 1.3.6.1.4.1.57264.1.1 (Deprecated)
// Reference to specific build instructions that are responsible for signing.
BuildSignerURI string `json:"BuildSignerURI,omitempty"` // 1.3.6.1.4.1.57264.1.9
// Immutable reference to the specific version of the build instructions that is responsible for signing.
BuildSignerDigest string `json:"BuildSignerDigest,omitempty"` // 1.3.6.1.4.1.57264.1.10
// Specifies whether the build took place in platform-hosted cloud infrastructure or customer/self-hosted infrastructure.
RunnerEnvironment string `json:"RunnerEnvironment,omitempty"` // 1.3.6.1.4.1.57264.1.11
// Source repository URL that the build was based on.
SourceRepositoryURI string `json:"SourceRepositoryURI,omitempty"` // 1.3.6.1.4.1.57264.1.12
// Immutable reference to a specific version of the source code that the build was based upon.
SourceRepositoryDigest string `json:"SourceRepositoryDigest,omitempty"` // 1.3.6.1.4.1.57264.1.13
// Source Repository Ref that the build run was based upon.
SourceRepositoryRef string `json:"SourceRepositoryRef,omitempty"` // 1.3.6.1.4.1.57264.1.14
// Immutable identifier for the source repository the workflow was based upon.
SourceRepositoryIdentifier string `json:"SourceRepositoryIdentifier,omitempty"` // 1.3.6.1.4.1.57264.1.15
// Source repository owner URL of the owner of the source repository that the build was based on.
SourceRepositoryOwnerURI string `json:"SourceRepositoryOwnerURI,omitempty"` // 1.3.6.1.4.1.57264.1.16
// Immutable identifier for the owner of the source repository that the workflow was based upon.
SourceRepositoryOwnerIdentifier string `json:"SourceRepositoryOwnerIdentifier,omitempty"` // 1.3.6.1.4.1.57264.1.17
// Build Config URL to the top-level/initiating build instructions.
BuildConfigURI string `json:"BuildConfigURI,omitempty"` // 1.3.6.1.4.1.57264.1.18
// Immutable reference to the specific version of the top-level/initiating build instructions.
BuildConfigDigest string `json:"BuildConfigDigest,omitempty"` // 1.3.6.1.4.1.57264.1.19
// Event or action that initiated the build.
BuildTrigger string `json:"BuildTrigger,omitempty"` // 1.3.6.1.4.1.57264.1.20
// Run Invocation URL to uniquely identify the build execution.
RunInvocationURI string `json:"RunInvocationURI,omitempty"` // 1.3.6.1.4.1.57264.1.21
// Source repository visibility at the time of signing the certificate.
SourceRepositoryVisibilityAtSigning string `json:"SourceRepositoryVisibilityAtSigning,omitempty"` // 1.3.6.1.4.1.57264.1.22
}

View File

@@ -2,9 +2,9 @@ package jsonstream
import "encoding/json"
// JSONMessage defines a message struct. It describes
// Message defines a message struct. It describes
// the created time, where it from, status, ID of the
// message. It's used for docker events.
// message.
type Message struct {
Stream string `json:"stream,omitempty"`
Status string `json:"status,omitempty"`

View File

@@ -58,9 +58,9 @@ func (es *EndpointSettings) Copy() *EndpointSettings {
// EndpointIPAMConfig represents IPAM configurations for the endpoint
type EndpointIPAMConfig struct {
IPv4Address netip.Addr `json:",omitempty"`
IPv6Address netip.Addr `json:",omitempty"`
LinkLocalIPs []netip.Addr `json:",omitempty"`
IPv4Address netip.Addr `json:"IPv4Address,omitzero"`
IPv6Address netip.Addr `json:"IPv6Address,omitzero"`
LinkLocalIPs []netip.Addr `json:"LinkLocalIPs,omitempty"`
}
// Copy makes a copy of the endpoint ipam config

View File

@@ -11,9 +11,11 @@ import (
// in the absence of go.dev/issue/29678.
type HardwareAddr net.HardwareAddr
var _ encoding.TextMarshaler = (HardwareAddr)(nil)
var _ encoding.TextUnmarshaler = (*HardwareAddr)(nil)
var _ fmt.Stringer = (HardwareAddr)(nil)
var (
_ encoding.TextMarshaler = (HardwareAddr)(nil)
_ encoding.TextUnmarshaler = (*HardwareAddr)(nil)
_ fmt.Stringer = (HardwareAddr)(nil)
)
func (m *HardwareAddr) UnmarshalText(text []byte) error {
if len(text) == 0 {

View File

@@ -13,9 +13,9 @@ type IPAM struct {
// IPAMConfig represents IPAM configurations
type IPAMConfig struct {
Subnet netip.Prefix `json:",omitempty"`
IPRange netip.Prefix `json:",omitempty"`
Gateway netip.Addr `json:",omitempty"`
Subnet netip.Prefix `json:"Subnet,omitzero"`
IPRange netip.Prefix `json:"IPRange,omitzero"`
Gateway netip.Addr `json:"Gateway,omitzero"`
AuxAddress map[string]netip.Addr `json:"AuxiliaryAddresses,omitempty"`
}

View File

@@ -61,7 +61,7 @@ type EndpointVirtualIP struct {
// Addr is the virtual ip address.
// This field accepts CIDR notation, for example `10.0.0.1/24`, to maintain backwards
// compatibility, but only the IP address is used.
Addr netip.Prefix `json:",omitempty"`
Addr netip.Prefix `json:"Addr,omitzero"`
}
// Network represents a network.
@@ -111,7 +111,7 @@ type IPAMOptions struct {
// IPAMConfig represents ipam configuration.
type IPAMConfig struct {
Subnet netip.Prefix `json:",omitempty"`
Range netip.Prefix `json:",omitempty"`
Gateway netip.Addr `json:",omitempty"`
Subnet netip.Prefix `json:"Subnet,omitzero"`
Range netip.Prefix `json:"Range,omitzero"`
Gateway netip.Addr `json:"Gateway,omitzero"`
}

View File

@@ -109,14 +109,14 @@ type Limit struct {
Pids int64 `json:",omitempty"`
}
// GenericResource represents a "user defined" resource which can
// GenericResource represents a "user-defined" resource which can
// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)
type GenericResource struct {
NamedResourceSpec *NamedGenericResource `json:",omitempty"`
DiscreteResourceSpec *DiscreteGenericResource `json:",omitempty"`
}
// NamedGenericResource represents a "user defined" resource which is defined
// NamedGenericResource represents a "user-defined" resource which is defined
// as a string.
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...)
@@ -125,7 +125,7 @@ type NamedGenericResource struct {
Value string `json:",omitempty"`
}
// DiscreteGenericResource represents a "user defined" resource which is defined
// DiscreteGenericResource represents a "user-defined" resource which is defined
// as an integer
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
// Value is used to count the resource (SSD=5, HDD=3, ...)
@@ -148,7 +148,7 @@ type ResourceRequirements struct {
// Tune container memory swappiness (0 to 100) - if not specified, defaults
// to the container OS's default - generally 60, or the value predefined in
// the image; set to -1 to unset a previously set value
MemorySwappiness *int64 `json:MemorySwappiness,omitzero"`
MemorySwappiness *int64 `json:"MemorySwappiness,omitzero"`
}
// Placement represents orchestration parameters.

View File

@@ -74,6 +74,7 @@ type Info struct {
FirewallBackend *FirewallInfo `json:"FirewallBackend,omitempty"`
CDISpecDirs []string
DiscoveredDevices []DeviceInfo `json:",omitempty"`
NRI *NRIInfo `json:",omitempty"`
Containerd *ContainerdInfo `json:",omitempty"`
@@ -163,3 +164,8 @@ type DeviceInfo struct {
// Example: CDI FQDN like "vendor.com/gpu=0", or other driver-specific device ID
ID string `json:"ID"`
}
// NRIInfo describes the NRI configuration.
type NRIInfo struct {
Info [][2]string `json:"Info,omitempty"`
}

View File

@@ -10,9 +10,12 @@ const (
// MediaTypeJSON is the MIME-Type for JSON objects.
MediaTypeJSON = "application/json"
// MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams.
// MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams (https://github.com/ndjson/ndjson-spec).
MediaTypeNDJSON = "application/x-ndjson"
// MediaTypeJSONLines is the MIME-Type for JSONLines objects streams (https://jsonlines.org/).
MediaTypeJSONLines = "application/jsonl"
// MediaTypeJSONSequence is the MIME-Type for JSON Text Sequences (RFC7464).
MediaTypeJSONSequence = "application/json-seq"
)

View File

@@ -1,7 +1,7 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
@@ -176,13 +176,24 @@
END OF TERMS AND CONDITIONS
Copyright 2013-2018 Docker, Inc.
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -59,6 +59,7 @@ import (
"net/http"
"net/url"
"path"
"slices"
"strings"
"sync"
"sync/atomic"
@@ -106,7 +107,7 @@ const DummyHost = "api.moby.localhost"
// overriding the version and disable API-version negotiation.
//
// This version may be lower than the version of the api library module used.
const MaxAPIVersion = "1.52"
const MaxAPIVersion = "1.53"
// MinAPIVersion is the minimum API version supported by the client. API versions
// below this version are not considered when performing API-version negotiation.
@@ -241,6 +242,13 @@ func New(ops ...Opt) (*Client, error) {
c.client.Transport = otelhttp.NewTransport(c.client.Transport, c.traceOpts...)
if len(cfg.responseHooks) > 0 {
c.client.Transport = &responseHookTransport{
base: c.client.Transport,
hooks: slices.Clone(cfg.responseHooks),
}
}
return c, nil
}

View File

@@ -2,6 +2,7 @@ package client
import (
"context"
"errors"
"fmt"
"net"
"net/http"
@@ -55,10 +56,19 @@ type clientConfig struct {
// takes precedence. Either field disables API-version negotiation.
envAPIVersion string
// responseHooks is a list of custom response hooks to call on responses.
responseHooks []ResponseHook
// traceOpts is a list of options to configure the tracing span.
traceOpts []otelhttp.Option
}
// ResponseHook is called for each HTTP response returned by the daemon.
// Hooks are invoked in the order they were added.
//
// Hooks must not read or close resp.Body.
type ResponseHook func(*http.Response)
// Opt is a configuration option to initialize a [Client].
type Opt func(*clientConfig) error
@@ -133,8 +143,6 @@ func (tf testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
return tf(req)
}
func (testRoundTripper) skipConfigureTransport() bool { return true }
// WithHostFromEnv overrides the client host with the host specified in the
// DOCKER_HOST ([EnvOverrideHost]) environment variable. If DOCKER_HOST is not set,
// or set to an empty value, the host is not modified.
@@ -151,7 +159,16 @@ func WithHostFromEnv() Opt {
func WithHTTPClient(client *http.Client) Opt {
return func(c *clientConfig) error {
if client != nil {
c.client = client
// Make a clone of client so modifications do not affect
// the caller's client. Clone here instead of in New()
// as other options (WithHost) also mutate c.client.
// Cloned clients share the same CookieJar as the
// original.
hc := *client
if ht, ok := hc.Transport.(*http.Transport); ok {
hc.Transport = ht.Clone()
}
c.client = &hc
}
return nil
}
@@ -341,3 +358,18 @@ func WithTraceOptions(opts ...otelhttp.Option) Opt {
return nil
}
}
// WithResponseHook adds a ResponseHook to the client. ResponseHooks are called
// for each HTTP response returned by the daemon. Hooks are invoked in the order
// they were added.
//
// Hooks must not read or close resp.Body.
func WithResponseHook(h ResponseHook) Opt {
return func(c *clientConfig) error {
if h == nil {
return errors.New("invalid response hook: hook is nil")
}
c.responseHooks = append(c.responseHooks, h)
return nil
}
}

View File

@@ -0,0 +1,23 @@
package client
import (
"net/http"
)
type responseHookTransport struct {
base http.RoundTripper
hooks []ResponseHook
}
func (t *responseHookTransport) RoundTrip(req *http.Request) (*http.Response, error) {
resp, err := t.base.RoundTrip(req)
if err != nil {
return resp, err
}
for _, h := range t.hooks {
h(resp)
}
return resp, nil
}

View File

@@ -23,7 +23,7 @@ type ContainerAttachResult struct {
// ContainerAttach attaches a connection to a container in the server.
// It returns a [HijackedResponse] with the hijacked connection
// and a reader to get output. It's up to the called to close
// and a reader to get output. It's up to the caller to close
// the hijacked connection by calling [HijackedResponse.Close].
//
// The stream format on the response uses one of two formats:

View File

@@ -5,7 +5,7 @@ import (
"encoding/json"
"net/http"
"github.com/containerd/errdefs"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container"
)
@@ -82,8 +82,7 @@ type ExecStartOptions struct {
}
// ExecStartResult holds the result of starting a container exec.
type ExecStartResult struct {
}
type ExecStartResult struct{}
// ExecStart starts an exec process already created in the docker host.
func (cli *Client) ExecStart(ctx context.Context, execID string, options ExecStartOptions) (ExecStartResult, error) {
@@ -118,7 +117,7 @@ type ExecAttachResult struct {
// ExecAttach attaches a connection to an exec process in the server.
//
// It returns a [HijackedResponse] with the hijacked connection
// and a reader to get output. It's up to the called to close
// and a reader to get output. It's up to the caller to close
// the hijacked connection by calling [HijackedResponse.Close].
//
// The stream format on the response uses one of two formats:
@@ -152,7 +151,7 @@ func (cli *Client) ExecAttach(ctx context.Context, execID string, options ExecAt
func getConsoleSize(hasTTY bool, consoleSize ConsoleSize) (*[2]uint, error) {
if consoleSize.Height != 0 || consoleSize.Width != 0 {
if !hasTTY {
return nil, errdefs.ErrInvalidArgument.WithMessage("console size is only supported when TTY is enabled")
return nil, cerrdefs.ErrInvalidArgument.WithMessage("console size is only supported when TTY is enabled")
}
return &[2]uint{consoleSize.Height, consoleSize.Width}, nil
}
@@ -160,8 +159,7 @@ func getConsoleSize(hasTTY bool, consoleSize ConsoleSize) (*[2]uint, error) {
}
// ExecInspectOptions holds options for inspecting a container exec.
type ExecInspectOptions struct {
}
type ExecInspectOptions struct{}
// ExecInspectResult holds the result of inspecting a container exec.
//

View File

@@ -13,11 +13,23 @@ import (
type ContainerListOptions struct {
Size bool
All bool
Latest bool
Since string
Before string
Limit int
Filters Filters
// Latest is non-functional and should not be used. Use Limit: 1 instead.
//
// Deprecated: the Latest option is non-functional and should not be used. Use Limit: 1 instead.
Latest bool
// Since is no longer supported. Use the "since" filter instead.
//
// Deprecated: the Since option is no longer supported since docker 1.12 (API 1.24). Use the "since" filter instead.
Since string
// Before is no longer supported. Use the "since" filter instead.
//
// Deprecated: the Before option is no longer supported since docker 1.12 (API 1.24). Use the "before" filter instead.
Before string
}
type ContainerListResult struct {
@@ -36,14 +48,6 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio
query.Set("limit", strconv.Itoa(options.Limit))
}
if options.Since != "" {
query.Set("since", options.Since)
}
if options.Before != "" {
query.Set("before", options.Before)
}
if options.Size {
query.Set("size", "1")
}

View File

@@ -5,7 +5,7 @@ import (
"net/url"
"strings"
"github.com/containerd/errdefs"
cerrdefs "github.com/containerd/errdefs"
)
// ContainerRenameOptions represents the options for renaming a container.
@@ -28,7 +28,7 @@ func (cli *Client) ContainerRename(ctx context.Context, containerID string, opti
if options.NewName == "" || strings.TrimPrefix(options.NewName, "/") == "" {
// daemons before v29.0 did not handle the canonical name ("/") well
// let's be nice and validate it here before sending
return ContainerRenameResult{}, errdefs.ErrInvalidArgument.WithMessage("new name cannot be blank")
return ContainerRenameResult{}, cerrdefs.ErrInvalidArgument.WithMessage("new name cannot be blank")
}
query := url.Values{}

View File

@@ -42,8 +42,7 @@ func (cli *Client) ContainerResize(ctx context.Context, containerID string, opti
type ExecResizeOptions ContainerResizeOptions
// ExecResizeResult holds the result of resizing a container exec TTY.
type ExecResizeResult struct {
}
type ExecResizeResult struct{}
// ExecResize changes the size of the tty for an exec process running inside a container.
func (cli *Client) ExecResize(ctx context.Context, execID string, options ExecResizeOptions) (ExecResizeResult, error) {
@@ -62,5 +61,4 @@ func (cli *Client) ExecResize(ctx context.Context, execID string, options ExecRe
return ExecResizeResult{}, err
}
return ExecResizeResult{}, nil
}

View File

@@ -17,7 +17,7 @@ func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn {
switch contentType {
case types.MediaTypeJSONSequence:
return json.NewDecoder(NewRSFilterReader(r)).Decode
case types.MediaTypeJSON, types.MediaTypeNDJSON:
case types.MediaTypeJSON, types.MediaTypeNDJSON, types.MediaTypeJSONLines:
fallthrough
default:
return json.NewDecoder(r).Decode

View File

@@ -45,12 +45,15 @@ func (r stream) Close() error {
// JSONMessages decodes the response stream as a sequence of JSONMessages.
// if stream ends or context is cancelled, the underlying [io.Reader] is closed.
func (r stream) JSONMessages(ctx context.Context) iter.Seq2[jsonstream.Message, error] {
context.AfterFunc(ctx, func() {
stop := context.AfterFunc(ctx, func() {
_ = r.Close()
})
dec := json.NewDecoder(r)
return func(yield func(jsonstream.Message, error) bool) {
defer r.Close()
defer func() {
stop() // unregister AfterFunc
r.Close()
}()
for {
var jm jsonstream.Message
err := dec.Decode(&jm)

View File

@@ -276,6 +276,8 @@ func containerDiskUsageFromLegacyAPI(du *legacyDiskUsage) ContainersDiskUsage {
case container.StateRunning, container.StatePaused, container.StateRestarting:
cdu.ActiveCount++
used += c.SizeRw
case container.StateCreated, container.StateRemoving, container.StateExited, container.StateDead:
// not active
}
}

View File

@@ -46,6 +46,7 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) Events
headers := http.Header{}
headers.Add("Accept", types.MediaTypeJSONSequence)
headers.Add("Accept", types.MediaTypeJSONLines)
headers.Add("Accept", types.MediaTypeNDJSON)
resp, err := cli.get(ctx, "/events", query, headers)
if err != nil {

View File

@@ -136,14 +136,19 @@ func newCancelReadCloser(ctx context.Context, rc io.ReadCloser) io.ReadCloser {
rc: rc,
close: sync.OnceValue(rc.Close),
}
context.AfterFunc(ctx, func() { _ = crc.Close() })
crc.stop = context.AfterFunc(ctx, func() { _ = crc.Close() })
return crc
}
type cancelReadCloser struct {
rc io.ReadCloser
close func() error
stop func() bool
}
func (c *cancelReadCloser) Read(p []byte) (int, error) { return c.rc.Read(p) }
func (c *cancelReadCloser) Close() error { return c.close() }
func (c *cancelReadCloser) Close() error {
c.stop() // unregister AfterFunc
return c.close()
}

View File

@@ -6,7 +6,7 @@ import (
"fmt"
"net/url"
"github.com/containerd/errdefs"
cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/volume"
)
@@ -29,7 +29,7 @@ type VolumePruneResult struct {
func (cli *Client) VolumePrune(ctx context.Context, options VolumePruneOptions) (VolumePruneResult, error) {
if options.All {
if _, ok := options.Filters["all"]; ok {
return VolumePruneResult{}, errdefs.ErrInvalidArgument.WithMessage(`conflicting options: cannot specify both "all" and "all" filter`)
return VolumePruneResult{}, cerrdefs.ErrInvalidArgument.WithMessage(`conflicting options: cannot specify both "all" and "all" filter`)
}
if options.Filters == nil {
options.Filters = Filters{}

View File

@@ -193,7 +193,9 @@ func (p *Pattern) match(path string) (bool, error) {
}
func (p *Pattern) compile() error {
regStr := "^"
var regStrBuilder strings.Builder
regStrBuilder.WriteString("^")
pattern := p.cleanedPattern
// Go through the pattern and convert it to a regexp.
// We use a scanner so we can support utf-8 chars.
@@ -222,46 +224,56 @@ func (p *Pattern) compile() error {
if scan.Peek() == scanner.EOF {
// is "**EOF" - to align with .gitignore just accept all
regStr += ".*"
regStrBuilder.WriteString(".*")
} else {
// is "**"
// Note that this allows for any # of /'s (even 0) because
// the .* will eat everything, even /'s
regStr += "(.*" + escSL + ")?"
regStrBuilder.WriteString("(.*")
regStrBuilder.WriteString(escSL)
regStrBuilder.WriteString(")?")
}
} else {
// is "*" so map it to anything but "/"
regStr += "[^" + escSL + "]*"
regStrBuilder.WriteString("[^")
regStrBuilder.WriteString(escSL)
regStrBuilder.WriteString("]*")
}
} else if ch == '?' {
// "?" is any char except "/"
regStr += "[^" + escSL + "]"
regStrBuilder.WriteString("[^")
regStrBuilder.WriteString(escSL)
regStrBuilder.WriteString("]")
} else if ch == '.' || ch == '$' {
// Escape some regexp special chars that have no meaning
// in golang's filepath.Match
regStr += bs + string(ch)
regStrBuilder.WriteString(bs)
regStrBuilder.WriteRune(ch)
} else if ch == '\\' {
// escape next char.
if sl == bs {
// On windows map "\" to "\\", meaning an escaped backslash,
// and then just continue because filepath.Match on
// Windows doesn't allow escaping at all
regStr += escSL
regStrBuilder.WriteString(escSL)
continue
}
if scan.Peek() != scanner.EOF {
regStr += bs + string(scan.Next())
regStrBuilder.WriteString(bs)
regStrBuilder.WriteRune(scan.Next())
} else {
return filepath.ErrBadPattern
}
} else {
regStr += string(ch)
regStrBuilder.WriteRune(ch)
}
}
regStr += "(" + escSL + ".*)?$"
regStrBuilder.WriteString("(")
regStrBuilder.WriteString(escSL)
regStrBuilder.WriteString(".*)?$")
re, err := regexp.Compile(regStr)
re, err := regexp.Compile(regStrBuilder.String())
if err != nil {
return err
}

10
vendor/modules.txt vendored
View File

@@ -185,7 +185,7 @@ github.com/mistifyio/go-zfs/v4
# github.com/moby/docker-image-spec v1.3.1
## explicit; go 1.18
github.com/moby/docker-image-spec/specs-go/v1
# github.com/moby/moby/api v1.52.0
# github.com/moby/moby/api v1.53.0
## explicit; go 1.24.0
github.com/moby/moby/api/types
github.com/moby/moby/api/types/blkiodev
@@ -204,7 +204,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.2.1
# github.com/moby/moby/client v0.2.2
## explicit; go 1.24.0
github.com/moby/moby/client
github.com/moby/moby/client/internal
@@ -357,7 +357,7 @@ go.opentelemetry.io/otel/trace
go.opentelemetry.io/otel/trace/embedded
go.opentelemetry.io/otel/trace/internal/telemetry
go.opentelemetry.io/otel/trace/noop
# go.podman.io/common v0.66.2-0.20260123202709-b5801a635dfa
# go.podman.io/common v0.66.2-0.20260130150631-28c83ab6f016
## explicit; go 1.24.6
go.podman.io/common/pkg/auth
go.podman.io/common/pkg/capabilities
@@ -367,7 +367,7 @@ go.podman.io/common/pkg/password
go.podman.io/common/pkg/report
go.podman.io/common/pkg/report/camelcase
go.podman.io/common/pkg/retry
# go.podman.io/image/v5 v5.38.1-0.20260123202709-b5801a635dfa
# go.podman.io/image/v5 v5.38.1-0.20260130150631-28c83ab6f016
## explicit; go 1.24.6
go.podman.io/image/v5/copy
go.podman.io/image/v5/directory
@@ -440,7 +440,7 @@ go.podman.io/image/v5/transports
go.podman.io/image/v5/transports/alltransports
go.podman.io/image/v5/types
go.podman.io/image/v5/version
# go.podman.io/storage v1.61.1-0.20260123202709-b5801a635dfa
# go.podman.io/storage v1.61.1-0.20260130150631-28c83ab6f016
## explicit; go 1.24.0
go.podman.io/storage
go.podman.io/storage/drivers