X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/eb0bb0118051b0acbff09cf87287ad83a48ee337..ab9fdb73256fb57a48aad2161fa022146031f7ca:/services/api/lib/config_loader.rb diff --git a/services/api/lib/config_loader.rb b/services/api/lib/config_loader.rb index 2d1ddd8b86..f421fb5b2a 100644 --- a/services/api/lib/config_loader.rb +++ b/services/api/lib/config_loader.rb @@ -76,7 +76,7 @@ class ConfigLoader remainders end - def coercion_and_check check_cfg + def coercion_and_check check_cfg, check_nonempty: true @config_types.each do |cfgkey, cfgtype| cfg = check_cfg k = cfgkey @@ -114,7 +114,7 @@ class ConfigLoader end if cfgtype == NonemptyString - if (!cfg[k] || cfg[k] == "") + if (!cfg[k] || cfg[k] == "") && check_nonempty raise "#{cfgkey} cannot be empty" end if cfg[k].is_a? String @@ -126,7 +126,7 @@ class ConfigLoader if cfg[k].is_a? Integer cfg[k] = cfg[k].seconds elsif cfg[k].is_a? String - cfg[k] = ConfigLoader.parse_duration cfg[k] + cfg[k] = ConfigLoader.parse_duration(cfg[k], cfgkey: cfgkey) end end @@ -134,6 +134,31 @@ class ConfigLoader cfg[k] = URI(cfg[k]) end + if cfgtype == Integer && cfg[k].is_a?(String) + v = cfg[k].sub(/B\s*$/, '') + if mt = /(-?\d*\.?\d+)\s*([KMGTPE]i?)$/.match(v) + if mt[1].index('.') + v = mt[1].to_f + else + v = mt[1].to_i + end + cfg[k] = v * { + 'K' => 1000, + 'Ki' => 1 << 10, + 'M' => 1000000, + 'Mi' => 1 << 20, + "G" => 1000000000, + "Gi" => 1 << 30, + "T" => 1000000000000, + "Ti" => 1 << 40, + "P" => 1000000000000000, + "Pi" => 1 << 50, + "E" => 1000000000000000000, + "Ei" => 1 << 60, + }[mt[2]] + end + end + if !cfg[k].is_a? cfgtype raise "#{cfgkey} expected #{cfgtype} but was #{cfg[k].class}" end @@ -155,16 +180,21 @@ class ConfigLoader end end - def self.parse_duration durstr + def self.parse_duration(durstr, cfgkey:) + sign = 1 + if durstr[0] == '-' + durstr = durstr[1..-1] + sign = -1 + end duration_re = /(\d+(\.\d+)?)(s|m|h)/ dursec = 0 while durstr != "" mt = duration_re.match durstr if !mt - raise "#{cfgkey} not a valid duration: '#{cfg[k]}', accepted suffixes are s, m, h" + raise "#{cfgkey} not a valid duration: '#{durstr}', accepted suffixes are s, m, h" end multiplier = {s: 1, m: 60, h: 3600} - dursec += (Float(mt[1]) * multiplier[mt[3].to_sym]) + dursec += (Float(mt[1]) * multiplier[mt[3].to_sym] * sign) durstr = durstr[mt[0].length..-1] end return dursec.seconds @@ -172,7 +202,33 @@ class ConfigLoader def self.copy_into_config src, dst src.each do |k, v| - dst.send "#{k}=", Marshal.load(Marshal.dump v) + dst.send "#{k}=", self.to_OrderedOptions(v) + end + end + + def self.to_OrderedOptions confs + if confs.is_a? Hash + opts = ActiveSupport::OrderedOptions.new + confs.each do |k,v| + opts[k] = self.to_OrderedOptions(v) + end + opts + elsif confs.is_a? Array + confs.map { |v| self.to_OrderedOptions v } + else + confs + end + end + + def self.load path, erb: false + if File.exist? path + yaml = IO.read path + if erb + yaml = ERB.new(yaml).result(binding) + end + YAML.load(yaml, deserialize_symbols: false) + else + {} end end