mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Implement proper detection with Podman support and enhance error handling across platforms
Signed-off-by: DeiAsPie <93835541+DeiAsPie@users.noreply.github.com>
This commit is contained in:
parent
0eec22e241
commit
cb517d9e09
6 changed files with 254 additions and 38 deletions
|
|
@ -72,8 +72,7 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
||||||
// Use new detection with caching and validation
|
// Use new detection with caching and validation
|
||||||
dockerHost, runtime, err := DetectDockerHost(log)
|
dockerHost, runtime, err := DetectDockerHost(log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Provide user-friendly error
|
return nil, fmt.Errorf("cannot connect to container runtime: %w", err)
|
||||||
return nil, fmt.Errorf("cannot connect to container runtime: %w; Troubleshooting: Docker - ensure Docker daemon is running; Podman - run 'systemctl --user enable --now podman.socket'; or set DOCKER_HOST environment variable explicitly", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Detected %s runtime at %s", runtime, dockerHost)
|
log.Infof("Detected %s runtime at %s", runtime, dockerHost)
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,17 @@ import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNoDockerSocket = fmt.Errorf("no working Docker/Podman socket found")
|
||||||
|
)
|
||||||
|
|
||||||
// Timeout for validating socket connectivity
|
// Timeout for validating socket connectivity
|
||||||
const socketValidationTimeout = 3 * time.Second
|
const socketValidationTimeout = 3 * time.Second
|
||||||
|
|
||||||
|
var (
|
||||||
|
validateSocketFunc = validateSocket
|
||||||
|
)
|
||||||
|
|
||||||
// Runtime type detection
|
// Runtime type detection
|
||||||
type ContainerRuntime string
|
type ContainerRuntime string
|
||||||
|
|
||||||
|
|
@ -31,27 +39,54 @@ const (
|
||||||
var (
|
var (
|
||||||
cachedDockerHost string
|
cachedDockerHost string
|
||||||
cachedRuntime ContainerRuntime
|
cachedRuntime ContainerRuntime
|
||||||
dockerHostOnce sync.Once
|
dockerHostMu sync.Mutex
|
||||||
dockerHostErr error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DetectDockerHost finds a working Docker/Podman socket
|
// DetectDockerHost finds a working Docker/Podman socket
|
||||||
// Results are cached after first successful detection
|
// Results are cached after first successful detection
|
||||||
func DetectDockerHost(log *logrus.Entry) (string, ContainerRuntime, error) {
|
func DetectDockerHost(log *logrus.Entry) (string, ContainerRuntime, error) {
|
||||||
dockerHostOnce.Do(func() {
|
dockerHostMu.Lock()
|
||||||
cachedDockerHost, cachedRuntime, dockerHostErr = detectDockerHostInternal(log)
|
defer dockerHostMu.Unlock()
|
||||||
})
|
|
||||||
return cachedDockerHost, cachedRuntime, dockerHostErr
|
if cachedDockerHost != "" {
|
||||||
|
return cachedDockerHost, cachedRuntime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
host, runtime, err := detectDockerHostInternal(log)
|
||||||
|
if err != nil {
|
||||||
|
return "", RuntimeUnknown, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedDockerHost = host
|
||||||
|
cachedRuntime = runtime
|
||||||
|
return host, runtime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetDockerHostCache resets the cached docker host. Used for testing.
|
||||||
|
func ResetDockerHostCache() {
|
||||||
|
dockerHostMu.Lock()
|
||||||
|
defer dockerHostMu.Unlock()
|
||||||
|
cachedDockerHost = ""
|
||||||
|
cachedRuntime = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectDockerHostInternal(log *logrus.Entry) (string, ContainerRuntime, error) {
|
func detectDockerHostInternal(log *logrus.Entry) (string, ContainerRuntime, error) {
|
||||||
// Priority 1: Explicit DOCKER_HOST environment variable
|
// Priority 1: Explicit DOCKER_HOST environment variable
|
||||||
if dockerHost := os.Getenv("DOCKER_HOST"); dockerHost != "" {
|
if dockerHost := os.Getenv("DOCKER_HOST"); dockerHost != "" {
|
||||||
log.Debugf("Using DOCKER_HOST from environment: %s", dockerHost)
|
log.Debugf("Using DOCKER_HOST from environment: %s", dockerHost)
|
||||||
|
|
||||||
|
// Handle plain paths without schema
|
||||||
|
if !strings.Contains(dockerHost, "://") {
|
||||||
|
if _, err := os.Stat(dockerHost); err == nil {
|
||||||
|
log.Debugf("DOCKER_HOST is a plain path, assuming unix://")
|
||||||
|
dockerHost = "unix://" + dockerHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(dockerHost, "ssh://") {
|
if !strings.HasPrefix(dockerHost, "ssh://") {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := validateSocket(ctx, dockerHost, true); err != nil {
|
if err := validateSocketFunc(ctx, dockerHost, true); err != nil {
|
||||||
log.Warnf("DOCKER_HOST=%s is set but not accessible: %v", dockerHost, err)
|
log.Warnf("DOCKER_HOST=%s is set but not accessible: %v", dockerHost, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +106,7 @@ func detectDockerHostInternal(log *logrus.Entry) (string, ContainerRuntime, erro
|
||||||
if !strings.HasPrefix(contextHost, "ssh://") {
|
if !strings.HasPrefix(contextHost, "ssh://") {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := validateSocket(ctx, contextHost, false); err != nil {
|
if err := validateSocketFunc(ctx, contextHost, false); err != nil {
|
||||||
log.Warnf("Context host %s is not accessible: %v", contextHost, err)
|
log.Warnf("Context host %s is not accessible: %v", contextHost, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -50,8 +51,7 @@ func TestDetectDockerHost_DOCKER_HOST_Priority(t *testing.T) {
|
||||||
os.Setenv("DOCKER_HOST", expectedHost)
|
os.Setenv("DOCKER_HOST", expectedHost)
|
||||||
|
|
||||||
// Reset cache for test
|
// Reset cache for test
|
||||||
dockerHostOnce = sync.Once{}
|
ResetDockerHostCache()
|
||||||
cachedDockerHost = ""
|
|
||||||
|
|
||||||
log := logrus.NewEntry(logrus.New())
|
log := logrus.NewEntry(logrus.New())
|
||||||
host, _, err := DetectDockerHost(log)
|
host, _, err := DetectDockerHost(log)
|
||||||
|
|
@ -66,8 +66,7 @@ func TestDetectDockerHost_Caching(t *testing.T) {
|
||||||
os.Setenv("DOCKER_HOST", "unix:///tmp/first.sock")
|
os.Setenv("DOCKER_HOST", "unix:///tmp/first.sock")
|
||||||
|
|
||||||
// Reset cache for test
|
// Reset cache for test
|
||||||
dockerHostOnce = sync.Once{}
|
ResetDockerHostCache()
|
||||||
cachedDockerHost = ""
|
|
||||||
|
|
||||||
log := logrus.NewEntry(logrus.New())
|
log := logrus.NewEntry(logrus.New())
|
||||||
host1, _, _ := DetectDockerHost(log)
|
host1, _, _ := DetectDockerHost(log)
|
||||||
|
|
@ -92,11 +91,90 @@ func TestDetectDockerHost_Context_Invalid(t *testing.T) {
|
||||||
os.Setenv("DOCKER_CONTEXT", "nonexistent-context-12345")
|
os.Setenv("DOCKER_CONTEXT", "nonexistent-context-12345")
|
||||||
|
|
||||||
// Reset cache for test
|
// Reset cache for test
|
||||||
dockerHostOnce = sync.Once{}
|
ResetDockerHostCache()
|
||||||
cachedDockerHost = ""
|
|
||||||
|
|
||||||
log := logrus.NewEntry(logrus.New())
|
log := logrus.NewEntry(logrus.New())
|
||||||
_, _, err := DetectDockerHost(log)
|
_, _, err := DetectDockerHost(log)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "failed to use DOCKER_CONTEXT")
|
assert.Contains(t, err.Error(), "failed to use DOCKER_CONTEXT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetHostFromContext(t *testing.T) {
|
||||||
|
// This test is tricky because it depends on the Docker CLI config.
|
||||||
|
// We'll skip it if we can't easily mock the config directory.
|
||||||
|
// But we can at least test the "default" case.
|
||||||
|
host, err := getHostFromContext()
|
||||||
|
if err == nil {
|
||||||
|
// If it succeeded, it should be empty or a valid host
|
||||||
|
assert.True(t, host == "" || host != "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateSocket_Failures(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Test non-existent path
|
||||||
|
err := validateSocket(ctx, "unix:///tmp/nonexistent-12345.sock", false)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
// Test invalid schema
|
||||||
|
err = validateSocket(ctx, "invalid:///tmp/test.sock", false)
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectPlatformCandidates_Unix(t *testing.T) {
|
||||||
|
// Mock validateSocketFunc to always fail
|
||||||
|
oldValidate := validateSocketFunc
|
||||||
|
defer func() { validateSocketFunc = oldValidate }()
|
||||||
|
|
||||||
|
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
|
||||||
|
return errors.New("mock failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock environment to ensure no candidates are found
|
||||||
|
oldXdg := os.Getenv("XDG_RUNTIME_DIR")
|
||||||
|
oldHome := os.Getenv("HOME")
|
||||||
|
defer func() {
|
||||||
|
os.Setenv("XDG_RUNTIME_DIR", oldXdg)
|
||||||
|
os.Setenv("HOME", oldHome)
|
||||||
|
}()
|
||||||
|
|
||||||
|
os.Setenv("XDG_RUNTIME_DIR", "/tmp/nonexistent-xdg")
|
||||||
|
os.Setenv("HOME", "/tmp/nonexistent-home")
|
||||||
|
|
||||||
|
log := logrus.NewEntry(logrus.New())
|
||||||
|
_, _, err := detectPlatformCandidates(log)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), ErrNoDockerSocket.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectPlatformCandidates_Unix_Success(t *testing.T) {
|
||||||
|
// Mock validateSocketFunc to succeed for a specific path
|
||||||
|
oldValidate := validateSocketFunc
|
||||||
|
oldStat := statFunc
|
||||||
|
defer func() {
|
||||||
|
validateSocketFunc = oldValidate
|
||||||
|
statFunc = oldStat
|
||||||
|
}()
|
||||||
|
|
||||||
|
expectedPath := "unix:///var/run/docker.sock"
|
||||||
|
statFunc = func(name string) (os.FileInfo, error) {
|
||||||
|
if name == "/var/run/docker.sock" {
|
||||||
|
return nil, nil // Mock success
|
||||||
|
}
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
|
||||||
|
if host == expectedPath {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("mock failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := logrus.NewEntry(logrus.New())
|
||||||
|
host, runtime, err := detectPlatformCandidates(log)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expectedPath, host)
|
||||||
|
assert.Equal(t, RuntimeDocker, runtime)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
statFunc = os.Stat
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DockerSocketSchema = "unix://"
|
DockerSocketSchema = "unix://"
|
||||||
DockerSocketPath = "/var/run/docker.sock"
|
DockerSocketPath = "/var/run/docker.sock"
|
||||||
|
|
@ -21,10 +25,6 @@ const (
|
||||||
defaultDockerHost = DockerSocketSchema + DockerSocketPath
|
defaultDockerHost = DockerSocketSchema + DockerSocketPath
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ErrNoDockerSocket = errors.New("no working Docker/Podman socket found")
|
|
||||||
)
|
|
||||||
|
|
||||||
// SocketCandidate represents a potential socket to try
|
// SocketCandidate represents a potential socket to try
|
||||||
type SocketCandidate struct {
|
type SocketCandidate struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
@ -107,6 +107,12 @@ func getSocketCandidates() []SocketCandidate {
|
||||||
// 14. Rootful Podman: /run/podman/podman.sock
|
// 14. Rootful Podman: /run/podman/podman.sock
|
||||||
addCandidate("/run/podman/podman.sock", RuntimePodman)
|
addCandidate("/run/podman/podman.sock", RuntimePodman)
|
||||||
|
|
||||||
|
// 15. Podman on macOS (default machine)
|
||||||
|
if home != "" {
|
||||||
|
addCandidate(filepath.Join(home, ".local", "share", "containers", "podman", "machine", "podman-machine-default", "podman.sock"), RuntimePodman)
|
||||||
|
addCandidate(filepath.Join(home, ".local", "share", "containers", "podman", "machine", "qemu", "podman.sock"), RuntimePodman)
|
||||||
|
}
|
||||||
|
|
||||||
return candidates
|
return candidates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,21 +124,24 @@ func detectPlatformCandidates(log *logrus.Entry) (string, ContainerRuntime, erro
|
||||||
socketPath := strings.TrimPrefix(candidate.Path, DockerSocketSchema)
|
socketPath := strings.TrimPrefix(candidate.Path, DockerSocketSchema)
|
||||||
|
|
||||||
// Fast path: check if socket file exists
|
// Fast path: check if socket file exists
|
||||||
if _, err := os.Stat(socketPath); err != nil {
|
if _, err := statFunc(socketPath); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate by actually connecting
|
// Validate by actually connecting
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
||||||
err := validateSocket(ctx, candidate.Path, false)
|
err := func() error {
|
||||||
cancel()
|
defer cancel()
|
||||||
|
return validateSocketFunc(ctx, candidate.Path, false)
|
||||||
|
}()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Socket %s exists but validation failed: %v", candidate.Path, err)
|
log.Debugf("Socket %s exists but validation failed: %v", candidate.Path, err)
|
||||||
if strings.Contains(err.Error(), "permission denied") {
|
errStr := strings.ToLower(err.Error())
|
||||||
|
if strings.Contains(errStr, "permission denied") || strings.Contains(errStr, "eacces") {
|
||||||
lastErr = fmt.Errorf("%s: permission denied (are you in the docker group?)", candidate.Path)
|
lastErr = fmt.Errorf("%s: permission denied (are you in the docker group?)", candidate.Path)
|
||||||
} else {
|
} else {
|
||||||
lastErr = fmt.Errorf("%s: %w", candidate.Path, err)
|
lastErr = fmt.Errorf("%s: %v", candidate.Path, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
@ -15,27 +18,57 @@ const (
|
||||||
defaultDockerHost = DockerSocketSchema + DockerSocketPath
|
defaultDockerHost = DockerSocketSchema + DockerSocketPath
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getPodmanPipes() []string {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return []string{"npipe:////./pipe/podman-machine-default"}
|
||||||
|
}
|
||||||
|
|
||||||
|
configDir := filepath.Join(home, ".config", "containers", "podman", "machine", "wsl")
|
||||||
|
files, err := os.ReadDir(configDir)
|
||||||
|
if err != nil {
|
||||||
|
return []string{"npipe:////./pipe/podman-machine-default"}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pipes []string
|
||||||
|
for _, f := range files {
|
||||||
|
if !f.IsDir() && filepath.Ext(f.Name()) == ".json" {
|
||||||
|
name := strings.TrimSuffix(f.Name(), ".json")
|
||||||
|
pipes = append(pipes, "npipe:////./pipe/"+name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pipes) == 0 {
|
||||||
|
return []string{"npipe:////./pipe/podman-machine-default"}
|
||||||
|
}
|
||||||
|
return pipes
|
||||||
|
}
|
||||||
|
|
||||||
func detectPlatformCandidates(log *logrus.Entry) (string, ContainerRuntime, error) {
|
func detectPlatformCandidates(log *logrus.Entry) (string, ContainerRuntime, error) {
|
||||||
// Try Docker Desktop first
|
// Try Docker Desktop first
|
||||||
dockerHost := defaultDockerHost
|
dockerHost := defaultDockerHost
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
err := func() error {
|
||||||
err := validateSocket(ctx, dockerHost, false)
|
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
||||||
cancel()
|
defer cancel()
|
||||||
|
return validateSocketFunc(ctx, dockerHost, false)
|
||||||
|
}()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return dockerHost, RuntimeDocker, nil
|
return dockerHost, RuntimeDocker, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try Podman on Windows
|
// Try Podman machines on Windows
|
||||||
podmanHost := "npipe:////./pipe/podman-machine-default"
|
for _, podmanHost := range getPodmanPipes() {
|
||||||
ctx, cancel = context.WithTimeout(context.Background(), socketValidationTimeout)
|
err = func() error {
|
||||||
err = validateSocket(ctx, podmanHost, false)
|
ctx, cancel := context.WithTimeout(context.Background(), socketValidationTimeout)
|
||||||
cancel()
|
defer cancel()
|
||||||
|
return validateSocketFunc(ctx, podmanHost, false)
|
||||||
|
}()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return podmanHost, RuntimePodman, nil
|
return podmanHost, RuntimePodman, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to default Docker host
|
return "", RuntimeUnknown, ErrNoDockerSocket
|
||||||
return dockerHost, RuntimeDocker, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
pkg/commands/socket_detection_windows_test.go
Normal file
62
pkg/commands/socket_detection_windows_test.go
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectPlatformCandidates_Windows_DockerSuccess(t *testing.T) {
|
||||||
|
oldValidate := validateSocketFunc
|
||||||
|
defer func() { validateSocketFunc = oldValidate }()
|
||||||
|
|
||||||
|
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
|
||||||
|
if host == "npipe:////./pipe/docker_engine" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("mock failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := logrus.NewEntry(logrus.New())
|
||||||
|
host, runtime, err := detectPlatformCandidates(log)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "npipe:////./pipe/docker_engine", host)
|
||||||
|
assert.Equal(t, RuntimeDocker, runtime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectPlatformCandidates_Windows_PodmanSuccess(t *testing.T) {
|
||||||
|
oldValidate := validateSocketFunc
|
||||||
|
defer func() { validateSocketFunc = oldValidate }()
|
||||||
|
|
||||||
|
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
|
||||||
|
if host == "npipe:////./pipe/podman-machine-default" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("mock failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := logrus.NewEntry(logrus.New())
|
||||||
|
host, runtime, err := detectPlatformCandidates(log)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "npipe:////./pipe/podman-machine-default", host)
|
||||||
|
assert.Equal(t, RuntimePodman, runtime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectPlatformCandidates_Windows_Failure(t *testing.T) {
|
||||||
|
oldValidate := validateSocketFunc
|
||||||
|
defer func() { validateSocketFunc = oldValidate }()
|
||||||
|
|
||||||
|
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
|
||||||
|
return errors.New("mock failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := logrus.NewEntry(logrus.New())
|
||||||
|
_, _, err := detectPlatformCandidates(log)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, ErrNoDockerSocket, err)
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue