tiller 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0faa026bbfbb368fe8d689c233cf79614e5dc9e1
4
- data.tar.gz: 3f90927d1e6c1185fb41f70a7f543f11c36a04a0
3
+ metadata.gz: 86fc7d0cf3873002d5592553f0f5149cf252f09a
4
+ data.tar.gz: b1d175a16e5ed95836d026b2c031d850a909dcd2
5
5
  SHA512:
6
- metadata.gz: 283636ada09058f6ecaa3c2ed1064f50d25a6354815eca4579e4d452663dcb1f576d34eb0d94f9c3f26a27866497d1aaadf64314530fcdfdcd4b1661d1dc9084
7
- data.tar.gz: a7645f090d7eba2e112b83c2ea96996fda23e10fe5b95d7e4e9fd8fc9e601e6aebab2c8a83c7cd234a3cfc7fc6860450cb94cef9c6acc95df94a046f80617c70
6
+ metadata.gz: 7014d7b4591b1611c949c8a9096f02310ebac01fde5b5ec6410390456be54dcf9c46765f242954cc59d1262d8b9493bc8e776671fc337e195d669c79f09397a7
7
+ data.tar.gz: bc6d9b5e25f7844ff07ff5325d63623950fafe3eb57228109090d570844ebe9dbf84d4ad250db6417a65f17488ad1905c26f496d868f9ddfc552f9b06ef0f4fd
data/bin/tiller CHANGED
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
  # Tiller - Dynamic configuration generator, intended for use in Dockerfiles
3
- # Named from the first ship-building (Docker) related term I could find that didn't have an existing gem named after it!
3
+ # Named from the first ship-building (Docker) related term I could find that
4
+ # didn't have an existing gem named after it!
4
5
  # Mark Round <github@markround.com>
5
6
 
6
- VERSION='0.1.0'
7
+ VERSION = '0.1.2'
7
8
 
8
9
  require 'erb'
9
10
  require 'ostruct'
@@ -24,25 +25,26 @@ def warn_merge(key, old, new, type, source)
24
25
  new
25
26
  end
26
27
 
28
+ # And we're on our way...
27
29
  module Tiller
28
-
29
- # Set these two environment variables if you want to debug a configuration in a temporary directory.
30
+ # Set these two environment variables if you want to debug a configuration
31
+ # in a temporary directory.
30
32
  # EG: $ tiller_base=/tmp tiller_lib=/tmp/lib ./tiller
31
33
  config = {
32
- :tiller_base => (ENV['tiller_base'].nil?) ? '/etc/tiller' : ENV['tiller_base'],
33
- :tiller_lib => (ENV['tiller_lib'].nil?) ? '/usr/local/lib' : ENV['tiller_lib'],
34
- # This is the main variable, usually the only one you pass into Docker.
35
- :environment => (ENV['environment'].nil?) ? 'production' : ENV['environment']
34
+ :tiller_base => (ENV['tiller_base'].nil?) ? '/etc/tiller' : ENV['tiller_base'],
35
+ :tiller_lib => (ENV['tiller_lib'].nil?) ? '/usr/local/lib' : ENV['tiller_lib'],
36
+ # This is the main variable, usually the only one you pass into Docker.
37
+ :environment => (ENV['environment'].nil?) ? 'production' : ENV['environment']
36
38
  }
37
39
 
40
+ # Add tiller_lib to the LOAD PATH so we can pull in user-defined plugins
38
41
  $LOAD_PATH.unshift(config[:tiller_lib]) unless $LOAD_PATH.include?(config[:tiller_lib])
39
42
 
40
- # User-provided sources.
41
43
  require 'tiller/templatesource.rb'
42
44
  require 'tiller/datasource.rb'
43
45
 
44
46
  # Load the common YAML configuration file
45
- config[:common_config] = YAML::load(open(File.join(config[:tiller_base], 'common.yaml')))
47
+ config[:common_config] = YAML.load(open(File.join(config[:tiller_base], 'common.yaml')))
46
48
 
