package runner import ( "context" "crypto/rand" "encoding/hex" "fmt" "net/url" "os" "path/filepath" "strings" "github.com/actions-oss/act-cli/pkg/common" "github.com/actions-oss/act-cli/pkg/container" "github.com/actions-oss/act-cli/pkg/tart" ) func (rc *RunContext) startTartEnvironment() common.Executor { return func(ctx context.Context) error { logger := common.Logger(ctx) rawLogger := logger.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 }) cacheDir := rc.ActionCacheDir() randBytes := make([]byte, 8) _, _ = rand.Read(randBytes) miscpath := filepath.Join(cacheDir, hex.EncodeToString(randBytes)) actPath := filepath.Join(miscpath, "act") if err := os.MkdirAll(actPath, 0o777); err != nil { return err } path := filepath.Join(miscpath, "hostexecutor") if err := os.MkdirAll(path, 0o777); err != nil { return err } runnerTmp := filepath.Join(miscpath, "tmp") if err := os.MkdirAll(runnerTmp, 0o777); err != nil { return err } toolCache := filepath.Join(cacheDir, "tool_cache") platImage := rc.runsOnImage(ctx) platURI, _ := url.Parse(platImage) query := platURI.Query() tenv := &tart.Environment{ HostEnvironment: container.HostEnvironment{ Path: path, TmpDir: runnerTmp, ToolCache: toolCache, Workdir: rc.Config.Workdir, ActPath: actPath, CleanUp: func() { os.RemoveAll(miscpath) }, StdOut: logWriter, }, Config: tart.Config{ SSHUsername: "admin", SSHPassword: "admin", Softnet: query.Get("softnet") == "1", Headless: query.Get("headless") != "0", AlwaysPull: rc.Config.ForcePull, }, Env: &tart.Env{ JobImage: platURI.Host + platURI.EscapedPath(), JobID: rc.jobContainerName(), }, Miscpath: miscpath, } if query.Has("pull") { tenv.Config.AlwaysPull = query.Get("pull") != "0" } rc.JobContainer = tenv if query.Has("sshusername") { tenv.Config.SSHUsername = query.Get("sshusername") } if query.Has("sshpassword") { tenv.Config.SSHPassword = query.Get("sshpassword") } rc.cleanUpJobContainer = rc.JobContainer.Remove() for k, v := range rc.JobContainer.GetRunnerContext(ctx) { if v, ok := v.(string); ok { rc.Env[fmt.Sprintf("RUNNER_%s", strings.ToUpper(k))] = v } } return common.NewPipelineExecutor( // rc.JobContainer.Remove(), rc.JobContainer.Start(false), rc.JobContainer.Copy(rc.JobContainer.GetActPath()+"/", &container.FileEntry{ Name: "workflow/event.json", Mode: 0o644, Body: rc.EventJSON, }, &container.FileEntry{ Name: "workflow/envs.txt", Mode: 0o666, Body: "", }), )(ctx) } }