Control: tags -1 - moreinfo + patch pending Control: severity -1 serious On 13:43 Mon 11 Mar , Kienan Stewart wrote: > Hi Apollon, > > On Sat, Mar 09, 2019 at 11:24:27PM +0200, Apollon Oikonomopoulos wrote: > > Control: tags -1 - unreproducible > > > > Hi, > > > > > > Thanks for the patch, it should do the trick. However, before applying > > it I want to be 100% sure that we know what's happening and why. > > > > So, I managed to reproduce this by simply installing ruby-multi-json, > > which allows Puppet to use different json backends. Can you verify that > > ruby-multi-json is installed, presumably on the master? > > > > ruby-multi-json (1.12.1-1) is installed. > > Checking with 'apt-cache policy rdepends ruby-multi-json', it's like because > we use r10k
OK, thanks for confirming this and thanks for the detailed report, it's very helpful! I'm bumping this bug to RC, as I don't think Puppet report storage should break merely by installing an unrelated Ruby package. Additionally this is a regression from Puppet 4.x. So, here's what's happening: - Puppet 5 switched from a custom wire format (PSON) to JSON for transmitting facts and reports. - There is no issue when using the ruby-json JSON library to parse reports. - Some JSON libraries (Oj and JrJackson) de-serialize floats with many decimal digits - such as the timing metrics found in a Puppet agent report - as BigDecimal. - When BigDecimal's are serialized again to JSON, they are serialized as Strings (and not floats), causing PuppetDB's schema validation to fail. - This path is only triggered when ruby-oj and ruby-multi-json are installed, enabling Puppet to use Oj via multi-json. (JrJackson is Jruby-only, and there are provisions upstream handling BigDecimal conversion in this case). Your patch fixes the issue, but it does so right before the report is transmitted to PuppetDB. I think it's best to instruct Oj to never deserialize floats as BigDecimals and avoid having to do any conversions in the first place. Additionally, this will guard all other report processors (e.g. store) which might want to handle metrics against similar issues. Can you test the attached patch and confirm that it works? Regards, Apollon
From: Apollon Oikonomopoulos <apoi...@debian.org> Date: Sun, 10 Mar 2019 01:22:29 +0200 Subject: Avoid BigDecimals when loading JSON using Oj This is already done for JrJackson and needs to be done for Oj as well to avoid sending malformed reports to PuppetDB. Bug-Debian: https://bugs.debian.org/923976 --- lib/puppet/util/json.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/util/json.rb b/lib/puppet/util/json.rb index 6baea59..3475990 100644 --- a/lib/puppet/util/json.rb +++ b/lib/puppet/util/json.rb @@ -32,13 +32,15 @@ module Puppet::Util def self.load(string, options = {}) if defined? MultiJson begin - # This ensures that JrJackson will parse very large or very small + # This ensures that JrJackson and Oj will parse very large or very small # numbers as floats rather than BigDecimals, which are serialized as # strings by the built-in JSON gem and therefore can cause schema errors, # for example, when we are rendering reports to JSON using `to_pson` in # PuppetDB. if MultiJson.adapter.name == "MultiJson::Adapters::JrJackson" options[:use_bigdecimal] = false + elsif MultiJson.adapter.name == "MultiJson::Adapters::Oj" + options[:bigdecimal_load] = :float end MultiJson.load(string, options)