2022-03-23 05:13:00 +08:00
|
|
|
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{}
|
|
|
|
|
2022-05-24 21:36:06 +08:00
|
|
|
return runStepExecutor(sd, stepStageMain, sd.runUsesContainer())
|
2022-03-23 05:13:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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) getStepModel() *model.Step {
|
|
|
|
return sd.Step
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sd *stepDocker) getEnv() *map[string]string {
|
|
|
|
return &sd.env
|
|
|
|
}
|
|
|
|
|
2022-06-17 23:55:21 +08:00
|
|
|
func (sd *stepDocker) getIfExpression(context context.Context, stage stepStage) string {
|
2022-05-24 21:36:06 +08:00
|
|
|
return sd.Step.If.Value
|
|
|
|
}
|
|
|
|
|
2022-03-23 05:13:00 +08:00
|
|
|
func (sd *stepDocker) runUsesContainer() common.Executor {
|
|
|
|
rc := sd.RunContext
|
|
|
|
step := sd.Step
|
|
|
|
|
|
|
|
return func(ctx context.Context) error {
|
|
|
|
image := strings.TrimPrefix(step.Uses, "docker://")
|
2022-06-17 23:55:21 +08:00
|
|
|
eval := rc.NewExpressionEvaluator(ctx)
|
|
|
|
cmd, err := shellquote.Split(eval.Interpolate(ctx, step.With["args"]))
|
2022-03-23 05:13:00 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-03-30 02:00:52 +08:00
|
|
|
|
|
|
|
var entrypoint []string
|
2022-06-17 23:55:21 +08:00
|
|
|
if entry := eval.Interpolate(ctx, step.With["entrypoint"]); entry != "" {
|
2022-03-30 02:00:52 +08:00
|
|
|
entrypoint = []string{entry}
|
|
|
|
}
|
|
|
|
|
2022-03-23 05:13:00 +08:00
|
|
|
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"))
|
2022-08-29 23:39:31 +08:00
|
|
|
envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_ARCH", container.RunnerArch(ctx)))
|
2022-03-23 05:13:00 +08:00
|
|
|
envList = append(envList, fmt.Sprintf("%s=%s", "RUNNER_TEMP", "/tmp"))
|
|
|
|
|
|
|
|
binds, mounts := rc.GetBindsAndMounts()
|
|
|
|
stepContainer := ContainerNewContainer(&container.NewContainerInput{
|
|
|
|
Cmd: cmd,
|
|
|
|
Entrypoint: entrypoint,
|
|
|
|
WorkingDir: rc.Config.ContainerWorkdir(),
|
|
|
|
Image: image,
|
|
|
|
Username: rc.Config.Secrets["DOCKER_USERNAME"],
|
|
|
|
Password: rc.Config.Secrets["DOCKER_PASSWORD"],
|
|
|
|
Name: createContainerName(rc.jobContainerName(), 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,
|
|
|
|
})
|
|
|
|
return stepContainer
|
|
|
|
}
|