Skip to content

CHEF-37444: add ~/.chef/ruby/VERSION/gems to GEM_PATH for dynamic plugin loading - #1963

Open
sanghinitin wants to merge 1 commit into
mainfrom
CHEF-37444-gem-ext-support
Open

CHEF-37444: add ~/.chef/ruby/VERSION/gems to GEM_PATH for dynamic plugin loading#1963
sanghinitin wants to merge 1 commit into
mainfrom
CHEF-37444-gem-ext-support

Conversation

@sanghinitin

Copy link
Copy Markdown
Contributor

Summary

Ohai plugins installed via chef gem install land in ~/.chef/ruby/<RUBY_API_VERSION>/gems, but this path was never added to the runtime GEM_PATH. As a result, any gem installed that way was invisible to the packaged ohai binary even after re-running the binstub.

This PR fixes the issue by expanding GEM_PATH in three places: the Ruby binstub patch, and both the Linux/macOS and Windows Habitat wrappers.

Root Cause Evidence

$ gem info some-ohai-plugin
some-ohai-plugin (x.y.z)
    Installed at: /Users/nsanghi/.chef/ruby/3.4.0/gems
# → not in GEM_PATH → LoadError at runtime

Changes Made

binstub_patch.rb

  • Removed the old single-path GEM_PATH assignment.
  • Now prepends three paths before any existing GEM_PATH:
    1. $pkg_prefix/vendor — ohai vendored deps (flat layout)
    2. Gem.user_dir~/.gem/ruby/VERSION — standard gem install target
    3. ~/.chef/ruby/RUBY_API_VERSION/gemschef gem install target
  • Uses .uniq so paths are never duplicated when the block runs twice.

habitat/plan.sh & habitat/aarch64-darwin/plan.sh

  • Runtime wrapper now exports four GEM_PATH entries:
    1. $pkg_prefix/vendor — flat vendor tree
    2. $pkg_prefix/vendor/ruby/VERSION — bundler-nested tree (train-core etc.)
    3. ${HOME}/.gem/ruby/VERSION — standard gem install
    4. ${HOME}/.chef/ruby/VERSION/gems — chef gem install
  • ruby_gem_version is now derived from the packaged Ruby's on-disk lib/ruby/gems/ directory via basename instead of executing ruby -e. The latter can silently fail during do_install (runtime lib paths are not yet set up), producing an empty version string that corrupts all GEM_PATH entries. Falls back to 3.4.0 with a build_line warning if the glob still yields nothing.

habitat/plan.ps1

  • After appbundler.bat generates Windows binstubs, injects binstub_patch.rb immediately after the require "rubygems" line in each binstub — the same insertion point used on Linux/macOS.

Verification

After hab pkg build . and hab pkg install:

# 1. Confirm wrapper GEM_PATH has all four segments and a non-empty version:
grep GEM_PATH /hab/pkgs/chef/ohai/*/*/bin/ohai

2. Install a test gem into the chef dir:

RUBY_API=3.4.0
gem install paint --install-dir "$HOME/.chef/ruby/$RUBY_API" --no-document

3. Run ohai with a plugin that requires the gem — must print version, not LoadError:

cat > /tmp/test.rb <<'PLUGIN'
Ohai.plugin(:GemPathCheck) do
provides "gem_path_check"
collect_data do
gem_path_check Mash.new
gem_path_check[:gem_path] = Gem.path
gem_path_check[:paint_found] = begin
require "paint"; Gem.loaded_specs["paint"]&.version.to_s
rescue LoadError => e; "FAILED: #{e.message}"; end
end
end
PLUGIN
/hab/pkgs/chef/ohai///bin/ohai -d /tmp gem_path_check

Expected: paint_found: "2.x.x" ← gem loaded from ~/.chef/ruby path

This work was completed with AI assistance following Progress AI policies

…gin loading

- binstub_patch.rb: inject Gem.user_dir (~/.gem/ruby/VERSION) and
  ~/.chef/ruby/RUBY_API_VERSION/gems into GEM_PATH ahead of existing
  paths so gems installed via `gem install` or `chef gem install`
  are immediately visible to the ohai binstub.

- habitat/plan.sh, habitat/aarch64-darwin/plan.sh: expand the runtime
  wrapper's GEM_PATH to four entries:
    1. $pkg_prefix/vendor          (ohai's vendored deps, flat)
    2. $pkg_prefix/vendor/ruby/VERSION (bundler-nested deps, e.g. train-core)
    3. ~/.gem/ruby/VERSION          (standard `gem install` target)
    4. ~/.chef/ruby/VERSION/gems   (`chef gem install` target)
  ruby_gem_version is now derived from the packaged Ruby's on-disk
  lib/ruby/gems/ directory instead of executing `ruby -e`, which
  could silently fail during Habitat's do_install phase and leave the
  version segment empty. Falls back to 3.4.0 with a build_line warning.

- habitat/plan.ps1: inject binstub_patch.rb into Windows binstubs after
  appbundler generates them, using the same require-rubygems insertion
  point used on Linux/macOS.

Signed-off-by: nitin sanghi <nsanghi@progress.com>
@sanghinitin
sanghinitin requested review from a team and jaymzh as code owners July 30, 2026 12:04
@sanghinitin sanghinitin self-assigned this Jul 30, 2026
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.

1 participant