tiller 0.9.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d50bc4389c299371589ded733f06078559c91555
4
- data.tar.gz: 3f6c1c9cdb4e504f7c5bddce477b684062a3993c
3
+ metadata.gz: e44d4f088a889a8fd6d1c4f23bad614e91bfb215
4
+ data.tar.gz: b1a5e3c7a157675b36dae9fabc71e40155beed0d
5
5
  SHA512:
6
- metadata.gz: a5f706f2109f84b7a015ce5173a67ee3025dd23394b344df5bdae4968adbd037f0f1615fc8c776f8226e60abeb8f2cc8b415ce67b00b5e297c98b28a53a7d472
7
- data.tar.gz: 883ace5cc0dbc824881c129d9d62533f1e27e005fc954cbac5f41ba2a0b24cc4d69eb04602904101e492edae003021e1fa9c7404d68b5d9a2fa465984eb033a0
6
+ metadata.gz: 29465a4eb5cbea636fc6ee2a20a65230e7e33a1ed7b2d41d325800d86e621c8d9bd39c754d7ba6e1f9c5cb3eb5cb3d723d82c8575880ae8e832a53c92bce49bf
7
+ data.tar.gz: 4c79f0d2c99294fd9372f3006a949791360f79d39cec70f1b44bc01a47114bdfbbdcd8028de89e5443a513bd237f41b3614201f8d7d04db45fc59ce9fe91f944
data/bin/tiller CHANGED
@@ -26,6 +26,7 @@ require 'tiller/datasource'
26
26
  require 'tiller/logger'
27
27
  require 'digest/md5'
28
28
  require 'tiller/render'
29
+ require 'tiller/kv'
29
30
  require 'tiller/version'
30
31
 
31
32
  EXIT_SUCCESS = 0
@@ -100,6 +101,8 @@ module Tiller
100
101
  log.info('Helper modules loaded ' + helper_modules.to_s)
101
102
  end
102
103
 
104
+ log.debug("Dynamic values specified. Will parse all values as ERb.") if config.assoc('dynamic_values')
105
+
103
106
  # We now don't actually use the global_values hash for anything when constructing the templates (as they can be
104
107
  # over-ridden by template values), but it's here to keep compatibility with the v1 API.
105
108
  global_values = { 'environment' => config[:environment] }
@@ -133,6 +136,8 @@ module Tiller
133
136
  all_templates = {}
134
137
  skipped_templates = 0
135
138
  updated_templates = 0
139
+ pids = []
140
+
136
141
 
137
142
  templates.each do |template, _content|
138
143
 
@@ -163,6 +168,27 @@ module Tiller
163
168
  target_values.tiller_merge!(dc.target_values(template)) do |key, old, new|
164
169
  warn_merge(key, old, new, 'target', data_class.to_s)
165
170
  end
171
+
172
+ # Dynamic config stuff, allows us to use ERb syntax inside configuration.
173
+ if config.assoc('dynamic_values')
174
+ # Need to recursively walk the hash, looking for ERb syntax
175
+ tiller.deep_traverse do |path,value|
176
+ if value.is_a?(String) && value.include?('<%')
177
+ log.debug("Found ERb syntax for #{value} at #{path}")
178
+ parsed_value = Tiller::render(value, direct_render: true)
179
+ # Proper Ruby voodoo here.
180
+ # See http://stackoverflow.com/questions/19304135/deep-nest-a-value-into-a-hash-given-a-path-array for
181
+ # explanation.
182
+ tiller.merge!((path + [parsed_value]).reverse.reduce { |s,e| { e => s } })
183
+ end
184
+ end
185
+ target_values.each do |key ,value|
186
+ if value.is_a?(String) && value.include?('<%')
187
+ log.debug("Found ERb syntax for target value #{key}:#{value}}")
188
+ target_values[key] = Tiller::render(value, direct_render: true)
189
+ end
190
+ end
191
+ end
166
192
  end
167
193
 
168
194
  # If our data source returned no values (e.g. we don't build this template
@@ -222,6 +248,17 @@ module Tiller
222
248
  "#{target_values['target']}")
223
249
  end
224
250
 
