github.com/nektos/act@v0.2.63/pkg/runner/step_docker.go (about) 1 package runner 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/kballard/go-shellquote" 9 "github.com/nektos/act/pkg/common" 10 "github.com/nektos/act/pkg/container" 11 "github.com/nektos/act/pkg/model" 12 ) 13 14 type stepDocker struct { 15 Step *model.Step 16 RunContext *RunContext 17 env map[string]string 18 } 19 20 func (sd *stepDocker) pre() common.Executor { 21 return func(ctx context.Context) error { 22 return nil 23 } 24 } 25 26 func (sd *stepDocker) main() common.Executor { 27 sd.env = map[string]string{} 28 29 return runStepExecutor(sd, stepStageMain, sd.runUsesContainer()) 30 } 31 32 func (sd *stepDocker) post() common.Executor { 33 return func(ctx context.Context) error { 34 return nil 35 } 36 } 37 38 func (sd *stepDocker) getRunContext() *RunContext { 39 return sd.RunContext 40 } 41 42 func (sd *stepDocker) getGithubContext(ctx context.Context) *model.GithubContext { 43 return sd.getRunContext().getGithubContext(ctx) 44 } 45 46 func (sd *stepDocker) getStepModel() *model.Step { 47 return sd.Step 48 } 49 50 func (sd *stepDocker) getEnv() *map[string]string { 51 return &sd.env 52 } 53 54 func (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) string { 55 return sd.Step.If.Value 56 } 57 58 func (sd *stepDocker) runUsesContainer() common.Executor { 59 rc := sd.RunContext 60 step := sd.Step 61 62 return func(ctx context.Context) error { 63 image := strings.TrimPrefix(step.Uses, "docker://") 64 eval := rc.NewExpressionEvaluator(ctx) 65 cmd, err := shellquote.Split(eval.Interpolate(ctx, step.With["args"])) 66 if err != nil { 67 return err 68 } 69 70 var entrypoint []string 71 if entry := eval.Interpolate(ctx, step.With["entrypoint"]); entry != "" { 72 entrypoint = []string{entry} 73 } 74 75 stepContainer := sd.newStepContainer(ctx, image, cmd, entrypoint) 76 77 return common.NewPipelineExecutor( 78 stepContainer.Pull(rc.Config.ForcePull), 79 stepContainer.Remove().IfBool(!rc.Config.ReuseContainers), 80 stepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop), 81 stepContainer.Start(true), 82 ).Finally( 83 stepContainer.Remove().IfBool(!rc.Config.ReuseContainers), 84 ).Finally(stepContainer.Close())(ctx) 85 } 86 } 87 88 var ( 89 ContainerNewContainer = container.NewContainer 90 ) 91 92 func (sd *stepDocker) newStepContainer(ctx context.Context, image string, cmd []string, entrypoint []string) container.Container { 93 rc := sd.RunContext 94 step := sd.Step 95 96 rawLogger := common.Logger(ctx).WithField("raw_output", true) 97 logWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool { 98 if rc.Config.LogOutput { 99 rawLogger.Infof("%s", s) 100 } else { 101 rawLogger.Debugf("%s", s) 102 } 103 return true 104 }) 105 envList := make([]string, 0) 106 for k, v := range sd.env { 107 envList = append(envList, fmt.Sprintf("%s=%s", k, v)) 108 } 109 110 envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_TOOL_CACHE", "/opt/hostedtoolcache")) 111 envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_OS", "Linux")) 112 envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_ARCH", container.RunnerArch(ctx))) 113 envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_TEMP", "/tmp")) 114 115 binds, mounts := rc.GetBindsAndMounts() 116 stepContainer := ContainerNewContainer(&container.NewContainerInput{ 117 Cmd: cmd, 118 Entrypoint: entrypoint, 119 WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir), 120 Image: image, 121 Username: rc.Config.Secrets["DOCKER_USERNAME"], 122 Password: rc.Config.Secrets["DOCKER_PASSWORD"], 123 Name: createContainerName(rc.jobContainerName(), step.ID), 124 Env: envList, 125 Mounts: mounts, 126 NetworkMode: fmt.Sprintf("container:%s", rc.jobContainerName()), 127 Binds: binds, 128 Stdout: logWriter, 129 Stderr: logWriter, 130 Privileged: rc.Config.Privileged, 131 UsernsMode: rc.Config.UsernsMode, 132 Platform: rc.Config.ContainerArchitecture, 133 }) 134 return stepContainer 135 }