mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 17:27:49 +08:00
vendor: github.com/docker/docker v28.1.0
full diff: https://github.com/docker/docker/compare/v28.0.4...v28.1.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
5398c33937
commit
ac970c03e7
2
go.mod
2
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
github.com/distribution/reference v0.6.0
|
github.com/distribution/reference v0.6.0
|
||||||
github.com/docker/cli v28.0.4+incompatible
|
github.com/docker/cli v28.0.4+incompatible
|
||||||
github.com/docker/cli-docs-tool v0.9.0
|
github.com/docker/cli-docs-tool v0.9.0
|
||||||
github.com/docker/docker v28.0.4+incompatible
|
github.com/docker/docker v28.1.0+incompatible
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
github.com/gofrs/flock v0.12.1
|
github.com/gofrs/flock v0.12.1
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
|
4
go.sum
4
go.sum
@ -119,8 +119,8 @@ github.com/docker/cli-docs-tool v0.9.0/go.mod h1:ClrwlNW+UioiRyH9GiAOe1o3J/TsY3T
|
|||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v28.0.4+incompatible h1:JNNkBctYKurkw6FrHfKqY0nKIDf5nrbxjVBtS+cdcok=
|
github.com/docker/docker v28.1.0+incompatible h1:4iqpcWQCt3Txcz7iWIb1U3SZ/n9ffo4U+ryY5/3eOp0=
|
||||||
github.com/docker/docker v28.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v28.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
|
4
vendor/github.com/docker/docker/AUTHORS
generated
vendored
4
vendor/github.com/docker/docker/AUTHORS
generated
vendored
@ -293,6 +293,7 @@ Brandon Liu <bdon@bdon.org>
|
|||||||
Brandon Philips <brandon.philips@coreos.com>
|
Brandon Philips <brandon.philips@coreos.com>
|
||||||
Brandon Rhodes <brandon@rhodesmill.org>
|
Brandon Rhodes <brandon@rhodesmill.org>
|
||||||
Brendan Dixon <brendand@microsoft.com>
|
Brendan Dixon <brendand@microsoft.com>
|
||||||
|
Brendon Smith <bws@bws.bio>
|
||||||
Brennan Kinney <5098581+polarathene@users.noreply.github.com>
|
Brennan Kinney <5098581+polarathene@users.noreply.github.com>
|
||||||
Brent Salisbury <brent.salisbury@docker.com>
|
Brent Salisbury <brent.salisbury@docker.com>
|
||||||
Brett Higgins <brhiggins@arbor.net>
|
Brett Higgins <brhiggins@arbor.net>
|
||||||
@ -347,6 +348,7 @@ Casey Bisson <casey.bisson@joyent.com>
|
|||||||
Catalin Pirvu <pirvu.catalin94@gmail.com>
|
Catalin Pirvu <pirvu.catalin94@gmail.com>
|
||||||
Ce Gao <ce.gao@outlook.com>
|
Ce Gao <ce.gao@outlook.com>
|
||||||
Cedric Davies <cedricda@microsoft.com>
|
Cedric Davies <cedricda@microsoft.com>
|
||||||
|
Cesar Talledo <cesar.talledo@docker.com>
|
||||||
Cezar Sa Espinola <cezarsa@gmail.com>
|
Cezar Sa Espinola <cezarsa@gmail.com>
|
||||||
Chad Swenson <chadswen@gmail.com>
|
Chad Swenson <chadswen@gmail.com>
|
||||||
Chance Zibolski <chance.zibolski@gmail.com>
|
Chance Zibolski <chance.zibolski@gmail.com>
|
||||||
@ -1281,6 +1283,7 @@ Krasi Georgiev <krasi@vip-consult.solutions>
|
|||||||
Krasimir Georgiev <support@vip-consult.co.uk>
|
Krasimir Georgiev <support@vip-consult.co.uk>
|
||||||
Kris-Mikael Krister <krismikael@protonmail.com>
|
Kris-Mikael Krister <krismikael@protonmail.com>
|
||||||
Kristian Haugene <kristian.haugene@capgemini.com>
|
Kristian Haugene <kristian.haugene@capgemini.com>
|
||||||
|
Kristian Heljas <kristian@kristian.ee>
|
||||||
Kristina Zabunova <triara.xiii@gmail.com>
|
Kristina Zabunova <triara.xiii@gmail.com>
|
||||||
Krystian Wojcicki <kwojcicki@sympatico.ca>
|
Krystian Wojcicki <kwojcicki@sympatico.ca>
|
||||||
Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
|
Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
|
||||||
@ -1712,6 +1715,7 @@ Patrick Hemmer <patrick.hemmer@gmail.com>
|
|||||||
Patrick St. laurent <patrick@saint-laurent.us>
|
Patrick St. laurent <patrick@saint-laurent.us>
|
||||||
Patrick Stapleton <github@gdi2290.com>
|
Patrick Stapleton <github@gdi2290.com>
|
||||||
Patrik Cyvoct <patrik@ptrk.io>
|
Patrik Cyvoct <patrik@ptrk.io>
|
||||||
|
Patrik Leifert <patrikleifert@hotmail.com>
|
||||||
pattichen <craftsbear@gmail.com>
|
pattichen <craftsbear@gmail.com>
|
||||||
Paul "TBBle" Hampson <Paul.Hampson@Pobox.com>
|
Paul "TBBle" Hampson <Paul.Hampson@Pobox.com>
|
||||||
Paul <paul9869@gmail.com>
|
Paul <paul9869@gmail.com>
|
||||||
|
2
vendor/github.com/docker/docker/api/common.go
generated
vendored
2
vendor/github.com/docker/docker/api/common.go
generated
vendored
@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
|
|||||||
// Common constants for daemon and client.
|
// Common constants for daemon and client.
|
||||||
const (
|
const (
|
||||||
// DefaultVersion of the current REST API.
|
// DefaultVersion of the current REST API.
|
||||||
DefaultVersion = "1.48"
|
DefaultVersion = "1.49"
|
||||||
|
|
||||||
// MinSupportedAPIVersion is the minimum API version that can be supported
|
// MinSupportedAPIVersion is the minimum API version that can be supported
|
||||||
// by the API server, specified as "major.minor". Note that the daemon
|
// by the API server, specified as "major.minor". Note that the daemon
|
||||||
|
93
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
93
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
@ -19,10 +19,10 @@ produces:
|
|||||||
consumes:
|
consumes:
|
||||||
- "application/json"
|
- "application/json"
|
||||||
- "text/plain"
|
- "text/plain"
|
||||||
basePath: "/v1.48"
|
basePath: "/v1.49"
|
||||||
info:
|
info:
|
||||||
title: "Docker Engine API"
|
title: "Docker Engine API"
|
||||||
version: "1.48"
|
version: "1.49"
|
||||||
x-logo:
|
x-logo:
|
||||||
url: "https://docs.docker.com/assets/images/logo-docker-main.png"
|
url: "https://docs.docker.com/assets/images/logo-docker-main.png"
|
||||||
description: |
|
description: |
|
||||||
@ -55,8 +55,8 @@ info:
|
|||||||
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
|
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
|
||||||
is returned.
|
is returned.
|
||||||
|
|
||||||
If you omit the version-prefix, the current version of the API (v1.48) is used.
|
If you omit the version-prefix, the current version of the API (v1.49) is used.
|
||||||
For example, calling `/info` is the same as calling `/v1.48/info`. Using the
|
For example, calling `/info` is the same as calling `/v1.49/info`. Using the
|
||||||
API without a version-prefix is deprecated and will be removed in a future release.
|
API without a version-prefix is deprecated and will be removed in a future release.
|
||||||
|
|
||||||
Engine releases in the near future should support this version of the API,
|
Engine releases in the near future should support this version of the API,
|
||||||
@ -6856,6 +6856,8 @@ definitions:
|
|||||||
description: "The network pool size"
|
description: "The network pool size"
|
||||||
type: "integer"
|
type: "integer"
|
||||||
example: "24"
|
example: "24"
|
||||||
|
FirewallBackend:
|
||||||
|
$ref: "#/definitions/FirewallInfo"
|
||||||
Warnings:
|
Warnings:
|
||||||
description: |
|
description: |
|
||||||
List of warnings / informational messages about missing features, or
|
List of warnings / informational messages about missing features, or
|
||||||
@ -6939,6 +6941,37 @@ definitions:
|
|||||||
default: "plugins.moby"
|
default: "plugins.moby"
|
||||||
example: "plugins.moby"
|
example: "plugins.moby"
|
||||||
|
|
||||||
|
FirewallInfo:
|
||||||
|
description: |
|
||||||
|
Information about the daemon's firewalling configuration.
|
||||||
|
|
||||||
|
This field is currently only used on Linux, and omitted on other platforms.
|
||||||
|
type: "object"
|
||||||
|
x-nullable: true
|
||||||
|
properties:
|
||||||
|
Driver:
|
||||||
|
description: |
|
||||||
|
The name of the firewall backend driver.
|
||||||
|
type: "string"
|
||||||
|
example: "nftables"
|
||||||
|
Info:
|
||||||
|
description: |
|
||||||
|
Information about the firewall backend, provided as
|
||||||
|
"label" / "value" pairs.
|
||||||
|
|
||||||
|
<p><br /></p>
|
||||||
|
|
||||||
|
> **Note**: The information returned in this field, including the
|
||||||
|
> formatting of values and labels, should not be considered stable,
|
||||||
|
> and may change without notice.
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
type: "string"
|
||||||
|
example:
|
||||||
|
- ["ReloadedAt", "2025-01-01T00:00:00Z"]
|
||||||
|
|
||||||
# PluginsInfo is a temp struct holding Plugins name
|
# PluginsInfo is a temp struct holding Plugins name
|
||||||
# registered with docker daemon. It is used by Info struct
|
# registered with docker daemon. It is used by Info struct
|
||||||
PluginsInfo:
|
PluginsInfo:
|
||||||
@ -6984,32 +7017,6 @@ definitions:
|
|||||||
type: "object"
|
type: "object"
|
||||||
x-nullable: true
|
x-nullable: true
|
||||||
properties:
|
properties:
|
||||||
AllowNondistributableArtifactsCIDRs:
|
|
||||||
description: |
|
|
||||||
List of IP ranges to which nondistributable artifacts can be pushed,
|
|
||||||
using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632).
|
|
||||||
|
|
||||||
<p><br /></p>
|
|
||||||
|
|
||||||
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
|
|
||||||
> and this field is always `null`. This field will be removed in a API v1.49.
|
|
||||||
type: "array"
|
|
||||||
items:
|
|
||||||
type: "string"
|
|
||||||
example: []
|
|
||||||
AllowNondistributableArtifactsHostnames:
|
|
||||||
description: |
|
|
||||||
List of registry hostnames to which nondistributable artifacts can be
|
|
||||||
pushed, using the format `<hostname>[:<port>]` or `<IP address>[:<port>]`.
|
|
||||||
|
|
||||||
<p><br /></p>
|
|
||||||
|
|
||||||
> **Deprecated**: Pushing nondistributable artifacts is now always enabled
|
|
||||||
> and this field is always `null`. This field will be removed in a API v1.49.
|
|
||||||
type: "array"
|
|
||||||
items:
|
|
||||||
type: "string"
|
|
||||||
example: []
|
|
||||||
InsecureRegistryCIDRs:
|
InsecureRegistryCIDRs:
|
||||||
description: |
|
description: |
|
||||||
List of IP ranges of insecure registries, using the CIDR syntax
|
List of IP ranges of insecure registries, using the CIDR syntax
|
||||||
@ -7179,13 +7186,6 @@ definitions:
|
|||||||
description: "Actual commit ID of external tool."
|
description: "Actual commit ID of external tool."
|
||||||
type: "string"
|
type: "string"
|
||||||
example: "cfb82a876ecc11b5ca0977d1733adbe58599088a"
|
example: "cfb82a876ecc11b5ca0977d1733adbe58599088a"
|
||||||
Expected:
|
|
||||||
description: |
|
|
||||||
Commit ID of external tool expected by dockerd as set at build time.
|
|
||||||
|
|
||||||
**Deprecated**: This field is deprecated and will be omitted in a API v1.49.
|
|
||||||
type: "string"
|
|
||||||
example: "2d41c047c83e09a6d61d464906feb2a2f3c52aa4"
|
|
||||||
|
|
||||||
SwarmInfo:
|
SwarmInfo:
|
||||||
description: |
|
description: |
|
||||||
@ -10491,13 +10491,9 @@ paths:
|
|||||||
|
|
||||||
### Image tarball format
|
### Image tarball format
|
||||||
|
|
||||||
An image tarball contains one directory per image layer (named using its long ID), each containing these files:
|
An image tarball contains [Content as defined in the OCI Image Layout Specification](https://github.com/opencontainers/image-spec/blob/v1.1.1/image-layout.md#content).
|
||||||
|
|
||||||
- `VERSION`: currently `1.0` - the file format version
|
Additionally, includes the manifest.json file associated with a backwards compatible docker save format.
|
||||||
- `json`: detailed layer information, similar to `docker inspect layer_id`
|
|
||||||
- `layer.tar`: A tarfile containing the filesystem changes in this layer
|
|
||||||
|
|
||||||
The `layer.tar` file contains `aufs` style `.wh..wh.aufs` files and directories for storing attribute changes and deletions.
|
|
||||||
|
|
||||||
If the tarball defines a repository, the tarball should also include a `repositories` file at the root that contains a list of repository and tag names mapped to layer IDs.
|
If the tarball defines a repository, the tarball should also include a `repositories` file at the root that contains a list of repository and tag names mapped to layer IDs.
|
||||||
|
|
||||||
@ -10537,6 +10533,7 @@ paths:
|
|||||||
If not provided, the full multi-platform image will be saved.
|
If not provided, the full multi-platform image will be saved.
|
||||||
|
|
||||||
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
|
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
|
||||||
|
tags: ["Image"]
|
||||||
/images/get:
|
/images/get:
|
||||||
get:
|
get:
|
||||||
summary: "Export several images"
|
summary: "Export several images"
|
||||||
@ -10571,6 +10568,16 @@ paths:
|
|||||||
type: "array"
|
type: "array"
|
||||||
items:
|
items:
|
||||||
type: "string"
|
type: "string"
|
||||||
|
- name: "platform"
|
||||||
|
type: "string"
|
||||||
|
in: "query"
|
||||||
|
description: |
|
||||||
|
JSON encoded OCI platform describing a platform which will be used
|
||||||
|
to select a platform-specific image to be saved if the image is
|
||||||
|
multi-platform.
|
||||||
|
If not provided, the full multi-platform image will be saved.
|
||||||
|
|
||||||
|
Example: `{"os": "linux", "architecture": "arm", "variant": "v5"}`
|
||||||
tags: ["Image"]
|
tags: ["Image"]
|
||||||
/images/load:
|
/images/load:
|
||||||
post:
|
post:
|
||||||
|
3
vendor/github.com/docker/docker/api/types/image/image_inspect.go
generated
vendored
3
vendor/github.com/docker/docker/api/types/image/image_inspect.go
generated
vendored
@ -132,7 +132,8 @@ type InspectResponse struct {
|
|||||||
// provides a more detailed view of the platform-specific image manifests or
|
// provides a more detailed view of the platform-specific image manifests or
|
||||||
// other image-attached data like build attestations.
|
// other image-attached data like build attestations.
|
||||||
//
|
//
|
||||||
// Only available if the daemon provides a multi-platform image store.
|
// Only available if the daemon provides a multi-platform image store, the client
|
||||||
|
// requests manifests AND does not request a specific platform.
|
||||||
//
|
//
|
||||||
// WARNING: This is experimental and may change at any time without any backward
|
// WARNING: This is experimental and may change at any time without any backward
|
||||||
// compatibility.
|
// compatibility.
|
||||||
|
5
vendor/github.com/docker/docker/api/types/image/opts.go
generated
vendored
5
vendor/github.com/docker/docker/api/types/image/opts.go
generated
vendored
@ -106,6 +106,11 @@ type LoadOptions struct {
|
|||||||
type InspectOptions struct {
|
type InspectOptions struct {
|
||||||
// Manifests returns the image manifests.
|
// Manifests returns the image manifests.
|
||||||
Manifests bool
|
Manifests bool
|
||||||
|
|
||||||
|
// Platform selects the specific platform of a multi-platform image to inspect.
|
||||||
|
//
|
||||||
|
// This option is only available for API version 1.49 and up.
|
||||||
|
Platform *ocispec.Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveOptions holds parameters to save images.
|
// SaveOptions holds parameters to save images.
|
||||||
|
28
vendor/github.com/docker/docker/api/types/registry/registry.go
generated
vendored
28
vendor/github.com/docker/docker/api/types/registry/registry.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||||
|
//go:build go1.22
|
||||||
|
|
||||||
package registry // import "github.com/docker/docker/api/types/registry"
|
package registry // import "github.com/docker/docker/api/types/registry"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -15,23 +18,26 @@ type ServiceConfig struct {
|
|||||||
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
|
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
|
||||||
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
|
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
|
||||||
Mirrors []string
|
Mirrors []string
|
||||||
|
|
||||||
|
// ExtraFields is for internal use to include deprecated fields on older API versions.
|
||||||
|
ExtraFields map[string]any `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements a custom marshaler to include legacy fields
|
// MarshalJSON implements a custom marshaler to include legacy fields
|
||||||
// in API responses.
|
// in API responses.
|
||||||
func (sc ServiceConfig) MarshalJSON() ([]byte, error) {
|
func (sc *ServiceConfig) MarshalJSON() ([]byte, error) {
|
||||||
tmp := map[string]interface{}{
|
type tmp ServiceConfig
|
||||||
"InsecureRegistryCIDRs": sc.InsecureRegistryCIDRs,
|
base, err := json.Marshal((*tmp)(sc))
|
||||||
"IndexConfigs": sc.IndexConfigs,
|
if err != nil {
|
||||||
"Mirrors": sc.Mirrors,
|
return nil, err
|
||||||
}
|
}
|
||||||
if sc.AllowNondistributableArtifactsCIDRs != nil {
|
var merged map[string]any
|
||||||
tmp["AllowNondistributableArtifactsCIDRs"] = nil
|
_ = json.Unmarshal(base, &merged)
|
||||||
|
|
||||||
|
for k, v := range sc.ExtraFields {
|
||||||
|
merged[k] = v
|
||||||
}
|
}
|
||||||
if sc.AllowNondistributableArtifactsHostnames != nil {
|
return json.Marshal(merged)
|
||||||
tmp["AllowNondistributableArtifactsHostnames"] = nil
|
|
||||||
}
|
|
||||||
return json.Marshal(tmp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetIPNet is the net.IPNet type, which can be marshalled and
|
// NetIPNet is the net.IPNet type, which can be marshalled and
|
||||||
|
11
vendor/github.com/docker/docker/api/types/system/info.go
generated
vendored
11
vendor/github.com/docker/docker/api/types/system/info.go
generated
vendored
@ -73,6 +73,7 @@ type Info struct {
|
|||||||
SecurityOptions []string
|
SecurityOptions []string
|
||||||
ProductLicense string `json:",omitempty"`
|
ProductLicense string `json:",omitempty"`
|
||||||
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
|
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
|
||||||
|
FirewallBackend *FirewallInfo `json:"FirewallBackend,omitempty"`
|
||||||
CDISpecDirs []string
|
CDISpecDirs []string
|
||||||
|
|
||||||
Containerd *ContainerdInfo `json:",omitempty"`
|
Containerd *ContainerdInfo `json:",omitempty"`
|
||||||
@ -143,7 +144,7 @@ type Commit struct {
|
|||||||
// Expected is the commit ID of external tool expected by dockerd as set at build time.
|
// Expected is the commit ID of external tool expected by dockerd as set at build time.
|
||||||
//
|
//
|
||||||
// Deprecated: this field is no longer used in API v1.49, but kept for backward-compatibility with older API versions.
|
// Deprecated: this field is no longer used in API v1.49, but kept for backward-compatibility with older API versions.
|
||||||
Expected string
|
Expected string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkAddressPool is a temp struct used by [Info] struct.
|
// NetworkAddressPool is a temp struct used by [Info] struct.
|
||||||
@ -151,3 +152,11 @@ type NetworkAddressPool struct {
|
|||||||
Base string
|
Base string
|
||||||
Size int
|
Size int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FirewallInfo describes the firewall backend.
|
||||||
|
type FirewallInfo struct {
|
||||||
|
// Driver is the name of the firewall backend driver.
|
||||||
|
Driver string `json:"Driver"`
|
||||||
|
// Info is a list of label/value pairs, containing information related to the firewall.
|
||||||
|
Info [][2]string `json:"Info,omitempty"`
|
||||||
|
}
|
||||||
|
2
vendor/github.com/docker/docker/client/container_commit.go
generated
vendored
2
vendor/github.com/docker/docker/client/container_commit.go
generated
vendored
@ -32,7 +32,7 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti
|
|||||||
if tagged, ok := ref.(reference.Tagged); ok {
|
if tagged, ok := ref.(reference.Tagged); ok {
|
||||||
tag = tagged.Tag()
|
tag = tagged.Tag()
|
||||||
}
|
}
|
||||||
repository = reference.FamiliarName(ref)
|
repository = ref.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
2
vendor/github.com/docker/docker/client/image_create.go
generated
vendored
2
vendor/github.com/docker/docker/client/image_create.go
generated
vendored
@ -21,7 +21,7 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("fromImage", reference.FamiliarName(ref))
|
query.Set("fromImage", ref.Name())
|
||||||
query.Set("tag", getAPITagFromNamedRef(ref))
|
query.Set("tag", getAPITagFromNamedRef(ref))
|
||||||
if options.Platform != "" {
|
if options.Platform != "" {
|
||||||
query.Set("platform", strings.ToLower(options.Platform))
|
query.Set("platform", strings.ToLower(options.Platform))
|
||||||
|
11
vendor/github.com/docker/docker/client/image_inspect.go
generated
vendored
11
vendor/github.com/docker/docker/client/image_inspect.go
generated
vendored
@ -32,6 +32,17 @@ func (cli *Client) ImageInspect(ctx context.Context, imageID string, inspectOpts
|
|||||||
query.Set("manifests", "1")
|
query.Set("manifests", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.apiOptions.Platform != nil {
|
||||||
|
if err := cli.NewVersionError(ctx, "1.49", "platform"); err != nil {
|
||||||
|
return image.InspectResponse{}, err
|
||||||
|
}
|
||||||
|
platform, err := encodePlatform(opts.apiOptions.Platform)
|
||||||
|
if err != nil {
|
||||||
|
return image.InspectResponse{}, err
|
||||||
|
}
|
||||||
|
query.Set("platform", platform)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
resp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
12
vendor/github.com/docker/docker/client/image_inspect_opts.go
generated
vendored
12
vendor/github.com/docker/docker/client/image_inspect_opts.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageInspectOption is a type representing functional options for the image inspect operation.
|
// ImageInspectOption is a type representing functional options for the image inspect operation.
|
||||||
@ -36,6 +37,17 @@ func ImageInspectWithManifests(manifests bool) ImageInspectOption {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageInspectWithPlatform sets platform API option for the image inspect operation.
|
||||||
|
// This option is only available for API version 1.49 and up.
|
||||||
|
// With this option set, the image inspect operation will return information for the
|
||||||
|
// specified platform variant of the multi-platform image.
|
||||||
|
func ImageInspectWithPlatform(platform *ocispec.Platform) ImageInspectOption {
|
||||||
|
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
|
||||||
|
clientOpts.apiOptions.Platform = platform
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ImageInspectWithAPIOpts sets the API options for the image inspect operation.
|
// ImageInspectWithAPIOpts sets the API options for the image inspect operation.
|
||||||
func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
|
func ImageInspectWithAPIOpts(opts image.InspectOptions) ImageInspectOption {
|
||||||
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
|
return imageInspectOptionFunc(func(clientOpts *imageInspectOpts) error {
|
||||||
|
2
vendor/github.com/docker/docker/client/image_pull.go
generated
vendored
2
vendor/github.com/docker/docker/client/image_pull.go
generated
vendored
@ -26,7 +26,7 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("fromImage", reference.FamiliarName(ref))
|
query.Set("fromImage", ref.Name())
|
||||||
if !options.All {
|
if !options.All {
|
||||||
query.Set("tag", getAPITagFromNamedRef(ref))
|
query.Set("tag", getAPITagFromNamedRef(ref))
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/docker/docker/client/image_push.go
generated
vendored
5
vendor/github.com/docker/docker/client/image_push.go
generated
vendored
@ -29,7 +29,6 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options image.Pu
|
|||||||
return nil, errors.New("cannot push a digest reference")
|
return nil, errors.New("cannot push a digest reference")
|
||||||
}
|
}
|
||||||
|
|
||||||
name := reference.FamiliarName(ref)
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
if !options.All {
|
if !options.All {
|
||||||
ref = reference.TagNameOnly(ref)
|
ref = reference.TagNameOnly(ref)
|
||||||
@ -52,13 +51,13 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options image.Pu
|
|||||||
query.Set("platform", string(pJson))
|
query.Set("platform", string(pJson))
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth)
|
resp, err := cli.tryImagePush(ctx, ref.Name(), query, options.RegistryAuth)
|
||||||
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
|
||||||
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
|
||||||
if privilegeErr != nil {
|
if privilegeErr != nil {
|
||||||
return nil, privilegeErr
|
return nil, privilegeErr
|
||||||
}
|
}
|
||||||
resp, err = cli.tryImagePush(ctx, name, query, newAuthHeader)
|
resp, err = cli.tryImagePush(ctx, ref.Name(), query, newAuthHeader)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
2
vendor/github.com/docker/docker/client/image_tag.go
generated
vendored
2
vendor/github.com/docker/docker/client/image_tag.go
generated
vendored
@ -26,7 +26,7 @@ func (cli *Client) ImageTag(ctx context.Context, source, target string) error {
|
|||||||
ref = reference.TagNameOnly(ref)
|
ref = reference.TagNameOnly(ref)
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("repo", reference.FamiliarName(ref))
|
query.Set("repo", ref.Name())
|
||||||
if tagged, ok := ref.(reference.Tagged); ok {
|
if tagged, ok := ref.(reference.Tagged); ok {
|
||||||
query.Set("tag", tagged.Tag())
|
query.Set("tag", tagged.Tag())
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/docker/docker/client/request.go
generated
vendored
2
vendor/github.com/docker/docker/client/request.go
generated
vendored
@ -237,7 +237,7 @@ func (cli *Client) checkResponseErr(serverResp *http.Response) (retErr error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var daemonErr error
|
var daemonErr error
|
||||||
if serverResp.Header.Get("Content-Type") == "application/json" && (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) {
|
if serverResp.Header.Get("Content-Type") == "application/json" {
|
||||||
var errorResponse types.ErrorResponse
|
var errorResponse types.ErrorResponse
|
||||||
if err := json.Unmarshal(body, &errorResponse); err != nil {
|
if err := json.Unmarshal(body, &errorResponse); err != nil {
|
||||||
return errors.Wrap(err, "Error reading JSON")
|
return errors.Wrap(err, "Error reading JSON")
|
||||||
|
224
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter.go
generated
vendored
224
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter.go
generated
vendored
@ -1,224 +0,0 @@
|
|||||||
package atomicwriter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
func validateDestination(fileName string) error {
|
|
||||||
if fileName == "" {
|
|
||||||
return errors.New("file name is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deliberately using Lstat here to match the behavior of [os.Rename],
|
|
||||||
// which is used when completing the write and does not resolve symlinks.
|
|
||||||
//
|
|
||||||
// TODO(thaJeztah): decide whether we want to disallow symlinks or to follow them.
|
|
||||||
if fi, err := os.Lstat(fileName); err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return fmt.Errorf("failed to stat output path: %w", err)
|
|
||||||
}
|
|
||||||
} else if err := validateFileMode(fi.Mode()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if dir := filepath.Dir(fileName); dir != "" && dir != "." {
|
|
||||||
if _, err := os.Stat(dir); errors.Is(err, os.ErrNotExist) {
|
|
||||||
return fmt.Errorf("invalid file path: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateFileMode(mode os.FileMode) error {
|
|
||||||
switch {
|
|
||||||
case mode.IsRegular():
|
|
||||||
return nil // Regular file
|
|
||||||
case mode&os.ModeDir != 0:
|
|
||||||
return errors.New("cannot write to a directory")
|
|
||||||
// TODO(thaJeztah): decide whether we want to disallow symlinks or to follow them.
|
|
||||||
// case mode&os.ModeSymlink != 0:
|
|
||||||
// return errors.New("cannot write to a symbolic link directly")
|
|
||||||
case mode&os.ModeNamedPipe != 0:
|
|
||||||
return errors.New("cannot write to a named pipe (FIFO)")
|
|
||||||
case mode&os.ModeSocket != 0:
|
|
||||||
return errors.New("cannot write to a socket")
|
|
||||||
case mode&os.ModeDevice != 0:
|
|
||||||
if mode&os.ModeCharDevice != 0 {
|
|
||||||
return errors.New("cannot write to a character device file")
|
|
||||||
}
|
|
||||||
return errors.New("cannot write to a block device file")
|
|
||||||
case mode&os.ModeSetuid != 0:
|
|
||||||
return errors.New("cannot write to a setuid file")
|
|
||||||
case mode&os.ModeSetgid != 0:
|
|
||||||
return errors.New("cannot write to a setgid file")
|
|
||||||
case mode&os.ModeSticky != 0:
|
|
||||||
return errors.New("cannot write to a sticky bit file")
|
|
||||||
default:
|
|
||||||
// Unknown file mode; let's assume it works
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a WriteCloser so that writing to it writes to a
|
|
||||||
// temporary file and closing it atomically changes the temporary file to
|
|
||||||
// destination path. Writing and closing concurrently is not allowed.
|
|
||||||
// NOTE: umask is not considered for the file's permissions.
|
|
||||||
func New(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
|
||||||
if err := validateDestination(filename); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
abspath, err := filepath.Abs(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.CreateTemp(filepath.Dir(abspath), ".tmp-"+filepath.Base(filename))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &atomicFileWriter{
|
|
||||||
f: f,
|
|
||||||
fn: abspath,
|
|
||||||
perm: perm,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteFile atomically writes data to a file named by filename and with the specified permission bits.
|
|
||||||
// NOTE: umask is not considered for the file's permissions.
|
|
||||||
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
|
||||||
f, err := New(filename, perm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n, err := f.Write(data)
|
|
||||||
if err == nil && n < len(data) {
|
|
||||||
err = io.ErrShortWrite
|
|
||||||
f.(*atomicFileWriter).writeErr = err
|
|
||||||
}
|
|
||||||
if err1 := f.Close(); err == nil {
|
|
||||||
err = err1
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type atomicFileWriter struct {
|
|
||||||
f *os.File
|
|
||||||
fn string
|
|
||||||
writeErr error
|
|
||||||
written bool
|
|
||||||
perm os.FileMode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *atomicFileWriter) Write(dt []byte) (int, error) {
|
|
||||||
w.written = true
|
|
||||||
n, err := w.f.Write(dt)
|
|
||||||
if err != nil {
|
|
||||||
w.writeErr = err
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *atomicFileWriter) Close() (retErr error) {
|
|
||||||
defer func() {
|
|
||||||
if err := os.Remove(w.f.Name()); !errors.Is(err, os.ErrNotExist) && retErr == nil {
|
|
||||||
retErr = err
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := w.f.Sync(); err != nil {
|
|
||||||
_ = w.f.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := w.f.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.Chmod(w.f.Name(), w.perm); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if w.writeErr == nil && w.written {
|
|
||||||
return os.Rename(w.f.Name(), w.fn)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteSet is used to atomically write a set
|
|
||||||
// of files and ensure they are visible at the same time.
|
|
||||||
// Must be committed to a new directory.
|
|
||||||
type WriteSet struct {
|
|
||||||
root string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWriteSet creates a new atomic write set to
|
|
||||||
// atomically create a set of files. The given directory
|
|
||||||
// is used as the base directory for storing files before
|
|
||||||
// commit. If no temporary directory is given the system
|
|
||||||
// default is used.
|
|
||||||
func NewWriteSet(tmpDir string) (*WriteSet, error) {
|
|
||||||
td, err := os.MkdirTemp(tmpDir, "write-set-")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &WriteSet{
|
|
||||||
root: td,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteFile writes a file to the set, guaranteeing the file
|
|
||||||
// has been synced.
|
|
||||||
func (ws *WriteSet) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
|
||||||
f, err := ws.FileWriter(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n, err := f.Write(data)
|
|
||||||
if err == nil && n < len(data) {
|
|
||||||
err = io.ErrShortWrite
|
|
||||||
}
|
|
||||||
if err1 := f.Close(); err == nil {
|
|
||||||
err = err1
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type syncFileCloser struct {
|
|
||||||
*os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w syncFileCloser) Close() error {
|
|
||||||
err := w.File.Sync()
|
|
||||||
if err1 := w.File.Close(); err == nil {
|
|
||||||
err = err1
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileWriter opens a file writer inside the set. The file
|
|
||||||
// should be synced and closed before calling commit.
|
|
||||||
func (ws *WriteSet) FileWriter(name string, flag int, perm os.FileMode) (io.WriteCloser, error) {
|
|
||||||
f, err := os.OpenFile(filepath.Join(ws.root, name), flag, perm)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return syncFileCloser{f}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel cancels the set and removes all temporary data
|
|
||||||
// created in the set.
|
|
||||||
func (ws *WriteSet) Cancel() error {
|
|
||||||
return os.RemoveAll(ws.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit moves all created files to the target directory. The
|
|
||||||
// target directory must not exist and the parent of the target
|
|
||||||
// directory must exist.
|
|
||||||
func (ws *WriteSet) Commit(target string) error {
|
|
||||||
return os.Rename(ws.root, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the location the set is writing to.
|
|
||||||
func (ws *WriteSet) String() string {
|
|
||||||
return ws.root
|
|
||||||
}
|
|
56
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter_deprecated.go
generated
vendored
Normal file
56
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter_deprecated.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package atomicwriter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/moby/sys/atomicwriter"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a WriteCloser so that writing to it writes to a
|
||||||
|
// temporary file and closing it atomically changes the temporary file to
|
||||||
|
// destination path. Writing and closing concurrently is not allowed.
|
||||||
|
// NOTE: umask is not considered for the file's permissions.
|
||||||
|
//
|
||||||
|
// New uses [sequential.CreateTemp] to use sequential file access on Windows,
|
||||||
|
// avoiding depleting the standby list un-necessarily. On Linux, this equates to
|
||||||
|
// a regular [os.CreateTemp]. Refer to the [Win32 API documentation] for details
|
||||||
|
// on sequential file access.
|
||||||
|
//
|
||||||
|
// Deprecated: use [atomicwriter.New] instead.
|
||||||
|
//
|
||||||
|
// [Win32 API documentation]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
func New(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||||
|
return atomicwriter.New(filename, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFile atomically writes data to a file named by filename and with the
|
||||||
|
// specified permission bits. The given filename is created if it does not exist,
|
||||||
|
// but the destination directory must exist. It can be used as a drop-in replacement
|
||||||
|
// for [os.WriteFile], but currently does not allow the destination path to be
|
||||||
|
// a symlink. WriteFile is implemented using [New] for its implementation.
|
||||||
|
//
|
||||||
|
// NOTE: umask is not considered for the file's permissions.
|
||||||
|
//
|
||||||
|
// Deprecated: use [atomicwriter.WriteFile] instead.
|
||||||
|
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
|
return atomicwriter.WriteFile(filename, data, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteSet is used to atomically write a set
|
||||||
|
// of files and ensure they are visible at the same time.
|
||||||
|
// Must be committed to a new directory.
|
||||||
|
//
|
||||||
|
// Deprecated: use [atomicwriter.WriteSet] instead.
|
||||||
|
type WriteSet = atomicwriter.WriteSet
|
||||||
|
|
||||||
|
// NewWriteSet creates a new atomic write set to
|
||||||
|
// atomically create a set of files. The given directory
|
||||||
|
// is used as the base directory for storing files before
|
||||||
|
// commit. If no temporary directory is given the system
|
||||||
|
// default is used.
|
||||||
|
//
|
||||||
|
// Deprecated: use [atomicwriter.NewWriteSet] instead.
|
||||||
|
func NewWriteSet(tmpDir string) (*atomicwriter.WriteSet, error) {
|
||||||
|
return atomicwriter.NewWriteSet(tmpDir)
|
||||||
|
}
|
6
vendor/github.com/docker/docker/registry/auth.go
generated
vendored
6
vendor/github.com/docker/docker/registry/auth.go
generated
vendored
@ -66,11 +66,11 @@ func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) {
|
|||||||
// loginV2 tries to login to the v2 registry server. The given registry
|
// loginV2 tries to login to the v2 registry server. The given registry
|
||||||
// endpoint will be pinged to get authorization challenges. These challenges
|
// endpoint will be pinged to get authorization challenges. These challenges
|
||||||
// will be used to authenticate against the registry to validate credentials.
|
// will be used to authenticate against the registry to validate credentials.
|
||||||
func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (token string, _ error) {
|
func loginV2(ctx context.Context, authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (token string, _ error) {
|
||||||
endpointStr := strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
|
endpointStr := strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
|
||||||
log.G(context.TODO()).Debugf("attempting v2 login to registry endpoint %s", endpointStr)
|
log.G(ctx).WithField("endpoint", endpointStr).Debug("attempting v2 login to registry endpoint")
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, endpointStr, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpointStr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/docker/docker/registry/config.go
generated
vendored
27
vendor/github.com/docker/docker/registry/config.go
generated
vendored
@ -19,8 +19,6 @@ import (
|
|||||||
|
|
||||||
// ServiceOptions holds command line options.
|
// ServiceOptions holds command line options.
|
||||||
type ServiceOptions struct {
|
type ServiceOptions struct {
|
||||||
AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
|
|
||||||
|
|
||||||
Mirrors []string `json:"registry-mirrors,omitempty"`
|
Mirrors []string `json:"registry-mirrors,omitempty"`
|
||||||
InsecureRegistries []string `json:"insecure-registries,omitempty"`
|
InsecureRegistries []string `json:"insecure-registries,omitempty"`
|
||||||
}
|
}
|
||||||
@ -294,12 +292,15 @@ func isCIDRMatch(cidrs []*registry.NetIPNet, URLHost string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateMirror validates an HTTP(S) registry mirror. It is used by the daemon
|
// ValidateMirror validates and normalizes an HTTP(S) registry mirror. It
|
||||||
// to validate the daemon configuration.
|
// returns an error if the given mirrorURL is invalid, or the normalized
|
||||||
func ValidateMirror(val string) (string, error) {
|
// format for the URL otherwise.
|
||||||
uri, err := url.Parse(val)
|
//
|
||||||
|
// It is used by the daemon to validate the daemon configuration.
|
||||||
|
func ValidateMirror(mirrorURL string) (string, error) {
|
||||||
|
uri, err := url.Parse(mirrorURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", invalidParamWrapf(err, "invalid mirror: %q is not a valid URI", val)
|
return "", invalidParamWrapf(err, "invalid mirror: %q is not a valid URI", mirrorURL)
|
||||||
}
|
}
|
||||||
if uri.Scheme != "http" && uri.Scheme != "https" {
|
if uri.Scheme != "http" && uri.Scheme != "https" {
|
||||||
return "", invalidParamf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri)
|
return "", invalidParamf("invalid mirror: unsupported scheme %q in %q", uri.Scheme, uri)
|
||||||
@ -312,7 +313,7 @@ func ValidateMirror(val string) (string, error) {
|
|||||||
uri.User = url.UserPassword(uri.User.Username(), "xxxxx")
|
uri.User = url.UserPassword(uri.User.Username(), "xxxxx")
|
||||||
return "", invalidParamf("invalid mirror: username/password not allowed in URI %q", uri)
|
return "", invalidParamf("invalid mirror: username/password not allowed in URI %q", uri)
|
||||||
}
|
}
|
||||||
return strings.TrimSuffix(val, "/") + "/", nil
|
return strings.TrimSuffix(mirrorURL, "/") + "/", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateIndexName validates an index name. It is used by the daemon to
|
// ValidateIndexName validates an index name. It is used by the daemon to
|
||||||
@ -414,7 +415,6 @@ func newRepositoryInfo(config *serviceConfig, name reference.Named) *RepositoryI
|
|||||||
func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
|
func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
|
||||||
indexName := normalizeIndexName(reference.Domain(reposName))
|
indexName := normalizeIndexName(reference.Domain(reposName))
|
||||||
if indexName == IndexName {
|
if indexName == IndexName {
|
||||||
officialRepo := !strings.ContainsRune(reference.FamiliarName(reposName), '/')
|
|
||||||
return &RepositoryInfo{
|
return &RepositoryInfo{
|
||||||
Name: reference.TrimNamed(reposName),
|
Name: reference.TrimNamed(reposName),
|
||||||
Index: ®istry.IndexInfo{
|
Index: ®istry.IndexInfo{
|
||||||
@ -423,21 +423,16 @@ func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
|
|||||||
Secure: true,
|
Secure: true,
|
||||||
Official: true,
|
Official: true,
|
||||||
},
|
},
|
||||||
Official: officialRepo,
|
Official: !strings.ContainsRune(reference.FamiliarName(reposName), '/'),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
insecure := false
|
|
||||||
if isInsecure(indexName) {
|
|
||||||
insecure = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return &RepositoryInfo{
|
return &RepositoryInfo{
|
||||||
Name: reference.TrimNamed(reposName),
|
Name: reference.TrimNamed(reposName),
|
||||||
Index: ®istry.IndexInfo{
|
Index: ®istry.IndexInfo{
|
||||||
Name: indexName,
|
Name: indexName,
|
||||||
Mirrors: []string{},
|
Mirrors: []string{},
|
||||||
Secure: !insecure,
|
Secure: !isInsecure(indexName),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
36
vendor/github.com/docker/docker/registry/registry.go
generated
vendored
36
vendor/github.com/docker/docker/registry/registry.go
generated
vendored
@ -29,15 +29,15 @@ func hostCertsDir(hostname string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newTLSConfig constructs a client TLS configuration based on server defaults
|
// newTLSConfig constructs a client TLS configuration based on server defaults
|
||||||
func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
|
func newTLSConfig(ctx context.Context, hostname string, isSecure bool) (*tls.Config, error) {
|
||||||
// PreferredServerCipherSuites should have no effect
|
// PreferredServerCipherSuites should have no effect
|
||||||
tlsConfig := tlsconfig.ServerDefault()
|
tlsConfig := tlsconfig.ServerDefault()
|
||||||
tlsConfig.InsecureSkipVerify = !isSecure
|
tlsConfig.InsecureSkipVerify = !isSecure
|
||||||
|
|
||||||
if isSecure {
|
if isSecure {
|
||||||
hostDir := hostCertsDir(hostname)
|
hostDir := hostCertsDir(hostname)
|
||||||
log.G(context.TODO()).Debugf("hostDir: %s", hostDir)
|
log.G(ctx).Debugf("hostDir: %s", hostDir)
|
||||||
if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil {
|
if err := loadTLSConfig(ctx, hostDir, tlsConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,12 +58,24 @@ func hasFile(files []os.DirEntry, name string) bool {
|
|||||||
// including roots and certificate pairs and updates the
|
// including roots and certificate pairs and updates the
|
||||||
// provided TLS configuration.
|
// provided TLS configuration.
|
||||||
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
||||||
|
return loadTLSConfig(context.TODO(), directory, tlsConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadTLSConfig reads the directory for TLS certificates including roots and
|
||||||
|
// certificate pairs, and updates the provided TLS configuration.
|
||||||
|
func loadTLSConfig(ctx context.Context, directory string, tlsConfig *tls.Config) error {
|
||||||
fs, err := os.ReadDir(directory)
|
fs, err := os.ReadDir(directory)
|
||||||
if err != nil && !os.IsNotExist(err) {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return invalidParam(err)
|
return invalidParam(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
switch filepath.Ext(f.Name()) {
|
switch filepath.Ext(f.Name()) {
|
||||||
case ".crt":
|
case ".crt":
|
||||||
if tlsConfig.RootCAs == nil {
|
if tlsConfig.RootCAs == nil {
|
||||||
@ -74,7 +86,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
|||||||
tlsConfig.RootCAs = systemPool
|
tlsConfig.RootCAs = systemPool
|
||||||
}
|
}
|
||||||
fileName := filepath.Join(directory, f.Name())
|
fileName := filepath.Join(directory, f.Name())
|
||||||
log.G(context.TODO()).Debugf("crt: %s", fileName)
|
log.G(ctx).Debugf("crt: %s", fileName)
|
||||||
data, err := os.ReadFile(fileName)
|
data, err := os.ReadFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -83,7 +95,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
|||||||
case ".cert":
|
case ".cert":
|
||||||
certName := f.Name()
|
certName := f.Name()
|
||||||
keyName := certName[:len(certName)-5] + ".key"
|
keyName := certName[:len(certName)-5] + ".key"
|
||||||
log.G(context.TODO()).Debugf("cert: %s", filepath.Join(directory, certName))
|
log.G(ctx).Debugf("cert: %s", filepath.Join(directory, certName))
|
||||||
if !hasFile(fs, keyName) {
|
if !hasFile(fs, keyName) {
|
||||||
return invalidParamf("missing key %s for client certificate %s. CA certificates must use the extension .crt", keyName, certName)
|
return invalidParamf("missing key %s for client certificate %s. CA certificates must use the extension .crt", keyName, certName)
|
||||||
}
|
}
|
||||||
@ -95,7 +107,7 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
|||||||
case ".key":
|
case ".key":
|
||||||
keyName := f.Name()
|
keyName := f.Name()
|
||||||
certName := keyName[:len(keyName)-4] + ".cert"
|
certName := keyName[:len(keyName)-4] + ".cert"
|
||||||
log.G(context.TODO()).Debugf("key: %s", filepath.Join(directory, keyName))
|
log.G(ctx).Debugf("key: %s", filepath.Join(directory, keyName))
|
||||||
if !hasFile(fs, certName) {
|
if !hasFile(fs, certName) {
|
||||||
return invalidParamf("missing client certificate %s for key %s", certName, keyName)
|
return invalidParamf("missing client certificate %s for key %s", certName, keyName)
|
||||||
}
|
}
|
||||||
@ -126,15 +138,13 @@ func newTransport(tlsConfig *tls.Config) http.RoundTripper {
|
|||||||
tlsConfig = tlsconfig.ServerDefault()
|
tlsConfig = tlsconfig.ServerDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
direct := &net.Dialer{
|
|
||||||
Timeout: 30 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}
|
|
||||||
|
|
||||||
return otelhttp.NewTransport(
|
return otelhttp.NewTransport(
|
||||||
&http.Transport{
|
&http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
DialContext: direct.DialContext,
|
DialContext: (&net.Dialer{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
KeepAlive: 30 * time.Second,
|
||||||
|
}).DialContext,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
TLSClientConfig: tlsConfig,
|
TLSClientConfig: tlsConfig,
|
||||||
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
||||||
|
7
vendor/github.com/docker/docker/registry/search.go
generated
vendored
7
vendor/github.com/docker/docker/registry/search.go
generated
vendored
@ -84,7 +84,6 @@ func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, headers http.Header) (*registry.SearchResults, error) {
|
func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int, authConfig *registry.AuthConfig, headers http.Header) (*registry.SearchResults, error) {
|
||||||
// TODO Use ctx when searching for repositories
|
|
||||||
if hasScheme(term) {
|
if hasScheme(term) {
|
||||||
return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)
|
return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)
|
||||||
}
|
}
|
||||||
@ -100,7 +99,7 @@ func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int,
|
|||||||
remoteName = strings.TrimPrefix(remoteName, "library/")
|
remoteName = strings.TrimPrefix(remoteName, "library/")
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint, err := newV1Endpoint(index, headers)
|
endpoint, err := newV1Endpoint(ctx, index, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -126,12 +125,12 @@ func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int,
|
|||||||
client = v2Client
|
client = v2Client
|
||||||
} else {
|
} else {
|
||||||
client = endpoint.client
|
client = endpoint.client
|
||||||
if err := authorizeClient(client, authConfig, endpoint); err != nil {
|
if err := authorizeClient(ctx, client, authConfig, endpoint); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newSession(client, endpoint).searchRepositories(remoteName, limit)
|
return newSession(client, endpoint).searchRepositories(ctx, remoteName, limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitReposSearchTerm breaks a search term into an index name and remote name
|
// splitReposSearchTerm breaks a search term into an index name and remote name
|
||||||
|
29
vendor/github.com/docker/docker/registry/search_endpoint_v1.go
generated
vendored
29
vendor/github.com/docker/docker/registry/search_endpoint_v1.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@ -31,8 +32,8 @@ type v1Endpoint struct {
|
|||||||
|
|
||||||
// newV1Endpoint parses the given address to return a registry endpoint.
|
// newV1Endpoint parses the given address to return a registry endpoint.
|
||||||
// TODO: remove. This is only used by search.
|
// TODO: remove. This is only used by search.
|
||||||
func newV1Endpoint(index *registry.IndexInfo, headers http.Header) (*v1Endpoint, error) {
|
func newV1Endpoint(ctx context.Context, index *registry.IndexInfo, headers http.Header) (*v1Endpoint, error) {
|
||||||
tlsConfig, err := newTLSConfig(index.Name, index.Secure)
|
tlsConfig, err := newTLSConfig(ctx, index.Name, index.Secure)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -50,7 +51,10 @@ func newV1Endpoint(index *registry.IndexInfo, headers http.Header) (*v1Endpoint,
|
|||||||
|
|
||||||
// Try HTTPS ping to registry
|
// Try HTTPS ping to registry
|
||||||
endpoint.URL.Scheme = "https"
|
endpoint.URL.Scheme = "https"
|
||||||
if _, err := endpoint.ping(); err != nil {
|
if _, err := endpoint.ping(ctx); err != nil {
|
||||||
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if endpoint.IsSecure {
|
if endpoint.IsSecure {
|
||||||
// If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry`
|
// If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry`
|
||||||
// in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fall back to HTTP.
|
// in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fall back to HTTP.
|
||||||
@ -58,9 +62,9 @@ func newV1Endpoint(index *registry.IndexInfo, headers http.Header) (*v1Endpoint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// registry is insecure and HTTPS failed, fallback to HTTP.
|
// registry is insecure and HTTPS failed, fallback to HTTP.
|
||||||
log.G(context.TODO()).WithError(err).Debugf("error from registry %q marked as insecure - insecurely falling back to HTTP", endpoint)
|
log.G(ctx).WithError(err).Debugf("error from registry %q marked as insecure - insecurely falling back to HTTP", endpoint)
|
||||||
endpoint.URL.Scheme = "http"
|
endpoint.URL.Scheme = "http"
|
||||||
if _, err2 := endpoint.ping(); err2 != nil {
|
if _, err2 := endpoint.ping(ctx); err2 != nil {
|
||||||
return nil, invalidParamf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2)
|
return nil, invalidParamf("invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +113,7 @@ func (e *v1Endpoint) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ping returns a v1PingResult which indicates whether the registry is standalone or not.
|
// ping returns a v1PingResult which indicates whether the registry is standalone or not.
|
||||||
func (e *v1Endpoint) ping() (v1PingResult, error) {
|
func (e *v1Endpoint) ping(ctx context.Context) (v1PingResult, error) {
|
||||||
if e.String() == IndexServer {
|
if e.String() == IndexServer {
|
||||||
// Skip the check, we know this one is valid
|
// Skip the check, we know this one is valid
|
||||||
// (and we never want to fallback to http in case of error)
|
// (and we never want to fallback to http in case of error)
|
||||||
@ -117,14 +121,17 @@ func (e *v1Endpoint) ping() (v1PingResult, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pingURL := e.String() + "_ping"
|
pingURL := e.String() + "_ping"
|
||||||
log.G(context.TODO()).WithField("url", pingURL).Debug("attempting v1 ping for registry endpoint")
|
log.G(ctx).WithField("url", pingURL).Debug("attempting v1 ping for registry endpoint")
|
||||||
req, err := http.NewRequest(http.MethodGet, pingURL, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, pingURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v1PingResult{}, invalidParam(err)
|
return v1PingResult{}, invalidParam(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := e.client.Do(req)
|
resp, err := e.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
return v1PingResult{}, err
|
||||||
|
}
|
||||||
return v1PingResult{}, invalidParam(err)
|
return v1PingResult{}, invalidParam(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +143,7 @@ func (e *v1Endpoint) ping() (v1PingResult, error) {
|
|||||||
if v == "1" || strings.EqualFold(v, "true") {
|
if v == "1" || strings.EqualFold(v, "true") {
|
||||||
info.Standalone = true
|
info.Standalone = true
|
||||||
}
|
}
|
||||||
log.G(context.TODO()).Debugf("v1PingResult.Standalone (from X-Docker-Registry-Standalone header): %t", info.Standalone)
|
log.G(ctx).Debugf("v1PingResult.Standalone (from X-Docker-Registry-Standalone header): %t", info.Standalone)
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,11 +153,11 @@ func (e *v1Endpoint) ping() (v1PingResult, error) {
|
|||||||
Standalone: true,
|
Standalone: true,
|
||||||
}
|
}
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
|
||||||
log.G(context.TODO()).WithError(err).Debug("error unmarshaling _ping response")
|
log.G(ctx).WithError(err).Debug("error unmarshaling _ping response")
|
||||||
// don't stop here. Just assume sane defaults
|
// don't stop here. Just assume sane defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
log.G(context.TODO()).Debugf("v1PingResult.Standalone: %t", info.Standalone)
|
log.G(ctx).Debugf("v1PingResult.Standalone: %t", info.Standalone)
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
vendor/github.com/docker/docker/registry/search_session.go
generated
vendored
36
vendor/github.com/docker/docker/registry/search_session.go
generated
vendored
@ -26,8 +26,8 @@ type session struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type authTransport struct {
|
type authTransport struct {
|
||||||
http.RoundTripper
|
base http.RoundTripper
|
||||||
*registry.AuthConfig
|
authConfig *registry.AuthConfig
|
||||||
|
|
||||||
alwaysSetBasicAuth bool
|
alwaysSetBasicAuth bool
|
||||||
token []string
|
token []string
|
||||||
@ -54,8 +54,8 @@ func newAuthTransport(base http.RoundTripper, authConfig *registry.AuthConfig, a
|
|||||||
base = http.DefaultTransport
|
base = http.DefaultTransport
|
||||||
}
|
}
|
||||||
return &authTransport{
|
return &authTransport{
|
||||||
RoundTripper: base,
|
base: base,
|
||||||
AuthConfig: authConfig,
|
authConfig: authConfig,
|
||||||
alwaysSetBasicAuth: alwaysSetBasicAuth,
|
alwaysSetBasicAuth: alwaysSetBasicAuth,
|
||||||
modReq: make(map[*http.Request]*http.Request),
|
modReq: make(map[*http.Request]*http.Request),
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ func (tr *authTransport) RoundTrip(orig *http.Request) (*http.Response, error) {
|
|||||||
// a 302 redirect is detected by looking at the Referrer header as go http package adds said header.
|
// a 302 redirect is detected by looking at the Referrer header as go http package adds said header.
|
||||||
// This is safe as Docker doesn't set Referrer in other scenarios.
|
// This is safe as Docker doesn't set Referrer in other scenarios.
|
||||||
if orig.Header.Get("Referer") != "" && !trustedLocation(orig) {
|
if orig.Header.Get("Referer") != "" && !trustedLocation(orig) {
|
||||||
return tr.RoundTripper.RoundTrip(orig)
|
return tr.base.RoundTrip(orig)
|
||||||
}
|
}
|
||||||
|
|
||||||
req := cloneRequest(orig)
|
req := cloneRequest(orig)
|
||||||
@ -123,22 +123,22 @@ func (tr *authTransport) RoundTrip(orig *http.Request) (*http.Response, error) {
|
|||||||
tr.mu.Unlock()
|
tr.mu.Unlock()
|
||||||
|
|
||||||
if tr.alwaysSetBasicAuth {
|
if tr.alwaysSetBasicAuth {
|
||||||
if tr.AuthConfig == nil {
|
if tr.authConfig == nil {
|
||||||
return nil, errors.New("unexpected error: empty auth config")
|
return nil, errors.New("unexpected error: empty auth config")
|
||||||
}
|
}
|
||||||
req.SetBasicAuth(tr.Username, tr.Password)
|
req.SetBasicAuth(tr.authConfig.Username, tr.authConfig.Password)
|
||||||
return tr.RoundTripper.RoundTrip(req)
|
return tr.base.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't override
|
// Don't override
|
||||||
if req.Header.Get("Authorization") == "" {
|
if req.Header.Get("Authorization") == "" {
|
||||||
if req.Header.Get("X-Docker-Token") == "true" && tr.AuthConfig != nil && len(tr.Username) > 0 {
|
if req.Header.Get("X-Docker-Token") == "true" && tr.authConfig != nil && len(tr.authConfig.Username) > 0 {
|
||||||
req.SetBasicAuth(tr.Username, tr.Password)
|
req.SetBasicAuth(tr.authConfig.Username, tr.authConfig.Password)
|
||||||
} else if len(tr.token) > 0 {
|
} else if len(tr.token) > 0 {
|
||||||
req.Header.Set("Authorization", "Token "+strings.Join(tr.token, ","))
|
req.Header.Set("Authorization", "Token "+strings.Join(tr.token, ","))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp, err := tr.RoundTripper.RoundTrip(req)
|
resp, err := tr.base.RoundTrip(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tr.mu.Lock()
|
tr.mu.Lock()
|
||||||
delete(tr.modReq, orig)
|
delete(tr.modReq, orig)
|
||||||
@ -164,7 +164,7 @@ func (tr *authTransport) CancelRequest(req *http.Request) {
|
|||||||
type canceler interface {
|
type canceler interface {
|
||||||
CancelRequest(*http.Request)
|
CancelRequest(*http.Request)
|
||||||
}
|
}
|
||||||
if cr, ok := tr.RoundTripper.(canceler); ok {
|
if cr, ok := tr.base.(canceler); ok {
|
||||||
tr.mu.Lock()
|
tr.mu.Lock()
|
||||||
modReq := tr.modReq[req]
|
modReq := tr.modReq[req]
|
||||||
delete(tr.modReq, req)
|
delete(tr.modReq, req)
|
||||||
@ -173,18 +173,18 @@ func (tr *authTransport) CancelRequest(req *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func authorizeClient(client *http.Client, authConfig *registry.AuthConfig, endpoint *v1Endpoint) error {
|
func authorizeClient(ctx context.Context, client *http.Client, authConfig *registry.AuthConfig, endpoint *v1Endpoint) error {
|
||||||
var alwaysSetBasicAuth bool
|
var alwaysSetBasicAuth bool
|
||||||
|
|
||||||
// If we're working with a standalone private registry over HTTPS, send Basic Auth headers
|
// If we're working with a standalone private registry over HTTPS, send Basic Auth headers
|
||||||
// alongside all our requests.
|
// alongside all our requests.
|
||||||
if endpoint.String() != IndexServer && endpoint.URL.Scheme == "https" {
|
if endpoint.String() != IndexServer && endpoint.URL.Scheme == "https" {
|
||||||
info, err := endpoint.ping()
|
info, err := endpoint.ping(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if info.Standalone && authConfig != nil {
|
if info.Standalone && authConfig != nil {
|
||||||
log.G(context.TODO()).Debugf("Endpoint %s is eligible for private registry. Enabling decorator.", endpoint.String())
|
log.G(ctx).WithField("endpoint", endpoint.String()).Debug("Endpoint is eligible for private registry; enabling alwaysSetBasicAuth")
|
||||||
alwaysSetBasicAuth = true
|
alwaysSetBasicAuth = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ func newSession(client *http.Client, endpoint *v1Endpoint) *session {
|
|||||||
const defaultSearchLimit = 25
|
const defaultSearchLimit = 25
|
||||||
|
|
||||||
// searchRepositories performs a search against the remote repository
|
// searchRepositories performs a search against the remote repository
|
||||||
func (r *session) searchRepositories(term string, limit int) (*registry.SearchResults, error) {
|
func (r *session) searchRepositories(ctx context.Context, term string, limit int) (*registry.SearchResults, error) {
|
||||||
if limit == 0 {
|
if limit == 0 {
|
||||||
limit = defaultSearchLimit
|
limit = defaultSearchLimit
|
||||||
}
|
}
|
||||||
@ -221,9 +221,9 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
|
|||||||
return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
|
return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
|
||||||
}
|
}
|
||||||
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
|
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
|
||||||
log.G(context.TODO()).WithField("url", u).Debug("searchRepositories")
|
log.G(ctx).WithField("url", u).Debug("searchRepositories")
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, invalidParamWrapf(err, "error building request")
|
return nil, invalidParamWrapf(err, "error building request")
|
||||||
}
|
}
|
||||||
|
38
vendor/github.com/docker/docker/registry/service.go
generated
vendored
38
vendor/github.com/docker/docker/registry/service.go
generated
vendored
@ -24,6 +24,9 @@ type Service struct {
|
|||||||
// an engine.
|
// an engine.
|
||||||
func NewService(options ServiceOptions) (*Service, error) {
|
func NewService(options ServiceOptions) (*Service, error) {
|
||||||
config, err := newServiceConfig(options)
|
config, err := newServiceConfig(options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Service{config: config}, err
|
return &Service{config: config}, err
|
||||||
}
|
}
|
||||||
@ -71,17 +74,20 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
|
|||||||
// Lookup endpoints for authentication but exclude mirrors to prevent
|
// Lookup endpoints for authentication but exclude mirrors to prevent
|
||||||
// sending credentials of the upstream registry to a mirror.
|
// sending credentials of the upstream registry to a mirror.
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
endpoints, err := s.lookupV2Endpoints(registryHostName, false)
|
endpoints, err := s.lookupV2Endpoints(ctx, registryHostName, false)
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errdefs.IsContext(err) {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
return "", "", invalidParam(err)
|
return "", "", invalidParam(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastErr error
|
var lastErr error
|
||||||
for _, endpoint := range endpoints {
|
for _, endpoint := range endpoints {
|
||||||
authToken, err := loginV2(authConfig, endpoint, userAgent)
|
authToken, err := loginV2(ctx, authConfig, endpoint, userAgent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsUnauthorized(err) {
|
if errdefs.IsContext(err) || errdefs.IsUnauthorized(err) {
|
||||||
// Failed to authenticate; don't continue with (non-TLS) endpoints.
|
// Failed to authenticate; don't continue with (non-TLS) endpoints.
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
@ -103,6 +109,8 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
|
|||||||
|
|
||||||
// ResolveRepository splits a repository name into its components
|
// ResolveRepository splits a repository name into its components
|
||||||
// and configuration of the associated registry.
|
// and configuration of the associated registry.
|
||||||
|
//
|
||||||
|
// Deprecated: this function was only used internally and is no longer used. It will be removed in the next release.
|
||||||
func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
|
func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
@ -110,12 +118,30 @@ func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, erro
|
|||||||
return newRepositoryInfo(s.config, name), nil
|
return newRepositoryInfo(s.config, name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveAuthConfig looks up authentication for the given reference from the
|
||||||
|
// given authConfigs.
|
||||||
|
//
|
||||||
|
// IMPORTANT: This function is for internal use and should not be used by external projects.
|
||||||
|
func (s *Service) ResolveAuthConfig(authConfigs map[string]registry.AuthConfig, ref reference.Named) registry.AuthConfig {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
// Simplified version of "newIndexInfo" without handling of insecure
|
||||||
|
// registries and mirrors, as we don't need that information to resolve
|
||||||
|
// the auth-config.
|
||||||
|
indexName := normalizeIndexName(reference.Domain(ref))
|
||||||
|
registryInfo, ok := s.config.IndexConfigs[indexName]
|
||||||
|
if !ok {
|
||||||
|
registryInfo = ®istry.IndexInfo{Name: indexName}
|
||||||
|
}
|
||||||
|
return ResolveAuthConfig(authConfigs, registryInfo)
|
||||||
|
}
|
||||||
|
|
||||||
// APIEndpoint represents a remote API endpoint
|
// APIEndpoint represents a remote API endpoint
|
||||||
type APIEndpoint struct {
|
type APIEndpoint struct {
|
||||||
Mirror bool
|
Mirror bool
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
AllowNondistributableArtifacts bool // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
|
AllowNondistributableArtifacts bool // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
|
||||||
Official bool
|
Official bool // Deprecated: this field was only used internally, and will be removed in the next release.
|
||||||
TrimHostname bool // Deprecated: hostname is now trimmed unconditionally for remote names. This field will be removed in the next release.
|
TrimHostname bool // Deprecated: hostname is now trimmed unconditionally for remote names. This field will be removed in the next release.
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
}
|
}
|
||||||
@ -126,7 +152,7 @@ func (s *Service) LookupPullEndpoints(hostname string) (endpoints []APIEndpoint,
|
|||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
return s.lookupV2Endpoints(hostname, true)
|
return s.lookupV2Endpoints(context.TODO(), hostname, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference.
|
// LookupPushEndpoints creates a list of v2 endpoints to try to push to, in order of preference.
|
||||||
@ -135,7 +161,7 @@ func (s *Service) LookupPushEndpoints(hostname string) (endpoints []APIEndpoint,
|
|||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
return s.lookupV2Endpoints(hostname, false)
|
return s.lookupV2Endpoints(context.TODO(), hostname, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInsecureRegistry returns true if the registry at given host is configured as
|
// IsInsecureRegistry returns true if the registry at given host is configured as
|
||||||
|
11
vendor/github.com/docker/docker/registry/service_v2.go
generated
vendored
11
vendor/github.com/docker/docker/registry/service_v2.go
generated
vendored
@ -1,17 +1,21 @@
|
|||||||
package registry // import "github.com/docker/docker/registry"
|
package registry // import "github.com/docker/docker/registry"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]APIEndpoint, error) {
|
func (s *Service) lookupV2Endpoints(ctx context.Context, hostname string, includeMirrors bool) ([]APIEndpoint, error) {
|
||||||
var endpoints []APIEndpoint
|
var endpoints []APIEndpoint
|
||||||
if hostname == DefaultNamespace || hostname == IndexHostname {
|
if hostname == DefaultNamespace || hostname == IndexHostname {
|
||||||
if includeMirrors {
|
if includeMirrors {
|
||||||
for _, mirror := range s.config.Mirrors {
|
for _, mirror := range s.config.Mirrors {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
|
if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
|
||||||
mirror = "https://" + mirror
|
mirror = "https://" + mirror
|
||||||
}
|
}
|
||||||
@ -19,7 +23,8 @@ func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]API
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, invalidParam(err)
|
return nil, invalidParam(err)
|
||||||
}
|
}
|
||||||
mirrorTLSConfig, err := newTLSConfig(mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host))
|
// TODO(thaJeztah); this should all be memoized when loading the config. We're resolving mirrors and loading TLS config every time.
|
||||||
|
mirrorTLSConfig, err := newTLSConfig(ctx, mirrorURL.Host, s.config.isSecureIndex(mirrorURL.Host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -39,7 +44,7 @@ func (s *Service) lookupV2Endpoints(hostname string, includeMirrors bool) ([]API
|
|||||||
return endpoints, nil
|
return endpoints, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig, err := newTLSConfig(hostname, s.config.isSecureIndex(hostname))
|
tlsConfig, err := newTLSConfig(ctx, hostname, s.config.isSecureIndex(hostname))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -272,7 +272,7 @@ github.com/docker/distribution/registry/client/auth/challenge
|
|||||||
github.com/docker/distribution/registry/client/transport
|
github.com/docker/distribution/registry/client/transport
|
||||||
github.com/docker/distribution/registry/storage/cache
|
github.com/docker/distribution/registry/storage/cache
|
||||||
github.com/docker/distribution/registry/storage/cache/memory
|
github.com/docker/distribution/registry/storage/cache/memory
|
||||||
# github.com/docker/docker v28.0.4+incompatible
|
# github.com/docker/docker v28.1.0+incompatible
|
||||||
## explicit
|
## explicit
|
||||||
github.com/docker/docker/api
|
github.com/docker/docker/api
|
||||||
github.com/docker/docker/api/types
|
github.com/docker/docker/api/types
|
||||||
|
Loading…
x
Reference in New Issue
Block a user