Skip to content

Issue #4881 Add Rosetta 2 support for Apple Silicon#5181

Open
cpepper96 wants to merge 1 commit into
crc-org:mainfrom
cpepper96:main
Open

Issue #4881 Add Rosetta 2 support for Apple Silicon#5181
cpepper96 wants to merge 1 commit into
crc-org:mainfrom
cpepper96:main

Conversation

@cpepper96

@cpepper96 cpepper96 commented Mar 16, 2026

Copy link
Copy Markdown

Description

Fixes: #4881

Hi folks! This PR adds support for enabling Rosetta 2 on MacOS. The issue linked above does a great a job of describing the problem and solution.

TLDR: CRC currently uses QEMU on ARM64 MacOS to emulate x86 instructions. This has known limitations and some x86 containers are unable to run on CRC on Mac. Swapping Rosetta for QEMU should result in faster and more stable performance when trying to run x86 containers with CRC on Mac.

My team has been using this solution for the last couple of weeks with no issues except for one edge case. x86 binaries that use reexec() (e.g., buildah) have a known limitation under Rosetta due to kernel-level binfmt_misc + memfd interactions.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change
  • Chore (non-breaking change which doesn't affect codebase;
    test, version modification, documentation, etc.)

Proposed changes

  • Added new use-rosetta config field to enable this feature
  • Added preflight check to validate host os has rosetta
  • Updated Darwin vfkit driver to expose Rosetta virtiofs share
  • During CRC start configureRosetta will use sshRunner to:
  1. Mount the Rosetta virtiofs share into the CRC VM
  2. Create an additional shared bindmount at var/lib/rosetta/rosetta to be accessible across namespace boundaries (helpful for stuff like buildah which uses unshare()).
  3. Mask QEMU binfmt config and register Rosetta as the x86_64 binfmt handler with CFP flags

Testing

  1. Setup and start crc with crc config set use-rosetta true
  2. SSH into running CRC VM and confirm that Rosetta binfmt is registered and Rosetta is mounted
[core@crc ~]$ cat /proc/sys/fs/binfmt_misc/rosetta
enabled
interpreter /var/lib/rosetta/rosetta
flags: POCF
offset 0
magic 7f454c4602010100000000000000000002003e00
mask fffffffffffefe00fffffffffffffffffeffffff
[core@crc ~]$ mount | grep rosetta
rosetta on /run/media/rosetta type virtiofs (rw,relatime,context=system_u:object_r:bin_t:s0)
  1. Run a container on the VM that is known to fail on CRC with QEMU
sudo podman run --rm --platform linux/amd64 quay.io/coreos/etcd:v3.5.9 etcd

Contribution Checklist

  • I Keep It Small and Simple: The smaller the PR is, the easier it is to review and have it merged
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Which platform have you tested the code changes on?
    • Linux
    • Windows
    • MacOS

Summary by CodeRabbit

  • New Features

    • Rosetta emulation support on Apple Silicon Macs
    • New "use-rosetta" config option to enable Rosetta during VM startup
    • VM startup performs in-VM Rosetta setup and host-side Rosetta share when enabled
    • Preflight checks added to verify Rosetta runtime installation
  • Validation

    • Option limited to supported Apple Silicon (macOS on arm64)
  • Tests

    • Preflight tests updated for Rosetta-enabled scenarios

@openshift-ci

openshift-ci Bot commented Mar 16, 2026

Copy link
Copy Markdown

Hi @cpepper96. Thanks for your PR.

I'm waiting for a crc-org member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai

coderabbitai Bot commented Mar 16, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1338bc41-264f-4d36-b32c-55f04bdcec4e

📥 Commits

Reviewing files that changed from the base of the PR and between 121f39c and daa322f.

