Merge pull request #1 from arvados/master
[arvados.git] / services / api / lib / config_loader.rb
index 87bfd93fcad3ac72773ba2fcb0b199a519d68c33..cf16993ca51054e220713c24cca1a33510e2a423 100644 (file)
@@ -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
@@ -190,9 +220,16 @@ class ConfigLoader
     end
   end
 
-  def self.load path
-    yaml = ERB.new(IO.read path).result(binding)
-    YAML.load(yaml, deserialize_symbols: false)
+  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
 
 end