mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 00:47:48 +08:00
vendor: github.com/docker/docker v28.0.2
full diff: https://github.com/docker/docker/compare/v28.0.1...v28.0.2 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
967fc2a696
commit
882ef0db91
2
go.mod
2
go.mod
@ -19,7 +19,7 @@ require (
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v28.0.1+incompatible
|
||||
github.com/docker/cli-docs-tool v0.9.0
|
||||
github.com/docker/docker v28.0.1+incompatible
|
||||
github.com/docker/docker v28.0.2+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/gofrs/flock v0.12.1
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
|
4
go.sum
4
go.sum
@ -129,8 +129,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.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/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
|
||||
github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.0.2+incompatible h1:9BILleFwug5FSSqWBgVevgL3ewDJfWWWyZVqlDMttE8=
|
||||
github.com/docker/docker v28.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
|
12
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
12
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
@ -5508,8 +5508,11 @@ definitions:
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Data:
|
||||
description: |
|
||||
Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5))
|
||||
data to store as secret.
|
||||
Data is the data to store as a secret, formatted as a Base64-url-safe-encoded
|
||||
([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5)) string.
|
||||
It must be empty if the Driver field is set, in which case the data is
|
||||
loaded from an external secret store. The maximum allowed size is 500KB,
|
||||
as defined in [MaxSecretSize](https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/api/validation#MaxSecretSize).
|
||||
|
||||
This field is only used to _create_ a secret, and is not returned by
|
||||
other endpoints.
|
||||
@ -5560,8 +5563,9 @@ definitions:
|
||||
type: "string"
|
||||
Data:
|
||||
description: |
|
||||
Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5))
|
||||
config data.
|
||||
Data is the data to store as a config, formatted as a Base64-url-safe-encoded
|
||||
([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5)) string.
|
||||
The maximum allowed size is 1000KB, as defined in [MaxConfigSize](https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/manager/controlapi#MaxConfigSize).
|
||||
type: "string"
|
||||
Templating:
|
||||
description: |
|
||||
|
16
vendor/github.com/docker/docker/api/types/registry/registry.go
generated
vendored
16
vendor/github.com/docker/docker/api/types/registry/registry.go
generated
vendored
@ -49,15 +49,17 @@ func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets the IPNet from a byte array of JSON
|
||||
func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {
|
||||
func (ipnet *NetIPNet) UnmarshalJSON(b []byte) error {
|
||||
var ipnetStr string
|
||||
if err = json.Unmarshal(b, &ipnetStr); err == nil {
|
||||
var cidr *net.IPNet
|
||||
if _, cidr, err = net.ParseCIDR(ipnetStr); err == nil {
|
||||
if err := json.Unmarshal(b, &ipnetStr); err != nil {
|
||||
return err
|
||||
}
|
||||
_, cidr, err := net.ParseCIDR(ipnetStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*ipnet = NetIPNet(*cidr)
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// IndexInfo contains information about a registry
|
||||
|
6
vendor/github.com/docker/docker/api/types/swarm/config.go
generated
vendored
6
vendor/github.com/docker/docker/api/types/swarm/config.go
generated
vendored
@ -12,6 +12,12 @@ type Config struct {
|
||||
// ConfigSpec represents a config specification from a config in swarm
|
||||
type ConfigSpec struct {
|
||||
Annotations
|
||||
|
||||
// Data is the data to store as a config.
|
||||
//
|
||||
// The maximum allowed size is 1000KB, as defined in [MaxConfigSize].
|
||||
//
|
||||
// [MaxConfigSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/manager/controlapi#MaxConfigSize
|
||||
Data []byte `json:",omitempty"`
|
||||
|
||||
// Templating controls whether and how to evaluate the config payload as
|
||||
|
16
vendor/github.com/docker/docker/api/types/swarm/secret.go
generated
vendored
16
vendor/github.com/docker/docker/api/types/swarm/secret.go
generated
vendored
@ -12,8 +12,22 @@ type Secret struct {
|
||||
// SecretSpec represents a secret specification from a secret in swarm
|
||||
type SecretSpec struct {
|
||||
Annotations
|
||||
|
||||
// Data is the data to store as a secret. It must be empty if a
|
||||
// [Driver] is used, in which case the data is loaded from an external
|
||||
// secret store. The maximum allowed size is 500KB, as defined in
|
||||
// [MaxSecretSize].
|
||||
//
|
||||
// This field is only used to create the secret, and is not returned
|
||||
// by other endpoints.
|
||||
//
|
||||
// [MaxSecretSize]: https://pkg.go.dev/github.com/moby/swarmkit/v2@v2.0.0-20250103191802-8c1959736554/api/validation#MaxSecretSize
|
||||
Data []byte `json:",omitempty"`
|
||||
Driver *Driver `json:",omitempty"` // name of the secrets driver used to fetch the secret's value from an external secret store
|
||||
|
||||
// Driver is the name of the secrets driver used to fetch the secret's
|
||||
// value from an external secret store. If not set, the default built-in
|
||||
// store is used.
|
||||
Driver *Driver `json:",omitempty"`
|
||||
|
||||
// Templating controls whether and how to evaluate the secret payload as
|
||||
// a template. If it is not set, no templating is used.
|
||||
|
14
vendor/github.com/docker/docker/client/container_create.go
generated
vendored
14
vendor/github.com/docker/docker/client/container_create.go
generated
vendored
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
@ -54,6 +55,19 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
||||
// When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
if versions.LessThan(cli.ClientVersion(), "1.44") {
|
||||
for _, m := range hostConfig.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
// ReadOnlyNonRecursive can be safely ignored when API < 1.44
|
||||
if m.BindOptions.ReadOnlyForceRecursive {
|
||||
return response, errors.New("bind-recursive=readonly requires API v1.44 or later")
|
||||
}
|
||||
if m.BindOptions.NonRecursive && versions.LessThan(cli.ClientVersion(), "1.40") {
|
||||
return response, errors.New("bind-recursive=disabled requires API v1.40 or later")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd)
|
||||
hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop)
|
||||
|
20
vendor/github.com/docker/docker/client/service_create.go
generated
vendored
20
vendor/github.com/docker/docker/client/service_create.go
generated
vendored
@ -37,6 +37,11 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
|
||||
if err := validateServiceSpec(service); err != nil {
|
||||
return response, err
|
||||
}
|
||||
if versions.LessThan(cli.version, "1.30") {
|
||||
if err := validateAPIVersion(service, cli.version); err != nil {
|
||||
return response, err
|
||||
}
|
||||
}
|
||||
|
||||
// ensure that the image is tagged
|
||||
var resolveWarning string
|
||||
@ -191,3 +196,18 @@ func validateServiceSpec(s swarm.ServiceSpec) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateAPIVersion(c swarm.ServiceSpec, apiVersion string) error {
|
||||
for _, m := range c.TaskTemplate.ContainerSpec.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
if m.BindOptions.NonRecursive && versions.LessThan(apiVersion, "1.40") {
|
||||
return errors.Errorf("bind-recursive=disabled requires API v1.40 or later")
|
||||
}
|
||||
// ReadOnlyNonRecursive can be safely ignored when API < 1.44
|
||||
if m.BindOptions.ReadOnlyForceRecursive && versions.LessThan(apiVersion, "1.44") {
|
||||
return errors.Errorf("bind-recursive=readonly requires API v1.44 or later")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
24
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
24
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
@ -236,11 +236,9 @@ func (r *readCloserWrapper) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
bufioReader32KPool = &sync.Pool{
|
||||
var bufioReader32KPool = &sync.Pool{
|
||||
New: func() interface{} { return bufio.NewReaderSize(nil, 32*1024) },
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
type bufferedReader struct {
|
||||
buf *bufio.Reader
|
||||
@ -252,17 +250,17 @@ func newBufferedReader(r io.Reader) *bufferedReader {
|
||||
return &bufferedReader{buf}
|
||||
}
|
||||
|
||||
func (r *bufferedReader) Read(p []byte) (n int, err error) {
|
||||
func (r *bufferedReader) Read(p []byte) (int, error) {
|
||||
if r.buf == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n, err = r.buf.Read(p)
|
||||
n, err := r.buf.Read(p)
|
||||
if err == io.EOF {
|
||||
r.buf.Reset(nil)
|
||||
bufioReader32KPool.Put(r.buf)
|
||||
r.buf = nil
|
||||
}
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *bufferedReader) Peek(n int) ([]byte, error) {
|
||||
@ -428,7 +426,7 @@ func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModi
|
||||
pipeWriter.CloseWithError(err)
|
||||
return
|
||||
}
|
||||
if _, err := copyWithBuffer(tarWriter, tarReader); err != nil {
|
||||
if err := copyWithBuffer(tarWriter, tarReader); err != nil {
|
||||
pipeWriter.CloseWithError(err)
|
||||
return
|
||||
}
|
||||
@ -731,7 +729,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = copyWithBuffer(ta.TarWriter, file)
|
||||
err = copyWithBuffer(ta.TarWriter, file)
|
||||
file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -778,11 +776,11 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := copyWithBuffer(file, reader); err != nil {
|
||||
file.Close()
|
||||
if err := copyWithBuffer(file, reader); err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
_ = file.Close()
|
||||
|
||||
case tar.TypeBlock, tar.TypeChar:
|
||||
if inUserns { // cannot create devices in a userns
|
||||
@ -1438,7 +1436,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := copyWithBuffer(tw, srcF); err != nil {
|
||||
if err := copyWithBuffer(tw, srcF); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
21
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
21
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
@ -20,7 +20,7 @@ func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter {
|
||||
|
||||
type overlayWhiteoutConverter struct{}
|
||||
|
||||
func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) (wo *tar.Header, err error) {
|
||||
func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) (wo *tar.Header, _ error) {
|
||||
// convert whiteouts to AUFS format
|
||||
if fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 {
|
||||
// we just rename the file and make it normal
|
||||
@ -31,7 +31,11 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
|
||||
hdr.Size = 0
|
||||
}
|
||||
|
||||
if fi.Mode()&os.ModeDir != 0 {
|
||||
if fi.Mode()&os.ModeDir == 0 {
|
||||
// FIXME(thaJeztah): return a sentinel error instead of nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
opaqueXattrName := "trusted.overlay.opaque"
|
||||
if userns.RunningInUserNS() {
|
||||
opaqueXattrName = "user.overlay.opaque"
|
||||
@ -42,12 +46,15 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(opaque) == 1 && opaque[0] == 'y' {
|
||||
if len(opaque) != 1 || opaque[0] != 'y' {
|
||||
// FIXME(thaJeztah): return a sentinel error instead of nil, nil
|
||||
return nil, nil
|
||||
}
|
||||
delete(hdr.PAXRecords, paxSchilyXattr+opaqueXattrName)
|
||||
|
||||
// create a header for the whiteout file
|
||||
// it should inherit some properties from the parent, but be a regular file
|
||||
wo = &tar.Header{
|
||||
return &tar.Header{
|
||||
Typeflag: tar.TypeReg,
|
||||
Mode: hdr.Mode & int64(os.ModePerm),
|
||||
Name: filepath.Join(hdr.Name, WhiteoutOpaqueDir), // #nosec G305 -- An archive is being created, not extracted.
|
||||
@ -58,11 +65,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
|
||||
Gname: hdr.Gname,
|
||||
AccessTime: hdr.AccessTime,
|
||||
ChangeTime: hdr.ChangeTime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) {
|
||||
|
11
vendor/github.com/docker/docker/pkg/archive/archive_unix.go
generated
vendored
11
vendor/github.com/docker/docker/pkg/archive/archive_unix.go
generated
vendored
@ -73,14 +73,13 @@ func statUnix(fi os.FileInfo, hdr *tar.Header) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInodeFromStat(stat interface{}) (inode uint64, err error) {
|
||||
func getInodeFromStat(stat interface{}) (uint64, error) {
|
||||
s, ok := stat.(*syscall.Stat_t)
|
||||
|
||||
if ok {
|
||||
inode = s.Ino
|
||||
if !ok {
|
||||
// FIXME(thaJeztah): this should likely return an error; see https://github.com/moby/moby/pull/49493#discussion_r1979152897
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return
|
||||
return s.Ino, nil
|
||||
}
|
||||
|
||||
func getFileUIDGID(stat interface{}) (idtools.Identity, error) {
|
||||
|
4
vendor/github.com/docker/docker/pkg/archive/archive_windows.go
generated
vendored
4
vendor/github.com/docker/docker/pkg/archive/archive_windows.go
generated
vendored
@ -48,9 +48,9 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (
|
||||
return
|
||||
}
|
||||
|
||||
func getInodeFromStat(stat interface{}) (inode uint64, err error) {
|
||||
func getInodeFromStat(stat interface{}) (uint64, error) {
|
||||
// do nothing. no notion of Inode in stat on Windows
|
||||
return
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
|
||||
|
2
vendor/github.com/docker/docker/pkg/archive/changes.go
generated
vendored
2
vendor/github.com/docker/docker/pkg/archive/changes.go
generated
vendored
@ -83,7 +83,7 @@ func aufsMetadataSkip(path string) (skip bool, err error) {
|
||||
if err != nil {
|
||||
skip = true
|
||||
}
|
||||
return
|
||||
return skip, err
|
||||
}
|
||||
|
||||
func aufsDeletedFile(root, path string, fi os.FileInfo) (string, error) {
|
||||
|
22
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
22
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
@ -25,11 +25,11 @@ var copyPool = sync.Pool{
|
||||
New: func() interface{} { s := make([]byte, 32*1024); return &s },
|
||||
}
|
||||
|
||||
func copyWithBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
func copyWithBuffer(dst io.Writer, src io.Reader) error {
|
||||
buf := copyPool.Get().(*[]byte)
|
||||
written, err = io.CopyBuffer(dst, src, *buf)
|
||||
_, err := io.CopyBuffer(dst, src, *buf)
|
||||
copyPool.Put(buf)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// PreserveTrailingDotOrSeparator returns the given cleaned path (after
|
||||
@ -105,13 +105,13 @@ func TarResource(sourceInfo CopyInfo) (content io.ReadCloser, err error) {
|
||||
|
||||
// TarResourceRebase is like TarResource but renames the first path element of
|
||||
// items in the resulting tar archive to match the given rebaseName if not "".
|
||||
func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, err error) {
|
||||
func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, _ error) {
|
||||
sourcePath = normalizePath(sourcePath)
|
||||
if _, err = os.Lstat(sourcePath); err != nil {
|
||||
if _, err := os.Lstat(sourcePath); err != nil {
|
||||
// Catches the case where the source does not exist or is not a
|
||||
// directory if asserted to be a directory, as this also causes an
|
||||
// error.
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Separate the source path between its directory and
|
||||
@ -442,11 +442,12 @@ func CopyTo(content io.Reader, srcInfo CopyInfo, dstPath string) error {
|
||||
// whether to follow symbol link or not, if followLink is true, resolvedPath will return
|
||||
// link target of any symbol link file, else it will only resolve symlink of directory
|
||||
// but return symbol link file itself without resolving.
|
||||
func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseName string, err error) {
|
||||
func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseName string, _ error) {
|
||||
if followLink {
|
||||
var err error
|
||||
resolvedPath, err = filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
return
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
resolvedPath, rebaseName = GetRebaseName(path, resolvedPath)
|
||||
@ -454,10 +455,9 @@ func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseNa
|
||||
dirPath, basePath := filepath.Split(path)
|
||||
|
||||
// if not follow symbol link, then resolve symbol link of parent dir
|
||||
var resolvedDirPath string
|
||||
resolvedDirPath, err = filepath.EvalSymlinks(dirPath)
|
||||
resolvedDirPath, err := filepath.EvalSymlinks(dirPath)
|
||||
if err != nil {
|
||||
return
|
||||
return "", "", err
|
||||
}
|
||||
// resolvedDirPath will have been cleaned (no trailing path separators) so
|
||||
// we can manually join it with the base path element.
|
||||
|
9
vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go
generated
vendored
9
vendor/github.com/docker/docker/pkg/archive/time_nonwindows.go
generated
vendored
@ -17,12 +17,13 @@ func chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
return os.Chtimes(name, atime, mtime)
|
||||
}
|
||||
|
||||
func timeToTimespec(time time.Time) (ts unix.Timespec) {
|
||||
func timeToTimespec(time time.Time) unix.Timespec {
|
||||
if time.IsZero() {
|
||||
// Return UTIME_OMIT special value
|
||||
ts.Sec = 0
|
||||
ts.Nsec = (1 << 30) - 2
|
||||
return
|
||||
return unix.Timespec{
|
||||
Sec: 0,
|
||||
Nsec: (1 << 30) - 2,
|
||||
}
|
||||
}
|
||||
return unix.NsecToTimespec(time.UnixNano())
|
||||
}
|
||||
|
6
vendor/github.com/docker/docker/pkg/archive/wrap.go
generated
vendored
6
vendor/github.com/docker/docker/pkg/archive/wrap.go
generated
vendored
@ -45,8 +45,8 @@ func Generate(input ...string) (io.Reader, error) {
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func parseStringPairs(input ...string) (output [][2]string) {
|
||||
output = make([][2]string, 0, len(input)/2+1)
|
||||
func parseStringPairs(input ...string) [][2]string {
|
||||
output := make([][2]string, 0, len(input)/2+1)
|
||||
for i := 0; i < len(input); i += 2 {
|
||||
var pair [2]string
|
||||
pair[0] = input[i]
|
||||
@ -55,5 +55,5 @@ func parseStringPairs(input ...string) (output [][2]string) {
|
||||
}
|
||||
output = append(output, pair)
|
||||
}
|
||||
return
|
||||
return output
|
||||
}
|
||||
|
4
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter.go
generated
vendored
4
vendor/github.com/docker/docker/pkg/atomicwriter/atomicwriter.go
generated
vendored
@ -11,12 +11,12 @@ import (
|
||||
// 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) {
|
||||
f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
|
||||
abspath, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
abspath, err := filepath.Abs(filename)
|
||||
f, err := os.CreateTemp(filepath.Dir(abspath), ".tmp-"+filepath.Base(filename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
8
vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go
generated
vendored
8
vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go
generated
vendored
@ -43,9 +43,9 @@ type stdWriter struct {
|
||||
// It inserts the prefix header before the buffer,
|
||||
// so stdcopy.StdCopy knows where to multiplex the output.
|
||||
// It makes stdWriter to implement io.Writer.
|
||||
func (w *stdWriter) Write(p []byte) (n int, err error) {
|
||||
func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
if w == nil || w.Writer == nil {
|
||||
return 0, errors.New("Writer not instantiated")
|
||||
return 0, errors.New("writer not instantiated")
|
||||
}
|
||||
if p == nil {
|
||||
return 0, nil
|
||||
@ -57,7 +57,7 @@ func (w *stdWriter) Write(p []byte) (n int, err error) {
|
||||
buf.Write(header[:])
|
||||
buf.Write(p)
|
||||
|
||||
n, err = w.Writer.Write(buf.Bytes())
|
||||
n, err := w.Writer.Write(buf.Bytes())
|
||||
n -= stdWriterPrefixLen
|
||||
if n < 0 {
|
||||
n = 0
|
||||
@ -65,7 +65,7 @@ func (w *stdWriter) Write(p []byte) (n int, err error) {
|
||||
|
||||
buf.Reset()
|
||||
bufPool.Put(buf)
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
// NewStdWriter instantiates a new Writer.
|
||||
|
16
vendor/github.com/docker/docker/registry/auth.go
generated
vendored
16
vendor/github.com/docker/docker/registry/auth.go
generated
vendored
@ -66,13 +66,13 @@ func (scs staticCredentialStore) SetRefreshToken(*url.URL, string, string) {
|
||||
// loginV2 tries to login to the v2 registry server. The given registry
|
||||
// endpoint will be pinged to get authorization challenges. These challenges
|
||||
// will be used to authenticate against the registry to validate credentials.
|
||||
func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (status string, token string, _ error) {
|
||||
func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent string) (token string, _ error) {
|
||||
endpointStr := strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
|
||||
log.G(context.TODO()).Debugf("attempting v2 login to registry endpoint %s", endpointStr)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, endpointStr, nil)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
return "", err
|
||||
}
|
||||
|
||||
var (
|
||||
@ -84,22 +84,22 @@ func loginV2(authConfig *registry.AuthConfig, endpoint APIEndpoint, userAgent st
|
||||
|
||||
loginClient, err := v2AuthHTTPClient(endpoint.URL, authTrans, modifiers, creds, nil)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := loginClient.Do(req)
|
||||
if err != nil {
|
||||
err = translateV2AuthError(err)
|
||||
return "", "", err
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return "Login Succeeded", credentialAuthConfig.IdentityToken, nil
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
|
||||
return "", errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||
}
|
||||
|
||||
// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
|
||||
return "", "", errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||
return credentialAuthConfig.IdentityToken, nil
|
||||
}
|
||||
|
||||
func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, error) {
|
||||
|
160
vendor/github.com/docker/docker/registry/config.go
generated
vendored
160
vendor/github.com/docker/docker/registry/config.go
generated
vendored
@ -4,13 +4,17 @@ import (
|
||||
"context"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/internal/lazyregexp"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
)
|
||||
|
||||
// ServiceOptions holds command line options.
|
||||
@ -56,26 +60,52 @@ var (
|
||||
Host: DefaultRegistryHost,
|
||||
}
|
||||
|
||||
emptyServiceConfig, _ = newServiceConfig(ServiceOptions{})
|
||||
validHostPortRegex = lazyregexp.New(`^` + reference.DomainRegexp.String() + `$`)
|
||||
|
||||
// certsDir is used to override defaultCertsDir.
|
||||
// certsDir is used to override defaultCertsDir when running with rootlessKit.
|
||||
//
|
||||
// TODO(thaJeztah): change to a sync.OnceValue once we remove [SetCertsDir]
|
||||
// TODO(thaJeztah): certsDir should not be a package variable, but stored in our config, and passed when needed.
|
||||
setCertsDirOnce sync.Once
|
||||
certsDir string
|
||||
)
|
||||
|
||||
func setCertsDir(dir string) string {
|
||||
setCertsDirOnce.Do(func() {
|
||||
if dir != "" {
|
||||
certsDir = dir
|
||||
return
|
||||
}
|
||||
if os.Getenv("ROOTLESSKIT_STATE_DIR") != "" {
|
||||
// Configure registry.CertsDir() when running in rootless-mode
|
||||
// This is the equivalent of [rootless.RunningWithRootlessKit],
|
||||
// but inlining it to prevent adding that as a dependency
|
||||
// for docker/cli.
|
||||
//
|
||||
// [rootless.RunningWithRootlessKit]: https://github.com/moby/moby/blob/b4bdf12daec84caaf809a639f923f7370d4926ad/pkg/rootless/rootless.go#L5-L8
|
||||
if configHome, _ := homedir.GetConfigHome(); configHome != "" {
|
||||
certsDir = filepath.Join(configHome, "docker/certs.d")
|
||||
return
|
||||
}
|
||||
}
|
||||
certsDir = defaultCertsDir
|
||||
})
|
||||
return certsDir
|
||||
}
|
||||
|
||||
// SetCertsDir allows the default certs directory to be changed. This function
|
||||
// is used at daemon startup to set the correct location when running in
|
||||
// rootless mode.
|
||||
//
|
||||
// Deprecated: the cert-directory is now automatically selected when running with rootlessKit, and should no longer be set manually.
|
||||
func SetCertsDir(path string) {
|
||||
certsDir = path
|
||||
setCertsDir(path)
|
||||
}
|
||||
|
||||
// CertsDir is the directory where certificates are stored.
|
||||
func CertsDir() string {
|
||||
if certsDir != "" {
|
||||
return certsDir
|
||||
}
|
||||
return defaultCertsDir
|
||||
// call setCertsDir with an empty path to synchronise with [SetCertsDir]
|
||||
return setCertsDir("")
|
||||
}
|
||||
|
||||
// newServiceConfig returns a new instance of ServiceConfig
|
||||
@ -181,7 +211,7 @@ skip:
|
||||
// Assume `host:port` if not CIDR.
|
||||
indexConfigs[r] = ®istry.IndexInfo{
|
||||
Name: r,
|
||||
Mirrors: make([]string, 0),
|
||||
Mirrors: []string{},
|
||||
Secure: false,
|
||||
Official: false,
|
||||
}
|
||||
@ -288,16 +318,22 @@ func ValidateMirror(val string) (string, error) {
|
||||
// ValidateIndexName validates an index name. It is used by the daemon to
|
||||
// validate the daemon configuration.
|
||||
func ValidateIndexName(val string) (string, error) {
|
||||
// TODO: upstream this to check to reference package
|
||||
if val == "index.docker.io" {
|
||||
val = "docker.io"
|
||||
}
|
||||
val = normalizeIndexName(val)
|
||||
if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") {
|
||||
return "", invalidParamf("invalid index name (%s). Cannot begin or end with a hyphen", val)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func normalizeIndexName(val string) string {
|
||||
// TODO(thaJeztah): consider normalizing other known options, such as "(https://)registry-1.docker.io", "https://index.docker.io/v1/".
|
||||
// TODO: upstream this to check to reference package
|
||||
if val == "index.docker.io" {
|
||||
return "docker.io"
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func hasScheme(reposName string) bool {
|
||||
return strings.Contains(reposName, "://")
|
||||
}
|
||||
@ -327,25 +363,20 @@ func validateHostPort(s string) error {
|
||||
}
|
||||
|
||||
// newIndexInfo returns IndexInfo configuration from indexName
|
||||
func newIndexInfo(config *serviceConfig, indexName string) (*registry.IndexInfo, error) {
|
||||
var err error
|
||||
indexName, err = ValidateIndexName(indexName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func newIndexInfo(config *serviceConfig, indexName string) *registry.IndexInfo {
|
||||
indexName = normalizeIndexName(indexName)
|
||||
|
||||
// Return any configured index info, first.
|
||||
if index, ok := config.IndexConfigs[indexName]; ok {
|
||||
return index, nil
|
||||
return index
|
||||
}
|
||||
|
||||
// Construct a non-configured index info.
|
||||
return ®istry.IndexInfo{
|
||||
Name: indexName,
|
||||
Mirrors: make([]string, 0),
|
||||
Mirrors: []string{},
|
||||
Secure: config.isSecureIndex(indexName),
|
||||
Official: false,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetAuthConfigKey special-cases using the full index address of the official
|
||||
@ -358,18 +389,22 @@ func GetAuthConfigKey(index *registry.IndexInfo) string {
|
||||
}
|
||||
|
||||
// newRepositoryInfo validates and breaks down a repository name into a RepositoryInfo
|
||||
func newRepositoryInfo(config *serviceConfig, name reference.Named) (*RepositoryInfo, error) {
|
||||
index, err := newIndexInfo(config, reference.Domain(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func newRepositoryInfo(config *serviceConfig, name reference.Named) *RepositoryInfo {
|
||||
index := newIndexInfo(config, reference.Domain(name))
|
||||
var officialRepo bool
|
||||
if index.Official {
|
||||
// RepositoryInfo.Official indicates whether the image repository
|
||||
// is an official (docker library official images) repository.
|
||||
//
|
||||
// We only need to check this if the image-repository is on Docker Hub.
|
||||
officialRepo = !strings.ContainsRune(reference.FamiliarName(name), '/')
|
||||
}
|
||||
official := !strings.ContainsRune(reference.FamiliarName(name), '/')
|
||||
|
||||
return &RepositoryInfo{
|
||||
Name: reference.TrimNamed(name),
|
||||
Index: index,
|
||||
Official: official,
|
||||
}, nil
|
||||
Official: officialRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// ParseRepositoryInfo performs the breakdown of a repository name into a
|
||||
@ -377,5 +412,70 @@ func newRepositoryInfo(config *serviceConfig, name reference.Named) (*Repository
|
||||
//
|
||||
// It is used by the Docker cli to interact with registry-related endpoints.
|
||||
func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
|
||||
return newRepositoryInfo(emptyServiceConfig, reposName)
|
||||
indexName := normalizeIndexName(reference.Domain(reposName))
|
||||
if indexName == IndexName {
|
||||
officialRepo := !strings.ContainsRune(reference.FamiliarName(reposName), '/')
|
||||
return &RepositoryInfo{
|
||||
Name: reference.TrimNamed(reposName),
|
||||
Index: ®istry.IndexInfo{
|
||||
Name: IndexName,
|
||||
Mirrors: []string{},
|
||||
Secure: true,
|
||||
Official: true,
|
||||
},
|
||||
Official: officialRepo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
insecure := false
|
||||
if isInsecure(indexName) {
|
||||
insecure = true
|
||||
}
|
||||
|
||||
return &RepositoryInfo{
|
||||
Name: reference.TrimNamed(reposName),
|
||||
Index: ®istry.IndexInfo{
|
||||
Name: indexName,
|
||||
Mirrors: []string{},
|
||||
Secure: !insecure,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// isInsecure is used to detect whether a registry domain or IP-address is allowed
|
||||
// to use an insecure (non-TLS, or self-signed cert) connection according to the
|
||||
// defaults, which allows for insecure connections with registries running on a
|
||||
// loopback address ("localhost", "::1/128", "127.0.0.0/8").
|
||||
//
|
||||
// It is used in situations where we don't have access to the daemon's configuration,
|
||||
// for example, when used from the client / CLI.
|
||||
func isInsecure(hostNameOrIP string) bool {
|
||||
// Attempt to strip port if present; this also strips brackets for
|
||||
// IPv6 addresses with a port (e.g. "[::1]:5000").
|
||||
//
|
||||
// This is best-effort; we'll continue using the address as-is if it fails.
|
||||
if host, _, err := net.SplitHostPort(hostNameOrIP); err == nil {
|
||||
hostNameOrIP = host
|
||||
}
|
||||
if hostNameOrIP == "127.0.0.1" || hostNameOrIP == "::1" || strings.EqualFold(hostNameOrIP, "localhost") {
|
||||
// Fast path; no need to resolve these, assuming nobody overrides
|
||||
// "localhost" for anything else than a loopback address (sorry, not sorry).
|
||||
return true
|
||||
}
|
||||
|
||||
var addresses []net.IP
|
||||
if ip := net.ParseIP(hostNameOrIP); ip != nil {
|
||||
addresses = append(addresses, ip)
|
||||
} else {
|
||||
// Try to resolve the host's IP-addresses.
|
||||
addrs, _ := lookupIP(hostNameOrIP)
|
||||
addresses = append(addresses, addrs...)
|
||||
}
|
||||
|
||||
for _, addr := range addresses {
|
||||
if addr.IsLoopback() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
31
vendor/github.com/docker/docker/registry/registry.go
generated
vendored
31
vendor/github.com/docker/docker/registry/registry.go
generated
vendored
@ -8,7 +8,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/log"
|
||||
@ -18,7 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// HostCertsDir returns the config directory for a specific host.
|
||||
//
|
||||
// Deprecated: this function was only used internally, and will be removed in a future release.
|
||||
func HostCertsDir(hostname string) string {
|
||||
return hostCertsDir(hostname)
|
||||
}
|
||||
|
||||
// hostCertsDir returns the config directory for a specific host.
|
||||
func hostCertsDir(hostname string) string {
|
||||
return filepath.Join(CertsDir(), cleanPath(hostname))
|
||||
}
|
||||
|
||||
@ -26,11 +32,10 @@ func HostCertsDir(hostname string) string {
|
||||
func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
|
||||
// PreferredServerCipherSuites should have no effect
|
||||
tlsConfig := tlsconfig.ServerDefault()
|
||||
|
||||
tlsConfig.InsecureSkipVerify = !isSecure
|
||||
|
||||
if isSecure && CertsDir() != "" {
|
||||
hostDir := HostCertsDir(hostname)
|
||||
if isSecure {
|
||||
hostDir := hostCertsDir(hostname)
|
||||
log.G(context.TODO()).Debugf("hostDir: %s", hostDir)
|
||||
if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil {
|
||||
return nil, err
|
||||
@ -59,7 +64,8 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if strings.HasSuffix(f.Name(), ".crt") {
|
||||
switch filepath.Ext(f.Name()) {
|
||||
case ".crt":
|
||||
if tlsConfig.RootCAs == nil {
|
||||
systemPool, err := tlsconfig.SystemCertPool()
|
||||
if err != nil {
|
||||
@ -67,17 +73,17 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
||||
}
|
||||
tlsConfig.RootCAs = systemPool
|
||||
}
|
||||
log.G(context.TODO()).Debugf("crt: %s", filepath.Join(directory, f.Name()))
|
||||
data, err := os.ReadFile(filepath.Join(directory, f.Name()))
|
||||
fileName := filepath.Join(directory, f.Name())
|
||||
log.G(context.TODO()).Debugf("crt: %s", fileName)
|
||||
data, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tlsConfig.RootCAs.AppendCertsFromPEM(data)
|
||||
}
|
||||
if strings.HasSuffix(f.Name(), ".cert") {
|
||||
case ".cert":
|
||||
certName := f.Name()
|
||||
keyName := certName[:len(certName)-5] + ".key"
|
||||
log.G(context.TODO()).Debugf("cert: %s", filepath.Join(directory, f.Name()))
|
||||
log.G(context.TODO()).Debugf("cert: %s", filepath.Join(directory, certName))
|
||||
if !hasFile(fs, keyName) {
|
||||
return invalidParamf("missing key %s for client certificate %s. CA certificates must use the extension .crt", keyName, certName)
|
||||
}
|
||||
@ -86,11 +92,10 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
|
||||
return err
|
||||
}
|
||||
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
|
||||
}
|
||||
if strings.HasSuffix(f.Name(), ".key") {
|
||||
case ".key":
|
||||
keyName := f.Name()
|
||||
certName := keyName[:len(keyName)-4] + ".cert"
|
||||
log.G(context.TODO()).Debugf("key: %s", filepath.Join(directory, f.Name()))
|
||||
log.G(context.TODO()).Debugf("key: %s", filepath.Join(directory, keyName))
|
||||
if !hasFile(fs, certName) {
|
||||
return invalidParamf("missing client certificate %s for key %s", certName, keyName)
|
||||
}
|
||||
|
27
vendor/github.com/docker/docker/registry/search.go
generated
vendored
27
vendor/github.com/docker/docker/registry/search.go
generated
vendored
@ -93,12 +93,8 @@ func (s *Service) searchUnfiltered(ctx context.Context, term string, limit int,
|
||||
|
||||
// Search is a long-running operation, just lock s.config to avoid block others.
|
||||
s.mu.RLock()
|
||||
index, err := newIndexInfo(s.config, indexName)
|
||||
index := newIndexInfo(s.config, indexName)
|
||||
s.mu.RUnlock()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if index.Official {
|
||||
// If pull "library/foo", it's stored locally under "foo"
|
||||
remoteName = strings.TrimPrefix(remoteName, "library/")
|
||||
@ -158,5 +154,24 @@ func splitReposSearchTerm(reposName string) (string, string) {
|
||||
// for that.
|
||||
func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
|
||||
indexName, _ := splitReposSearchTerm(reposName)
|
||||
return newIndexInfo(emptyServiceConfig, indexName)
|
||||
indexName = normalizeIndexName(indexName)
|
||||
if indexName == IndexName {
|
||||
return ®istry.IndexInfo{
|
||||
Name: IndexName,
|
||||
Mirrors: []string{},
|
||||
Secure: true,
|
||||
Official: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
insecure := false
|
||||
if isInsecure(indexName) {
|
||||
insecure = true
|
||||
}
|
||||
|
||||
return ®istry.IndexInfo{
|
||||
Name: indexName,
|
||||
Mirrors: []string{},
|
||||
Secure: !insecure,
|
||||
}, nil
|
||||
}
|
||||
|
6
vendor/github.com/docker/docker/registry/search_session.go
generated
vendored
6
vendor/github.com/docker/docker/registry/search_session.go
generated
vendored
@ -83,12 +83,12 @@ type onEOFReader struct {
|
||||
Fn func()
|
||||
}
|
||||
|
||||
func (r *onEOFReader) Read(p []byte) (n int, err error) {
|
||||
n, err = r.Rc.Read(p)
|
||||
func (r *onEOFReader) Read(p []byte) (int, error) {
|
||||
n, err := r.Rc.Read(p)
|
||||
if err == io.EOF {
|
||||
r.runFunc()
|
||||
}
|
||||
return
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Close closes the file and run the function.
|
||||
|
28
vendor/github.com/docker/docker/registry/service.go
generated
vendored
28
vendor/github.com/docker/docker/registry/service.go
generated
vendored
@ -52,7 +52,7 @@ func (s *Service) ReplaceConfig(options ServiceOptions) (commit func(), err erro
|
||||
// Auth contacts the public registry with the provided credentials,
|
||||
// and returns OK if authentication was successful.
|
||||
// It can be used to verify the validity of a client's credentials.
|
||||
func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (status, token string, err error) {
|
||||
func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (statusMessage, token string, _ error) {
|
||||
// TODO Use ctx when searching for repositories
|
||||
registryHostName := IndexHostname
|
||||
|
||||
@ -77,19 +77,28 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
|
||||
return "", "", invalidParam(err)
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for _, endpoint := range endpoints {
|
||||
status, token, err = loginV2(authConfig, endpoint, userAgent)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
authToken, err := loginV2(authConfig, endpoint, userAgent)
|
||||
if err != nil {
|
||||
if errdefs.IsUnauthorized(err) {
|
||||
// Failed to authenticate; don't continue with (non-TLS) endpoints.
|
||||
return status, token, err
|
||||
return "", "", err
|
||||
}
|
||||
log.G(ctx).WithError(err).Infof("Error logging in to endpoint, trying next endpoint")
|
||||
// Try next endpoint
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"error": err,
|
||||
"endpoint": endpoint,
|
||||
}).Infof("Error logging in to endpoint, trying next endpoint")
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
|
||||
return "", "", err
|
||||
// TODO(thaJeztah): move the statusMessage to the API endpoint; we don't need to produce that here?
|
||||
return "Login Succeeded", authToken, nil
|
||||
}
|
||||
|
||||
return "", "", lastErr
|
||||
}
|
||||
|
||||
// ResolveRepository splits a repository name into its components
|
||||
@ -97,7 +106,8 @@ func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, use
|
||||
func (s *Service) ResolveRepository(name reference.Named) (*RepositoryInfo, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return newRepositoryInfo(s.config, name)
|
||||
// TODO(thaJeztah): remove error return as it's no longer used.
|
||||
return newRepositoryInfo(s.config, name), nil
|
||||
}
|
||||
|
||||
// APIEndpoint represents a remote API endpoint
|
||||
|
2
vendor/github.com/docker/docker/registry/types.go
generated
vendored
2
vendor/github.com/docker/docker/registry/types.go
generated
vendored
@ -13,6 +13,8 @@ type RepositoryInfo struct {
|
||||
// Official indicates whether the repository is considered official.
|
||||
// If the registry is official, and the normalized name does not
|
||||
// contain a '/' (e.g. "foo"), then it is considered an official repo.
|
||||
//
|
||||
// Deprecated: this field is no longer used and will be removed in the next release. The information captured in this field can be obtained from the [Name] field instead.
|
||||
Official bool
|
||||
// Class represents the class of the repository, such as "plugin"
|
||||
// or "image".
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -283,7 +283,7 @@ github.com/docker/distribution/registry/client/transport
|
||||
github.com/docker/distribution/registry/storage/cache
|
||||
github.com/docker/distribution/registry/storage/cache/memory
|
||||
github.com/docker/distribution/uuid
|
||||
# github.com/docker/docker v28.0.1+incompatible
|
||||
# github.com/docker/docker v28.0.2+incompatible
|
||||
## explicit
|
||||
github.com/docker/docker/api
|
||||
github.com/docker/docker/api/types
|
||||
|
Loading…
x
Reference in New Issue
Block a user