From 35b4b18412928e5b042b9b0e26b0120e82cd16a2 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 18 Aug 2022 16:55:04 +0200 Subject: [PATCH] Fix issue with old rubygems not detecting musl linux properly (#40) * Fix issue with old rubygems not detecting musl linux properly Old versions of rubygems (for instance 3.0.3) don't properly detect alternative libc implementations on Linux; in particular for our case, they don't detect musl. (For reference, Rubies older than 2.7 may have shipped with an affected version of rubygems). In such cases, we fall back to use RbConfig::CONFIG['arch'] instead. Why not use `RbConfig::CONFIG['arch']` always? Because `Gem::Platform.local.to_s` does some normalization we want in other situations -- for instance, it turns `x86_64-linux-gnu` to `x86_64-linux`. So for now we only add this workaround in a specific situation where we actually know it is wrong. See also https://github.com/rubygems/rubygems/pull/2922 and https://github.com/rubygems/rubygems/pull/4082 Fixes datadog/dd-trace-rb#2222 * Bump libdatadog minor version in preparation for release I'm planning to release 0.7.0.1.1 with the musl fix. This will be automatically picked up by customers using the currently-released version of dd-trace-rb (1.3.0). * Fix file open permissions / directory creation Otherwise this breaks in Linux due to the rest of the spec flow. * Remove redundant directory creation in spec --- ruby/lib/libdatadog.rb | 17 +++++++++++++++++ ruby/lib/libdatadog/version.rb | 2 +- ruby/spec/libdatadog_spec.rb | 30 ++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/ruby/lib/libdatadog.rb b/ruby/lib/libdatadog.rb index 1438ae1ca..f9b2e751c 100644 --- a/ruby/lib/libdatadog.rb +++ b/ruby/lib/libdatadog.rb @@ -11,6 +11,23 @@ def self.available_binaries def self.pkgconfig_folder(pkgconfig_file_name = "ddprof_ffi_with_rpath.pc") current_platform = Gem::Platform.local.to_s + if RbConfig::CONFIG["arch"].include?("-musl") && !current_platform.include?("-musl") + # Fix/workaround for https://github.com/DataDog/dd-trace-rb/issues/2222 + # + # Old versions of rubygems (for instance 3.0.3) don't properly detect alternative libc implementations on Linux; + # in particular for our case, they don't detect musl. (For reference, Rubies older than 2.7 may have shipped with + # an affected version of rubygems). + # In such cases, we fall back to use RbConfig::CONFIG['arch'] instead. + # + # Why not use RbConfig::CONFIG['arch'] always? Because Gem::Platform.local.to_s does some normalization we want + # in other situations -- for instance, it turns `x86_64-linux-gnu` to `x86_64-linux`. So for now we only add this + # workaround in a specific situation where we actually know it is wrong. + # + # See also https://github.com/rubygems/rubygems/pull/2922 and https://github.com/rubygems/rubygems/pull/4082 + + current_platform = RbConfig::CONFIG["arch"] + end + return unless available_binaries.include?(current_platform) pkgconfig_file = Dir.glob("#{vendor_directory}/#{current_platform}/**/#{pkgconfig_file_name}").first diff --git a/ruby/lib/libdatadog/version.rb b/ruby/lib/libdatadog/version.rb index 448380605..c48310ab9 100644 --- a/ruby/lib/libdatadog/version.rb +++ b/ruby/lib/libdatadog/version.rb @@ -5,7 +5,7 @@ module Libdatadog LIB_VERSION = "0.7.0" GEM_MAJOR_VERSION = "1" - GEM_MINOR_VERSION = "0" + GEM_MINOR_VERSION = "1" GEM_PRERELEASE_VERSION = "" # remember to include dot prefix, if needed! private_constant :GEM_MAJOR_VERSION, :GEM_MINOR_VERSION, :GEM_PRERELEASE_VERSION diff --git a/ruby/spec/libdatadog_spec.rb b/ruby/spec/libdatadog_spec.rb index d8274917a..84c2a10d1 100644 --- a/ruby/spec/libdatadog_spec.rb +++ b/ruby/spec/libdatadog_spec.rb @@ -66,8 +66,17 @@ let(:pkgconfig_folder) { "#{temporary_directory}/#{Gem::Platform.local}/some/folder/containing/the/pkgconfig/file" } before do - FileUtils.mkdir_p(pkgconfig_folder) - File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w") {} + create_dummy_pkgconfig_file(pkgconfig_folder) + end + + def create_dummy_pkgconfig_file(pkgconfig_folder) + begin + FileUtils.mkdir_p(pkgconfig_folder) + rescue Errno::EEXIST + # No problem, a few specs try to create the same folder + end + + File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w+") {} end describe ".pkgconfig_folder" do @@ -75,6 +84,23 @@ expect(Libdatadog.pkgconfig_folder).to eq pkgconfig_folder end end + + context "when `RbConfig::CONFIG[\"arch\"]` indicates we're on musl libc, but `Gem::Platform.local.to_s` does not detect it" do + # Fix for https://github.com/DataDog/dd-trace-rb/issues/2222 + + before do + allow(RbConfig::CONFIG).to receive(:[]).with("arch").and_return("x86_64-linux-musl") + allow(Gem::Platform).to receive(:local).and_return("x86_64-linux") + + ["x86_64-linux", "x86_64-linux-musl"].each do |arch| + create_dummy_pkgconfig_file("#{temporary_directory}/#{arch}/some/folder/containing/the/pkgconfig/file") + end + end + + it "returns the folder containing the pkgconfig file for the musl variant" do + expect(Libdatadog.pkgconfig_folder).to eq "#{temporary_directory}/x86_64-linux-musl/some/folder/containing/the/pkgconfig/file" + end + end end context "but not for the current platform" do