rubber 1.0.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.
- data/CHANGELOG +39 -0
- data/COPYING +339 -0
- data/README +6 -0
- data/TODO +11 -0
- data/VERSION +1 -0
- data/bin/vulcanize +41 -0
- data/generators/vulcanize/USAGE +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +51 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/deflate.conf +10 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/expires.conf +9 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/headers.conf +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/monit-apache.conf +8 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/ports.conf +5 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/apache/setenvif.conf +52 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache-vhost.conf +62 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-apache.auth +7 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web_tools/tools-index.html +30 -0
- data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +7 -0
- data/generators/vulcanize/templates/apache/templates.yml +1 -0
- data/generators/vulcanize/templates/base/Capfile +14 -0
- data/generators/vulcanize/templates/base/config/deploy.rb +55 -0
- data/generators/vulcanize/templates/base/config/rubber/common/crontab +16 -0
- data/generators/vulcanize/templates/base/config/rubber/common/profile.rc +9 -0
- data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +104 -0
- data/generators/vulcanize/templates/base/config/rubber/rubber.yml +241 -0
- data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +15 -0
- data/generators/vulcanize/templates/base/script/cron-rake +18 -0
- data/generators/vulcanize/templates/base/script/cron-runner +18 -0
- data/generators/vulcanize/templates/base/script/cron-sh +67 -0
- data/generators/vulcanize/templates/base/templates.yml +1 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/haproxy/haproxy-mongrel.conf +23 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/role/nginx/nginx-mongrel.conf +113 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/config/rubber/rubber-complete.yml +41 -0
- data/generators/vulcanize/templates/complete_mongrel_mysql/templates.yml +6 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/role/haproxy/haproxy-passenger.conf +19 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/config/rubber/rubber-complete.yml +40 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +10 -0
- data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +72 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/cruise +40 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/my.cnf +165 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/production.rb +8 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/cruise/site_config.rb +76 -0
- data/generators/vulcanize/templates/cruise/config/rubber/role/web_tools/cruise-nginx.conf +11 -0
- data/generators/vulcanize/templates/cruise/config/rubber/rubber-cruise.yml +18 -0
- data/generators/vulcanize/templates/cruise/templates.yml +1 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/deploy-haproxy.rb +45 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-base.conf +26 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy-default.conf +8 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/monit-haproxy.conf +9 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslog-haproxy.conf +6 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/syslogd-default.conf +17 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/web_tools/haproxy-nginx.conf +10 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/rubber-haproxy.yml +7 -0
- data/generators/vulcanize/templates/haproxy/templates.yml +1 -0
- data/generators/vulcanize/templates/memcached/config/memcached.yml +28 -0
- data/generators/vulcanize/templates/memcached/config/rubber/common/memcached.yml +14 -0
- data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached.conf +52 -0
- data/generators/vulcanize/templates/memcached/config/rubber/role/memcached/memcached_munin_plugin +249 -0
- data/generators/vulcanize/templates/memcached/config/rubber/rubber-memcached.yml +7 -0
- data/generators/vulcanize/templates/memcached/templates.yml +1 -0
- data/generators/vulcanize/templates/minimal_mysql/templates.yml +7 -0
- data/generators/vulcanize/templates/minimal_nodb/templates.yml +6 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/deploy-mongrel.rb +75 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/mongrel_cluster.yml +12 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/role/mongrel/monit-mongrel.conf +20 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/rubber-mongrel.yml +9 -0
- data/generators/vulcanize/templates/mongrel/templates.yml +1 -0
- data/generators/vulcanize/templates/monit/config/rubber/common/monit-default.conf +15 -0
- data/generators/vulcanize/templates/monit/config/rubber/common/monit.conf +251 -0
- data/generators/vulcanize/templates/monit/config/rubber/deploy-monit.rb +32 -0
- data/generators/vulcanize/templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf +10 -0
- data/generators/vulcanize/templates/monit/config/rubber/rubber-monit.yml +6 -0
- data/generators/vulcanize/templates/monit/templates.yml +1 -0
- data/generators/vulcanize/templates/munin/config/rubber/common/monit-munin.conf +8 -0
- data/generators/vulcanize/templates/munin/config/rubber/common/munin-node.conf +48 -0
- data/generators/vulcanize/templates/munin/config/rubber/deploy-munin.rb +46 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-nginx.conf +8 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin-plugins.conf +31 -0
- data/generators/vulcanize/templates/munin/config/rubber/role/web_tools/munin.conf +80 -0
- data/generators/vulcanize/templates/munin/config/rubber/rubber-munin.yml +8 -0
- data/generators/vulcanize/templates/munin/script/munin/example_mysql_query.rb +57 -0
- data/generators/vulcanize/templates/munin/script/munin/example_simple.rb +24 -0
- data/generators/vulcanize/templates/munin/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql/config/rubber/common/database.yml +11 -0
- data/generators/vulcanize/templates/mysql/config/rubber/deploy-mysql.rb +156 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/crontab +14 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/monit-mysql.cnf +10 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/db/my.cnf +167 -0
- data/generators/vulcanize/templates/mysql/config/rubber/role/mysql_slave/mysql_slave_munin_plugin +51 -0
- data/generators/vulcanize/templates/mysql/config/rubber/rubber-mysql.yml +46 -0
- data/generators/vulcanize/templates/mysql/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/common/mysql_cluster_migrations.rb +13 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/deploy-mysql_cluster.rb +173 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_data/my.cnf +15 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_mgm/ndb_mgmd.cnf +39 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/monit-mysql_cluster_sql.cnf +10 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/role/mysql_sql/my.cnf +23 -0
- data/generators/vulcanize/templates/mysql_cluster/config/rubber/rubber-mysql_cluster.yml +32 -0
- data/generators/vulcanize/templates/mysql_cluster/templates.yml +1 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/database.yml +16 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/monit-mysql_proxy.cnf +10 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy +153 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.conf +10 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/common/mysql-proxy.lua +5 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/deploy-mysql_proxy.rb +52 -0
- data/generators/vulcanize/templates/mysql_proxy/config/rubber/rubber-mysql_proxy.yml +11 -0
- data/generators/vulcanize/templates/mysql_proxy/templates.yml +1 -0
- data/generators/vulcanize/templates/nginx/config/rubber/deploy-nginx.rb +45 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/crontab +9 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/monit-nginx.conf +8 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/nginx/nginx.conf +42 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +55 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-index.html +30 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/tools-nginx.auth +7 -0
- data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +10 -0
- data/generators/vulcanize/templates/nginx/templates.yml +1 -0
- data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +37 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-sudoers.conf +6 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger.conf +47 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger-apache-vhost.conf +46 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/passenger.conf +10 -0
- data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +12 -0
- data/generators/vulcanize/templates/passenger/templates.yml +1 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/common/sphinx.yml +46 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/deploy-sphinx.rb +112 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/crontab +11 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/role/sphinx/monit-sphinx.conf +10 -0
- data/generators/vulcanize/templates/sphinx/config/rubber/rubber-sphinx.yml +6 -0
- data/generators/vulcanize/templates/sphinx/templates.yml +1 -0
- data/generators/vulcanize/vulcanize_generator.rb +67 -0
- data/lib/capistrano/hostcmd.rb +12 -0
- data/lib/rubber.rb +38 -0
- data/lib/rubber/capistrano.rb +1 -0
- data/lib/rubber/cloud.rb +13 -0
- data/lib/rubber/cloud/aws.rb +305 -0
- data/lib/rubber/cloud/base.rb +16 -0
- data/lib/rubber/configuration.rb +47 -0
- data/lib/rubber/dns.rb +13 -0
- data/lib/rubber/dns/base.rb +69 -0
- data/lib/rubber/dns/dyndns.rb +63 -0
- data/lib/rubber/dns/nettica.rb +73 -0
- data/lib/rubber/dns/zerigo.rb +131 -0
- data/lib/rubber/environment.rb +161 -0
- data/lib/rubber/generator.rb +197 -0
- data/lib/rubber/instance.rb +165 -0
- data/lib/rubber/recipes/rubber.rb +89 -0
- data/lib/rubber/recipes/rubber/bundles.rb +28 -0
- data/lib/rubber/recipes/rubber/deploy.rb +90 -0
- data/lib/rubber/recipes/rubber/instances.rb +348 -0
- data/lib/rubber/recipes/rubber/load_balancers.rb +44 -0
- data/lib/rubber/recipes/rubber/security_groups.rb +189 -0
- data/lib/rubber/recipes/rubber/setup.rb +357 -0
- data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
- data/lib/rubber/recipes/rubber/utils.rb +203 -0
- data/lib/rubber/recipes/rubber/volumes.rb +264 -0
- data/lib/rubber/tasks/rubber.rb +221 -0
- data/lib/rubber/util.rb +37 -0
- data/test/environment_test.rb +118 -0
- data/test/generator_test.rb +323 -0
- data/test/instance_test.rb +93 -0
- data/test/test_helper.rb +4 -0
- data/test/util_test.rb +16 -0
- metadata +274 -0
|
@@ -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,165 @@
|
|
|
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
|
+
|
|
85
|
+
def initialize(name, domain, roles, instance_id, security_group_list=[])
|
|
86
|
+
@name = name
|
|
87
|
+
@domain = domain
|
|
88
|
+
@roles = roles
|
|
89
|
+
@instance_id = instance_id
|
|
90
|
+
@security_groups = security_group_list
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def full_name
|
|
94
|
+
"#@name.#@domain"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def role_names()
|
|
98
|
+
roles.collect {|r| r.name}
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The configuration for a single role contained in the list
|
|
103
|
+
# of roles in InstanceItem
|
|
104
|
+
class RoleItem
|
|
105
|
+
attr_reader :name, :options
|
|
106
|
+
|
|
107
|
+
def self.expand_role_dependencies(roles, dependency_map, expanded=[])
|
|
108
|
+
roles = Array(roles)
|
|
109
|
+
roles.each do |role|
|
|
110
|
+
unless expanded.include?(role)
|
|
111
|
+
expanded << role
|
|
112
|
+
needed = dependency_map[role]
|
|
113
|
+
expand_role_dependencies(needed, dependency_map, expanded)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
return expanded
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def self.parse(str)
|
|
120
|
+
data = str.split(':');
|
|
121
|
+
role = Rubber::Configuration::RoleItem.new(data[0])
|
|
122
|
+
if data[1]
|
|
123
|
+
data[1].split(';').each do |pair|
|
|
124
|
+
p = pair.split('=')
|
|
125
|
+
val = case p[1]
|
|
126
|
+
when 'true' then true
|
|
127
|
+
when 'false' then false
|
|
128
|
+
else p[1] end
|
|
129
|
+
role.options[p[0]] = val
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
return role
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def to_s
|
|
136
|
+
str = @name
|
|
137
|
+
@options.each_with_index do |kv, i|
|
|
138
|
+
str += (i == 0 ? ':' : ';')
|
|
139
|
+
str += "#{kv[0]}=#{kv[1]}"
|
|
140
|
+
end
|
|
141
|
+
return str
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def initialize(name, options={})
|
|
145
|
+
@name = name
|
|
146
|
+
@options = options || {}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def eql?(rhs)
|
|
150
|
+
rhs && @name == rhs.name && @options == rhs.options
|
|
151
|
+
end
|
|
152
|
+
alias == eql?
|
|
153
|
+
|
|
154
|
+
def hash()
|
|
155
|
+
@name.hash
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def <=>(rhs)
|
|
159
|
+
return @name <=> rhs.name
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# add this plugins lib dir to load path for capistrano
|
|
2
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require "socket"
|
|
5
|
+
require 'resolv'
|
|
6
|
+
require 'enumerator'
|
|
7
|
+
require 'capistrano/hostcmd'
|
|
8
|
+
require 'pp'
|
|
9
|
+
require 'rubber'
|
|
10
|
+
|
|
11
|
+
namespace :rubber do
|
|
12
|
+
|
|
13
|
+
# advise capistrano's task method so that tasks for non-existant roles don't
|
|
14
|
+
# fail when roles isn't defined due to using a FILTER for load_roles
|
|
15
|
+
# If you have a task you need to execute even when there are no
|
|
16
|
+
# roles, you have to use required_task instead of task - see rubber:create
|
|
17
|
+
# as an example of this role bootstrapping problem.
|
|
18
|
+
def allow_optional_tasks(ns)
|
|
19
|
+
class << ns
|
|
20
|
+
alias :required_task :task
|
|
21
|
+
def task(name, options={}, &block)
|
|
22
|
+
required_task(name, options) do
|
|
23
|
+
# define empty roles for the case when a task has a role that we don't define anywhere
|
|
24
|
+
[*options[:roles]].each do |r|
|
|
25
|
+
roles[r] ||= []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if find_servers_for_task(current_task).empty?
|
|
29
|
+
logger.info "No servers for task #{name}, skipping"
|
|
30
|
+
next
|
|
31
|
+
end
|
|
32
|
+
block.call
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
allow_optional_tasks(self)
|
|
39
|
+
on :load, "rubber:init"
|
|
40
|
+
|
|
41
|
+
required_task :init do
|
|
42
|
+
# Require cap 2.4 since we depend on bugs that have been fixed
|
|
43
|
+
require 'capistrano/version'
|
|
44
|
+
if Capistrano::Version::MAJOR < 2 || Capistrano::Version::MINOR < 4
|
|
45
|
+
fatal "rubber requires capistrano 2.4.0 or greater"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
set :rubber_cfg, Rubber::Configuration.get_configuration(RUBBER_ENV)
|
|
49
|
+
set :rubber_env, rubber_cfg.environment.bind()
|
|
50
|
+
set :rubber_instances, rubber_cfg.instance
|
|
51
|
+
|
|
52
|
+
set :cloud, Rubber::Cloud::get_provider(rubber_env.cloud_provider || "aws", rubber_env, self)
|
|
53
|
+
|
|
54
|
+
load_roles() unless rubber_env.disable_auto_roles
|
|
55
|
+
# NOTE: for some reason Capistrano requires you to have both the public and
|
|
56
|
+
# the private key in the same folder, the public key should have the
|
|
57
|
+
# extension ".pub".
|
|
58
|
+
ssh_options[:keys] = rubber_env.cloud_providers[rubber_env.cloud_provider].key_file
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Automatically load and define capistrano roles from instance config
|
|
63
|
+
def load_roles
|
|
64
|
+
top.roles.clear
|
|
65
|
+
|
|
66
|
+
# define empty roles for all known ones so tasks don't fail if a role
|
|
67
|
+
# doesn't exist due to a filter
|
|
68
|
+
all_roles = rubber_instances.all_roles
|
|
69
|
+
all_roles += rubber_cfg.environment.known_roles
|
|
70
|
+
all_roles.uniq!
|
|
71
|
+
all_roles.each {|name| top.roles[name.to_sym] = []}
|
|
72
|
+
|
|
73
|
+
# define capistrano host => role mapping for all instances
|
|
74
|
+
rubber_instances.filtered.each do |ic|
|
|
75
|
+
ic.roles.each do |role|
|
|
76
|
+
opts = Rubber::Util::symbolize_keys(role.options)
|
|
77
|
+
msg = "Auto role: #{role.name.to_sym} => #{ic.full_name}"
|
|
78
|
+
msg << ", #{opts.inspect}" if opts.inspect.size > 0
|
|
79
|
+
logger.info msg
|
|
80
|
+
top.role role.name.to_sym, ic.full_name, opts
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Dir[File.join(File.dirname(__FILE__), 'rubber/*.rb')].each do |rubber_part|
|
|
88
|
+
load(rubber_part)
|
|
89
|
+
end
|