📒 Files selected for processing (15)
  • cmd/crc/cmd/start.go
  • pkg/crc/config/settings.go
  • pkg/crc/config/validations.go
  • pkg/crc/machine/config/config.go
  • pkg/crc/machine/start.go
  • pkg/crc/machine/types/types.go
  • pkg/crc/machine/vfkit/driver_darwin.go
  • pkg/crc/preflight/preflight.go
  • pkg/crc/preflight/preflight_checks_darwin.go
  • pkg/crc/preflight/preflight_darwin.go
  • pkg/crc/preflight/preflight_darwin_test.go
  • pkg/crc/preflight/preflight_linux.go
  • pkg/crc/preflight/preflight_windows.go
  • pkg/crc/preflight/preflight_windows_test.go
  • pkg/drivers/vfkit/driver_darwin.go
✅ Files skipped from review due to trivial changes (2)
  • pkg/crc/machine/types/types.go
  • pkg/crc/machine/config/config.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • pkg/crc/preflight/preflight_checks_darwin.go
  • pkg/crc/config/settings.go
  • pkg/crc/preflight/preflight_darwin.go
  • pkg/crc/preflight/preflight_windows_test.go
  • pkg/crc/preflight/preflight_windows.go
  • pkg/crc/preflight/preflight_linux.go
  • pkg/crc/machine/start.go
  • pkg/crc/preflight/preflight_darwin_test.go

Walkthrough

Adds optional Rosetta 2 support for Apple Silicon macOS: new config key with validation, flag propagation into start/machine configs and VFKit driver, VM-side Rosetta virtiofs device and in-VM binfmt setup during startup, and Darwin preflight checks and test updates.

Changes

Rosetta 2 integration

Layer / File(s) Summary
Config: settings and validation
pkg/crc/config/settings.go, pkg/crc/config/validations.go
Adds UseRosetta config key, registers it with validateRosetta (darwin/arm64 only), notifier, and help text.
Types and machine config
pkg/crc/machine/types/types.go, pkg/crc/machine/config/config.go, cmd/crc/cmd/start.go, pkg/crc/machine/vfkit/driver_darwin.go
Adds EnableRosetta to StartConfig and MachineConfig, reads UseRosetta into StartConfig in start flow, and propagates into host/driver creation.
VFKit driver wiring
pkg/drivers/vfkit/driver_darwin.go
Adds exported Driver.Rosetta and, when true, creates and attaches a Rosetta virtiofs share device to the VM during Start.
Start flow: VM-side Rosetta configuration
pkg/crc/machine/start.go
Adds configureRosetta(sshRunner) which mounts the virtiofs share, bind-mounts the Rosetta binary, masks qemu-x86_64-static binfmt, writes a Rosetta binfmt config, restarts systemd-binfmt, and invokes this after SSH when enabled.
Darwin preflight check
pkg/crc/preflight/preflight_checks_darwin.go, pkg/crc/preflight/preflight_darwin.go
Adds rosettaPath and checkRosettaInstalled(); appends rosettaPreflightCheck to Darwin preflight list when enableRosetta is true.
Preflight plumbing on other platforms & tests
pkg/crc/preflight/preflight.go, pkg/crc/preflight/preflight_windows.go, pkg/crc/preflight/preflight_linux.go, pkg/crc/preflight/preflight_darwin_test.go, pkg/crc/preflight/preflight_windows_test.go
Propagates an extra enableRosetta boolean through preflight assembly; non-Darwin implementations accept the extra trailing bool (unused). Tests updated to pass the extra arg and adjust expected counts for Darwin Rosetta-enabled scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

kind/task