47
49
  puts "tiller v#{VERSION} (https://github.com/markround/tiller) <github@markround.com>"
48
50
  puts "Using configuration from #{config[:tiller_base]}"
@@ -61,83 +63,93 @@ module Tiller
61
63
  puts 'Data sources loaded ' + DataSource.subclasses.to_s
62
64
 
63
65
  # Get all Templates for the given environment
64
- templates = {}
66
+ templates = Hash.new
65
67
  TemplateSource.subclasses.each do |template_class|
66
68
  ts = template_class.new(config)
67
69
  ts.templates.each do |t|
68
- templates[t]=ts.template(t)
70
+ templates[t] = ts.template(t)
69
71
  end
70
72
  end
71
73
 
72
- puts "Templates to build #{templates.keys.to_s}"
74
+ puts "Templates to build #{templates.keys}"
73
75
 
74
- # Now go through all our data sources and start to assemble our "tiller_global" hash.
75
- # As hashes are getting merged, new values will take precedence over older ones, and a warning will be displayed.
76
- # Add in environment ti start with as it's very useful for all templates.
77
- global_values = {'environment' => config[:environment]}
76
+ # Now go through all our data sources and start to assemble our global_values
77
+ # hash. As hashes are getting merged, new values will take precedence over
78
+ # older ones, and a warning will be displayed.
79
+ # We also add in 'environment' to start with as it's very useful for all
80
+ # templates.
81
+ global_values = { 'environment' => config[:environment] }
78
82
  DataSource.subclasses.each do |data_class|
79
83
  global_values.merge!(data_class.new(config).global_values) do |key, old, new|
80
84
  warn_merge(key, old, new, 'global', data_class.to_s)
81
85
  end
82
86
  end
83
87
 
84
- # Now we go through each template we've identified, and get the values for each one.
88
+ # Now we go through each template we've identified, and get the
89
+ # values for each one.
85
90
  templates.each do |template, content|
86
91
  values = Hash.new
87
92
  target_values = Hash.new
88
- puts "Building template #{template}"
89
93
 
90
- # Now we populate the hash with values from each DataSource, warning if we get duplicate values.
94
+ # Now we populate the hash with values from each DataSource, warning if we
95
+ # get duplicate values.
91
96
  DataSource.subclasses.each do |data_class|
92
97
  dc = data_class.new(config)
93
98
  values.merge!(dc.values(template)) do |key, old, new|
94
99
  warn_merge(key, old, new, 'data', data_class.to_s)
95
100
  end
96
101
 
97
- # Now get target_values (where the file should be installed to, permissions and so on)
102
+ # Now get target_values (where the file should be installed to,
103
+ # permissions and so on)
98
104
  target_values.merge!(dc.target_values(template)) do |key, old, new|
99
105
  warn_merge(key, old, new, 'target', data_class.to_s)
100
106
  end
101
107
  end
102
108
 
103
- # If our data source returned no values (e.g. we don't build this template for this environment)
104
- # We move onto the next one.
109
+ # If our data source returned no values (e.g. we don't build this template
110
+ # for this environment), we move onto the next one.
105
111
  next if target_values.empty?
106
112
 
107
113
  # Now, we build the template
114
+ puts "Building template #{template}"
108
115
  tiller = values.merge(global_values) do |key, old, new|
109
116
  warn_merge(key, old, new, 'global and local', 'merged configuration')
110
117
  end
111
118
 
112
- # Use an OpenStruct namespace, as it's way easier than faffing around with manual binding, and also
113
- # non-existing values just get replaced by <nil> instead of failing on errors.
119
+ # Use an OpenStruct namespace, as it's way easier than faffing around with
120
+ # manual binding, and also non-existing values just get replaced by <nil>
121
+ # instead of failing on errors.
114
122
  ns = OpenStruct.new(tiller)
