nirvdrum-rubber 1.1.7

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.
Files changed (186) hide show
  1. data/CHANGELOG +146 -0
  2. data/COPYING +339 -0
  3. data/README +6 -0
  4. data/TODO +11 -0
  5. data/VERSION +1 -0
  6. data/bin/vulcanize +41 -0
  7. data/generators/vulcanize/USAGE +6 -0
  8. data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +51 -0
  9. data/generators/vulcanize/templates/apache/config/rubber/role/apache/deflate.conf +10 -0
  10. data/generators/vulcanize/templates/apache/config/rubber/role/apache/expires.conf +9 -0
  11. data/generators/vulcanize/templates/apache/config/rubber/role/apache/headers.conf +6 -0
  12. data/generators/vulcanize/templates/apache/config/rubber/role/apache/monit-apache.conf +8 -0
  13. data/generators/vulcanize/templates/apache/config/rubber/role/apache/ports.conf +5 -0
  14. data/generators/vulcanize/templates/apache/config/rubber/role/apache/setenvif.conf +52 -0
  15. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache-vhost.conf +66 -0
  16. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache.auth +7 -0
  17. data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-index.html +34 -0
  18. data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +6 -0
  19. data/generators/vulcanize/templates/apache/templates.yml +1 -0
  20. data/generators/vulcanize/templates/base/Capfile +14 -0
  21. data/generators/vulcanize/templates/base/config/deploy.rb +55 -0
  22. data/generators/vulcanize/templates/base/config/rubber/common/crontab +17 -0
  23. data/generators/vulcanize/templates/base/config/rubber/common/monit-postfix.conf +8 -0
  24. data/generators/vulcanize/templates/base/config/rubber/common/rubber.profile +14 -0
  25. data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +84 -0
  26. data/generators/vulcanize/templates/base/config/rubber/rubber-dns.yml +79 -0
  27. data/generators/vulcanize/templates/base/config/rubber/rubber.yml +227 -0
  28. data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +15 -0
  29. data/generators/vulcanize/templates/base/script/cron-rake +18 -0
  30. data/generators/vulcanize/templates/base/script/cron-runner +18 -0
  31. data/generators/vulcanize/templates/base/script/cron-sh +67 -0
  32. data/generators/vulcanize/templates/base/templates.yml +1 -0
  33. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/haproxy/haproxy-mongrel.conf +23 -0
  34. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/nginx/nginx-mongrel.conf +113 -0
  35. data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/rubber-complete.yml +41 -0
  36. data/generators/vulcanize/templates/complete_mongrel_mysql/templates.yml +6 -0
  37. data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/role/haproxy/haproxy-passenger.conf +21 -0
  38. data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/rubber-complete.yml +40 -0
  39. data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +10 -0
  40. data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +72 -0
  41. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/cruise +40 -0
  42. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/my.cnf +165 -0
  43. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/production.rb +8 -0
  44. data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/site_config.rb +76 -0
  45. data/generators/vulcanize/templates/cruise/config/rubber/role/web_tools/cruise-nginx.conf +11 -0
  46. data/generators/vulcanize/templates/cruise/config/rubber/rubber-cruise.yml +18 -0
  47. data/generators/vulcanize/templates/cruise/templates.yml +1 -0
  48. data/generators/vulcanize/templates/haproxy/config/rubber/deploy-haproxy.rb +45 -0
  49. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-base.conf +26 -0
  50. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-default.conf +8 -0
  51. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/monit-haproxy.conf +9 -0
  52. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslog-haproxy.conf +6 -0
  53. data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslogd-default.conf +17 -0
  54. data/generators/vulcanize/templates/haproxy/config/rubber/role/web_tools/haproxy-nginx.conf +10 -0
  55. data/generators/vulcanize/templates/haproxy/config/rubber/rubber-haproxy.yml +7 -0
  56. data/generators/vulcanize/templates/haproxy/templates.yml +1 -0
  57. data/generators/vulcanize/templates/jetty/config/rubber/deploy-jetty.rb +59 -0
  58. data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/jetty.sh +589 -0
  59. data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/jetty.xml +199 -0
  60. data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/monit-jetty.conf +9 -0
  61. data/generators/vulcanize/templates/jetty/config/rubber/rubber-jetty.yml +10 -0
  62. data/generators/vulcanize/templates/jetty/templates.yml +1 -0
  63. data/generators/vulcanize/templates/memcached/config/memcached.yml +28 -0
  64. data/generators/vulcanize/templates/memcached/config/rubber/common/memcached.yml +14 -0
  65. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached.conf +52 -0
  66. data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached_munin_plugin +249 -0
  67. data/generators/vulcanize/templates/memcached/config/rubber/rubber-memcached.yml +7 -0
  68. data/generators/vulcanize/templates/memcached/templates.yml +1 -0
  69. data/generators/vulcanize/templates/minimal_mysql/templates.yml +7 -0
  70. data/generators/vulcanize/templates/minimal_nodb/templates.yml +6 -0
  71. data/generators/vulcanize/templates/mongrel/config/rubber/deploy-mongrel.rb +75 -0
  72. data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/mongrel_cluster.yml +12 -0
  73. data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/monit-mongrel.conf +20 -0
  74. data/generators/vulcanize/templates/mongrel/config/rubber/rubber-mongrel.yml +9 -0
  75. data/generators/vulcanize/templates/mongrel/templates.yml +1 -0
  76. data/generators/vulcanize/templates/monit/config/rubber/common/monit-default.conf +15 -0
  77. data/generators/vulcanize/templates/monit/config/rubber/common/monit.conf +251 -0
  78. data/generators/vulcanize/templates/monit/config/rubber/deploy-monit.rb +32 -0
  79. data/generators/vulcanize/templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf +10 -0
  80. data/generators/vulcanize/templates/monit/config/rubber/rubber-monit.yml +6 -0
  81. data/generators/vulcanize/templates/monit/templates.yml +1 -0
  82. data/generators/vulcanize/templates/munin/config/rubber/common/monit-munin.conf +8 -0
  83. data/generators/vulcanize/templates/munin/config/rubber/common/munin-node.conf +48 -0
  84. data/generators/vulcanize/templates/munin/config/rubber/common/munin-plugins.conf +9 -0
  85. data/generators/vulcanize/templates/munin/config/rubber/deploy-munin.rb +46 -0
  86. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-nginx.conf +8 -0
  87. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-plugins.conf +31 -0
  88. data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin.conf +80 -0
  89. data/generators/vulcanize/templates/munin/config/rubber/rubber-munin.yml +8 -0
  90. data/generators/vulcanize/templates/munin/script/munin/example_mysql_query.rb +57 -0
  91. data/generators/vulcanize/templates/munin/script/munin/example_simple.rb +24 -0
  92. data/generators/vulcanize/templates/munin/templates.yml +1 -0
  93. data/generators/vulcanize/templates/mysql/config/rubber/common/database.yml +11 -0
  94. data/generators/vulcanize/templates/mysql/config/rubber/deploy-mysql.rb +156 -0
  95. data/generators/vulcanize/templates/mysql/config/rubber/role/db/crontab +14 -0
  96. data/generators/vulcanize/templates/mysql/config/rubber/role/db/monit-mysql.cnf +10 -0
  97. data/generators/vulcanize/templates/mysql/config/rubber/role/db/my.cnf +167 -0
  98. data/generators/vulcanize/templates/mysql/config/rubber/role/mysql_slave/mysql_slave_munin_plugin +51 -0
  99. data/generators/vulcanize/templates/mysql/config/rubber/rubber-mysql.yml +46 -0
  100. data/generators/vulcanize/templates/mysql/templates.yml +1 -0
  101. data/generators/vulcanize/templates/mysql_cluster/config/rubber/common/mysql_cluster_migrations.rb +13 -0
  102. data/generators/vulcanize/templates/mysql_cluster/config/rubber/deploy-mysql_cluster.rb +173 -0
  103. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_data/my.cnf +15 -0
  104. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_mgm/ndb_mgmd.cnf +39 -0
  105. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/monit-mysql_cluster_sql.cnf +10 -0
  106. data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/my.cnf +23 -0
  107. data/generators/vulcanize/templates/mysql_cluster/config/rubber/rubber-mysql_cluster.yml +32 -0
  108. data/generators/vulcanize/templates/mysql_cluster/templates.yml +1 -0
  109. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/database.yml +16 -0
  110. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/monit-mysql_proxy.cnf +10 -0
  111. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy +153 -0
  112. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.conf +10 -0
  113. data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.lua +5 -0
  114. data/generators/vulcanize/templates/mysql_proxy/config/rubber/deploy-mysql_proxy.rb +52 -0
  115. data/generators/vulcanize/templates/mysql_proxy/config/rubber/rubber-mysql_proxy.yml +11 -0
  116. data/generators/vulcanize/templates/mysql_proxy/templates.yml +1 -0
  117. data/generators/vulcanize/templates/nginx/config/rubber/deploy-nginx.rb +45 -0
  118. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/crontab +9 -0
  119. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/monit-nginx.conf +8 -0
  120. data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/nginx.conf +42 -0
  121. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +55 -0
  122. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-index.html +30 -0
  123. data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-nginx.auth +7 -0
  124. data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +10 -0
  125. data/generators/vulcanize/templates/nginx/templates.yml +1 -0
  126. data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +37 -0
  127. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-memory.conf +34 -0
  128. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-sudoers.conf +7 -0
  129. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger.conf +47 -0
  130. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger-apache-vhost.conf +46 -0
  131. data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger.conf +10 -0
  132. data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +15 -0
  133. data/generators/vulcanize/templates/passenger/templates.yml +3 -0
  134. data/generators/vulcanize/templates/redis/config/rubber/deploy-redis.rb +36 -0
  135. data/generators/vulcanize/templates/redis/config/rubber/role/redis/crontab +8 -0
  136. data/generators/vulcanize/templates/redis/config/rubber/role/redis/monit-redis.conf +9 -0
  137. data/generators/vulcanize/templates/redis/config/rubber/role/redis/redis.conf +141 -0
  138. data/generators/vulcanize/templates/redis/config/rubber/rubber-redis.yml +4 -0
  139. data/generators/vulcanize/templates/redis/templates.yml +1 -0
  140. data/generators/vulcanize/templates/resque/config/rubber/deploy-resque-worker-default.rb +38 -0
  141. data/generators/vulcanize/templates/resque/config/rubber/deploy-resque.rb +39 -0
  142. data/generators/vulcanize/templates/resque/config/rubber/role/resque_worker_default/monit-resque_worker_default.conf +19 -0
  143. data/generators/vulcanize/templates/resque/config/rubber/rubber-resque.yml +10 -0
  144. data/generators/vulcanize/templates/resque/templates.yml +3 -0
  145. data/generators/vulcanize/templates/sphinx/config/rubber/common/sphinx.yml +46 -0
  146. data/generators/vulcanize/templates/sphinx/config/rubber/deploy-sphinx.rb +112 -0
  147. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/crontab +11 -0
  148. data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/monit-sphinx.conf +10 -0
  149. data/generators/vulcanize/templates/sphinx/config/rubber/rubber-sphinx.yml +6 -0
  150. data/generators/vulcanize/templates/sphinx/templates.yml +1 -0
  151. data/generators/vulcanize/vulcanize_generator.rb +67 -0
  152. data/lib/capistrano/hostcmd.rb +12 -0
  153. data/lib/rubber.rb +38 -0
  154. data/lib/rubber/capistrano.rb +1 -0
  155. data/lib/rubber/cloud.rb +13 -0
  156. data/lib/rubber/cloud/aws.rb +334 -0
  157. data/lib/rubber/cloud/base.rb +16 -0
  158. data/lib/rubber/configuration.rb +47 -0
  159. data/lib/rubber/dns.rb +13 -0
  160. data/lib/rubber/dns/base.rb +84 -0
  161. data/lib/rubber/dns/dyndns.rb +78 -0
  162. data/lib/rubber/dns/nettica.rb +117 -0
  163. data/lib/rubber/dns/zerigo.rb +174 -0
  164. data/lib/rubber/environment.rb +169 -0
  165. data/lib/rubber/generator.rb +197 -0
  166. data/lib/rubber/instance.rb +166 -0
  167. data/lib/rubber/recipes/rubber.rb +89 -0
  168. data/lib/rubber/recipes/rubber/bundles.rb +28 -0
  169. data/lib/rubber/recipes/rubber/deploy.rb +90 -0
  170. data/lib/rubber/recipes/rubber/instances.rb +393 -0
  171. data/lib/rubber/recipes/rubber/load_balancers.rb +44 -0
  172. data/lib/rubber/recipes/rubber/security_groups.rb +189 -0
  173. data/lib/rubber/recipes/rubber/setup.rb +457 -0
  174. data/lib/rubber/recipes/rubber/spot_requests.rb +17 -0
  175. data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
  176. data/lib/rubber/recipes/rubber/utils.rb +203 -0
  177. data/lib/rubber/recipes/rubber/volumes.rb +264 -0
  178. data/lib/rubber/tasks/rubber.rb +279 -0
  179. data/lib/rubber/util.rb +37 -0
  180. data/rails/init.rb +9 -0
  181. data/test/environment_test.rb +133 -0
  182. data/test/generator_test.rb +323 -0
  183. data/test/instance_test.rb +93 -0
  184. data/test/test_helper.rb +8 -0
  185. data/test/util_test.rb +16 -0
  186. metadata +298 -0