🐰 I found a tiny share named "rosetta" bright,
I mounted it with care in the silvery night,
I masked QEMU's tune and wrote a binfmt tune,
Now x86 hops where it once didn't belong soon,
Hooray — containers dance under Apple-light!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature added: Rosetta 2 support for Apple Silicon, which aligns directly with the primary change across all modified files.
Description check ✅ Passed The PR description addresses all key sections: it links to issue #4881, clearly explains the solution (use-rosetta config, preflight check, virtiofs share, binfmt configuration), details proposed changes, includes testing instructions, and checks appropriate contribution items.
Linked Issues check ✅ Passed The code changes comprehensively implement all objectives from issue #4881: configuration toggle (use-rosetta), preflight Rosetta check, vfkit virtiofs device attachment, binfmt handler registration, shared bind-mount for namespace boundaries, and optional behavior without silent installation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing Rosetta 2 support: configuration registration, preflight checks, vfkit driver updates, machine config propagation, and startup orchestration. No unrelated changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/crc/preflight/preflight_windows.go (1)

214-216: ⚠️ Potential issue | 🔴 Critical

Compilation error: Missing argument in getAllPreflightChecks.

The call to getPreflightChecks on line 215 passes only 5 arguments, but the function signature on line 234 requires 6 parameters. This will fail to compile.

🐛 Proposed fix
 func getAllPreflightChecks() []Check {
-	return getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(crcpreset.OpenShift), crcpreset.OpenShift, false)
+	return getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(crcpreset.OpenShift), crcpreset.OpenShift, false, false)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/crc/preflight/preflight_windows.go` around lines 214 - 216,
getAllPreflightChecks calls getPreflightChecks with only five arguments but the
getPreflightChecks signature expects six; update the call in
getAllPreflightChecks to pass the missing sixth parameter (match the exact type
and semantics required by getPreflightChecks) so the argument list and types
align with the function signature — locate getPreflightChecks and add the
appropriate value (constant, variable, or literal) to the call in
getAllPreflightChecks to fix the compilation error.
🧹 Nitpick comments (3)
pkg/crc/preflight/preflight_darwin_test.go (1)

26-28: Consider adding the Rosetta case for the alternate first-flag path too.

You now cover Rosetta-enabled counts for getPreflightChecks(false, ...). Adding the corresponding getPreflightChecks(true, ..., true) assertion would make this regression-proof if behavior diverges by that first flag later.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/crc/preflight/preflight_darwin_test.go` around lines 26 - 28, The test
currently asserts Rosetta-enabled preflight check counts only for
getPreflightChecks(false, ...); add the matching assertions for the alternate
first-flag path by calling getPreflightChecks(true,
network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift),
preset.OpenShift, false, true) and getPreflightChecks(true,
network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift),
preset.OpenShift, false, true) and assert their lengths match the expected 21
and 20 respectively so both code paths are covered.
pkg/drivers/vfkit/driver_darwin.go (1)

236-236: Use a shared constant for the Rosetta mount tag.

Line 236 hardcodes "rosetta". Since guest-side mount/config must match this tag exactly, a shared constant helps avoid drift across files.