115
123
  parsed_template = ERB.new(content).result(ns.instance_eval { binding })
116
124
 
117
- # Write the template, and also create the directory path if it doesn't exist.
125
+ # Write the template, and also create the directory path if it
126
+ # doesn't exist.
118
127
  target_path = File.dirname(target_values['target'])
119
- FileUtils.mkdir_p(target_path) if not File.directory?(target_path)
120
- target = open(target_values['target'], "w")
128
+ FileUtils.mkdir_p(target_path) unless File.directory?(target_path)
129
+ target = open(target_values['target'], 'w')
121
130
  target.puts(parsed_template)
122
131
  target.close
123
132
 
124
133
  # Set permissions if we are running as root
125
- if Process::Sys.geteuid == 0 then
134
+ if Process::Sys.geteuid == 0
126
135
  puts "Setting ownership/permissions on #{target_values['target']}"
127
- FileUtils.chmod(target_values['perms'], target_values['target']) if target_values.has_key?('perms')
128
- # Don't need to check for the presence of these, as they're ignored if null.
129
- FileUtils.chown(target_values['user'], target_values['group'], target_values['target'])
136
+ if target_values.key?('perms')
137
+ FileUtils.chmod(target_values['perms'], target_values['target'])
138
+ end
139
+ # Don't need to check for the presence of these, as they're ignored
140
+ # if they are null.
141
+ FileUtils.chown(target_values['user'], target_values['group'],
142
+ target_values['target'])
130
143
  else
131
- puts "Not running as root, so not setting ownership/permissions on #{target_values['target']}"
144
+ puts 'Not running as root, so not setting ownership/permissions on ' \
145
+ "#{target_values['target']}"
132
146
  end
133
147
 
134
148
  end
135
149
 
136
- # All templates created, so let's handover to the replacement process then it's home in time for tea and medals.
137
- puts "Template generation completed, about to exec replacement process."
150
+ # All templates created, so let's handover to the replacement process then
151
+ # it's home in time for tea and medals.
152
+ puts 'Template generation completed, about to exec replacement process.'
138
153
  puts "Calling #{config[:common_config]['exec']}..."
139
154
  exec(config[:common_config]['exec'])
140
-
141
155
  end
142
-
143
-
@@ -1,27 +1,25 @@
1
- # This is a "dummy" datasource for Tiller. All it does is provide a single global and local value,
2
- # And shows how you can provide a hash of target values to configure where templates are written.
3
-
1
+ # This is a "dummy" datasource for Tiller. All it does is provide a single
2
+ # global and local value, and shows how you can provide a hash of target values
3
+ # to configure where templates are written.
4
4
  class DummyDataSource < Tiller::DataSource
5
-
6
5
  def global_values
7
6
  { 'dummy_global' => 'dummy global replacement text' }
8
7
  end
9
8
 
10
- def values(template_name)
9
+ def values(_template_name)
11
10
  { 'dummy' => 'dummy replacement text' }
12
11
  end
13
12
 
14
- # Dummy values, useful for testing. Will just result in the template being built and written to /tmp/dummy.
15
- # Remember that perms must be in octal (no quotes).
16
- # Note that as you have the environment name in the @@config hash, you can always return different values
17
- # for different environments.
13
+ # Dummy values, useful for testing. Will just result in the template being
14
+ # built and written to /tmp/dummy. Remember that perms must be in octal
15
+ # (no quotes). Note that as you have the environment name in the @config hash,
16
+ # you can always return different values for different environments.
18
17
  def target_values(template_name)
19
18
  {
20
- 'target' => "/tmp/dummy/#{template_name}",
21
- 'user' => 'root',
22
- 'group' => 'root',
23
- 'perms' => 0644
19
+ 'target' => "/tmp/dummy/#{template_name}",
20
+ 'user' => 'root',
21
+ 'group' => 'root',
22
+ 'perms' => 0644
24
23
  }
