forked from Ivasoft/github-actions
Alow not a DinD mode of operation
All checks were successful
continuous-integration/drone Build is passing
All checks were successful
continuous-integration/drone Build is passing
This commit is contained in:
99
plugin.go
99
plugin.go
@@ -6,10 +6,17 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"bufio"
|
||||
"path"
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
"github.com/drone-plugins/drone-github-actions/daemon"
|
||||
"github.com/drone-plugins/drone-github-actions/utils"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
docker "github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -17,6 +24,9 @@ const (
|
||||
secretFile = "/tmp/action.secrets"
|
||||
workflowFile = "/tmp/workflow.yml"
|
||||
eventPayloadFile = "/tmp/event.json"
|
||||
|
||||
stdDockerSocketPath = "/var/run/docker.sock"
|
||||
hiddenDockerSocketPath = "/var/run/hidden_docker.sock"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -64,7 +74,6 @@ func (p Plugin) Exec() error {
|
||||
secretFile,
|
||||
"--env-file",
|
||||
envFile,
|
||||
"-b",
|
||||
"--detect-event",
|
||||
}
|
||||
|
||||
@@ -86,11 +95,35 @@ func (p Plugin) Exec() error {
|
||||
cmdArgs = append(cmdArgs, "-v")
|
||||
}
|
||||
|
||||
if p.Daemon.Disabled {
|
||||
hostWorkDirPath, guestWorkDirPath, err := getWorkDirPath(p, context.Background())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to locate working directory on the host. You may use DinD instead by disabling daemon_off.")
|
||||
}
|
||||
|
||||
bindModifiers := ""
|
||||
if runtime.GOOS == "darwin" {
|
||||
bindModifiers = ":delegated"
|
||||
}
|
||||
if selinux.GetEnabled() {
|
||||
bindModifiers = ":z"
|
||||
}
|
||||
cmdArgs = append(cmdArgs, "--container-options", fmt.Sprintf("--volume=%s:%s%s", hostWorkDirPath, guestWorkDirPath, bindModifiers))
|
||||
|
||||
} else {
|
||||
cmdArgs = append(cmdArgs, "-b")
|
||||
}
|
||||
|
||||
|
||||
cmd := exec.Command("act", cmdArgs...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
trace(cmd)
|
||||
|
||||
if p.Daemon.Disabled && !p.Daemon.NotHiddenSocket {
|
||||
cmd.Env = append(os.Environ(), fmt.Sprintf("DOCKER_HOST=%s", "unix://" + hiddenDockerSocketPath))
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -103,3 +136,67 @@ func (p Plugin) Exec() error {
|
||||
func trace(cmd *exec.Cmd) {
|
||||
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
|
||||
}
|
||||
|
||||
func getWorkDirPath(p Plugin, ctx context.Context) (string, string, error) {
|
||||
// Connect to the docker
|
||||
// Note: We use a custom "hidden" socket path
|
||||
dockerSockPath := ""
|
||||
if p.Daemon.NotHiddenSocket {
|
||||
dockerSockPath = stdDockerSocketPath
|
||||
} else {
|
||||
dockerSockPath = hiddenDockerSocketPath
|
||||
}
|
||||
|
||||
docker, err := docker.NewClient("unix://" + dockerSockPath, "v1.13.1", nil, nil)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to create docker client")
|
||||
}
|
||||
defer docker.Close()
|
||||
|
||||
// Determine our container identifier
|
||||
cntrId, err := getContainerId()
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to get our container id")
|
||||
}
|
||||
|
||||
// Find the proper mount
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to locate the working directory in the container")
|
||||
}
|
||||
|
||||
cntr, err := docker.ContainerInspect(ctx, cntrId)
|
||||
if err != nil {
|
||||
return "", "", errors.Wrap(err, "failed to inspect ourselves as a container")
|
||||
}
|
||||
for _, i := range cntr.Mounts {
|
||||
if i.Destination == cwd {
|
||||
return i.Source, i.Destination, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", "", errors.New("mount point with working directory not found")
|
||||
}
|
||||
|
||||
func getContainerId() (string, error) {
|
||||
file, err := os.Open("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
if !scanner.Scan() {
|
||||
return "", errors.New("cgroup is empty")
|
||||
}
|
||||
|
||||
// The file name is the container identifier
|
||||
// Example: 12:rdma:/docker/a33940bf95ec6c57b6d79a3edfa784a1364ce840fb92c9a7f3951b9f7b0ccccb/docker/330d9b057fdd54b224cd38daf370524f7e8c567ccf95f33a2388f02c0b854982
|
||||
cgroup := scanner.Text()
|
||||
result := path.Base(cgroup)
|
||||
if result == "." {
|
||||
return "", errors.New("cgroup is unexpected")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user