diff --git a/cmd/root.go b/cmd/root.go index 1742e8a1ed9..cf6a9560258 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -80,7 +80,7 @@ func Execute(ctx context.Context, version string) { rootCmd.PersistentFlags().StringVarP(&input.envfile, "env-file", "", ".env", "environment file to read and use as env in the containers") rootCmd.PersistentFlags().StringVarP(&input.inputfile, "input-file", "", ".input", "input file to read and use as action input") rootCmd.PersistentFlags().StringVarP(&input.containerArchitecture, "container-architecture", "", "", "Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.") - rootCmd.PersistentFlags().StringVarP(&input.containerDaemonSocket, "container-daemon-socket", "", "/var/run/docker.sock", "Path to Docker daemon socket which will be mounted to containers") + rootCmd.PersistentFlags().StringVarP(&input.containerDaemonSocket, "container-daemon-socket", "", "", "URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock)") rootCmd.PersistentFlags().StringVarP(&input.containerOptions, "container-options", "", "", "Custom docker container options for the job container without an options property in the job definition") rootCmd.PersistentFlags().StringVarP(&input.githubInstance, "github-instance", "", "github.com", "GitHub instance to use. Don't use this if you are not using GitHub Enterprise Server.") rootCmd.PersistentFlags().StringVarP(&input.artifactServerPath, "artifact-server-path", "", "", "Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.") @@ -118,6 +118,33 @@ func configLocations() []string { } } +var commonSocketPaths = []string{ + "/var/run/docker.sock", + "/var/run/podman/podman.sock", + "$HOME/.colima/docker.sock", + "$XDG_RUNTIME_DIR/docker.sock", + `\\.\pipe\docker_engine`, + "$HOME/.docker/run/docker.sock", +} + +// returns socket path or false if not found any +func socketLocation() (string, bool) { + if dockerHost, exists := os.LookupEnv("DOCKER_HOST"); exists { + return dockerHost, true + } + + for _, p := range commonSocketPaths { + if _, err := os.Lstat(os.ExpandEnv(p)); err == nil { + if strings.HasPrefix(p, `\\.\`) { + return "npipe://" + os.ExpandEnv(p), true + } + return "unix://" + os.ExpandEnv(p), true + } + } + + return "", false +} + func args() []string { actrc := configLocations() @@ -131,15 +158,6 @@ func args() []string { } func bugReport(ctx context.Context, version string) error { - var commonSocketPaths = []string{ - "/var/run/docker.sock", - "/var/run/podman/podman.sock", - "$HOME/.colima/docker.sock", - "$XDG_RUNTIME_DIR/docker.sock", - `\\.\pipe\docker_engine`, - "$HOME/.docker/run/docker.sock", - } - sprintf := func(key, val string) string { return fmt.Sprintf("%-24s%s\n", key, val) } @@ -150,22 +168,20 @@ func bugReport(ctx context.Context, version string) error { report += sprintf("NumCPU:", fmt.Sprint(runtime.NumCPU())) var dockerHost string - if dockerHost = os.Getenv("DOCKER_HOST"); dockerHost == "" { - dockerHost = "DOCKER_HOST environment variable is unset/empty." + var exists bool + if dockerHost, exists = os.LookupEnv("DOCKER_HOST"); !exists { + dockerHost = "DOCKER_HOST environment variable is not set" + } else if dockerHost == "" { + dockerHost = "DOCKER_HOST environment variable is empty." } report += sprintf("Docker host:", dockerHost) report += fmt.Sprintln("Sockets found:") for _, p := range commonSocketPaths { - if strings.HasPrefix(p, `$`) { - v := strings.Split(p, `/`)[0] - p = strings.Replace(p, v, os.Getenv(strings.TrimPrefix(v, `$`)), 1) - } - if _, err := os.Stat(p); err != nil { + if _, err := os.Stat(os.ExpandEnv(p)); err != nil { continue - } else { - report += fmt.Sprintf("\t%s\n", p) } + report += fmt.Sprintf("\t%s\n", p) } report += sprintf("Config files:", "") @@ -342,6 +358,19 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str return bugReport(ctx, cmd.Version) } + var socketPath string + if input.containerDaemonSocket != "" { + socketPath = input.containerDaemonSocket + } else { + socket, found := socketLocation() + if !found && input.containerDaemonSocket == "" { + log.Errorln("daemon Docker Engine socket not found and containerDaemonSocket option was not set") + } else { + socketPath = socket + } + } + os.Setenv("DOCKER_HOST", socketPath) + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" && input.containerArchitecture == "" { l := log.New() l.SetFormatter(&log.TextFormatter{ @@ -533,7 +562,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str Privileged: input.privileged, UsernsMode: input.usernsMode, ContainerArchitecture: input.containerArchitecture, - ContainerDaemonSocket: input.containerDaemonSocket, + ContainerDaemonSocket: socketPath, ContainerOptions: input.containerOptions, UseGitIgnore: input.useGitIgnore, GitHubInstance: input.githubInstance, diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go index 1b194eac9ae..df296e0d083 100644 --- a/pkg/container/docker_run.go +++ b/pkg/container/docker_run.go @@ -189,9 +189,6 @@ type containerReference struct { } func GetDockerClient(ctx context.Context) (cli client.APIClient, err error) { - // TODO: this should maybe need to be a global option, not hidden in here? - // though i'm not sure how that works out when there's another Executor :D - // I really would like something that works on OSX native for eg dockerHost := os.Getenv("DOCKER_HOST") if strings.HasPrefix(dockerHost, "ssh://") {