Suggested refactor
+const rosettaMountTag = "rosetta"
...
-		rosettaDev, err := config.RosettaShareNew("rosetta")
+		rosettaDev, err := config.RosettaShareNew(rosettaMountTag)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/drivers/vfkit/driver_darwin.go` at line 236, Replace the hardcoded
"rosetta" string in the call rosettaDev, err :=
config.RosettaShareNew("rosetta") with a shared constant (e.g.,
config.RosettaTag) so guest-side mount/config matches the same identifier
everywhere; update this call to use the constant from the config package and, if
the constant does not yet exist, add it in the config package (name it clearly
like RosettaTag or RosettaMountTag) and update any other callers to use that
constant to prevent drift.
pkg/crc/machine/start.go (1)

270-325: Consider using POSIX-compatible shell syntax for binfmt configuration.

The code uses here-string syntax (<<<) on line 314, which is a bash-specific feature and will fail on systems using only POSIX sh. While RHEL/Fedora-based systems typically include bash, this reduces portability.

♻️ Suggested improvement for broader shell compatibility
 	// Write Rosetta binfmt config pointing to the bind mount path
 	rosettaBinfmt := `:rosetta:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/var/lib/rosetta/rosetta:CFP`
 	if _, _, err := sshRunner.RunPrivileged("Writing Rosetta binfmt config",
-		fmt.Sprintf("tee /etc/binfmt.d/rosetta.conf <<< '%s'", rosettaBinfmt)); err != nil {
+		"sh", "-c", fmt.Sprintf("echo '%s' > /etc/binfmt.d/rosetta.conf", rosettaBinfmt)); err != nil {
 		return err
 	}

Note: Similar bash-ism appears at line 509 for chrony config; consider applying the same fix there.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/crc/machine/start.go` around lines 270 - 325, The use of a bash-only
here-string in configureRosetta should be replaced with a POSIX-compatible write
(e.g., use a heredoc or printf piped to tee) so that rosettaBinfmt is written to
/etc/binfmt.d/rosetta.conf without relying on <<<; update the RunPrivileged call
that currently uses fmt.Sprintf("tee /etc/binfmt.d/rosetta.conf <<< '%s'",
rosettaBinfmt) to instead pipe the content via a POSIX-safe form (for example:
printf '%s\n' '<content>' | tee /etc/binfmt.d/rosetta.conf or tee
/etc/binfmt.d/rosetta.conf <<'EOF' ... EOF) and apply the same change to the
similar chrony config write elsewhere in the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/crc/config/validations.go`:
- Around line 159-162: The current platform check blocks any setting of the
rosetta flag on non-Apple-Silicon hosts; instead first validate the boolean
using ValidateBool(value), and only block when the validated value is true on
unsupported platforms. Concretely: call ValidateBool(value) (same symbol) to get
the parsed boolean and message, if parsing failed return that failure; if parsed
value is false return success (allow explicit false); if parsed value is true
then check runtime.GOOS and runtime.GOARCH and, if not darwin/arm64, return the
existing error message "Rosetta is only supported on Apple Silicon Macs",
otherwise return success.

In `@pkg/crc/preflight/preflight_checks_darwin.go`:
- Around line 232-234: The os.Stat(rosettaPath) error is currently always
reported as "Rosetta is not installed", which hides other failures; change the
handling so that if os.IsNotExist(err) you return the existing "Rosetta is not
installed" error, otherwise return a distinct error that includes the underlying
error (e.g., "failed to stat rosettaPath: <err>") so permission/I/O errors are
preserved; locate the os.Stat(rosettaPath) call in preflight_checks_darwin.go
and update the conditional to use os.IsNotExist(err) and return the
wrapped/original error for non-ENOENT cases.

---

Outside diff comments:
In `@pkg/crc/preflight/preflight_windows.go`:
- Around line 214-216: getAllPreflightChecks calls getPreflightChecks with only
five arguments but the getPreflightChecks signature expects six; update the call
in getAllPreflightChecks to pass the missing sixth parameter (match the exact
type and semantics required by getPreflightChecks) so the argument list and
types align with the function signature — locate getPreflightChecks and add the
appropriate value (constant, variable, or literal) to the call in
getAllPreflightChecks to fix the compilation error.

---

Nitpick comments:
In `@pkg/crc/machine/start.go`:
- Around line 270-325: The use of a bash-only here-string in configureRosetta
should be replaced with a POSIX-compatible write (e.g., use a heredoc or printf
piped to tee) so that rosettaBinfmt is written to /etc/binfmt.d/rosetta.conf
without relying on <<<; update the RunPrivileged call that currently uses
fmt.Sprintf("tee /etc/binfmt.d/rosetta.conf <<< '%s'", rosettaBinfmt) to instead
pipe the content via a POSIX-safe form (for example: printf '%s\n' '<content>' |
tee /etc/binfmt.d/rosetta.conf or tee /etc/binfmt.d/rosetta.conf <<'EOF' ...
EOF) and apply the same change to the similar chrony config write elsewhere in
the code.

In `@pkg/crc/preflight/preflight_darwin_test.go`:
- Around line 26-28: The test currently asserts Rosetta-enabled preflight check
counts only for getPreflightChecks(false, ...); add the matching assertions for
the alternate first-flag path by calling getPreflightChecks(true,
network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift),
preset.OpenShift, false, true) and getPreflightChecks(true,
network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift),
preset.OpenShift, false, true) and assert their lengths match the expected 21
and 20 respectively so both code paths are covered.

In `@pkg/drivers/vfkit/driver_darwin.go`:
- Line 236: Replace the hardcoded "rosetta" string in the call rosettaDev, err
:= config.RosettaShareNew("rosetta") with a shared constant (e.g.,
config.RosettaTag) so guest-side mount/config matches the same identifier
everywhere; update this call to use the constant from the config package and, if
the constant does not yet exist, add it in the config package (name it clearly
like RosettaTag or RosettaMountTag) and update any other callers to use that
constant to prevent drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 07a9fe6e-c8bf-475b-b0b9-71d0f1971f16

📥 Commits

Reviewing files that changed from the base of the PR and between 26e31d0 and 4964fef.

📒 Files selected for processing (15)
  • cmd/crc/cmd/start.go
  • pkg/crc/config/settings.go
  • pkg/crc/config/validations.go
  • pkg/crc/machine/config/config.go
  • pkg/crc/machine/start.go
  • pkg/crc/machine/types/types.go
  • pkg/crc/machine/vfkit/driver_darwin.go
  • pkg/crc/preflight/preflight.go
  • pkg/crc/preflight/preflight_checks_darwin.go
  • pkg/crc/preflight/preflight_darwin.go
  • pkg/crc/preflight/preflight_darwin_test.go
  • pkg/crc/preflight/preflight_linux.go
  • pkg/crc/preflight/preflight_windows.go
  • pkg/crc/preflight/preflight_windows_test.go
  • pkg/drivers/vfkit/driver_darwin.go

Comment on lines +159 to +162
if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
return false, "Rosetta is only supported on Apple Silicon Macs"
}
return ValidateBool(value)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Allow explicit false for unsupported platforms.

Line 159 currently rejects the setting regardless of value on non-Apple-Silicon hosts. This prevents users from explicitly setting use-rosetta=false (useful for config portability/reset flows).

Suggested fix
 func validateRosetta(value interface{}) (bool, string) {
-	if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
-		return false, "Rosetta is only supported on Apple Silicon Macs"
-	}
-	return ValidateBool(value)
+	enabled, err := cast.ToBoolE(value)
+	if err != nil {
+		return false, "must be true or false"
+	}
+	if !enabled {
+		return true, ""
+	}
+	if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
+		return false, "Rosetta is only supported on Apple Silicon Macs"
+	}
+	return true, ""
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/crc/config/validations.go` around lines 159 - 162, The current platform
check blocks any setting of the rosetta flag on non-Apple-Silicon hosts; instead
first validate the boolean using ValidateBool(value), and only block when the
validated value is true on unsupported platforms. Concretely: call
ValidateBool(value) (same symbol) to get the parsed boolean and message, if
parsing failed return that failure; if parsed value is false return success
(allow explicit false); if parsed value is true then check runtime.GOOS and
runtime.GOARCH and, if not darwin/arm64, return the existing error message
"Rosetta is only supported on Apple Silicon Macs", otherwise return success.

