Skip to content

Conversation

@lstocchi
Copy link
Collaborator

@lstocchi lstocchi commented Sep 30, 2025

This patch updates the way macadam detect binaries to stop using the upstream config.FindHelperBinary which uses entries from the containers.conf.

Macadam does not use that file.

This work is to simplify how the search is done but still maintain compatibility with the locations used by podman to re-use its binaries like gvproxy.

This also cleans up the error message displayed if one required binary is not available. It resolves #153

Summary by CodeRabbit

  • New Features

    • Added support for CONTAINERS_HELPER_BINARY_DIR environment variable to customize helper binary search paths.
  • Chores

    • Standardized build system to use consistent version flags across Darwin and Linux platforms.
    • Reorganized preflight checks with platform-specific validation.

@coderabbitai
Copy link

coderabbitai bot commented Sep 30, 2025

Walkthrough

The changes refactor binary discovery from config-based to environment-based lookup via a new findBinary() utility function supporting $BINDIR prefix resolution. Platform-specific preflight checks are isolated into build-tagged files, and the Makefile is updated to consistently use VERSION_LDFLAGS instead of MACADAM_LDFLAGS.

Changes

Cohort / File(s) Summary
Build Configuration
Makefile
Replaced MACADAM_LDFLAGS with VERSION_LDFLAGS in all build targets (macadam-darwin-amd64, macadam-darwin-arm64, macadam-linux-amd64); removed HELPER_BINARIES_DIR variable and references.
Binary Discovery Refactor
pkg/preflights/preflights.go
Introduced findBinary(name) and findBindir() utilities for environment-based binary discovery with $BINDIR prefix support; replaced config.FindHelperBinary with findBinary() in checkBinaryArg; removed obsolete version checks (checkGvproxyVersion, checkVfkitVersion, checkKrunKitAvailability) and config imports.
Platform-Specific Checks — Darwin
pkg/preflights/preflights_darwin.go
New file (darwin build tag) with checkGvproxyVersion(), checkVfkitVersion(), and checkKrunKitAvailability() re-implementing version validation; added getBinariesDirs() for macOS-specific search paths (/opt/macadam/bin, Homebrew, libexec/lib locations).
Platform-Specific Checks — Windows
pkg/preflights/preflights_windows.go
New file (windows build tag) exporting stub implementations of version check functions returning nil; getBinariesDirs() returns ["C:\Program Files\RedHat\Podman"].
Platform-Specific Checks — Other
pkg/preflights/preflights_other.go
New file (non-darwin, non-windows build tag) with checkGvproxyVersion() performing actual validation, checkVfkitVersion() and checkKrunKitAvailability() as stubs; getBinariesDirs() returns standard Linux Podman helper directories.

Sequence Diagram

sequenceDiagram
    participant checkBinaryArg
    participant findBinary
    participant findBindir
    participant ENV as Environment
    participant FS as Filesystem
    
    checkBinaryArg->>findBinary: findBinary(name)
    
    alt CONTAINERS_HELPER_BINARY_DIR set
        findBinary->>ENV: getenv("CONTAINERS_HELPER_BINARY_DIR")
        ENV-->>findBinary: override_dir
        findBinary->>FS: search override_dir first
    end
    
    findBinary->>findBindir: findBindir()
    findBindir->>FS: readlink(executable) + filepath.Dir
    findBindir-->>findBinary: $BINDIR resolved
    
    findBinary->>FS: search getBinariesDirs() (platform-specific)
    alt Binary found
        FS-->>findBinary: binary_path
        findBinary-->>checkBinaryArg: path
    else Not found
        FS-->>findBinary: error
        findBinary-->>checkBinaryArg: error
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes involve refactored binary discovery logic (findBinary, findBindir) requiring verification of correctness, plus platform-specific isolation through build-tagged files. While mostly straightforward, the new discovery mechanism and its integration across multiple files necessitate careful review to ensure proper fallback behavior and environment override semantics.

Possibly related PRs

Poem

