From 62241b136de247b236695956b770ff40968253d6 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 18 Aug 2022 15:04:59 +0200 Subject: [PATCH 1/4] 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 --- ruby/lib/libdatadog.rb | 17 +++++++++++++++++ ruby/spec/libdatadog_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) 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/spec/libdatadog_spec.rb b/ruby/spec/libdatadog_spec.rb index d8274917a..c76642294 100644 --- a/ruby/spec/libdatadog_spec.rb +++ b/ruby/spec/libdatadog_spec.rb @@ -66,6 +66,10 @@ let(:pkgconfig_folder) { "#{temporary_directory}/#{Gem::Platform.local}/some/folder/containing/the/pkgconfig/file" } before do + create_dummy_pkgconfig_file(pkgconfig_folder) + end + + def create_dummy_pkgconfig_file(pkgconfig_folder) FileUtils.mkdir_p(pkgconfig_folder) File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w") {} end @@ -75,6 +79,24 @@ 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| + Dir.mkdir("#{temporary_directory}/#{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 From 490472ca58d991ee11835c9fa5c7e2e883e914e1 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 18 Aug 2022 15:09:31 +0200 Subject: [PATCH 2/4] 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). --- ruby/lib/libdatadog/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 4c091c0ff0ece4b321c82108c882c9bf812cc9c2 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 18 Aug 2022 15:18:22 +0200 Subject: [PATCH 3/4] Fix file open permissions / directory creation Otherwise this breaks in Linux due to the rest of the spec flow. --- ruby/spec/libdatadog_spec.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ruby/spec/libdatadog_spec.rb b/ruby/spec/libdatadog_spec.rb index c76642294..40f5f25e8 100644 --- a/ruby/spec/libdatadog_spec.rb +++ b/ruby/spec/libdatadog_spec.rb @@ -70,8 +70,13 @@ end def create_dummy_pkgconfig_file(pkgconfig_folder) - FileUtils.mkdir_p(pkgconfig_folder) - File.open("#{pkgconfig_folder}/ddprof_ffi_with_rpath.pc", "w") {} + 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 From 38681d041c7193ac030a54e1a910d97f0834c669 Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 18 Aug 2022 15:26:30 +0200 Subject: [PATCH 4/4] Remove redundant directory creation in spec --- ruby/spec/libdatadog_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/ruby/spec/libdatadog_spec.rb b/ruby/spec/libdatadog_spec.rb index 40f5f25e8..84c2a10d1 100644 --- a/ruby/spec/libdatadog_spec.rb +++ b/ruby/spec/libdatadog_spec.rb @@ -93,7 +93,6 @@ def create_dummy_pkgconfig_file(pkgconfig_folder) allow(Gem::Platform).to receive(:local).and_return("x86_64-linux") ["x86_64-linux", "x86_64-linux-musl"].each do |arch| - Dir.mkdir("#{temporary_directory}/#{arch}") create_dummy_pkgconfig_file("#{temporary_directory}/#{arch}/some/folder/containing/the/pkgconfig/file") end end