tiller 0.1.0 → 0.1.2

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: 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.