251
+ # Exec on write
252
+ if target_values.key?('exec_on_write')
253
+ if ! target_values['exec_on_write'].is_a?(Array)
254
+ log.warn("Warning: exec_on_write for template #{template} is not in array format")
255
+ else
256
+ eow_pid=launch(target_values['exec_on_write'])
257
+ pids.push(eow_pid)
258
+ log.info("exec_on_write process for #{template} forked with PID #{eow_pid}")
259
+ end
260
+ end
261
+
225
262
  end
226
263
 
227
264
  if config['md5sum']
@@ -254,24 +291,38 @@ module Tiller
254
291
  puts "Executing #{config['exec']}..."
255
292
 
256
293
  # Spawn and wait so API can continue to run
257
- child_pid = launch(config['exec'], :verbose => config[:verbose])
294
+ child_pid = launch(config['exec'])
295
+ pids.push(child_pid)
258
296
 
259
- log.info("Child process forked with PID #{child_pid}.")
297
+ log.info("Child process forked with PID #{child_pid}")
260
298
 
261
- # Catch signals and send them on to the child process
299
+ # Catch signals and send them on to the child processes
262
300
  [ :INT, :TERM, :HUP ].each do |sig|
263
- Signal.trap(sig) { signal(sig, child_pid, :verbose => config[:verbose]) }
301
+ Signal.trap(sig) do
302
+ pids.each { |p| signal(sig, p, :verbose => config[:verbose])}
303
+ end
264
304
  end
265
305
 
266
- Process.wait(child_pid)
267
-
268
- # Capture the child process status, so we can also exit with this code
269
- exit_status = ($?.exitstatus == nil) ? 0 : $?.exitstatus
306
+ # Wait for all PIDs
307
+ main_exit_status = 0
308
+ while pids.length >= 1 do
309
+ collected_pid = Process.wait
310
+ exit_status = ($?.exitstatus == nil) ? 0 : $?.exitstatus
311
+ if collected_pid == child_pid
312
+ log.info("Main child process with PID #{collected_pid} exited with status #{exit_status}")
313
+ main_exit_status = exit_status
314
+ else
315
+ log.info("exec_on_write process with PID #{collected_pid} exited with status #{exit_status}")
316
+ end
317
+ pids.delete(collected_pid)
318
+ end
270
319
 
271
- log.info("Child process exited with status #{exit_status}")
320
+ log.info("Child process exited with status #{main_exit_status}")
272
321
  log.info('Child process finished, Tiller is stopping.')
273
322
  exit exit_status
274
323
 
275
324
  end
276
325
 
326
+
327
+
277
328
  end
@@ -2,10 +2,11 @@ require 'tiller/json'
2
2
  require 'tiller/api/handlers/404'
3
3
 
4
4
  def handle_globals(api_version, tiller_api_hash)
5
+ warning_json = { deprecation_warning: 'The v1 Tiller API is deprecated. Expect this endpoint to be removed in future versions.' }
5
6
  case api_version
6
7
  when 'v1'
7
8
  {
8
- :content => dump_json(tiller_api_hash['global_values']),
9
+ :content => dump_json(tiller_api_hash['global_values'].merge(warning_json)),
9
10
  :status => '200 OK'
10
11
  }
11
12
  else
@@ -36,7 +36,8 @@ module Tiller
36
36
  # 'target' => "/tmp/#{template_name}",
37
37
  # 'user' => 'root',
38
38
  # 'group' => 'root',
39
- # 'perms' => '0644'
39
+ # 'perms' => '0644',
40
+ # 'exec_on_write' => [ "/usr/bin/touch" , "somefile.tmp" ]
40
41
  # }
41
42
  # Again, we should always return a hash; if we have no data for the given
42
43
  # template, just return an empty hash.