🐰 A rabbit's refrain:
No more config files to parse,
$BINDIR leads the way,
Platform paths, each in their place,
Finding binaries, come what may!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Update how binaries are detected by macadam" directly reflects the core changes in the changeset. The pull request replaces the config-based binary discovery mechanism with a new findBinary utility function, removes reliance on containers.conf, introduces environment-based overrides, and reorganizes preflight checks across platform-specific files. The title is concise, clear, and specific enough to convey the primary change without being vague or overly broad.
Linked Issues Check ✅ Passed The code changes directly address the objectives from issue #153. The refactor removes config.FindHelperBinary and all references to containers.conf, eliminating the problematic error messages that directed users to configure containers.conf—a file macadam does not use. The new error messages in platform-specific preflight checks now provide clearer guidance, suggesting specific minimum versions (e.g., "gvproxy v0.8.3 or newer") without referencing containers.conf. The binary detection logic is simplified through the new findBinary utility and environment-based override via CONTAINERS_HELPER_BINARY_DIR, while maintaining compatibility with standard podman helper binary locations.
Out of Scope Changes Check ✅ Passed All changes in the pull request align with the objectives of issue #153. The Makefile updates (removing MACADAM_LDFLAGS and HELPER_BINARIES_DIR references, replacing with VERSION_LDFLAGS) are in-scope supporting infrastructure changes that complement the removal of the helper binaries directory concept from the codebase. The refactored preflights.go, new platform-specific preflight files, and introduction of the findBinary utility are all directly necessary to implement the binary detection redesign and eliminate containers.conf references. No extraneous or tangential modifications were identified.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c629ae6 and 6d3d85b.

📒 Files selected for processing (5)
  • Makefile (1 hunks)
  • pkg/preflights/preflights.go (3 hunks)
  • pkg/preflights/preflights_darwin.go (1 hunks)
  • pkg/preflights/preflights_other.go (1 hunks)
  • pkg/preflights/preflights_windows.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/preflights/preflights.go
  • pkg/preflights/preflights_darwin.go
🧰 Additional context used
🧬 Code graph analysis (2)
pkg/preflights/preflights_other.go (1)
vendor/github.com/containers/podman/v5/pkg/machine/vmconfigs/config.go (1)
  • VMProvider (63-85)