25
24
  end
26
-
27
25
  end
@@ -1,17 +1,15 @@
1
1
  require 'socket'
2
-
3
- # This is a quick example of a global datasource for Tiller. It shows how you might provide some basic
4
- # network-related information to your templates. It's a super quick and hacky, but serves as a useful example.
5
- # You can then do things like <%= fqdn %> or <%= ipv4_addresses[0][3] %> in your templates.
6
-
2
+ # This is a quick example of a global datasource for Tiller.
3
+ # It shows how you might provide some basic network-related information to your
4
+ # templates. It's a super quick and hacky, but serves as a useful example.
5
+ # You can then do things like <%= fqdn %> or <%= ipv4_addresses[0][3] %> in
6
+ # your templates.
7
7
  class NetworkDataSource < Tiller::DataSource
8
-
9
8
  def global_values
10
9
  # Note, these rely on DNS being available and configured correctly!
11
10
  {
12
- 'fqdn' => Socket.gethostbyname(Socket.gethostname).first,
13
- 'ipv4_addresses' => Socket.getaddrinfo(Socket.gethostbyname(Socket.gethostname).first, nil, :INET)
11
+ 'fqdn' => Socket.gethostbyname(Socket.gethostname).first,
12
+ 'ipv4_addresses' => Socket.getaddrinfo(Socket.gethostbyname(Socket.gethostname).first, nil, :INET)
14
13
  }
15
14
  end
16
-
17
15
  end
@@ -1,18 +1,15 @@
1
1
  # This is another quick example of how to create a template source.
2
-
3
2
  class DummyTemplateSource < Tiller::TemplateSource
4
-
5
3
  # Just provide a single dummy template
6
4
  def templates
7
- ["dummy.erb"]
5
+ ['dummy.erb']
8
6
  end
9
7
 
10
8
  # And return some sample ERB content.
11
- # Note that as you have the environment name in the @@config hash, you can always return different templates
12
- # for different environments.
13
- def template(template_name)
14
- "This is a dummy template! <%= dummy %> \n Here is a global value <%= dummy_global %>"
9
+ # Note that as you have the environment name in the @config hash, you can
10
+ # always return different templates for different environments.
11
+ def template(_template_name)
12
+ "This is a dummy template! <%= dummy %> \n "\
13
+ 'Here is a global value <%= dummy_global %>'
15
14
  end
16
-
17
15
  end
18
-
@@ -1,12 +1,10 @@
1
- # Environment datasource for Tiller. This extracts all environment variables, and makes them available to templates
2
- # by converting to lowercase and preceeding them with env_. E.G. env_home, env_logname and so on.
3
-
1
+ # Environment datasource for Tiller. This extracts all environment variables,
2
+ # and makes them available to templates by converting to lowercase and
3
+ # preceeding them with env_. E.G. env_home, env_logname and so on.
4
4
  class EnvironmentDataSource < Tiller::DataSource
5
-
6
5
  def global_values
7
6
  values = Hash.new
8
- ENV.each { |k,v| values["env_#{k.downcase}"] = v }
7
+ ENV.each { |k, v| values["env_#{k.downcase}"] = v }
9
8
  values
10
9
  end
11
-
12
10
  end
@@ -1,26 +1,23 @@
1
- # File datasource for Tiller. This works the same way as the default behaviour in Runner.rb - it loads your
2
- # <environment>.yaml file and provides data from it. See examples/etc/tiller/environments/production.yaml to see
3
- # what this file looks like.
1
+ require 'yaml'
2
+ # File datasource for Tiller. This works the same way as the default behaviour
3
+ # in Runner.rb - it loads your <environment>.yaml file and pulls data from it.
4
+ # See examples/etc/tiller/environments/production.yaml to see what this file
5
+ # looks like.
4
6
  #
5
7
  # We also don't provide any global values, just ones specific to a template.