Comment on lines +232 to +234
if _, err := os.Stat(rosettaPath); err != nil {
return fmt.Errorf("Rosetta is not installed, which is required for x86_64 emulation")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Handle non-ENOENT errors separately in Rosetta preflight.

Line 232 currently treats every os.Stat failure as “not installed”. That can mask permission/I/O errors and mislead remediation.

Suggested fix
 func checkRosettaInstalled() error {
-	if _, err := os.Stat(rosettaPath); err != nil {
-		return fmt.Errorf("Rosetta is not installed, which is required for x86_64 emulation")
+	if _, err := os.Stat(rosettaPath); err != nil {
+		if os.IsNotExist(err) {
+			return fmt.Errorf("Rosetta is not installed, which is required for x86_64 emulation")
+		}
+		return fmt.Errorf("failed to verify Rosetta installation at %s: %w", rosettaPath, err)
 	}
 	return nil
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if _, err := os.Stat(rosettaPath); err != nil {
return fmt.Errorf("Rosetta is not installed, which is required for x86_64 emulation")
}
func checkRosettaInstalled() error {
if _, err := os.Stat(rosettaPath); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("Rosetta is not installed, which is required for x86_64 emulation")
}
return fmt.Errorf("failed to verify Rosetta installation at %s: %w", rosettaPath, err)
}
return nil
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/crc/preflight/preflight_checks_darwin.go` around lines 232 - 234, The
os.Stat(rosettaPath) error is currently always reported as "Rosetta is not
installed", which hides other failures; change the handling so that if
os.IsNotExist(err) you return the existing "Rosetta is not installed" error,
otherwise return a distinct error that includes the underlying error (e.g.,
"failed to stat rosettaPath: <err>") so permission/I/O errors are preserved;
locate the os.Stat(rosettaPath) call in preflight_checks_darwin.go and update
the conditional to use os.IsNotExist(err) and return the wrapped/original error
for non-ENOENT cases.

@cfergeau

Copy link
Copy Markdown
Contributor

My team has been using this solution for the last couple of weeks

Could you share more details about your usecase for this? Last time we checked, running amd64 images in an openshift/microshift arm64 cluster was not supported, and there were complications with running images from other arches

@cpepper96

Copy link
Copy Markdown
Author

My team has been using this solution for the last couple of weeks

Could you share more details about your usecase for this? Last time we checked, running amd64 images in an openshift/microshift arm64 cluster was not supported, and there were complications with running images from other arches

We have arm64 macs as our dev laptops but our target environment is an amd64 openshift cluster. We are receiving amd64 container images from an upstream vendor (we don't control the build process). So our use case is local development and testing of these amd64 images on our arm64 macs prior to deploying to our amd64 openshift cluster.

@cfergeau

Copy link
Copy Markdown
Contributor

our use case is local development and testing of these amd64 images on our arm64 macs

can you be more specific about how you pull these images in the cluster and then run them? is this done using oc? The previous discussion around this was in #3483

@cpepper96

Copy link
Copy Markdown
Author

our use case is local development and testing of these amd64 images on our arm64 macs

can you be more specific about how you pull these images in the cluster and then run them? is this done using oc? The previous discussion around this was in #3483

sure! we push the x86 images to the internal image registry in the openshift local cluster and configure the deployments to pull from there. oc cli isn't used in the process, we use podman to push the images to the cluster.

@praveenkumar

Copy link
Copy Markdown
Member

We have arm64 macs as our dev laptops but our target environment is an amd64 openshift cluster.

@cpepper96 This target environment is not the mac-M1

testing of these amd64 images on our arm64 macs prior to deploying to our amd64 openshift cluster.

So when you testing those amd64 images before pushing/deploying to your amd64 cluster, does it really required the OCP cluster locally or you just need podman to test those on M1? I am thinking you might just need podman desktop on your dev machine to test the images locally before push to cluster which does support running the amd64 images.

@cpepper96

Copy link
Copy Markdown
Author

We have arm64 macs as our dev laptops but our target environment is an amd64 openshift cluster.

@cpepper96 This target environment is not the mac-M1

testing of these amd64 images on our arm64 macs prior to deploying to our amd64 openshift cluster.

So when you testing those amd64 images before pushing/deploying to your amd64 cluster, does it really required the OCP cluster locally or you just need podman to test those on M1? I am thinking you might just need podman desktop on your dev machine to test the images locally before push to cluster which does support running the amd64 images.

Hi @praveenkumar! We currently use podman/podman desktop and have used the workaround you suggested. There is no hard requirement to testing using OCP local but we have found it quite helpful to be able to do so and these changes enabled us to do that.

@praveenkumar

Copy link
Copy Markdown
Member

There is no hard requirement to testing using OCP local but we have found it quite helpful to be able to do so and these changes enabled us to do that.

@cpepper96 Happy to hear that you find OCP local helpful. I am just trying to understand the usecase which you described with OCP local because to me that is really just running a different arch container for which you really don't need a cluster but container runtime which podman desktop provides. Are you using this OCP local for podman operations also and not consuming the podman-machine?

@cpepper96

Copy link
Copy Markdown
Author

@cpepper96 Happy to hear that you find OCP local helpful. I am just trying to understand the usecase which you described with OCP local because to me that is really just running a different arch container for which you really don't need a cluster but container runtime which podman desktop provides. Are you using this OCP local for podman operations also and not consuming the podman-machine?

Yeah let me try to be more specific here. We are building applications to integrate with an existing platform that gets delivered to us as a Helm chart + images. Can't get too specific but its about 10 different microservices. So our two big use cases are:

  1. Platform engineers receive a new update of this platform. Typically they'll try to install/upgrade/test the new platform locally using OCP local prior to promoting update to our cloud environment.
  2. SWE are developing applications to integrate with this platform. They have OCP local + platform deployed for development prior to promoting changes to our cloud environment.

So the use case is not just running a different arch container on mac but being able to develop/test against a OCP based platform locally that is comprised of different arch containers.

@praveenkumar

Copy link
Copy Markdown
Member

make cross fails with following error

# github.com/crc-org/crc/v2/pkg/crc/preflight
pkg/crc/preflight/preflight_windows.go:215:136: not enough arguments in call to getPreflightChecks
	have (bool, network.Mode, string, preset.Preset, bool)
	want (bool, network.Mode, string, preset.Preset, bool, bool)
make: *** [out/windows-amd64/crc.exe] Error 1

@praveenkumar

Copy link
Copy Markdown
Member

@cpepper96 can you update this PR and make sure the CI succeed?

@cpepper96

Copy link
Copy Markdown
Author

@cpepper96 can you update this PR and make sure the CI succeed?

Hey @praveenkumar! Apologies for the late response but yes I can update this and make sure CI is passing

@cpepper96

Copy link
Copy Markdown
Author

@praveenkumar Updated. I think y'all will have to kick off that CI job

@praveenkumar

Copy link
Copy Markdown
Member

/ok-to-test

@cpepper96

Copy link
Copy Markdown
Author

/retest

1 similar comment
@cpepper96

Copy link
Copy Markdown
Author

/retest

@cpepper96

Copy link
Copy Markdown
Author

Hi @praveenkumar, any thing I can do to move this PR along?

@praveenkumar

Copy link
Copy Markdown
Member

Hi @praveenkumar, any thing I can do to move this PR along?

One thing you need to do is squash all the commits to single one since it contains around 16 commits and mostly around syncing the branch or a normal fixup.

Add the enable-rosetta configuration path and plumb it through preflight, machine configuration, vfkit, and startup so Apple Silicon hosts can use Rosetta for x86_64 container support.
@openshift-ci

openshift-ci Bot commented Jun 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from cfergeau. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@praveenkumar

Copy link
Copy Markdown
Member

According to https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment/ looks like mac support for rosetta-2 is going to end when macOS-27 is released.

@cfergeau

Copy link
Copy Markdown
Contributor

https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment/ says

Rosetta […] will be available through macOS 27
which I read as "Rosetta will still be available in macOS 27" (and then they said somewhere this would be supported for 3 years after it’s released)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Rosetta 2 on macOS

3 participants