summaryrefslogtreecommitdiffstats
path: root/pkg/runner/step_docker.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/runner/step_docker.go')
-rw-r--r--pkg/runner/step_docker.go137
1 files changed, 137 insertions, 0 deletions
diff --git a/pkg/runner/step_docker.go b/pkg/runner/step_docker.go
new file mode 100644
index 0000000..2f23986
--- /dev/null
+++ b/pkg/runner/step_docker.go
@@ -0,0 +1,137 @@
+package runner
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/kballard/go-shellquote"
+ "github.com/nektos/act/pkg/common"
+ "github.com/nektos/act/pkg/container"
+ "github.com/nektos/act/pkg/model"
+)
+
+type stepDocker struct {
+ Step *model.Step
+ RunContext *RunContext
+ env map[string]string
+}
+
+func (sd *stepDocker) pre() common.Executor {
+ return func(ctx context.Context) error {
+ return nil
+ }
+}
+
+func (sd *stepDocker) main() common.Executor {
+ sd.env = map[string]string{}
+
+ return runStepExecutor(sd, stepStageMain, sd.runUsesContainer())
+}
+
+func (sd *stepDocker) post() common.Executor {
+ return func(ctx context.Context) error {
+ return nil
+ }
+}
+
+func (sd *stepDocker) getRunContext() *RunContext {
+ return sd.RunContext
+}
+
+func (sd *stepDocker) getGithubContext(ctx context.Context) *model.GithubContext {
+ return sd.getRunContext().getGithubContext(ctx)
+}
+
+func (sd *stepDocker) getStepModel() *model.Step {
+ return sd.Step
+}
+
+func (sd *stepDocker) getEnv() *map[string]string {
+ return &sd.env
+}
+
+func (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) string {
+ return sd.Step.If.Value
+}
+
+func (sd *stepDocker) runUsesContainer() common.Executor {
+ rc := sd.RunContext
+ step := sd.Step
+
+ return func(ctx context.Context) error {
+ image := strings.TrimPrefix(step.Uses, "docker://")
+ eval := rc.NewExpressionEvaluator(ctx)
+ cmd, err := shellquote.Split(eval.Interpolate(ctx, step.With["args"]))
+ if err != nil {
+ return err
+ }
+
+ var entrypoint []string
+ if entry := eval.Interpolate(ctx, step.With["entrypoint"]); entry != "" {
+ entrypoint = []string{entry}
+ }
+
+ stepContainer := sd.newStepContainer(ctx, image, cmd, entrypoint)
+
+ return common.NewPipelineExecutor(
+ stepContainer.Pull(rc.Config.ForcePull),
+ stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
+ stepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
+ stepContainer.Start(true),
+ ).Finally(
+ stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
+ ).Finally(stepContainer.Close())(ctx)
+ }
+}
+
+var (
+ ContainerNewContainer = container.NewContainer
+)
+
+func (sd *stepDocker) newStepContainer(ctx context.Context, image string, cmd []string, entrypoint []string) container.Container {
+ rc := sd.RunContext
+ step := sd.Step
+
+ rawLogger := common.Logger(ctx).WithField("raw_output", true)
+ logWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {
+ if rc.Config.LogOutput {
+ rawLogger.Infof("%s", s)
+ } else {
+ rawLogger.Debugf("%s", s)
+ }
+ return true
+ })
+ envList := make([]string, 0)
+ for k, v := range sd.env {
+ envList = append(envList, fmt.Sprintf("%s=%s", k, v))
+ }
+
+ envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_TOOL_CACHE", "/opt/hostedtoolcache"))
+ envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_OS", "Linux"))
+ envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_ARCH", container.RunnerArch(ctx)))
+ envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_TEMP", "/tmp"))
+
+ binds, mounts := rc.GetBindsAndMounts()
+ stepContainer := ContainerNewContainer(&container.NewContainerInput{
+ Cmd: cmd,
+ Entrypoint: entrypoint,
+ WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir),
+ Image: image,
+ Username: rc.Config.Secrets["DOCKER_USERNAME"],
+ Password: rc.Config.Secrets["DOCKER_PASSWORD"],
+ Name: createSimpleContainerName(rc.jobContainerName(), "STEP-"+step.ID),
+ Env: envList,
+ Mounts: mounts,
+ NetworkMode: fmt.Sprintf("container:%s", rc.jobContainerName()),
+ Binds: binds,
+ Stdout: logWriter,
+ Stderr: logWriter,
+ Privileged: rc.Config.Privileged,
+ UsernsMode: rc.Config.UsernsMode,
+ Platform: rc.Config.ContainerArchitecture,
+ AutoRemove: rc.Config.AutoRemove,
+ ValidVolumes: rc.Config.ValidVolumes,
+ })
+ return stepContainer
+}