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 +4 -4
- data/bin/tiller +60 -9
- data/lib/tiller/api/handlers/globals.rb +2 -1
- data/lib/tiller/datasource.rb +2 -1
- data/lib/tiller/kv.rb +26 -0
- data/lib/tiller/logger.rb +6 -0
- data/lib/tiller/render.rb +9 -1
- data/lib/tiller/util.rb +17 -4
- data/lib/tiller/version.rb +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e44d4f088a889a8fd6d1c4f23bad614e91bfb215
|
4
|
+
data.tar.gz: b1a5e3c7a157675b36dae9fabc71e40155beed0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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']
|
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
|
299
|
+
# Catch signals and send them on to the child processes
|
262
300
|
[ :INT, :TERM, :HUP ].each do |sig|
|
263
|
-
Signal.trap(sig)
|
301
|
+
Signal.trap(sig) do
|
302
|
+
pids.each { |p| signal(sig, p, :verbose => config[:verbose])}
|
303
|
+
end
|
264
304
|
end
|
265
305
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
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 #{
|
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
|
data/lib/tiller/datasource.rb
CHANGED
@@ -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
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
|
-
|
28
|
-
|
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
|
-
#
|
43
|
-
def launch(cmd
|
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)
|
data/lib/tiller/version.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
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.
|
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:
|
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
|