data/lib/tiller/kv.rb ADDED
@@ -0,0 +1,26 @@
1
+ module Tiller
2
+
3
+ # Simple KV implementation to facilitate passing 'private' data between datasources and helpers
4
+
5
+ class Kv
6
+ @@kv = {}
7
+
8
+ def self.set(path, value, options={})
9
+ ns = options[:namespace] || 'tiller'
10
+ hash = path.sub(/^\//, '').split('/').reverse.inject(value) { |h, s| {s => h} }
11
+ Tiller::log.debug("#{self} : Setting [#{ns}]#{path} = #{value}")
12
+ @@kv[ns]=hash
13
+ end
14
+
15
+ def self.get(path, options={})
16
+ ns = options[:namespace] || 'tiller'
17
+ value = path.sub(/^\//, '').split('/').inject(@@kv[ns]) { |h,v| h[v] }
18
+ if value == nil
19
+ Tiller::log.warn("#{self} : Request for non-existent key [#{ns}]#{path}")
20
+ end
21
+ value
22
+ end
23
+
24
+ end
25
+ end
26
+
data/lib/tiller/logger.rb CHANGED
@@ -26,6 +26,12 @@ module Tiller
26
26
  self.messages.push(msg)
27
27
  end
28
28
 
29
+ # Quick hack to remove duplicate informational messages
30
+ def debug(msg)
31
+ super(msg) unless self.messages.include?(msg)
32
+ self.messages.push(msg)
33
+ end
34
+
29
35
  end
30
36
 
31
37
  end
data/lib/tiller/render.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  module Tiller
2
- def self.render(template)
2
+ def self.render(template, options={})
3
+
4
+ # This is used for rendering content in dynamic configuration files
5
+ if options.has_key?(:direct_render)
6
+ content = template
7
+ ns = OpenStruct.new(Tiller::tiller)
8
+ return ERB.new(content, nil, '-').result(ns.instance_eval { binding })
9
+ end
10
+
3
11
  if Tiller::templates.key?(template)
4
12
  content = Tiller::templates[template]
5
13
  ns = OpenStruct.new(Tiller::tiller)
data/lib/tiller/util.rb CHANGED
@@ -13,6 +13,19 @@ class ::Hash
13
13
  merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
14
14
  self.merge!(second, &merger)
15
15
  end
16
+
17
+ # https://gist.github.com/sepastian/8688143
18
+ def deep_traverse(&block)
19
+ stack = self.map{ |k,v| [ [k], v ] }
20
+ while not stack.empty?
21
+ key, value = stack.pop
22
+ yield(key, value)
23
+ if value.is_a? Hash
24
+ value.each{ |k,v| stack.push [ key.dup << k, v ] }
25
+ end
26
+ end
27
+ end
28
+
16
29
  end
17
30
 
18
31
  # This is needed so we can enumerate all the loaded plugins later
@@ -24,8 +37,8 @@ end
24
37
 
25
38
  # Warn if values are being merged
26
39
  def warn_merge(key, old, new, type, source)
27
- puts "Warning, merging duplicate #{type} values."
28
- puts "#{key} => '#{old}' being replaced by : '#{new}' from #{source}"
40
+ Tiller::log.info("Merging duplicate #{type} values")
41
+ Tiller::log.info("#{key} => '#{old}' being replaced by : '#{new}' from #{source}")
29
42
  new
30
43
  end
31
44
 
@@ -39,8 +52,8 @@ def signal(sig, pid, options={})
39
52
  end
40
53
  end
41
54
 
42
- # Launch the replacement process.
43
- def launch(cmd, _options={})
55
+ # Fork and launch a process.
56
+ def launch(cmd)
44
57
  # If an array, then we use a different form of spawn() which
45
58
  # avoids a subshell. See https://github.com/markround/tiller/issues/8
46
59
  if cmd.is_a?(Array)
@@ -1 +1,2 @@
1
- VERSION="0.9.7"
1
+ # http://semver.org/
2
+ VERSION="1.0.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.7
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Dastmalchi-Round
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-14 00:00:00.000000000 Z
11
+ date: 2017-02-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A tool to create configuration files from a variety of sources, particularly
14
14
  useful for Docker containers. See https://github.com/markround/tiller for examples
@@ -44,6 +44,7 @@ files:
44
44
  - lib/tiller/defaults.rb
45
45
  - lib/tiller/http.rb
46
46
  - lib/tiller/json.rb
47
+ - lib/tiller/kv.rb
47
48
  - lib/tiller/loader.rb
48
49
  - lib/tiller/logger.rb
49
50
  - lib/tiller/options.rb