diff --git a/go.mod b/go.mod index 90623bdf4..446c244d0 100644 --- a/go.mod +++ b/go.mod @@ -38,6 +38,7 @@ require ( go.opentelemetry.io/otel/sdk v1.37.0 go.opentelemetry.io/otel/sdk/metric v1.37.0 go.uber.org/mock v0.5.2 + golang.ngrok.com/ngrok/v2 v2.0.0 golang.org/x/exp/jsonrpc2 v0.0.0-20250718183923-645b1fa84792 golang.org/x/mod v0.27.0 golang.org/x/oauth2 v0.30.0 @@ -238,7 +239,6 @@ require ( go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.ngrok.com/muxado/v2 v2.0.1 // indirect - golang.ngrok.com/ngrok/v2 v2.0.0 // indirect golang.org/x/exp/event v0.0.0-20250620022241-b7579e27df2b // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/text v0.27.0 // indirect diff --git a/go.sum b/go.sum index 6d69713c1..b0f3c052e 100644 --- a/go.sum +++ b/go.sum @@ -1145,6 +1145,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= diff --git a/pkg/container/docker/sdk/client_unix.go b/pkg/container/docker/sdk/client_unix.go index 464db850f..9d2e072b2 100644 --- a/pkg/container/docker/sdk/client_unix.go +++ b/pkg/container/docker/sdk/client_unix.go @@ -62,6 +62,15 @@ func findPlatformContainerSocket(rt runtime.Type) (string, runtime.Type, error) return customSocketPath, runtime.TypeDocker, nil } + if customSocketPath := os.Getenv(ColimaSocketEnv); customSocketPath != "" { + logger.Debugf("Using Colima socket from env: %s", customSocketPath) + // validate the socket path + if _, err := os.Stat(customSocketPath); err != nil { + return "", runtime.TypeDocker, fmt.Errorf("invalid Colima socket path: %w", err) + } + return customSocketPath, runtime.TypeDocker, nil + } + if rt == runtime.TypePodman { socketPath, err := findPodmanSocket() if err == nil { @@ -76,6 +85,13 @@ func findPlatformContainerSocket(rt runtime.Type) (string, runtime.Type, error) } } + if rt == runtime.TypeColima { + socketPath, err := findColimaSocket() + if err == nil { + return socketPath, runtime.TypeColima, nil + } + } + return "", "", ErrRuntimeNotFound } @@ -159,3 +175,30 @@ func findDockerSocket() (string, error) { return "", fmt.Errorf("docker socket not found in standard locations") } + +// findColimaSocket attempts to locate a Colima socket +func findColimaSocket() (string, error) { + // Check standard Colima location + _, err := os.Stat(ColimaDesktopMacSocketPath) + if err == nil { + logger.Debugf("Found Colima socket at %s", ColimaDesktopMacSocketPath) + return ColimaDesktopMacSocketPath, nil + } + + logger.Debugf("Failed to check Colima socket at %s: %v", ColimaDesktopMacSocketPath, err) + + // Check user-specific location for Colima + if home := os.Getenv("HOME"); home != "" { + userSocketPath := filepath.Join(home, ColimaDesktopMacSocketPath) + _, err := os.Stat(userSocketPath) + + if err == nil { + logger.Debugf("Found Colima socket at %s", userSocketPath) + return userSocketPath, nil + } + + logger.Debugf("Failed to check Colima socket at %s: %v", userSocketPath, err) + } + + return "", fmt.Errorf("colima socket not found in standard locations") +} diff --git a/pkg/container/docker/sdk/factory.go b/pkg/container/docker/sdk/factory.go index ec940c0f6..63a710bcc 100644 --- a/pkg/container/docker/sdk/factory.go +++ b/pkg/container/docker/sdk/factory.go @@ -22,6 +22,8 @@ const ( DockerSocketEnv = "TOOLHIVE_DOCKER_SOCKET" // PodmanSocketEnv is the environment variable for custom Podman socket path PodmanSocketEnv = "TOOLHIVE_PODMAN_SOCKET" + // ColimaSocketEnv is the environment variable for custom Colima socket path + ColimaSocketEnv = "TOOLHIVE_COLIMA_SOCKET" ) // Common socket paths @@ -36,9 +38,11 @@ const ( DockerDesktopMacSocketPath = ".docker/run/docker.sock" // RancherDesktopMacSocketPath is the Docker socket path for Rancher Desktop on macOS RancherDesktopMacSocketPath = ".rd/docker.sock" + // ColimaDesktopMacSocketPath is the Docker socket path for Colima on macOS + ColimaDesktopMacSocketPath = ".colima/default/docker.sock" ) -var supportedSocketPaths = []runtime.Type{runtime.TypePodman, runtime.TypeDocker} +var supportedSocketPaths = []runtime.Type{runtime.TypePodman, runtime.TypeDocker, runtime.TypeColima} // NewDockerClient creates a new container client func NewDockerClient(ctx context.Context) (*client.Client, string, runtime.Type, error) { diff --git a/pkg/container/runtime/types.go b/pkg/container/runtime/types.go index 393c3032e..0697e7add 100644 --- a/pkg/container/runtime/types.go +++ b/pkg/container/runtime/types.go @@ -186,6 +186,8 @@ const ( TypeDocker Type = "docker" // TypeKubernetes represents the Kubernetes runtime TypeKubernetes Type = "kubernetes" + // TypeColima represents the Colima runtime + TypeColima Type = "colima" ) // MountType represents the type of mount