vendor: github.com/docker/docker v24.0.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>pull/1806/head
parent
9bd0202312
commit
75ad5d732b
@ -1,22 +1,7 @@
|
|||||||
package types // import "github.com/docker/docker/api/types"
|
package types // import "github.com/docker/docker/api/types"
|
||||||
|
import "github.com/docker/docker/api/types/registry"
|
||||||
|
|
||||||
// AuthConfig contains authorization information for connecting to a Registry
|
// AuthConfig contains authorization information for connecting to a Registry.
|
||||||
type AuthConfig struct {
|
//
|
||||||
Username string `json:"username,omitempty"`
|
// Deprecated: use github.com/docker/docker/api/types/registry.AuthConfig
|
||||||
Password string `json:"password,omitempty"`
|
type AuthConfig = registry.AuthConfig
|
||||||
Auth string `json:"auth,omitempty"`
|
|
||||||
|
|
||||||
// Email is an optional value associated with the username.
|
|
||||||
// This field is deprecated and will be removed in a later
|
|
||||||
// version of docker.
|
|
||||||
Email string `json:"email,omitempty"`
|
|
||||||
|
|
||||||
ServerAddress string `json:"serveraddress,omitempty"`
|
|
||||||
|
|
||||||
// IdentityToken is used to authenticate the user and get
|
|
||||||
// an access token for the registry.
|
|
||||||
IdentityToken string `json:"identitytoken,omitempty"`
|
|
||||||
|
|
||||||
// RegistryToken is a bearer token to be sent to a registry
|
|
||||||
RegistryToken string `json:"registrytoken,omitempty"`
|
|
||||||
}
|
|
||||||
|
6
vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go
generated
vendored
6
vendor/github.com/docker/docker/api/types/container/change_response_deprecated.go
generated
vendored
@ -0,0 +1,6 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
// ContainerChangeResponseItem change item in response to ContainerChanges operation
|
||||||
|
//
|
||||||
|
// Deprecated: use [FilesystemChange].
|
||||||
|
type ContainerChangeResponseItem = FilesystemChange
|
@ -0,0 +1,15 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
// ChangeType Kind of change
|
||||||
|
//
|
||||||
|
// Can be one of:
|
||||||
|
//
|
||||||
|
// - `0`: Modified ("C")
|
||||||
|
// - `1`: Added ("A")
|
||||||
|
// - `2`: Deleted ("D")
|
||||||
|
//
|
||||||
|
// swagger:model ChangeType
|
||||||
|
type ChangeType uint8
|
@ -0,0 +1,23 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ChangeModify represents the modify operation.
|
||||||
|
ChangeModify ChangeType = 0
|
||||||
|
// ChangeAdd represents the add operation.
|
||||||
|
ChangeAdd ChangeType = 1
|
||||||
|
// ChangeDelete represents the delete operation.
|
||||||
|
ChangeDelete ChangeType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ct ChangeType) String() string {
|
||||||
|
switch ct {
|
||||||
|
case ChangeModify:
|
||||||
|
return "C"
|
||||||
|
case ChangeAdd:
|
||||||
|
return "A"
|
||||||
|
case ChangeDelete:
|
||||||
|
return "D"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
package container // import "github.com/docker/docker/api/types/container"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Code generated by `swagger generate operation`. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// See hack/generate-swagger-api.sh
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// ContainerChangeResponseItem change item in response to ContainerChanges operation
|
|
||||||
// swagger:model ContainerChangeResponseItem
|
|
||||||
type ContainerChangeResponseItem struct {
|
|
||||||
|
|
||||||
// Kind of change
|
|
||||||
// Required: true
|
|
||||||
Kind uint8 `json:"Kind"`
|
|
||||||
|
|
||||||
// Path to file that has changed
|
|
||||||
// Required: true
|
|
||||||
Path string `json:"Path"`
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package container // import "github.com/docker/docker/api/types/container"
|
|
||||||
|
|
||||||
// ContainerCreateCreatedBody OK response to ContainerCreate operation
|
|
||||||
//
|
|
||||||
// Deprecated: use CreateResponse
|
|
||||||
type ContainerCreateCreatedBody = CreateResponse
|
|
||||||
|
|
||||||
// ContainerWaitOKBody OK response to ContainerWait operation
|
|
||||||
//
|
|
||||||
// Deprecated: use WaitResponse
|
|
||||||
type ContainerWaitOKBody = WaitResponse
|
|
||||||
|
|
||||||
// ContainerWaitOKBodyError container waiting error, if any
|
|
||||||
//
|
|
||||||
// Deprecated: use WaitExitError
|
|
||||||
type ContainerWaitOKBodyError = WaitExitError
|
|
@ -0,0 +1,19 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
// FilesystemChange Change in the container's filesystem.
|
||||||
|
//
|
||||||
|
// swagger:model FilesystemChange
|
||||||
|
type FilesystemChange struct {
|
||||||
|
|
||||||
|
// kind
|
||||||
|
// Required: true
|
||||||
|
Kind ChangeType `json:"Kind"`
|
||||||
|
|
||||||
|
// Path to file or directory that has changed.
|
||||||
|
//
|
||||||
|
// Required: true
|
||||||
|
Path string `json:"Path"`
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package types // import "github.com/docker/docker/api/types"
|
|
||||||
|
|
||||||
import "github.com/docker/docker/api/types/volume"
|
|
||||||
|
|
||||||
// Volume volume
|
|
||||||
//
|
|
||||||
// Deprecated: use github.com/docker/docker/api/types/volume.Volume
|
|
||||||
type Volume = volume.Volume
|
|
||||||
|
|
||||||
// VolumeUsageData Usage details about the volume. This information is used by the
|
|
||||||
// `GET /system/df` endpoint, and omitted in other endpoints.
|
|
||||||
//
|
|
||||||
// Deprecated: use github.com/docker/docker/api/types/volume.UsageData
|
|
||||||
type VolumeUsageData = volume.UsageData
|
|
@ -0,0 +1,37 @@
|
|||||||
|
package filters
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// invalidFilter indicates that the provided filter or its value is invalid
|
||||||
|
type invalidFilter struct {
|
||||||
|
Filter string
|
||||||
|
Value []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e invalidFilter) Error() string {
|
||||||
|
msg := "invalid filter"
|
||||||
|
if e.Filter != "" {
|
||||||
|
msg += " '" + e.Filter
|
||||||
|
if e.Value != nil {
|
||||||
|
msg = fmt.Sprintf("%s=%s", msg, e.Value)
|
||||||
|
}
|
||||||
|
msg += "'"
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvalidParameter marks this error as ErrInvalidParameter
|
||||||
|
func (e invalidFilter) InvalidParameter() {}
|
||||||
|
|
||||||
|
// unreachableCode is an error indicating that the code path was not expected to be reached.
|
||||||
|
type unreachableCode struct {
|
||||||
|
Filter string
|
||||||
|
Value []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// System marks this error as ErrSystem
|
||||||
|
func (e unreachableCode) System() {}
|
||||||
|
|
||||||
|
func (e unreachableCode) Error() string {
|
||||||
|
return fmt.Sprintf("unreachable code reached for filter: %q with values: %s", e.Filter, e.Value)
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package image
|
||||||
|
|
||||||
|
import specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
|
||||||
|
// GetImageOpts holds parameters to inspect an image.
|
||||||
|
type GetImageOpts struct {
|
||||||
|
Platform *specs.Platform
|
||||||
|
Details bool
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package registry // import "github.com/docker/docker/api/types/registry"
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AuthHeader is the name of the header used to send encoded registry
|
||||||
|
// authorization credentials for registry operations (push/pull).
|
||||||
|
const AuthHeader = "X-Registry-Auth"
|
||||||
|
|
||||||
|
// AuthConfig contains authorization information for connecting to a Registry.
|
||||||
|
type AuthConfig struct {
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
Auth string `json:"auth,omitempty"`
|
||||||
|
|
||||||
|
// Email is an optional value associated with the username.
|
||||||
|
// This field is deprecated and will be removed in a later
|
||||||
|
// version of docker.
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
|
||||||
|
ServerAddress string `json:"serveraddress,omitempty"`
|
||||||
|
|
||||||
|
// IdentityToken is used to authenticate the user and get
|
||||||
|
// an access token for the registry.
|
||||||
|
IdentityToken string `json:"identitytoken,omitempty"`
|
||||||
|
|
||||||
|
// RegistryToken is a bearer token to be sent to a registry
|
||||||
|
RegistryToken string `json:"registrytoken,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeAuthConfig serializes the auth configuration as a base64url encoded
|
||||||
|
// RFC4648, section 5) JSON string for sending through the X-Registry-Auth header.
|
||||||
|
//
|
||||||
|
// For details on base64url encoding, see:
|
||||||
|
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
|
||||||
|
func EncodeAuthConfig(authConfig AuthConfig) (string, error) {
|
||||||
|
buf, err := json.Marshal(authConfig)
|
||||||
|
if err != nil {
|
||||||
|
return "", errInvalidParameter{err}
|
||||||
|
}
|
||||||
|
return base64.URLEncoding.EncodeToString(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON
|
||||||
|
// authentication information as sent through the X-Registry-Auth header.
|
||||||
|
//
|
||||||
|
// This function always returns an AuthConfig, even if an error occurs. It is up
|
||||||
|
// to the caller to decide if authentication is required, and if the error can
|
||||||
|
// be ignored.
|
||||||
|
//
|
||||||
|
// For details on base64url encoding, see:
|
||||||
|
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
|
||||||
|
func DecodeAuthConfig(authEncoded string) (*AuthConfig, error) {
|
||||||
|
if authEncoded == "" {
|
||||||
|
return &AuthConfig{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
|
||||||
|
return decodeAuthConfigFromReader(authJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeAuthConfigBody decodes authentication information as sent as JSON in the
|
||||||
|
// body of a request. This function is to provide backward compatibility with old
|
||||||
|
// clients and API versions. Current clients and API versions expect authentication
|
||||||
|
// to be provided through the X-Registry-Auth header.
|
||||||
|
//
|
||||||
|
// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an
|
||||||
|
// error occurs. It is up to the caller to decide if authentication is required,
|
||||||
|
// and if the error can be ignored.
|
||||||
|
func DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) {
|
||||||
|
return decodeAuthConfigFromReader(rdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) {
|
||||||
|
authConfig := &AuthConfig{}
|
||||||
|
if err := json.NewDecoder(rdr).Decode(authConfig); err != nil {
|
||||||
|
// always return an (empty) AuthConfig to increase compatibility with
|
||||||
|
// the existing API.
|
||||||
|
return &AuthConfig{}, invalid(err)
|
||||||
|
}
|
||||||
|
return authConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func invalid(err error) error {
|
||||||
|
return errInvalidParameter{errors.Wrap(err, "invalid X-Registry-Auth header")}
|
||||||
|
}
|
||||||
|
|
||||||
|
type errInvalidParameter struct{ error }
|
||||||
|
|
||||||
|
func (errInvalidParameter) InvalidParameter() {}
|
||||||
|
|
||||||
|
func (e errInvalidParameter) Cause() error { return e.error }
|
||||||
|
|
||||||
|
func (e errInvalidParameter) Unwrap() error { return e.error }
|
@ -1,11 +0,0 @@
|
|||||||
package volume // import "github.com/docker/docker/api/types/volume"
|
|
||||||
|
|
||||||
// VolumeCreateBody Volume configuration
|
|
||||||
//
|
|
||||||
// Deprecated: use CreateOptions
|
|
||||||
type VolumeCreateBody = CreateOptions
|
|
||||||
|
|
||||||
// VolumeListOKBody Volume list response
|
|
||||||
//
|
|
||||||
// Deprecated: use ListResponse
|
|
||||||
type VolumeListOKBody = ListResponse
|
|
@ -1 +0,0 @@
|
|||||||
This code provides helper functions for dealing with archive files.
|
|
@ -0,0 +1,20 @@
|
|||||||
|
package archive
|
||||||
|
|
||||||
|
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
||||||
|
// is the system drive.
|
||||||
|
// On Linux: this is a no-op.
|
||||||
|
// On Windows: this does the following>
|
||||||
|
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
|
||||||
|
// This is used, for example, when validating a user provided path in docker cp.
|
||||||
|
// If a drive letter is supplied, it must be the system drive. The drive letter
|
||||||
|
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
||||||
|
// need the path in this syntax so that it can ultimately be concatenated with
|
||||||
|
// a Windows long-path which doesn't support drive-letters. Examples:
|
||||||
|
// C: --> Fail
|
||||||
|
// C:\ --> \
|
||||||
|
// a --> a
|
||||||
|
// /a --> \a
|
||||||
|
// d:\ --> Fail
|
||||||
|
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||||
|
return checkSystemDriveAndRemoveDriveLetter(path)
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package archive
|
||||||
|
|
||||||
|
// checkSystemDriveAndRemoveDriveLetter is the non-Windows implementation
|
||||||
|
// of CheckSystemDriveAndRemoveDriveLetter
|
||||||
|
func checkSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||||
|
return path, nil
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checkSystemDriveAndRemoveDriveLetter is the Windows implementation
|
||||||
|
// of CheckSystemDriveAndRemoveDriveLetter
|
||||||
|
func checkSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||||
|
if len(path) == 2 && string(path[1]) == ":" {
|
||||||
|
return "", fmt.Errorf("no relative path specified in %q", path)
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(path) || len(path) < 2 {
|
||||||
|
return filepath.FromSlash(path), nil
|
||||||
|
}
|
||||||
|
if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
|
||||||
|
return "", fmt.Errorf("the specified path is not on the system drive (C:)")
|
||||||
|
}
|
||||||
|
return filepath.FromSlash(path[2:]), nil
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
// TempDir on Unix systems is equivalent to os.MkdirTemp.
|
|
||||||
func TempDir(dir, prefix string) (string, error) {
|
|
||||||
return os.MkdirTemp(dir, prefix)
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package ioutils // import "github.com/docker/docker/pkg/ioutils"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/longpath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TempDir is the equivalent of os.MkdirTemp, except that the result is in Windows longpath format.
|
|
||||||
func TempDir(dir, prefix string) (string, error) {
|
|
||||||
tempDir, err := os.MkdirTemp(dir, prefix)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return longpath.AddPrefix(tempDir), nil
|
|
||||||
}
|
|
@ -0,0 +1,10 @@
|
|||||||
|
package ioutils
|
||||||
|
|
||||||
|
import "github.com/docker/docker/pkg/longpath"
|
||||||
|
|
||||||
|
// TempDir is the equivalent of [os.MkdirTemp], except that on Windows
|
||||||
|
// the result is in Windows longpath format. On Unix systems it is
|
||||||
|
// equivalent to [os.MkdirTemp].
|
||||||
|
//
|
||||||
|
// Deprecated: use [longpath.MkdirTemp].
|
||||||
|
var TempDir = longpath.MkdirTemp
|
@ -0,0 +1,26 @@
|
|||||||
|
// Package meminfo provides utilites to retrieve memory statistics of
|
||||||
|
// the host system.
|
||||||
|
package meminfo
|
||||||
|
|
||||||
|
// Read retrieves memory statistics of the host system and returns a
|
||||||
|
// Memory type. It is only supported on Linux and Windows, and returns an
|
||||||
|
// error on other platforms.
|
||||||
|
func Read() (*Memory, error) {
|
||||||
|
return readMemInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory contains memory statistics of the host system.
|
||||||
|
type Memory struct {
|
||||||
|
// Total usable RAM (i.e. physical RAM minus a few reserved bits and the
|
||||||
|
// kernel binary code).
|
||||||
|
MemTotal int64
|
||||||
|
|
||||||
|
// Amount of free memory.
|
||||||
|
MemFree int64
|
||||||
|
|
||||||
|
// Total amount of swap space available.
|
||||||
|
SwapTotal int64
|
||||||
|
|
||||||
|
// Amount of swap space that is currently unused.
|
||||||
|
SwapFree int64
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
//go:build !linux && !windows
|
||||||
|
// +build !linux,!windows
|
||||||
|
|
||||||
|
package meminfo
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// readMemInfo is not supported on platforms other than linux and windows.
|
||||||
|
func readMemInfo() (*Memory, error) {
|
||||||
|
return nil, errors.New("platform and architecture is not supported")
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
// Package process provides a set of basic functions to manage individual
|
||||||
|
// processes.
|
||||||
|
package process
|
@ -0,0 +1,82 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alive returns true if process with a given pid is running. It only considers
|
||||||
|
// positive PIDs; 0 (all processes in the current process group), -1 (all processes
|
||||||
|
// with a PID larger than 1), and negative (-n, all processes in process group
|
||||||
|
// "n") values for pid are never considered to be alive.
|
||||||
|
func Alive(pid int) bool {
|
||||||
|
if pid < 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
// OS X does not have a proc filesystem. Use kill -0 pid to judge if the
|
||||||
|
// process exists. From KILL(2): https://www.freebsd.org/cgi/man.cgi?query=kill&sektion=2&manpath=OpenDarwin+7.2.1
|
||||||
|
//
|
||||||
|
// Sig may be one of the signals specified in sigaction(2) or it may
|
||||||
|
// be 0, in which case error checking is performed but no signal is
|
||||||
|
// actually sent. This can be used to check the validity of pid.
|
||||||
|
err := unix.Kill(pid, 0)
|
||||||
|
|
||||||
|
// Either the PID was found (no error) or we get an EPERM, which means
|
||||||
|
// the PID exists, but we don't have permissions to signal it.
|
||||||
|
return err == nil || err == unix.EPERM
|
||||||
|
default:
|
||||||
|
_, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid)))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill force-stops a process. It only considers positive PIDs; 0 (all processes
|
||||||
|
// in the current process group), -1 (all processes with a PID larger than 1),
|
||||||
|
// and negative (-n, all processes in process group "n") values for pid are
|
||||||
|
// ignored. Refer to [KILL(2)] for details.
|
||||||
|
//
|
||||||
|
// [KILL(2)]: https://man7.org/linux/man-pages/man2/kill.2.html
|
||||||
|
func Kill(pid int) error {
|
||||||
|
if pid < 1 {
|
||||||
|
return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid)
|
||||||
|
}
|
||||||
|
err := unix.Kill(pid, unix.SIGKILL)
|
||||||
|
if err != nil && err != unix.ESRCH {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zombie return true if process has a state with "Z". It only considers positive
|
||||||
|
// PIDs; 0 (all processes in the current process group), -1 (all processes with
|
||||||
|
// a PID larger than 1), and negative (-n, all processes in process group "n")
|
||||||
|
// values for pid are ignored. Refer to [PROC(5)] for details.
|
||||||
|
//
|
||||||
|
// [PROC(5)]: https://man7.org/linux/man-pages/man5/proc.5.html
|
||||||
|
func Zombie(pid int) (bool, error) {
|
||||||
|
if pid < 1 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if cols := bytes.SplitN(data, []byte(" "), 4); len(cols) >= 3 && string(cols[2]) == "Z" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alive returns true if process with a given pid is running.
|
||||||
|
func Alive(pid int) bool {
|
||||||
|
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var c uint32
|
||||||
|
err = windows.GetExitCodeProcess(h, &c)
|
||||||
|
_ = windows.CloseHandle(h)
|
||||||
|
if err != nil {
|
||||||
|
// From the GetExitCodeProcess function (processthreadsapi.h) API docs:
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
|
||||||
|
//
|
||||||
|
// The GetExitCodeProcess function returns a valid error code defined by the
|
||||||
|
// application only after the thread terminates. Therefore, an application should
|
||||||
|
// not use STILL_ACTIVE (259) as an error code (STILL_ACTIVE is a macro for
|
||||||
|
// STATUS_PENDING (minwinbase.h)). If a thread returns STILL_ACTIVE (259) as
|
||||||
|
// an error code, then applications that test for that value could interpret it
|
||||||
|
// to mean that the thread is still running, and continue to test for the
|
||||||
|
// completion of the thread after the thread has terminated, which could put
|
||||||
|
// the application into an infinite loop.
|
||||||
|
return c == uint32(windows.STATUS_PENDING)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill force-stops a process.
|
||||||
|
func Kill(pid int) error {
|
||||||
|
p, err := os.FindProcess(pid)
|
||||||
|
if err == nil {
|
||||||
|
err = p.Kill()
|
||||||
|
if err != nil && err != os.ErrProcessDone {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zombie is not supported on Windows.
|
||||||
|
//
|
||||||
|
// TODO(thaJeztah): remove once we remove the stubs from pkg/system.
|
||||||
|
func Zombie(_ int) (bool, error) {
|
||||||
|
return false, nil
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/moby/sys/sequential"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateSequential is deprecated.
|
|
||||||
//
|
|
||||||
// Deprecated: use os.Create or github.com/moby/sys/sequential.Create()
|
|
||||||
func CreateSequential(name string) (*os.File, error) {
|
|
||||||
return sequential.Create(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenSequential is deprecated.
|
|
||||||
//
|
|
||||||
// Deprecated: use os.Open or github.com/moby/sys/sequential.Open
|
|
||||||
func OpenSequential(name string) (*os.File, error) {
|
|
||||||
return sequential.Open(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenFileSequential is deprecated.
|
|
||||||
//
|
|
||||||
// Deprecated: use github.com/moby/sys/sequential.OpenFile()
|
|
||||||
func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, error) {
|
|
||||||
return sequential.OpenFile(name, flag, perm)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TempFileSequential is deprecated.
|
|
||||||
//
|
|
||||||
// Deprecated: use os.CreateTemp or github.com/moby/sys/sequential.CreateTemp
|
|
||||||
func TempFileSequential(dir, prefix string) (f *os.File, err error) {
|
|
||||||
return sequential.CreateTemp(dir, prefix)
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Used by chtimes
|
|
||||||
var maxTime time.Time
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// chtimes initialization
|
|
||||||
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
|
|
||||||
// This is a 64 bit timespec
|
|
||||||
// os.Chtimes limits time to the following
|
|
||||||
maxTime = time.Unix(0, 1<<63-1)
|
|
||||||
} else {
|
|
||||||
// This is a 32 bit timespec
|
|
||||||
maxTime = time.Unix(1<<31-1, 0)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
// MemInfo contains memory statistics of the host system.
|
|
||||||
type MemInfo struct {
|
|
||||||
// Total usable RAM (i.e. physical RAM minus a few reserved bits and the
|
|
||||||
// kernel binary code).
|
|
||||||
MemTotal int64
|
|
||||||
|
|
||||||
// Amount of free memory.
|
|
||||||
MemFree int64
|
|
||||||
|
|
||||||
// Total amount of swap space available.
|
|
||||||
SwapTotal int64
|
|
||||||
|
|
||||||
// Amount of swap space that is currently unused.
|
|
||||||
SwapFree int64
|
|
||||||
}
|
|
@ -0,0 +1,16 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "github.com/docker/docker/pkg/meminfo"
|
||||||
|
|
||||||
|
// MemInfo contains memory statistics of the host system.
|
||||||
|
//
|
||||||
|
// Deprecated: use [meminfo.Memory].
|
||||||
|
type MemInfo = meminfo.Memory
|
||||||
|
|
||||||
|
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||||
|
// MemInfo type.
|
||||||
|
//
|
||||||
|
// Deprecated: use [meminfo.Read].
|
||||||
|
func ReadMemInfo() (*meminfo.Memory, error) {
|
||||||
|
return meminfo.Read()
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
//go:build !linux && !windows
|
|
||||||
// +build !linux,!windows
|
|
||||||
|
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
// ReadMemInfo is not supported on platforms other than linux and windows.
|
|
||||||
func ReadMemInfo() (*MemInfo, error) {
|
|
||||||
return nil, ErrNotSupportedPlatform
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
||||||
|
|
||||||
// DefaultPathEnv is unix style list of directories to search for
|
|
||||||
// executables. Each directory is separated from the next by a colon
|
|
||||||
// ':' character .
|
|
||||||
// For Windows containers, an empty string is returned as the default
|
|
||||||
// path will be set by the container, and Docker has no context of what the
|
|
||||||
// default path should be.
|
|
||||||
func DefaultPathEnv(os string) string {
|
|
||||||
if os == "windows" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return defaultUnixPathEnv
|
|
||||||
}
|
|
||||||
|
|
||||||
// PathVerifier defines the subset of a PathDriver that CheckSystemDriveAndRemoveDriveLetter
|
|
||||||
// actually uses in order to avoid system depending on containerd/continuity.
|
|
||||||
type PathVerifier interface {
|
|
||||||
IsAbs(string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
|
||||||
// is the system drive.
|
|
||||||
// On Linux: this is a no-op.
|
|
||||||
// On Windows: this does the following>
|
|
||||||
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
|
|
||||||
// This is used, for example, when validating a user provided path in docker cp.
|
|
||||||
// If a drive letter is supplied, it must be the system drive. The drive letter
|
|
||||||
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
|
||||||
// need the path in this syntax so that it can ultimately be concatenated with
|
|
||||||
// a Windows long-path which doesn't support drive-letters. Examples:
|
|
||||||
// C: --> Fail
|
|
||||||
// C:\ --> \
|
|
||||||
// a --> a
|
|
||||||
// /a --> \a
|
|
||||||
// d:\ --> Fail
|
|
||||||
func CheckSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) {
|
|
||||||
return checkSystemDriveAndRemoveDriveLetter(path, driver)
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
|
// DefaultPathEnv is unix style list of directories to search for
|
||||||
|
// executables. Each directory is separated from the next by a colon
|
||||||
|
// ':' character .
|
||||||
|
// For Windows containers, an empty string is returned as the default
|
||||||
|
// path will be set by the container, and Docker has no context of what the
|
||||||
|
// default path should be.
|
||||||
|
//
|
||||||
|
// Deprecated: use oci.DefaultPathEnv
|
||||||
|
func DefaultPathEnv(os string) string {
|
||||||
|
if os == "windows" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return defaultUnixPathEnv
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
// GetLongPathName converts Windows short pathnames to full pathnames.
|
|
||||||
// For example C:\Users\ADMIN~1 --> C:\Users\Administrator.
|
|
||||||
// It is a no-op on non-Windows platforms
|
|
||||||
func GetLongPathName(path string) (string, error) {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkSystemDriveAndRemoveDriveLetter is the non-Windows implementation
|
|
||||||
// of CheckSystemDriveAndRemoveDriveLetter
|
|
||||||
func checkSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetLongPathName converts Windows short pathnames to full pathnames.
|
|
||||||
// For example C:\Users\ADMIN~1 --> C:\Users\Administrator.
|
|
||||||
// It is a no-op on non-Windows platforms
|
|
||||||
func GetLongPathName(path string) (string, error) {
|
|
||||||
// See https://groups.google.com/forum/#!topic/golang-dev/1tufzkruoTg
|
|
||||||
p, err := windows.UTF16FromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
b := p // GetLongPathName says we can reuse buffer
|
|
||||||
n, err := windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if n > uint32(len(b)) {
|
|
||||||
b = make([]uint16, n)
|
|
||||||
_, err = windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return windows.UTF16ToString(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkSystemDriveAndRemoveDriveLetter is the Windows implementation
|
|
||||||
// of CheckSystemDriveAndRemoveDriveLetter
|
|
||||||
func checkSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) {
|
|
||||||
if len(path) == 2 && string(path[1]) == ":" {
|
|
||||||
return "", fmt.Errorf("No relative path specified in %q", path)
|
|
||||||
}
|
|
||||||
if !driver.IsAbs(path) || len(path) < 2 {
|
|
||||||
return filepath.FromSlash(path), nil
|
|
||||||
}
|
|
||||||
if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
|
|
||||||
return "", fmt.Errorf("The specified path is not on the system drive (C:)")
|
|
||||||
}
|
|
||||||
return filepath.FromSlash(path[2:]), nil
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
//go:build linux || freebsd || darwin || windows
|
||||||
|
// +build linux freebsd darwin windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import "github.com/docker/docker/pkg/process"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// IsProcessAlive returns true if process with a given pid is running.
|
||||||
|
//
|
||||||
|
// Deprecated: use [process.Alive].
|
||||||
|
IsProcessAlive = process.Alive
|
||||||
|
|
||||||
|
// IsProcessZombie return true if process has a state with "Z"
|
||||||
|
//
|
||||||
|
// Deprecated: use [process.Zombie].
|
||||||
|
//
|
||||||
|
// TODO(thaJeztah): remove the Windows implementation in process once we remove this stub.
|
||||||
|
IsProcessZombie = process.Zombie
|
||||||
|
)
|
||||||
|
|
||||||
|
// KillProcess force-stops a process.
|
||||||
|
//
|
||||||
|
// Deprecated: use [process.Kill].
|
||||||
|
func KillProcess(pid int) {
|
||||||
|
_ = process.Kill(pid)
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
//go:build linux || freebsd || darwin
|
|
||||||
// +build linux freebsd darwin
|
|
||||||
|
|
||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsProcessAlive returns true if process with a given pid is running.
|
|
||||||
func IsProcessAlive(pid int) bool {
|
|
||||||
err := unix.Kill(pid, syscall.Signal(0))
|
|
||||||
if err == nil || err == unix.EPERM {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// KillProcess force-stops a process.
|
|
||||||
func KillProcess(pid int) {
|
|
||||||
unix.Kill(pid, unix.SIGKILL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsProcessZombie return true if process has a state with "Z"
|
|
||||||
// http://man7.org/linux/man-pages/man5/proc.5.html
|
|
||||||
func IsProcessZombie(pid int) (bool, error) {
|
|
||||||
statPath := fmt.Sprintf("/proc/%d/stat", pid)
|
|
||||||
dataBytes, err := os.ReadFile(statPath)
|
|
||||||
if err != nil {
|
|
||||||
// TODO(thaJeztah) should we ignore os.IsNotExist() here? ("/proc/<pid>/stat" will be gone if the process exited)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
data := string(dataBytes)
|
|
||||||
sdata := strings.SplitN(data, " ", 4)
|
|
||||||
if len(sdata) >= 3 && sdata[2] == "Z" {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
// IsProcessAlive returns true if process with a given pid is running.
|
|
||||||
func IsProcessAlive(pid int) bool {
|
|
||||||
_, err := os.FindProcess(pid)
|
|
||||||
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// KillProcess force-stops a process.
|
|
||||||
func KillProcess(pid int) {
|
|
||||||
p, err := os.FindProcess(pid)
|
|
||||||
if err == nil {
|
|
||||||
_ = p.Kill()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package system // import "github.com/docker/docker/pkg/system"
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
|
||||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|
||||||
return &StatT{size: s.Size,
|
|
||||||
mode: s.Mode,
|
|
||||||
uid: s.Uid,
|
|
||||||
gid: s.Gid,
|
|
||||||
rdev: s.Rdev,
|
|
||||||
mtim: s.Mtim}, nil
|
|
||||||
}
|
|
@ -0,0 +1,139 @@
|
|||||||
|
package registry // import "github.com/docker/docker/registry"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/api/types/registry"
|
||||||
|
"github.com/docker/docker/errdefs"
|
||||||
|
|
||||||
|
"github.com/docker/distribution/registry/client/auth"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var acceptedSearchFilterTags = map[string]bool{
|
||||||
|
"is-automated": true,
|
||||||
|
"is-official": true,
|
||||||
|
"stars": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search queries the public registry for repositories matching the specified
|
||||||
|
// search term and filters.
|
||||||
|
func (s *Service) Search(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) ([]registry.SearchResult, error) {
|
||||||
|
if err := searchFilters.Validate(acceptedSearchFilterTags); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
isAutomated, err := searchFilters.GetBoolOrDefault("is-automated", false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
isOfficial, err := searchFilters.GetBoolOrDefault("is-official", false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hasStarFilter := 0
|
||||||
|
if searchFilters.Contains("stars") {
|
||||||
|
hasStars := searchFilters.Get("stars")
|
||||||
|
for _, hasStar := range hasStars {
|
||||||
|
iHasStar, err := strconv.Atoi(hasStar)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errdefs.InvalidParameter(errors.Wrapf(err, "invalid filter 'stars=%s'", hasStar))
|
||||||
|
}
|
||||||
|
if iHasStar > hasStarFilter {
|
||||||
|
hasStarFilter = iHasStar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unfilteredResult, err := s.searchUnfiltered(ctx, term, limit, authConfig, headers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredResults := []registry.SearchResult{}
|
||||||
|
for _, result := range unfilteredResult.Results {
|
||||||
|
if searchFilters.Contains("is-automated") {
|
||||||
|
if isAutomated != result.IsAutomated {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if searchFilters.Contains("is-official") {
|
||||||
|
if isOfficial != result.IsOfficial {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if searchFilters.Contains("stars") {
|
||||||
|
if result.StarCount < hasStarFilter {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredResults = append(filteredResults, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredResults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return nil, invalidParamf("invalid repository name: repository name (%s) should not have a scheme", term)
|
||||||
|
}
|
||||||
|
|
||||||
|
indexName, remoteName := splitReposSearchTerm(term)
|
||||||
|
|
||||||
|
// Search is a long-running operation, just lock s.config to avoid block others.
|
||||||
|
s.mu.RLock()
|
||||||
|
index, err := 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/")
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint, err := newV1Endpoint(index, headers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var client *http.Client
|
||||||
|
if authConfig != nil && authConfig.IdentityToken != "" && authConfig.Username != "" {
|
||||||
|
creds := NewStaticCredentialStore(authConfig)
|
||||||
|
scopes := []auth.Scope{
|
||||||
|
auth.RegistryScope{
|
||||||
|
Name: "catalog",
|
||||||
|
Actions: []string{"search"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(thaJeztah); is there a reason not to include other headers here? (originally added in 19d48f0b8ba59eea9f2cac4ad1c7977712a6b7ac)
|
||||||
|
modifiers := Headers(headers.Get("User-Agent"), nil)
|
||||||
|
v2Client, err := v2AuthHTTPClient(endpoint.URL, endpoint.client.Transport, modifiers, creds, scopes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Copy non transport http client features
|
||||||
|
v2Client.Timeout = endpoint.client.Timeout
|
||||||
|
v2Client.CheckRedirect = endpoint.client.CheckRedirect
|
||||||
|
v2Client.Jar = endpoint.client.Jar
|
||||||
|
|
||||||
|
logrus.Debugf("using v2 client for search to %s", endpoint.URL)
|
||||||
|
client = v2Client
|
||||||
|
} else {
|
||||||
|
client = endpoint.client
|
||||||
|
if err := authorizeClient(client, authConfig, endpoint); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSession(client, endpoint).searchRepositories(remoteName, limit)
|
||||||
|
}
|
Loading…
Reference in New Issue