6
-
7
-
8
- require 'yaml'
9
-
10
8
  class FileDataSource < Tiller::DataSource
11
-
12
9
  # Open and parse the environment file
13
10
  def setup
14
- env_file = File.join(@@config[:tiller_base], "environments", "#{@@config[:environment]}.yaml")
15
- @config_hash = YAML::load(open(env_file))
11
+ env_file = File.join(@config[:tiller_base], 'environments',
12
+ "#{@config[:environment]}.yaml")
13
+ @config_hash = YAML.load(open(env_file))
16
14
  end
17
15
 
18
16
  def values(template_name)
19
- @config_hash.has_key?(template_name) ? @config_hash[template_name]['config'] : Hash.new
17
+ @config_hash.key?(template_name) ? @config_hash[template_name]['config'] : Hash.new
20
18
  end
21
19
 
22
20
  def target_values(template_name)
23
- @config_hash.has_key?(template_name) ? @config_hash[template_name] : Hash.new
21
+ @config_hash.key?(template_name) ? @config_hash[template_name] : Hash.new
24
22
  end
25
-
26
23
  end
@@ -1,20 +1,17 @@
1
- # Random datasource for Tiller. Provides Base64, UUID and other useful random strings
2
-
3
1
  require 'securerandom'
4
-
2
+ # Random datasource for Tiller. Provides Base64, UUID and other useful
3
+ # random strings.
5
4
  class RandomDataSource < Tiller::DataSource
6
-
7
5
  def global_values
8
6
  {
9
- 'random_base64' => SecureRandom.base64,
10
- 'random_hex' => SecureRandom.hex,
11
- 'random_bytes' => SecureRandom.random_bytes,
12
- 'random_number_10' => SecureRandom.random_number(10),
13
- 'random_number_100' => SecureRandom.random_number(100),
14
- 'random_number_1000' => SecureRandom.random_number(1000),
15
- 'random_urlsafe_base64' => SecureRandom.urlsafe_base64,
16
- 'random_uuid' => SecureRandom.uuid
7
+ 'random_base64' => SecureRandom.base64,
8
+ 'random_hex' => SecureRandom.hex,
9
+ 'random_bytes' => SecureRandom.random_bytes,
10
+ 'random_number_10' => SecureRandom.random_number(10),
11
+ 'random_number_100' => SecureRandom.random_number(100),
12
+ 'random_number_1000' => SecureRandom.random_number(1000),
13
+ 'random_urlsafe_base64' => SecureRandom.urlsafe_base64,
14
+ 'random_uuid' => SecureRandom.uuid
17
15
  }
18
16
  end
19
-
20
17
  end
@@ -1,20 +1,20 @@
1
1
  # Tiller data source base class.
2
- #
3
- # Subclasses provide global_values and/or values (things local to a specific template) and target_values (meta data
4
- # about a template, e.g. target location, permissions, owner and so on)
5
-
6
2
  module Tiller
3
+ # Subclasses provide global_values and/or values (things local to a specific
4
+ # template) and target_values (meta data about a template, e.g. target
5
+ # location, permissions, owner and so on)
7
6
  class DataSource
8
-
9
- # All subclasses get this, which is a hash containing tiller_base, tiller_lib and environment.
10
- @@config = Array.new
7
+ # All subclasses get this, which is a hash containing tiller_base,
8
+ # tiller_lib and environment.
9
+ @config = Array.new
11
10
 
12
11
  def initialize(config)
13
- @@config = config
14
- self.setup
12
+ @config = config
13
+ setup
15
14
  end
16
15
 
17
- # This is where any post-initialisation logic happens (connecting to a database etc.)
16
+ # This is where any post-initialisation logic happens
17
+ # (connecting to a database etc.)
18
18
  def setup
19
19
  end
20
20
 
@@ -22,26 +22,27 @@ module Tiller
22
22
  Hash.new
