Skip to content

feat: support Apple container#614

Draft
janishorsts wants to merge 5 commits into
mainfrom
385-proposal-support-apple-container
Draft

feat: support Apple container#614
janishorsts wants to merge 5 commits into
mainfrom
385-proposal-support-apple-container

Conversation

@janishorsts

Copy link
Copy Markdown
Collaborator

No description provided.

@janishorsts janishorsts self-assigned this Jun 26, 2026
@janishorsts janishorsts added enhancement New feature or request ai-assisted Authored with AI assistance labels Jun 26, 2026
@janishorsts janishorsts linked an issue Jun 26, 2026 that may be closed by this pull request
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

⚠️ Are we earthbuild yet?

Warning: "earthly" occurrences have increased by 345 (6.45%)

📈 Overall Progress

Branch Total Count
main 5346
This PR 5691
Difference +345 (6.45%)

📁 Changes by file type:

File Type Change
Go files (.go) ❌ +1
Documentation (.md) ➖ No change
Earthfiles ➖ No change

Keep up the great work migrating from Earthly to Earthbuild! 🚀

💡 Tips for finding more occurrences

Run locally to see detailed breakdown:

./.github/scripts/count-earthly.sh

Note that the goal is not to reach 0.
There is anticipated to be at least some occurences of earthly in the source code due to backwards compatibility with config files and language constructs.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for a new container frontend, "Apple Container" (using the container binary), alongside Docker and Podman. It adds the implementation for managing containers, images, and volumes under this frontend, updates configuration and autodetection logic, and includes corresponding unit tests. A review comment points out critical resource leak and error-handling issues in the ImageLoad function of the new frontend, suggesting an anonymous function wrapper to properly scope deferred file closures and cleanups.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +396 to +421
func (asf *appleShellFrontend) ImageLoad(ctx context.Context, images ...io.Reader) error {
var err error

for _, image := range images {
file, tmpErr := os.CreateTemp("", "earthly-apple-load-*")
if tmpErr != nil {
err = multierror.Append(err, errors.Wrap(tmpErr, "failed to create temp tarball"))
continue
}

_, copyErr := io.Copy(file, image)
if copyErr != nil {
err = multierror.Append(err, errors.Wrapf(tmpErr, "failed to write to %s", file.Name()))
continue
}
defer file.Close()
defer os.Remove(file.Name())

output, cmdErr := asf.commandContextOutput(ctx, "image", "load", "--input", file.Name())
if cmdErr != nil {
err = multierror.Append(err, errors.Wrapf(cmdErr, "image load failed: %s", output.string()))
}
}

return err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There are three distinct issues in this function:

  1. Resource Leak in Loop: defer file.Close() and defer os.Remove(...) are used inside a for loop. In Go, defer is evaluated when the surrounding function returns, not when the loop iteration ends. This will keep all temporary files open and on disk until the entire ImageLoad function completes.
  2. Permanent Leak on Copy Error: If io.Copy fails, the loop continues before the defer statements are registered, meaning the temporary file is never closed or deleted.
  3. Wrapping nil Error: When copyErr != nil, the code wraps tmpErr (which is nil at this point) instead of copyErr. This silences the actual copy error.

Wrapping the loop body in an anonymous function resolves the defer scope issue, ensures files are cleaned up even on copy errors, and allows us to correctly wrap copyErr.

func (asf *appleShellFrontend) ImageLoad(ctx context.Context, images ...io.Reader) error {
	var err error

	for _, image := range images {
		func() {
			file, tmpErr := os.CreateTemp("", "earthly-apple-load-*")
			if tmpErr != nil {
				err = multierror.Append(err, errors.Wrap(tmpErr, "failed to create temp tarball"))
				return
			}
			defer file.Close()
			defer os.Remove(file.Name())

			_, copyErr := io.Copy(file, image)
			if copyErr != nil {
				err = multierror.Append(err, errors.Wrapf(copyErr, "failed to write to %s", file.Name()))
				return
			}

			output, cmdErr := asf.commandContextOutput(ctx, "image", "load", "--input", file.Name())
			if cmdErr != nil {
				err = multierror.Append(err, errors.Wrapf(cmdErr, "image load failed: %s", output.string()))
			}
		}()
	}

	return err
}
References
  1. In Go, avoid using an if statement with an initializer. Instead, declare the variable on a preceding line to prevent potential conflicts with project linting rules.

@janishorsts

Copy link
Copy Markdown
Collaborator Author

Blocked by #615

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted Authored with AI assistance enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

proposal: Support apple container

1 participant