@@ -0,0 +1,169 @@
1
+ require 'yaml'
2
+ require 'socket'
3
+ require 'delegate'
4
+
5
+ module Rubber
6
+ module Configuration
7
+ # Contains the configuration defined in rubber.yml
8
+ # Handles selecting of correct config values based on
9
+ # the host/role passed into bind
10
+ class Environment
11
+ attr_reader :config_root
12
+ attr_reader :config_files
13
+ attr_reader :config_secret
14
+
15
+ def initialize(config_root)
16
+ @config_root = config_root
17
+ @config_files = ["#{@config_root}/rubber.yml"] + Dir["#{@config_root}/rubber-*.yml"].sort
18
+ @items = {}
19
+ @config_files.each { |file| read_config(file) }
20
+ @config_secret = bind().rubber_secret
21
+ read_config(@config_secret) if @config_secret
22
+ end
23
+
24
+ def read_config(file)
25
+ LOGGER.debug{"Reading rubber configuration from #{file}"}
26
+ if File.exist?(file)
27
+ @items = Environment.combine(@items, YAML.load_file(file) || {})
28
+ end
29
+ end
30
+
31
+ def known_roles
32
+ roles_dir = File.join(@config_root, "role")
33
+ roles = Dir.entries(roles_dir)
34
+ roles.delete_if {|d| d =~ /(^\..*)/}
35
+ roles += @items['roles'].keys
36
+ return roles.compact.uniq
37
+ end
38
+
39
+ def current_host
40
+ Socket::gethostname.gsub(/\..*/, '')
41
+ end
42
+
43
+ def current_full_host
44
+ Socket::gethostname
45
+ end
46
+
47
+ def bind(roles = nil, host = nil)
48
+ BoundEnv.new(@items, roles, host)
49
+ end
50
+
51
+ # combine old and new into a single value:
52
+ # non-nil wins if other is nil
53
+ # arrays just get unioned
54
+ # hashes also get unioned, but the values of conflicting keys get combined
55
+ # All else, the new value wins
56
+ def self.combine(old, new)
57
+ return old if new.nil?
58
+ return new if old.nil?
59
+ value = old
60
+ if old.is_a?(Hash) && new.is_a?(Hash)
61
+ value = old.clone
62
+ new.each do |nk, nv|
63
+ value[nk] = combine(value[nk], nv)
64
+ end
65
+ elsif old.is_a?(Array) && new.is_a?(Array)
66
+ value = old | new
67
+ else
68
+ value = new
69
+ end
70
+ return value
71
+ end
72
+
73
+ class HashValueProxy < Hash
74
+ attr_reader :global
75
+
76
+ def initialize(global, receiver)
77
+ @global = global
78
+ super()
79
+ replace(receiver)
80
+ end
81
+
82
+ def rubber_instances
83
+ @rubber_instances ||= Rubber::Configuration::rubber_instances
84
+ end
85
+
86
+ def [](name)
87
+ value = super(name)
88
+ value = global[name] if global && !value
89
+ return expand(value)
90
+ end
91
+
92
+ def each
93
+ each_key do |key|
94
+ yield key, self[key]
95
+ end
96
+ end
97
+
98
+ def method_missing(method_id)
99
+ key = method_id.id2name
100
+ return self[key]
101
+ end
102
+
103
+ def expand_string(val)
104
+ while val =~ /\#\{[^\}]+\}/
105
+ val = eval('%Q{' + val + '}', binding)
106
+ end
107
+ val = true if val =="true"
108
+ val = false if val == "false"
109
+ return val
110
+ end
111
+
112
+ def expand(value)
113
+ val = case value
114
+ when Hash
115
+ HashValueProxy.new(global || self, value)
116
+ when String
117
+ expand_string(value)
118
+ when Enumerable
119
+ value.collect {|v| expand(v) }
120
+ else
121
+ value
122
+ end
123
+ return val
124
+ end
125
+
126
+ end
127
+
128
+ class BoundEnv < HashValueProxy
129
+ attr_reader :roles
130
+ attr_reader :host
131
+
132
+ def initialize(global, roles, host)
133
+ @roles = roles
134
+ @host = host
135
+ bound_global = bind_config(global)
136
+ super(nil, bound_global)
137
+ end
138
+
139
+ def full_host
140
+ @full_host ||= "#{host}.#{domain}" rescue nil
141
+ end
142
+
143
+ # Forces role/host overrides into config
144
+ def bind_config(global)
145
+ global = global.clone()
146
+ role_overrides = global.delete("roles") || {}
147
+ host_overrides = global.delete("hosts") || {}
148
+ roles.to_a.each do |role|
149
+ role_overrides[role].each do |k, v|
150
+ global[k] = Environment.combine(global[k], v)
151
+ end if role_overrides[role]
152
+ end
153
+ host_overrides[host].each do |k, v|
154
+ global[k] = Environment.combine(global[k], v)
155
+ end if host_overrides[host]
156
+ return global
157
+ end
158
+
159
+ def method_missing(method_id)
160
+ key = method_id.id2name
161
+ return self[key]
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+ end
@@ -0,0 +1,197 @@
1
+ require 'erb'
2
+ require 'find'
3
+ require 'fileutils'
4
+
5
+ module Rubber
6
+ module Configuration
7
+
8
+ # Handles selection and transformation of a set of config files
9
+ # based on the host/role they belong to
10
+ class Generator
11
+ attr_accessor :file_pattern
12
+ attr_accessor :no_post
13
+ attr_accessor :force
14
+ attr_accessor :fake_root
15
+ attr_accessor :stop_on_error_cmd
16
+
17
+ def initialize(config_dir, roles, host, options={})
18
+ @config_dir = config_dir
19
+ @roles = roles.to_a.reverse #First roles take precedence
20
+ @host = host || 'no_host'
21
+ @options=options
22
+ end
23
+
24
+ def run
25
+ config_dirs = []
26
+ config_dirs << "#{@config_dir}/common/**/**"
27
+ @roles.sort.each {|role| config_dirs << "#{@config_dir}/role/#{role}/**/**" }
28
+ config_dirs << "#{@config_dir}/host/#{@host}/**/**"
29
+
30
+ pat = Regexp.new(file_pattern) if file_pattern
31
+
32
+ config_dirs.each do |dir|
33
+ Dir[dir].sort.each do |f|
34
+ next if f =~ /\/(CVS|\.svn)\//
35
+ if File.file?(f) && (! pat || pat.match(f))
36
+ LOGGER.info{"Transforming #{f}"}
37
+ begin
38
+ transform(IO.read(f), @options)
39
+ rescue Exception => e
40
+ lines = e.backtrace.grep(/^\(erb\):([0-9]+)/) {|b| Regexp.last_match(1) }
41
+ LOGGER.error{"Transformation failed for #{f}#{':' + lines.first if lines.first}"}
42
+ LOGGER.error e.message
43
+ exit 1
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ # Transforms the ERB template given in srcfile and writes the result to
51
+ # dest_file (if not nil) before returning it
52
+ def transform(src_data, options={})
53
+ config = ConfigDescriptor.new
54
+
55
+ # for development/test, if we have a fake root, echo any
56
+ # calls to system
57
+ if fake_root
58
+ class << config
59
+ def system(*args)
60
+ puts ("Not running system command during a fake_root transformation: #{args.inspect}")
61
+ end
62
+ def open(*args)
63
+ if args.first && args.first =~ /^|/
64
+ puts ("Not running open/pipe command during a fake_root transformation: #{args.inspect}")
65
+ else
66
+ super
67
+ end
68
+ end
69
+ alias ` system
70
+ alias exec system
71
+ alias fork system
72
+ end
73
+ end
74
+
75
+ config.options = options
76
+ template = ERB.new(src_data, nil, "-")
77
+ result = template.result(config.get_binding())
78
+
79
+ return if config.skip
80
+
81
+ config_path = config.path
82
+
83
+ # for development/test, if we have a fake root, then send config
84
+ # output there, and also put write_cmd output there
85
+ if fake_root
86
+ config_path = "write_cmd_" + config.write_cmd.gsub(/[^a-z0-9_-]/i, '') if config.write_cmd
87
+ config_path = "#{fake_root}/#{config_path}" if config_path
88
+ end
89
+
90
+ if ! config_path && ! (config.read_cmd && config.write_cmd)
91
+ raise "Transformation requires either a output filename or command"
92
+ end
93
+
94
+ reader = config_path || "|#{config.read_cmd}"
95
+ orig = IO.read(reader) rescue ""
96
+
97
+ # When additive is set we need to only replace between our delimiters
98
+ if config.additive
99
+ additive = ["# start rubber #{@host}", "# end rubber #{@host}"] unless additive.is_a? Array
100
+ pat = /#{config.additive[0]}.*#{config.additive[1]}/m
101
+ new = "#{config.additive[0]}#{result}#{config.additive[1]}"
102
+ if orig =~ pat
103
+ result = orig.gsub(pat, new)
104
+ else
105
+ result = orig + new + "\n"
106
+ end
107
+ end
108
+
109
+ # Only do something if the transformed result is different than what
110
+ # is currently in the destination file
111
+ if orig != result || force
112
+ # create dirs as needed
113
+ FileUtils.mkdir_p(File.dirname(config_path)) if config_path
114
+
115
+ # Write a backup of original
116
+ open("#{config_path}.bak", 'w') { |f| f.write(orig) } if config_path
117
+
118
+ # Write out transformed file
119
+ writer = config_path || "|#{config.write_cmd}"
120
+ open(writer, 'w') do |pipe|
121
+ pipe.write(result)
122
+ end
123
+ if config.write_cmd && ! fake_root && $?.exitstatus != 0
124
+ raise "Config command failed execution: #{config.write_cmd}"
125
+ end
126
+
127
+ # Set file permissions and owner if needed
128
+ FileUtils.chmod(config.perms, config_path) if config.perms && config_path
129
+ FileUtils.chown(config.owner, config.group, config_path) if config_path && (config.owner || config.group)
130
+
131
+ # Run post transform command if needed
132
+ if config.post
133
+ if orig == result
134
+ LOGGER.info("Nothing to do, not running post command")
135
+ elsif no_post
136
+ LOGGER.info("Not running post command as no post specified")
137
+ elsif fake_root
138
+ LOGGER.info("Not running post command as a fake root was given: #{config.post}")
139
+ else
140
+ # this lets us abort a script if a command in the middle of it errors out
141
+ # stop_on_error_cmd = "function error_exit { exit 99; }; trap error_exit ERR"
142
+ config.post = "#{stop_on_error_cmd}\n#{config.post}" if stop_on_error_cmd
143
+
144
+ LOGGER.info{"Transformation executing post config command: #{config.post}"}
145
+ LOGGER.info `#{config.post}`
146
+ if $?.exitstatus != 0
147
+ raise "Post command failed execution: #{config.post}"
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ # Instances of this object are used accept settings from with
157
+ # a config file for when it is transformed by Generator
158
+ class ConfigDescriptor
159
+ # The output path to write the transformed config file to
160
+ attr_accessor :path
161
+ # The command to use for reading the original config file from (e.g. "crontab -l")
162
+ attr_accessor :read_cmd
163
+ # The command to use for piping the transformed config file to (e.g. "crontab -")
164
+ attr_accessor :write_cmd
165
+ # The command to run after generating the config file if it has changed
166
+ attr_accessor :post
167
+ # The owner the output file should have, e.g. "root"
168
+ attr_accessor :owner
169
+ # The group the output file should have, e.g. "system"
170
+ attr_accessor :group
171
+ # The permissions the output file should have, e.g. 0644 (octal, leading zero is significant)
172
+ attr_accessor :perms
173
+ # Sets transformation to be additive, only replaces between given delimiters, e/g/ additive = ["## start", "## end"]
174
+ attr_accessor :additive
175
+ # Lets one dynamically determine if a given file gets skipped during transformation
176
+ attr_accessor :skip
177
+ # use sudo to write the output file
178
+ # attr_accessor :sudo
179
+ # options passed in through code
180
+ attr_accessor :options
181
+
182
+ def get_binding
183
+ binding
184
+ end
185
+
186
+ def rubber_env()
187
+ Rubber::Configuration.rubber_env
188
+ end
189
+
190
+ def rubber_instances()
191
+ Rubber::Configuration.rubber_instances
192
+ end
193
+
194
+ end
195
+
196
+ end
197
+ end
@@ -0,0 +1,166 @@
1
+ require 'yaml'
2
+
3
+ module Rubber
4
+ module Configuration
5
+
6
+ # Contains the ec2 instance configuration defined in instance.yml
7
+ #
8
+ class Instance
9
+ attr_reader :file, :artifacts
10
+ include Enumerable
11
+
12
+ def initialize(file)
13
+ LOGGER.debug{"Reading rubber instances from #{file}"}
14
+ @file = file
15
+ @items = {}
16
+ @artifacts = {'volumes' => {}, 'static_ips' => {}}
17
+ if ENV['FILTER']
18
+ @filters = ENV['FILTER'].split(/\s*,\s*/)
19
+ end
20
+
21
+ if File.exist?(@file)
22
+ item_list = File.open(@file) { |f| YAML.load(f) }
23
+ if item_list
24
+ item_list.each do |i|
25
+ if i.is_a? InstanceItem
26
+ @items[i.name] = i
27
+ elsif i.is_a? Hash
28
+ @artifacts.merge!(i)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def save()
36
+ data = []
37
+ data.push(*@items.values)
38
+ data.push(@artifacts)
39
+ File.open(@file, "w") { |f| f.write(YAML.dump(data)) }
40
+ end
41
+
42
+ def [](name)
43
+ @items[name] || @items[name.gsub(/\..*/, '')]
44
+ end
45
+
46
+ # gets the instances for the given role. If options is nil, all roles
47
+ # match, otherwise the role has to have options that match exactly
48
+ def for_role(role_name, options=nil)
49
+ @items.values.find_all {|ic| ic.roles.any? {|r| r.name == role_name && (! options || r.options == options)}}
50
+ end
51
+
52
+ def filtered()
53
+ @items.values.find_all {|ic| ! @filters || @filters.include?(ic.name)}
54
+ end
55
+
56
+ def all_roles()
57
+ @items.collect {|n, i| i.role_names}.flatten.uniq
58
+ end
59
+
60
+ def add(instance_item)
61
+ @items[instance_item.name] = instance_item
62
+ end
63
+
64
+ def remove(name)
65
+ @items.delete(name)
66
+ end
67
+
68
+ def each(&block)
69
+ @items.values.each &block
70
+ end
71
+
72
+ def size
73
+ @items.size
74
+ end
75
+ end
76
+
77
+ # The configuration for a single instance
78
+ class InstanceItem
79
+ attr_reader :name, :domain, :instance_id, :security_groups
80
+ attr_accessor :roles, :zone
81
+ attr_accessor :external_host, :external_ip
82
+ attr_accessor :internal_host, :internal_ip
83
+ attr_accessor :static_ip, :volumes, :partitions
84
+ attr_accessor :spot_instance_request_id
85
+
86
+ def initialize(name, domain, roles, instance_id, security_group_list=[])
87
+ @name = name
88
+ @domain = domain
89
+ @roles = roles
90
+ @instance_id = instance_id
91
+ @security_groups = security_group_list
92
+ end
93
+
94
+ def full_name
95
+ "#@name.#@domain"
96
+ end
97
+
98
+ def role_names()
99
+ roles.collect {|r| r.name}
100
+ end
101
+ end
102
+
103
+ # The configuration for a single role contained in the list
104
+ # of roles in InstanceItem
105
+ class RoleItem
106
+ attr_reader :name, :options
107
+
108
+ def self.expand_role_dependencies(roles, dependency_map, expanded=[])
109
+ roles = Array(roles)
110
+ roles.each do |role|
111
+ unless expanded.include?(role)
112
+ expanded << role
113
+ needed = dependency_map[role]
114
+ expand_role_dependencies(needed, dependency_map, expanded)
115
+ end
116
+ end
117
+ return expanded
118
+ end
119
+
120
+ def self.parse(str)
121
+ data = str.split(':');
122
+ role = Rubber::Configuration::RoleItem.new(data[0])
123
+ if data[1]
124
+ data[1].split(';').each do |pair|
125
+ p = pair.split('=')
126
+ val = case p[1]
127
+ when 'true' then true
128
+ when 'false' then false
129
+ else p[1] end
130
+ role.options[p[0]] = val
131
+ end
132
+ end
133
+ return role
134
+ end
135
+
136
+ def to_s
137
+ str = @name
138
+ @options.each_with_index do |kv, i|
139
+ str += (i == 0 ? ':' : ';')
140
+ str += "#{kv[0]}=#{kv[1]}"
141
+ end
142
+ return str
143
+ end
144
+
145
+ def initialize(name, options={})
146
+ @name = name
147
+ @options = options || {}
148
+ end
149
+
150
+ def eql?(rhs)
151
+ rhs && @name == rhs.name && @options == rhs.options
152
+ end
153
+ alias == eql?
154
+
155
+ def hash()
156
+ @name.hash
157
+ end
158
+
159
+ def <=>(rhs)
160
+ return @name <=> rhs.name
161
+ end
162
+ end
163
+
164
+ end
165
+ end
166
+