23
23
  end
24
24
 
25
- # We should always return a hash; if we have no data for the given template, just return an empty hash.
26
- def values(template_name)
25
+ # We should always return a hash; if we have no data for the given
26
+ # template, just return an empty hash.
27
+ def values(_template_name)
27
28
  Hash.new
28
29
  end
29
30
 
30
31
  # This should provide a hash similar to this example :
31
- #{
32
+ # {
32
33
  # 'target' => "/tmp/#{template_name}",
33
34
  # 'user' => 'root',
34
35
  # 'group' => 'root',
35
36
  # 'perms' => '0644'
36
- #}
37
- # Again, we should always return a hash; if we have no data for the given template, just return an empty hash.
38
- def target_values(template_name)
37
+ # }
38
+ # Again, we should always return a hash; if we have no data for the given
39
+ # template, just return an empty hash.
40
+ def target_values(_template_name)
39
41
  Hash.new
40
42
  end
41
43
 
42
44
  def ping
43
- "ping!" + @@config.to_s
45
+ 'ping!' + @config.to_s
44
46
  end
45
-
46
47
  end
47
48
  end
@@ -1,15 +1,14 @@
1
- # File template datasource for Tiller. This works the same way that Runner.rb used to - it returns templates files
2
- # present under /etc/tiller/templates (or wherever the tiller_base environment is set).
3
-
1
+ # File template datasource for Tiller. This works the same way that Runner.rb
2
+ # used to - it returns templates files present under /etc/tiller/templates
3
+ # (or wherever the tiller_base environment is set).
4
4
  class FileTemplateSource < Tiller::TemplateSource
5
-
6
5
  def initialize(config)
7
6
  super
8
- @template_dir = File.join(@@config[:tiller_base], 'templates/')
7
+ @template_dir = File.join(@config[:tiller_base], 'templates/')
9
8
  end
10
9
 
11
- # Simply return a list of all the templates in the $tiller_base/templates directory
12
- # With the preceeding directory path stripped off
10
+ # Simply return a list of all the templates in the $tiller_base/templates
11
+ # directory with the preceeding directory path stripped off
13
12
  def templates
14
13
  Dir.glob(File.join(@template_dir, '**', '*.erb')).each do |t|
15
14
  t.sub!(@template_dir, '')
@@ -20,6 +19,4 @@ class FileTemplateSource < Tiller::TemplateSource
20
19
  def template(template_name)
21
20
  open(File.join(@template_dir, template_name)).read
22
21
  end
23
-
24
22
  end
25
-
@@ -1,17 +1,18 @@
1
1
  # Tiller template source base class
2
- # Subclasses provide templates (an array), and individual template contents (a string containing ERB data)
3
-
4
2
  module Tiller
3
+ # Subclasses provide templates (an array), and individual template contents
4
+ # (a string containing ERB data)
5
5
  class TemplateSource
6
-
7
- # All subclasses get this, which is a hash containing tiller_base, tiller_lib and environment.
8
- @@config = Array.new
6
+ # All subclasses get this, which is a hash containing tiller_base,
7
+ # tiller_lib and environment.
8
+ @config = Array.new
9
9
 
10
10
  def initialize(config)
11
- @@config = config
11
+ @config = config
12
12
  end
13
13
 
14
- # This is where any post-initialisation logic happens (connecting to a database etc.)
14
+ # This is where any post-initialisation logic happens
15
+ # (connecting to a database etc.)
15
16
  def setup
16
17
  end
17
18
 
@@ -24,7 +25,7 @@ module Tiller
24
25
  end
25
26
 
26
27
  def ping
27
- "ping!" + @@config.to_s
28
+ 'ping!' + @config.to_s
28
29
  end
29
30
  end
30
31
  end
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.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Round
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-08 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A tool to create configuration files in Docker containers from a variety
14
14
  of sources. See https://github.com/markround/tiller for examples and documentation.