build: upgrade dependencies and build with go 1.21
This commit is contained in:
67
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/client.go
generated
vendored
Normal file
67
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/client.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/testcontainers/testcontainers-go/internal"
|
||||
"github.com/testcontainers/testcontainers-go/internal/config"
|
||||
"github.com/testcontainers/testcontainers-go/internal/testcontainerssession"
|
||||
)
|
||||
|
||||
// NewClient returns a new docker client extracting the docker host from the different alternatives
|
||||
func NewClient(ctx context.Context, ops ...client.Opt) (*client.Client, error) {
|
||||
tcConfig := config.Read()
|
||||
|
||||
dockerHost := ExtractDockerHost(ctx)
|
||||
|
||||
opts := []client.Opt{client.FromEnv, client.WithAPIVersionNegotiation()}
|
||||
if dockerHost != "" {
|
||||
opts = append(opts, client.WithHost(dockerHost))
|
||||
|
||||
// for further information, read https://docs.docker.com/engine/security/protect-access/
|
||||
if tcConfig.TLSVerify == 1 {
|
||||
cacertPath := filepath.Join(tcConfig.CertPath, "ca.pem")
|
||||
certPath := filepath.Join(tcConfig.CertPath, "cert.pem")
|
||||
keyPath := filepath.Join(tcConfig.CertPath, "key.pem")
|
||||
|
||||
opts = append(opts, client.WithTLSClientConfig(cacertPath, certPath, keyPath))
|
||||
}
|
||||
}
|
||||
|
||||
opts = append(opts, client.WithHTTPHeaders(
|
||||
map[string]string{
|
||||
"x-tc-sid": testcontainerssession.String(),
|
||||
"User-Agent": "tc-go/" + internal.Version,
|
||||
}),
|
||||
)
|
||||
|
||||
// passed options have priority over the default ones
|
||||
opts = append(opts, ops...)
|
||||
|
||||
cli, err := client.NewClientWithOpts(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err = cli.Ping(context.Background()); err != nil {
|
||||
// Fallback to environment, including the original options
|
||||
cli, err = defaultClient(context.Background(), ops...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
// defaultClient returns a plain, new docker client with the default options
|
||||
func defaultClient(ctx context.Context, ops ...client.Opt) (*client.Client, error) {
|
||||
if len(ops) == 0 {
|
||||
ops = []client.Opt{client.FromEnv, client.WithAPIVersionNegotiation()}
|
||||
}
|
||||
|
||||
return client.NewClientWithOpts(ops...)
|
||||
}
|
269
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_host.go
generated
vendored
Normal file
269
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_host.go
generated
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/testcontainers/testcontainers-go/internal/config"
|
||||
)
|
||||
|
||||
type dockerHostContext string
|
||||
|
||||
var DockerHostContextKey = dockerHostContext("docker_host")
|
||||
|
||||
var (
|
||||
ErrDockerHostNotSet = errors.New("DOCKER_HOST is not set")
|
||||
ErrDockerSocketOverrideNotSet = errors.New("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE is not set")
|
||||
ErrDockerSocketNotSetInContext = errors.New("socket not set in context")
|
||||
ErrDockerSocketNotSetInProperties = errors.New("socket not set in ~/.testcontainers.properties")
|
||||
ErrNoUnixSchema = errors.New("URL schema is not unix")
|
||||
ErrSocketNotFound = errors.New("socket not found")
|
||||
ErrSocketNotFoundInPath = errors.New("docker socket not found in " + DockerSocketPath)
|
||||
// ErrTestcontainersHostNotSetInProperties this error is specific to Testcontainers
|
||||
ErrTestcontainersHostNotSetInProperties = errors.New("tc.host not set in ~/.testcontainers.properties")
|
||||
)
|
||||
|
||||
var dockerHostCache string
|
||||
var dockerHostOnce sync.Once
|
||||
|
||||
var dockerSocketPathCache string
|
||||
var dockerSocketPathOnce sync.Once
|
||||
|
||||
// deprecated
|
||||
// see https://github.com/testcontainers/testcontainers-java/blob/main/core/src/main/java/org/testcontainers/dockerclient/DockerClientConfigUtils.java#L46
|
||||
func DefaultGatewayIP() (string, error) {
|
||||
// see https://github.com/testcontainers/testcontainers-java/blob/3ad8d80e2484864e554744a4800a81f6b7982168/core/src/main/java/org/testcontainers/dockerclient/DockerClientConfigUtils.java#L27
|
||||
cmd := exec.Command("sh", "-c", "ip route|awk '/default/ { print $3 }'")
|
||||
stdout, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", errors.New("failed to detect docker host")
|
||||
}
|
||||
ip := strings.TrimSpace(string(stdout))
|
||||
if len(ip) == 0 {
|
||||
return "", errors.New("failed to parse default gateway IP")
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
// ExtractDockerHost Extracts the docker host from the different alternatives, caching the result to avoid unnecessary
|
||||
// calculations. Use this function to get the actual Docker host. This function does not consider Windows containers at the moment.
|
||||
// The possible alternatives are:
|
||||
//
|
||||
// 1. Docker host from the "tc.host" property in the ~/.testcontainers.properties file.
|
||||
// 2. DOCKER_HOST environment variable.
|
||||
// 3. Docker host from context.
|
||||
// 4. Docker host from the default docker socket path, without the unix schema.
|
||||
// 5. Docker host from the "docker.host" property in the ~/.testcontainers.properties file.
|
||||
// 6. Rootless docker socket path.
|
||||
// 7. Else, the default Docker socket including schema will be returned.
|
||||
func ExtractDockerHost(ctx context.Context) string {
|
||||
dockerHostOnce.Do(func() {
|
||||
dockerHostCache = extractDockerHost(ctx)
|
||||
})
|
||||
|
||||
return dockerHostCache
|
||||
}
|
||||
|
||||
// ExtractDockerSocket Extracts the docker socket from the different alternatives, removing the socket schema and
|
||||
// caching the result to avoid unnecessary calculations. Use this function to get the docker socket path,
|
||||
// not the host (e.g. mounting the socket in a container). This function does not consider Windows containers at the moment.
|
||||
// The possible alternatives are:
|
||||
//
|
||||
// 1. Docker host from the "tc.host" property in the ~/.testcontainers.properties file.
|
||||
// 2. The TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variable.
|
||||
// 3. Using a Docker client, check if the Info().OperativeSystem is "Docker Desktop" and return the default docker socket path for rootless docker.
|
||||
// 4. Else, Get the current Docker Host from the existing strategies: see ExtractDockerHost.
|
||||
// 5. If the socket contains the unix schema, the schema is removed (e.g. unix:///var/run/docker.sock -> /var/run/docker.sock)
|
||||
// 6. Else, the default location of the docker socket is used (/var/run/docker.sock)
|
||||
//
|
||||
// In any case, if the docker socket schema is "tcp://", the default docker socket path will be returned.
|
||||
func ExtractDockerSocket(ctx context.Context) string {
|
||||
dockerSocketPathOnce.Do(func() {
|
||||
dockerSocketPathCache = extractDockerSocket(ctx)
|
||||
})
|
||||
|
||||
return dockerSocketPathCache
|
||||
}
|
||||
|
||||
// extractDockerHost Extracts the docker host from the different alternatives, without caching the result.
|
||||
// This internal method is handy for testing purposes.
|
||||
func extractDockerHost(ctx context.Context) string {
|
||||
dockerHostFns := []func(context.Context) (string, error){
|
||||
testcontainersHostFromProperties,
|
||||
dockerHostFromEnv,
|
||||
dockerHostFromContext,
|
||||
dockerSocketPath,
|
||||
dockerHostFromProperties,
|
||||
rootlessDockerSocketPath,
|
||||
}
|
||||
|
||||
outerErr := ErrSocketNotFound
|
||||
for _, dockerHostFn := range dockerHostFns {
|
||||
dockerHost, err := dockerHostFn(ctx)
|
||||
if err != nil {
|
||||
outerErr = fmt.Errorf("%w: %v", outerErr, err)
|
||||
continue
|
||||
}
|
||||
|
||||
return dockerHost
|
||||
}
|
||||
|
||||
// We are not supporting Windows containers at the moment
|
||||
return DockerSocketPathWithSchema
|
||||
}
|
||||
|
||||
// extractDockerHost Extracts the docker socket from the different alternatives, without caching the result.
|
||||
// It will internally use the default Docker client, calling the internal method extractDockerSocketFromClient with it.
|
||||
// This internal method is handy for testing purposes.
|
||||
// If a Docker client cannot be created, the program will panic.
|
||||
func extractDockerSocket(ctx context.Context) string {
|
||||
cli, err := NewClient(ctx)
|
||||
if err != nil {
|
||||
panic(err) // a Docker client is required to get the Docker info
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
return extractDockerSocketFromClient(ctx, cli)
|
||||
}
|
||||
|
||||
// extractDockerSocketFromClient Extracts the docker socket from the different alternatives, without caching the result,
|
||||
// and receiving an instance of the Docker API client interface.
|
||||
// This internal method is handy for testing purposes, passing a mock type simulating the desired behaviour.
|
||||
func extractDockerSocketFromClient(ctx context.Context, cli client.APIClient) string {
|
||||
// check that the socket is not a tcp or unix socket
|
||||
checkDockerSocketFn := func(socket string) string {
|
||||
// this use case will cover the case when the docker host is a tcp socket
|
||||
if strings.HasPrefix(socket, TCPSchema) {
|
||||
return DockerSocketPath
|
||||
}
|
||||
|
||||
if strings.HasPrefix(socket, DockerSocketSchema) {
|
||||
return strings.Replace(socket, DockerSocketSchema, "", 1)
|
||||
}
|
||||
|
||||
return socket
|
||||
}
|
||||
|
||||
tcHost, err := testcontainersHostFromProperties(ctx)
|
||||
if err == nil {
|
||||
return checkDockerSocketFn(tcHost)
|
||||
}
|
||||
|
||||
testcontainersDockerSocket, err := dockerSocketOverridePath(ctx)
|
||||
if err == nil {
|
||||
return checkDockerSocketFn(testcontainersDockerSocket)
|
||||
}
|
||||
|
||||
info, err := cli.Info(ctx)
|
||||
if err != nil {
|
||||
panic(err) // Docker Info is required to get the Operating System
|
||||
}
|
||||
|
||||
// Because Docker Desktop runs in a VM, we need to use the default docker path for rootless docker
|
||||
if info.OperatingSystem == "Docker Desktop" {
|
||||
if IsWindows() {
|
||||
return WindowsDockerSocketPath
|
||||
}
|
||||
|
||||
return DockerSocketPath
|
||||
}
|
||||
|
||||
dockerHost := extractDockerHost(ctx)
|
||||
|
||||
return checkDockerSocketFn(dockerHost)
|
||||
}
|
||||
|
||||
// dockerHostFromEnv returns the docker host from the DOCKER_HOST environment variable, if it's not empty
|
||||
func dockerHostFromEnv(ctx context.Context) (string, error) {
|
||||
if dockerHostPath := os.Getenv("DOCKER_HOST"); dockerHostPath != "" {
|
||||
return dockerHostPath, nil
|
||||
}
|
||||
|
||||
return "", ErrDockerHostNotSet
|
||||
}
|
||||
|
||||
// dockerHostFromContext returns the docker host from the Go context, if it's not empty
|
||||
func dockerHostFromContext(ctx context.Context) (string, error) {
|
||||
if socketPath, ok := ctx.Value(DockerHostContextKey).(string); ok && socketPath != "" {
|
||||
parsed, err := parseURL(socketPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
return "", ErrDockerSocketNotSetInContext
|
||||
}
|
||||
|
||||
// dockerHostFromProperties returns the docker host from the ~/.testcontainers.properties file, if it's not empty
|
||||
func dockerHostFromProperties(ctx context.Context) (string, error) {
|
||||
cfg := config.Read()
|
||||
socketPath := cfg.Host
|
||||
if socketPath != "" {
|
||||
parsed, err := parseURL(socketPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
return "", ErrDockerSocketNotSetInProperties
|
||||
}
|
||||
|
||||
// dockerSocketOverridePath returns the docker socket from the TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variable,
|
||||
// if it's not empty
|
||||
func dockerSocketOverridePath(ctx context.Context) (string, error) {
|
||||
if dockerHostPath, exists := os.LookupEnv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"); exists {
|
||||
return dockerHostPath, nil
|
||||
}
|
||||
|
||||
return "", ErrDockerSocketOverrideNotSet
|
||||
}
|
||||
|
||||
// dockerSocketPath returns the docker socket from the default docker socket path, if it's not empty
|
||||
// and the socket exists
|
||||
func dockerSocketPath(ctx context.Context) (string, error) {
|
||||
if fileExists(DockerSocketPath) {
|
||||
return DockerSocketPathWithSchema, nil
|
||||
}
|
||||
|
||||
return "", ErrSocketNotFoundInPath
|
||||
}
|
||||
|
||||
// testcontainersHostFromProperties returns the testcontainers host from the ~/.testcontainers.properties file, if it's not empty
|
||||
func testcontainersHostFromProperties(ctx context.Context) (string, error) {
|
||||
cfg := config.Read()
|
||||
testcontainersHost := cfg.TestcontainersHost
|
||||
if testcontainersHost != "" {
|
||||
parsed, err := parseURL(testcontainersHost)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
return "", ErrTestcontainersHostNotSetInProperties
|
||||
}
|
||||
|
||||
// InAContainer returns true if the code is running inside a container
|
||||
// See https://github.com/docker/docker/blob/a9fa38b1edf30b23cae3eade0be48b3d4b1de14b/daemon/initlayer/setup_unix.go#L25
|
||||
func InAContainer() bool {
|
||||
return inAContainer("/.dockerenv")
|
||||
}
|
||||
|
||||
func inAContainer(path string) bool {
|
||||
// see https://github.com/testcontainers/testcontainers-java/blob/3ad8d80e2484864e554744a4800a81f6b7982168/core/src/main/java/org/testcontainers/dockerclient/DockerClientConfigUtils.java#L15
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
146
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_rootless.go
generated
vendored
Normal file
146
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_rootless.go
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRootlessDockerNotFound = errors.New("rootless Docker not found")
|
||||
ErrRootlessDockerNotFoundHomeDesktopDir = errors.New("checked path: ~/.docker/desktop/docker.sock")
|
||||
ErrRootlessDockerNotFoundHomeRunDir = errors.New("checked path: ~/.docker/run/docker.sock")
|
||||
ErrRootlessDockerNotFoundRunDir = errors.New("checked path: /run/user/${uid}/docker.sock")
|
||||
ErrRootlessDockerNotFoundXDGRuntimeDir = errors.New("checked path: $XDG_RUNTIME_DIR")
|
||||
ErrRootlessDockerNotSupportedWindows = errors.New("rootless Docker is not supported on Windows")
|
||||
ErrXDGRuntimeDirNotSet = errors.New("XDG_RUNTIME_DIR is not set")
|
||||
)
|
||||
|
||||
// baseRunDir is the base directory for the "/run/user/${uid}" directory.
|
||||
// It is a variable so it can be modified for testing.
|
||||
var baseRunDir = "/run"
|
||||
|
||||
// IsWindows returns if the current OS is Windows. For that it checks the GOOS environment variable or the runtime.GOOS constant.
|
||||
func IsWindows() bool {
|
||||
return os.Getenv("GOOS") == "windows" || runtime.GOOS == "windows"
|
||||
}
|
||||
|
||||
// rootlessDockerSocketPath returns if the path to the rootless Docker socket exists.
|
||||
// The rootless socket path is determined by the following order:
|
||||
//
|
||||
// 1. XDG_RUNTIME_DIR environment variable.
|
||||
// 2. ~/.docker/run/docker.sock file.
|
||||
// 3. ~/.docker/desktop/docker.sock file.
|
||||
// 4. /run/user/${uid}/docker.sock file.
|
||||
// 5. Else, return ErrRootlessDockerNotFound, wrapping secific errors for each of the above paths.
|
||||
//
|
||||
// It should include the Docker socket schema (unix://) in the returned path.
|
||||
func rootlessDockerSocketPath(_ context.Context) (string, error) {
|
||||
// adding a manner to test it on non-windows machines, setting the GOOS env var to windows
|
||||
// This is needed because runtime.GOOS is a constant that returns the OS of the machine running the test
|
||||
if IsWindows() {
|
||||
return "", ErrRootlessDockerNotSupportedWindows
|
||||
}
|
||||
|
||||
socketPathFns := []func() (string, error){
|
||||
rootlessSocketPathFromEnv,
|
||||
rootlessSocketPathFromHomeRunDir,
|
||||
rootlessSocketPathFromHomeDesktopDir,
|
||||
rootlessSocketPathFromRunDir,
|
||||
}
|
||||
|
||||
outerErr := ErrRootlessDockerNotFound
|
||||
for _, socketPathFn := range socketPathFns {
|
||||
s, err := socketPathFn()
|
||||
if err != nil {
|
||||
outerErr = fmt.Errorf("%w: %v", outerErr, err)
|
||||
continue
|
||||
}
|
||||
|
||||
return DockerSocketSchema + s, nil
|
||||
}
|
||||
|
||||
return "", outerErr
|
||||
}
|
||||
|
||||
func fileExists(f string) bool {
|
||||
_, err := os.Stat(f)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func parseURL(s string) (string, error) {
|
||||
var hostURL *url.URL
|
||||
if u, err := url.Parse(s); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
hostURL = u
|
||||
}
|
||||
|
||||
switch hostURL.Scheme {
|
||||
case "unix", "npipe":
|
||||
return hostURL.Path, nil
|
||||
case "tcp":
|
||||
// return the original URL, as it is a valid TCP URL
|
||||
return s, nil
|
||||
default:
|
||||
return "", ErrNoUnixSchema
|
||||
}
|
||||
}
|
||||
|
||||
// rootlessSocketPathFromEnv returns the path to the rootless Docker socket from the XDG_RUNTIME_DIR environment variable.
|
||||
// It should include the Docker socket schema (unix://) in the returned path.
|
||||
func rootlessSocketPathFromEnv() (string, error) {
|
||||
xdgRuntimeDir, exists := os.LookupEnv("XDG_RUNTIME_DIR")
|
||||
if exists {
|
||||
f := filepath.Join(xdgRuntimeDir, "docker.sock")
|
||||
if fileExists(f) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
return "", ErrRootlessDockerNotFoundXDGRuntimeDir
|
||||
}
|
||||
|
||||
return "", ErrXDGRuntimeDirNotSet
|
||||
}
|
||||
|
||||
// rootlessSocketPathFromHomeRunDir returns the path to the rootless Docker socket from the ~/.docker/run/docker.sock file.
|
||||
func rootlessSocketPathFromHomeRunDir() (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f := filepath.Join(home, ".docker", "run", "docker.sock")
|
||||
if fileExists(f) {
|
||||
return f, nil
|
||||
}
|
||||
return "", ErrRootlessDockerNotFoundHomeRunDir
|
||||
}
|
||||
|
||||
// rootlessSocketPathFromHomeDesktopDir returns the path to the rootless Docker socket from the ~/.docker/desktop/docker.sock file.
|
||||
func rootlessSocketPathFromHomeDesktopDir() (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f := filepath.Join(home, ".docker", "desktop", "docker.sock")
|
||||
if fileExists(f) {
|
||||
return f, nil
|
||||
}
|
||||
return "", ErrRootlessDockerNotFoundHomeDesktopDir
|
||||
}
|
||||
|
||||
// rootlessSocketPathFromRunDir returns the path to the rootless Docker socket from the /run/user/<uid>/docker.sock file.
|
||||
func rootlessSocketPathFromRunDir() (string, error) {
|
||||
uid := os.Getuid()
|
||||
f := filepath.Join(baseRunDir, "user", fmt.Sprintf("%d", uid), "docker.sock")
|
||||
if fileExists(f) {
|
||||
return f, nil
|
||||
}
|
||||
return "", ErrRootlessDockerNotFoundRunDir
|
||||
}
|
49
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_socket.go
generated
vendored
Normal file
49
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/docker_socket.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
// DockerSocketSchema is the unix schema.
|
||||
var DockerSocketSchema = "unix://"
|
||||
|
||||
// DockerSocketPath is the path to the docker socket under unix systems.
|
||||
var DockerSocketPath = "/var/run/docker.sock"
|
||||
|
||||
// DockerSocketPathWithSchema is the path to the docker socket under unix systems with the unix schema.
|
||||
var DockerSocketPathWithSchema = DockerSocketSchema + DockerSocketPath
|
||||
|
||||
// TCPSchema is the tcp schema.
|
||||
var TCPSchema = "tcp://"
|
||||
|
||||
// WindowsDockerSocketPath is the path to the docker socket under windows systems.
|
||||
var WindowsDockerSocketPath = "//var/run/docker.sock"
|
||||
|
||||
func init() {
|
||||
const DefaultDockerHost = client.DefaultDockerHost
|
||||
|
||||
u, err := url.Parse(DefaultDockerHost)
|
||||
if err != nil {
|
||||
// unsupported default host specified by the docker client package,
|
||||
// so revert to the default unix docker socket path
|
||||
return
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "unix", "npipe":
|
||||
DockerSocketSchema = u.Scheme + "://"
|
||||
DockerSocketPath = u.Path
|
||||
if !strings.HasPrefix(DockerSocketPath, "/") {
|
||||
// seeing as the code in this module depends on DockerSocketPath having
|
||||
// a slash (`/`) prefix, we add it here if it is missing.
|
||||
// for the known environments, we do not foresee how the socket-path
|
||||
// should miss the slash, however this extra if-condition is worth to
|
||||
// save future pain from innocent users.
|
||||
DockerSocketPath = "/" + DockerSocketPath
|
||||
}
|
||||
DockerSocketPathWithSchema = DockerSocketSchema + DockerSocketPath
|
||||
}
|
||||
}
|
126
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/images.go
generated
vendored
Normal file
126
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/images.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
IndexDockerIO = "https://index.docker.io/v1/"
|
||||
maxURLRuneCount = 2083
|
||||
minURLRuneCount = 3
|
||||
URLSchema = `((ftp|tcp|udp|wss?|https?):\/\/)`
|
||||
URLUsername = `(\S+(:\S*)?@)`
|
||||
URLIP = `([1-9]\d?|1\d\d|2[01]\d|22[0-3]|24\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-5]))`
|
||||
IP = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
|
||||
URLSubdomain = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))`
|
||||
URLPath = `((\/|\?|#)[^\s]*)`
|
||||
URLPort = `(:(\d{1,5}))`
|
||||
URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`
|
||||
)
|
||||
|
||||
var rxURL = regexp.MustCompile(URL)
|
||||
|
||||
func ExtractImagesFromDockerfile(dockerfile string, buildArgs map[string]*string) ([]string, error) {
|
||||
var images []string
|
||||
|
||||
file, err := os.Open(dockerfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var lines []string
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
if scanner.Err() != nil {
|
||||
return nil, scanner.Err()
|
||||
}
|
||||
|
||||
// extract images from dockerfile
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if !strings.HasPrefix(strings.ToUpper(line), "FROM") {
|
||||
continue
|
||||
}
|
||||
|
||||
// remove FROM
|
||||
line = strings.TrimPrefix(line, "FROM")
|
||||
parts := strings.Split(strings.TrimSpace(line), " ")
|
||||
if len(parts) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// interpolate build args
|
||||
for k, v := range buildArgs {
|
||||
if v != nil {
|
||||
parts[0] = strings.Replace(parts[0], "${"+k+"}", *v, -1)
|
||||
}
|
||||
}
|
||||
images = append(images, parts[0])
|
||||
}
|
||||
|
||||
return images, nil
|
||||
}
|
||||
|
||||
// ExtractRegistry extracts the registry from the image name, using a regular expression to extract the registry from the image name.
|
||||
// regular expression to extract the registry from the image name
|
||||
// the regular expression is based on the grammar defined in
|
||||
// - image:tag
|
||||
// - image
|
||||
// - repository/image:tag
|
||||
// - repository/image
|
||||
// - registry/image:tag
|
||||
// - registry/image
|
||||
// - registry/repository/image:tag
|
||||
// - registry/repository/image
|
||||
// - registry:port/repository/image:tag
|
||||
// - registry:port/repository/image
|
||||
// - registry:port/image:tag
|
||||
// - registry:port/image
|
||||
// Once extracted the registry, it is validated to check if it is a valid URL or an IP address.
|
||||
func ExtractRegistry(image string, fallback string) string {
|
||||
exp := regexp.MustCompile(`^(?:(?P<registry>(https?://)?[^/]+)(?::(?P<port>\d+))?/)?(?:(?P<repository>[^/]+)/)?(?P<image>[^:]+)(?::(?P<tag>.+))?$`).FindStringSubmatch(image)
|
||||
if len(exp) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
registry := exp[1]
|
||||
|
||||
if IsURL(registry) {
|
||||
return registry
|
||||
}
|
||||
|
||||
return fallback
|
||||
}
|
||||
|
||||
// IsURL checks if the string is an URL.
|
||||
// Extracted from https://github.com/asaskevich/govalidator/blob/f21760c49a8d/validator.go#L104
|
||||
func IsURL(str string) bool {
|
||||
if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") {
|
||||
return false
|
||||
}
|
||||
strTemp := str
|
||||
if strings.Contains(str, ":") && !strings.Contains(str, "://") {
|
||||
// support no indicated urlscheme but with colon for port number
|
||||
// http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString
|
||||
strTemp = "http://" + str
|
||||
}
|
||||
u, err := url.Parse(strTemp)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(u.Host, ".") {
|
||||
return false
|
||||
}
|
||||
if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
|
||||
return false
|
||||
}
|
||||
return rxURL.MatchString(str)
|
||||
}
|
19
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/labels.go
generated
vendored
Normal file
19
vendor/github.com/testcontainers/testcontainers-go/internal/testcontainersdocker/labels.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package testcontainersdocker
|
||||
|
||||
import "github.com/testcontainers/testcontainers-go/internal"
|
||||
|
||||
const (
|
||||
LabelBase = "org.testcontainers"
|
||||
LabelLang = LabelBase + ".lang"
|
||||
LabelReaper = LabelBase + ".reaper"
|
||||
LabelSessionID = LabelBase + ".sessionId"
|
||||
LabelVersion = LabelBase + ".version"
|
||||
)
|
||||
|
||||
func DefaultLabels() map[string]string {
|
||||
return map[string]string{
|
||||
LabelBase: "true",
|
||||
LabelLang: "go",
|
||||
LabelVersion: internal.Version,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user