Alow not a DinD mode of operation
All checks were successful
continuous-integration/drone Build is passing

This commit is contained in:
2023-07-28 18:24:39 +02:00
parent b4057e26e5
commit 836c1329fa
6 changed files with 199 additions and 36 deletions

View File

@@ -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
}