Skip to content
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

Install missing dependencies for Ruby 3.2 #763

Merged
merged 4 commits into from
Nov 20, 2023

Conversation

joshcooper
Copy link
Contributor

Previously, the pdk-vanagon's gem prune command[1] failed on Windows with Ruby 3.2:

 $ GEM_PATH="C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/puppet/ruby/3.2.0;C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/share/cache/ruby/3.2.0" RUBYOPT="-Irubygems-prune" C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/bin/gem.bat prune
    .. The specified module could not be found.   - C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/lib/ruby/3.2.0/x64-mingw32/psych.so (LoadError)

This commit:

  • Installs libffi-8.dll, libyaml-0-2.dll and libssp-0.dll into the pdk's primary ruby 3.2 bin directory
  • Removes libffi-6.dll from ruby 3.2 bin directory

See individual commits for gory details

[1] https://github.com/puppetlabs/pdk-vanagon/blob/c7d35b03fa014f95570cee9c84fcfd2bbfc7df32/configs/components/gem-prune.rb#L37

@joshcooper joshcooper requested review from a team as code owners November 17, 2023 07:41
@joshcooper joshcooper marked this pull request as draft November 17, 2023 17:11
@joshcooper
Copy link
Contributor Author

/usr/bin/cp -p 'C:/tools/pl-build-tools/bin/libffi-6.dll' 'C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/2.7.8/bin/libffi-6.dll'
Makefile:329: recipe for target 'runtime-pdk-install' failed
/usr/bin/cp: cannot stat 'C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/bin/libffi-8.dll': No such file or directory
make: *** [runtime-pdk-install] Error 1

We compile ruby 3.2 with strong stack protection. This causes ruby to be linked
against libssp-0, which must be redistributed with the runtime:

    $ objdump -p ruby.exe | grep libssp
            DLL Name: libssp-0.dll

Windows doesn't have an RPATH equivalent, so the dll must be copied into the
same directory as ruby.

This was partially addressed in commmit ba4c955, however, the _base-ruby
component is already responsible for installing Windows specific library
dependencies when the main bin dir is different than ruby's bin dir, so
move that logic there.
Previously, we were copying libffi-6.dll to both ruby 2.7 and 3.2 bin directories
on Windows:

    $ find . -type f -name "libffi*dll"
    ./2.7.8/bin/libffi-6.dll
    ./3.2.2/bin/libffi-6.dll

However, we build libffi-8 with ruby 3.2, and it will be installed to the pdk
bin directories in a future commit. So restrict libffi-6 to ruby 2.
Previously, the pdk-vanagon's gem prune command[1] failed on Windows with Ruby
3.2:

    $ GEM_PATH="C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/puppet/ruby/3.2.0;C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/share/cache/ruby/3.2.0"  \
    RUBYOPT="-Irubygems-prune" C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/bin/gem.bat prune
    ...
    The specified module could not be found.   - C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/lib/ruby/3.2.0/x64-mingw32/psych.so (LoadError)

The error is misleading, because it found psych.so, but couldn't load its
dependency libyaml-0.2.dll.

The reason this occurred was because the pdk-runtime installed libyaml into its
prefix bin directory, which is different than its primary ruby bin directory:

    prefix   C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/bin/
    ruby_dir C:/ProgramFiles64Folder/PuppetLabs/DevelopmentKit/private/ruby/3.2.2/bin

However, the prefix bin directory is not in the PATH, so it couldn't load libyaml.

This wasn't an issue for non-pdk runtimes, because the prefix and ruby_dir are
the same. And on Windows the default Dll search path includes "The folder from
which the application loaded."[2]

This is not an issue for pdk runtimes on *nix, because we embed
/opt/puppetlabs/pdk/lib into the RPATH:

    # objdump -p /opt/puppetlabs/pdk/private/ruby/3.2.2/lib/ruby/3.2.0/x86_64-linux/psych.so | grep -i path
      RUNPATH              /opt/puppetlabs/pdk/lib:/opt/puppetlabs/pdk/private/ruby/3.2.2/lib

So psych.so can load libyaml:

    # ldd /opt/puppetlabs/pdk/private/ruby/3.2.2/lib/ruby/3.2.0/x86_64-linux/psych.so | grep libyaml
           libyaml-0.so.2 => /opt/puppetlabs/pdk/lib/libyaml-0.so.2

This is not an issue when running the pdk on Windows, because the wrapper adds
the directory to the PATH[3]

The same issue existed when the ffi_c.so native extension tried to load libffi.

Since libyaml and libffi may be depended on by more than just ruby 3.2, install
the libraries in to the prefix directory and copy them into the ruby 3.2 bin
directory.

This was partially addressed in ba4c955 and reverted in 811a384, but is
implemented differently here.

[1] https://github.com/puppetlabs/pdk-vanagon/blob/c7d35b03fa014f95570cee9c84fcfd2bbfc7df32/configs/components/gem-prune.rb#L37
[2] https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
[3] https://github.com/puppetlabs/pdk-vanagon/blob/c7d35b03fa014f95570cee9c84fcfd2bbfc7df32/resources/files/windows/pdk.bat#L7
@joshcooper joshcooper marked this pull request as ready for review November 18, 2023 00:49
@joshcooper
Copy link
Contributor Author

@joshcooper
Copy link
Contributor Author

I was able to build the pdk with this runtime using puppetlabs/pdk-vanagon#345:

diff --git a/configs/components/puppet-runtime.json b/configs/components/puppet-runtime.json
index 156f652..938179d 100644
--- a/configs/components/puppet-runtime.json
+++ b/configs/components/puppet-runtime.json
@@ -1 +1 @@
-{"version":"202311141","location":"https://builds.delivery.puppetlabs.net/puppet-runtime/202311141/artifacts/"}
+{"version":"202308240.86.g81059f6","location":"https://builds.delivery.puppetlabs.net/puppet-runtime/81059f6336c6b8f5f77ab9a3700eb0b2b58d5bcc/artifacts/"}

$ bundle exec vanagon build pdk windows-2019-x64 silly-teamwork.delivery.puppetlabs.net
...
Moving file 'C:\Users\Administrator\2elwyr4c\2elwyr4c\pdk-3.0.1.0.rc.2.7.g22ea5b7-x64.msi' to 'C:\cygwin64\var\tmp\tmp.s4iDZ1XmQ6\output\windows\pdk-3.0.1.0.rc.2.7.g22ea5b7-x64.msi'.

Copy link
Contributor

@LukasAud LukasAud left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks @joshcooper for your help with this.

@LukasAud LukasAud merged commit 73ba872 into puppetlabs:master Nov 20, 2023
3 checks passed
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.

2 participants