-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: tart macOS vm's as job container #2434
base: master
Are you sure you want to change the base?
Conversation
🦙 MegaLinter status: ✅ SUCCESS
See detailed report in MegaLinter reports |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2434 +/- ##
===========================================
+ Coverage 61.56% 75.07% +13.51%
===========================================
Files 53 63 +10
Lines 9002 10019 +1017
===========================================
+ Hits 5542 7522 +1980
+ Misses 3020 1935 -1085
- Partials 440 562 +122 ☔ View full report in Codecov by Sentry. |
func (e *Environment) Copy(destPath string, files ...*container.FileEntry) common.Executor { | ||
return e.HostEnvironment.Copy(e.ToHostPath(destPath), files...) | ||
} | ||
func (e *Environment) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error { | ||
return e.HostEnvironment.CopyTarStream(ctx, e.ToHostPath(destPath), tarStream) | ||
} | ||
func (e *Environment) CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor { | ||
return e.HostEnvironment.CopyDir(e.ToHostPath(destPath), srcPath, useGitIgnore) | ||
} | ||
func (e *Environment) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) { | ||
return e.HostEnvironment.GetContainerArchive(ctx, e.ToHostPath(srcPath)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I'm overriding GetActPath with a relocated vm path and I'm copying into the bind mount those change needs to be undone by ToHostPath before calling the super implementation
func (e *Environment) GetRunnerContext(ctx context.Context) map[string]interface{} { | ||
rctx := e.HostEnvironment.GetRunnerContext(ctx) | ||
rctx["temp"] = e.ToContainerPath(e.TmpDir) | ||
rctx["tool_cache"] = e.ToContainerPath(e.ToolCache) | ||
return rctx | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed so RUNNER_TEMP
are valid inside the vm, when used by actions cache
func (e *Environment) GetActPath() string { | ||
return e.ToContainerPath(e.HostEnvironment.GetActPath()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed so script paths passed to exec are valid inside the vm
return err | ||
} | ||
|
||
return e.execRaw(ctx, "ln -sf '/Volumes/My Shared Files/act' /private/tmp/act") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed for working around bugs with paths using spaces, e.g. the shell templates of run steps
} | ||
|
||
func (e Env) VirtualMachineID() string { | ||
return e.JobID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm reusing the docker container names used by containers, so no prefix and so on
|
||
func (rc *RunContext) startTartEnvironment() common.Executor { | ||
return func(_ context.Context) error { | ||
return fmt.Errorf("You need macOS for tart") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If someone thinks to run this mode on another OS, abort as tart is not available and some syscall part doesn't compile anyway.
toolCache := filepath.Join(cacheDir, "tool_cache") | ||
platImage := rc.runsOnImage(ctx) | ||
platURI, _ := url.Parse(platImage) | ||
query := platURI.Query() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that I'm smart, but no providing options in the -P <label>=tart://test?...
query doesn't actually work so only defaults for now
"github.com/nektos/act/pkg/tart" | ||
) | ||
|
||
func (rc *RunContext) startTartEnvironment() common.Executor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This started as a copy of hostenvironment, but is now different
func (rc *RunContext) IsTartEnv(ctx context.Context) bool { | ||
platform := rc.runsOnImage(ctx) | ||
image := rc.containerImage(ctx) | ||
return image == "" && strings.HasPrefix(platform, "tart://") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like -self-hosted
, but with tart://
. I forget this variant has only been used in act_runner as of now, but looks better.
Just starting to test this out and it looks good on first pass. testing on a mac m1 mbp if the gh action step fails, the container is left in a running state. if the container fails to start (say 2 vm limit is reached), the container is left in a stopped state. I've been using ssh, with tart / parallels / qemu to run jobs with I had a play with your runner.server & github-act-runner to build gh actions in my homelab with a set of vm's on a few diff machines. Cheers for your work |
Does
Yeah I have written and use my runner.server prog exactly for such a use case, but mostly with actions/runner as the actual runner. |
_, _ = rand.Read(randBytes) | ||
miscpath := filepath.Join(cacheDir, hex.EncodeToString(randBytes)) | ||
actPath := filepath.Join(miscpath, "act") | ||
if err := os.MkdirAll(actPath, 0o777); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should 0o777
be added as a constant? Maybe FULL_RWX or FULL_PERMS
|
||
func (rc *RunContext) startTartEnvironment() common.Executor { | ||
return func(_ context.Context) error { | ||
return fmt.Errorf("You need macOS for tart") |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing not test coverage, do we require them in a PR in order to get merged in this repo?
This requires a self-hosted runner, macos-14 github runner cannot be used due to running already in a Virtual Machine. Or stubbing tart, but then do we really know if tart works? This is not like intel macOS with nested virtualization... :(. |
@ChristopherHX this pull request has failed checks 🛠 |
@ChristopherHX this pull request has failed checks 🛠 |
Added a test for the error caused by using the tart mapping in linux where it is not supported, now coverage is green. We have a coverage collection problem for platforms outside of linux anyway. |
adds the tart:// protocol to platform mapping
e.g.
-P macos-14=tart://ghcr.io/cirruslabs/macos-sonoma-base:latest
if you have a mac.I have written the code in a payed dedicated host machine that is now deallocated, expenses satisfied by sponsoring of my other act based project while I don't see anything here, as I don't own a mac.
add-path
is probably broken, but I ignore the fact as of now.