pkg/preflights/preflights_windows.go (1)
vendor/github.com/containers/podman/v5/pkg/machine/vmconfigs/config.go (1)
  • VMProvider (63-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint
  • GitHub Check: e2e (ubuntu-24.04)
🔇 Additional comments (8)
Makefile (1)

39-45: Consistent ldflags usage looks good.

Switching the Darwin targets to VERSION_LDFLAGS matches the rest of the build matrix and keeps version embedding uniform.

pkg/preflights/preflights_other.go (4)

1-2: Build constraints are correct.

The !darwin && !windows constraint properly targets Linux and other Unix-like systems, and the _other.go filename convention is appropriate for this use case.


31-41: Linux binary paths are appropriate.

The paths align with standard Podman helper binary locations on Linux systems and match the upstream podman/common configuration. The reference to the upstream source is helpful for maintainability.


14-19: checkBinaryArg definition verified: The helper is defined in pkg/preflights/preflights.go (line 37); no changes needed.


27-29: No krunkit check required on Linux. The real implementation lives in preflights_darwin.go for the LibKrun hypervisor; the stub in preflights_other.go is intentional.

pkg/preflights/preflights_windows.go (3)

1-2: Build constraint is correct.

The //go:build windows constraint properly targets Windows systems.


13-19: Stubs are appropriate for Windows.

Both checkVfkitVersion and checkKrunKitAvailability correctly return nil, as vfkit is macOS-specific and krunkit is not used on Windows.


21-28: Windows binary path is correct.

The path C:\Program Files\RedHat\Podman matches the standard Podman installation directory on Windows. The upstream reference is helpful for validation.


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.

@lstocchi lstocchi marked this pull request as ready for review October 1, 2025 09:28
@lstocchi lstocchi requested a review from cfergeau October 1, 2025 09:28
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
pkg/preflights/preflights.go (2)

30-46: Harden external call with a timeout.

exec.Command(..., "--help") can hang; use a short timeout to avoid blocking preflights.

@@
-import (
+import (
+	"context"
@@
-	cmd := exec.Command(binary, "--help")
-	out, err := cmd.CombinedOutput()
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	cmd := exec.CommandContext(ctx, binary, "--help")
+	out, err := cmd.CombinedOutput()
 	if err != nil {
-		slog.Error("failed to run binary", "path", binary, "error", err)
+		// keep going: many CLIs return non‑zero for --help
+		if ctx.Err() == context.DeadlineExceeded {
+			return fmt.Errorf("%s --help timed out after 5s", binary)
+		}
+		slog.Error("failed to run binary", "path", binary, "error", err)
 	}

48-67: Improve not-found UX and (optionally) allow PATH fallback.

  • Current error lists dirs as a Go slice; suggest a more user-friendly message with a clear remediation hint.
  • Optional: behind an env toggle, fall back to PATH for dev setups without reintroducing containers.conf semantics.
@@
-import (
+import (
@@
-	"path/filepath"
+	"path/filepath"
+	"strings"
@@
 func findBinary(name string) (string, error) {
@@
 	for _, path := range dirList {
@@
 	}
 
-	return "", fmt.Errorf("could not find %q in one of %v", name, dirList)
+	// Optional PATH fallback when explicitly enabled
+	if v := os.Getenv("MACADAM_FIND_BINARY_USE_PATH"); strings.EqualFold(v, "1") || strings.EqualFold(v, "true") {
+		if lp, err := exec.LookPath(name); err == nil {
+			return lp, nil
+		}
+	}
+
+	return "", fmt.Errorf(
+		"could not find %q in: %s. Set CONTAINERS_HELPER_BINARY_DIR=/path/to/dir to override.",
+		name, strings.Join(dirList, ", "),
+	)

If you enable the PATH fallback, please confirm no tests depend on the stricter behavior.

pkg/preflights/preflights_unix.go (1)

21-25: Clarify platform in comment.

This vfkit note applies to darwin; on Linux the stub returns nil. Tweak comment to avoid confusion.

-// macadam/podman needs a vfkit binary which supports the --cloud-init
-// argument to inject ssh keys in RHEL cloud images
+// darwin-only: vfkit must support --cloud-init to inject SSH keys in cloud images.
+// On non-darwin builds this check is a no-op.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf5676e and c629ae6.

📒 Files selected for processing (5)
  • Makefile (1 hunks)
  • pkg/preflights/preflights.go (3 hunks)
  • pkg/preflights/preflights_darwin.go (1 hunks)
  • pkg/preflights/preflights_unix.go (1 hunks)
  • pkg/preflights/preflights_windows.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
pkg/preflights/preflights_darwin.go (1)
vendor/github.com/containers/podman/v5/pkg/machine/vmconfigs/config.go (1)
  • VMProvider (63-85)
pkg/preflights/preflights_windows.go (1)
vendor/github.com/containers/podman/v5/pkg/machine/vmconfigs/config.go (1)
  • VMProvider (63-85)
pkg/preflights/preflights_unix.go (1)
vendor/github.com/containers/podman/v5/pkg/machine/vmconfigs/config.go (1)
  • VMProvider (63-85)
🔇 Additional comments (10)
pkg/preflights/preflights_unix.go (2)

12-19: Gvproxy capability check — LGTM.

Minimal and clear; message guides users to v0.8.3+. No containers.conf references.


31-41: Approve Linux helper binary dirs in preflights_unix.go
Dirs align with containers/common; pkg/preflights contains no containers.conf or FindHelperBinary references. Revisit if containers/common updates.

Makefile (1)

39-39: Approve changes and confirm cleanup: No stale uses of MACADAM_LDFLAGS or HELPER_BINARIES_DIR remain in the repository.

pkg/preflights/preflights_darwin.go (5)

1-11: LGTM! Build tag and imports are correct.

The darwin build tag properly gates this code to macOS, and the imports are minimal and appropriate for the functionality.


22-32: LGTM! Conditional check for AppleHvVirt is appropriate.

The function correctly guards vfkit validation by checking the VM provider type, only validating when AppleHvVirt is in use. The error message provides clear version guidance.


34-42: LGTM! LibKrun conditional check is appropriate.

The function correctly guards krunkit validation by checking the VM provider type, only validating when LibKrun is in use. The error message provides clear installation guidance.


13-20: No changes needed: checkBinaryArg correctly invokes the binary’s help output, checks for the -services flag, and the wrapped error messages are clear and free of podman-specific references.


44-63: $BINDIR placeholder is expanded by containers/common — no action required.

containers/common implements $BINDIR expansion (bindirPrefix = "$BINDIR"; findBindir uses os.Executable() + filepath.EvalSymlinks and replaces the prefix when scanning dirs). See vendor/github.com/containers/common/pkg/config/config.go (findBindir + replacement logic, ~lines 1059–1072 and 1088–1103) and vendor/github.com/containers/common/pkg/config/config_darwin.go (contains "$BINDIR/../libexec/podman").

pkg/preflights/preflights_windows.go (2)

1-7: LGTM! Build tag and imports are correct.

The windows build tag properly gates this code to Windows, and the minimal import is appropriate.


21-28: LGTM! Windows binary path is correctly specified.

The function returns the standard Windows Podman installation path, properly escaped with double backslashes. The comment references the upstream source, which helps maintain consistency.

Comment on lines +9 to +19
func checkGvproxyVersion(provider vmconfigs.VMProvider) error {
return nil
}

func checkVfkitVersion(provider vmconfigs.VMProvider) error {
return nil
}

func checkKrunKitAvailability(provider vmconfigs.VMProvider) error {
return nil
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify whether Windows requires these binary checks.

All three preflight checks are stubbed to return nil, which means:

  • No gvproxy version validation on Windows
  • No vfkit version validation on Windows (likely correct, as vfkit is macOS-specific)
  • No krunkit availability check on Windows (likely correct, as krunkit is Linux/macOS-specific)

Confirm whether gvproxy validation is intentionally skipped on Windows or if it should be implemented similarly to the Darwin version.


🏁 Script executed:

#!/bin/bash
# Description: Verify if gvproxy is used on Windows and whether version checks are needed
# Expected: Find gvproxy usage patterns on Windows to determine if validation is required

# Check for Windows-specific gvproxy usage
rg -n -C5 'gvproxy|ForwarderBinaryName' --type=go

# Look for Windows-specific machine/provider implementations
fd -e go -g '*windows*.go' --exec rg -l 'gvproxy|StartNetworking'

# Check if there are any Windows VM providers that require these binaries
ast-grep --pattern 'type $_ struct {
  $$$
}

func ($_ $_) VMType() define.VMType {
  $$$
}'

Length of output: 76188


Implement Windows gvproxy version validation

In pkg/preflights/preflights_windows.go, replace the stubbed checkGvproxyVersion with a call to checkBinaryArg(machine.ForwarderBinaryName, "-services") (as done in preflights_unix.go/preflights_darwin.go), returning an error instructing users to upgrade to gvproxy v0.8.3 or newer.

🤖 Prompt for AI Agents
In pkg/preflights/preflights_windows.go around lines 9 to 19, the stubbed
checkGvproxyVersion should be implemented; replace the stub with a call to
checkBinaryArg(machine.ForwarderBinaryName, "-services") (matching the
implementations in preflights_unix.go/preflights_darwin.go), return any error
from checkBinaryArg wrapped or converted into a clear error message telling the
user to upgrade to gvproxy v0.8.3 or newer if the check fails, and ensure
imports/types used in that call are available in this file.

// macadam/podman needs a gvproxy version which supports the --services
// argument
func checkGvproxyVersion(provider vmconfigs.VMProvider) error {
if err := checkBinaryArg(machine.ForwarderBinaryName, "-services"); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

There’s a slight inconsistency between -services here and --services in the comment. And this is actually no longer required since the switch to 5.6 even if this will be needed again in some form when crc starts using macadam.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't get if you wanted it removed or keep it as it could be useful for crc. I just fixed the comment for the moment.

Copy link
Collaborator

@cfergeau cfergeau Oct 16, 2025

Choose a reason for hiding this comment

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

Given the ongoing convos around crc using macadam, we can keep it for now, even though I think podman no longer adds the flag.

// We use the same to detect the binaries
return []string{
// Relative to the binary directory
"$BINDIR/../libexec/podman",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we still have the code to resolve $BINDIR to the binary directory? This seems to be handled by FindHelperBinary so I guess not. This is needed when macadam is installed by the installer

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nice catch, I missed the resolve code. Added a simplified version as we only check the BINDIR once and there is no need to cache its value

in following commit macadam will implement a custom func to detect a
binary on some specific directories. By splitting preflights it makes
the code cleaner and easier to maintain as each platform works
differently and also require different binaries

Signed-off-by: lstocchi <[email protected]>
this patch adds a custom findBinary func to stop relying on the upstream
config.FindHelperBinary which uses entries from the containers.conf
file. Macadam does not use that file.

This work is to simplify how the
search works but still maintaining compatibility with the locations used
by podman to reuse its gvproxy, vfkit, libkrun binaries.

Signed-off-by: lstocchi <[email protected]>
so far to force macadam to use its own "installed" gvproxy/vfkit/libkrun we forced podman to look at their paths by setting the variable config.additionalHelperBinariesDir.

With our own findBinary implementation this is not needed anymore as we search directly the path /opt/macadam/bin as first option

Signed-off-by: Luca Stocchi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error messages are not always very user friendly/can be quite podman specific

2 participants