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,279 @@
1
+ require 'fileutils'
2
+ require 'date'
3
+ require 'time'
4
+ require 'aws/s3'
5
+ require 'rubber'
6
+
7
+ namespace :rubber do
8
+
9
+ def rubber_env()
10
+ Rubber::Configuration.rubber_env
11
+ end
12
+
13
+ def rubber_instances()
14
+ Rubber::Configuration.rubber_instances
15
+ end
16
+
17
+ def cloud_provider
18
+ rubber_env.cloud_providers[rubber_env.cloud_provider]
19
+ end
20
+
21
+ def init_s3()
22
+ AWS::S3::Base.establish_connection!(:access_key_id => cloud_provider.access_key, :secret_access_key => cloud_provider.secret_access_key)
23
+ end
24
+
25
+ desc "Generate system config files by transforming the files in the config tree"
26
+ task :config do
27
+ cfg = Rubber::Configuration.get_configuration(RUBBER_ENV)
28
+ instance_alias = cfg.environment.current_host
29
+ instance = cfg.instance[instance_alias]
30
+ if instance
31
+ roles = instance.role_names
32
+ env = cfg.environment.bind(roles, instance_alias)
33
+ gen = Rubber::Configuration::Generator.new("#{RUBBER_ROOT}/config/rubber", roles, instance_alias)
34
+ elsif RUBBER_ENV == 'development'
35
+ roles = cfg.environment.known_roles
36
+ role_items = roles.collect do |r|
37
+ Rubber::Configuration::RoleItem.new(r, r == "db" ? {'primary' => true} : {})
38
+ end
39
+ env = cfg.environment.bind(roles, instance_alias)
40
+ domain = env.domain
41
+ instance = Rubber::Configuration::InstanceItem.new(instance_alias, domain, role_items, 'dummyid', ['dummygroup'])
42
+ instance.external_host = instance.full_name
43
+ instance.external_ip = "127.0.0.1"
44
+ instance.internal_host = instance.full_name
45
+ instance.internal_ip = "127.0.0.1"
46
+ cfg.instance.add(instance)
47
+ gen = Rubber::Configuration::Generator.new("#{RUBBER_ROOT}/config/rubber", roles, instance_alias)
48
+ gen.fake_root ="#{RUBBER_ROOT}/tmp/rubber"
49
+ else
50
+ puts "Instance not found for host: #{instance_alias}"
51
+ exit 1
52
+ end
53
+
54
+ if ENV['NO_POST']
55
+ gen.no_post = true
56
+ end
57
+ if ENV['FILE']
58
+ gen.file_pattern = ENV['FILE']
59
+ end
60
+ if ENV['FORCE']
61
+ gen.force = true
62
+ end
63
+ gen.stop_on_error_cmd = env.stop_on_error_cmd
64
+ gen.run
65
+
66
+ end
67
+
68
+ desc <<-DESC
69
+ Rotate rails app server logfiles. Should be run right after midnight.
70
+ The following arguments affect behavior:
71
+ LOG_DIR (required): Directory where log files are located
72
+ LOG_FILE (*.log): File pattern to match to find logs to rotate
73
+ LOG_AGE (7): Delete rotated logs older than this many days in the past
74
+ DESC
75
+ task :rotate_logs do
76
+ log_src_dir = get_env('LOG_DIR', true)
77
+ log_file_glob = get_env('LOG_FILES') || "*.log"
78
+ log_file_age = (get_env('LOG_AGE') || 7).to_i
79
+
80
+ rotated_date = (Date.today - 1).strftime('%Y%m%d')
81
+ puts "Rotating logfiles located at: #{log_src_dir}/#{log_file_glob}"
82
+ Dir["#{log_src_dir}/#{log_file_glob}"].each do |logfile|
83
+ rotated_file = "#{logfile}.#{rotated_date}"
84
+ if File.exist?(rotated_file)
85
+ rotated_file += "_#{Time.now.to_i}"
86
+ end
87
+ FileUtils.cp(logfile, rotated_file)
88
+ File.truncate logfile, 0
89
+ end
90
+
91
+ tdate = Date.today - log_file_age
92
+ threshold = Time.local(tdate.year, tdate.month, tdate.day)
93
+ puts "Cleaning rotated log files older than #{log_file_age} days"
94
+ Dir["#{log_src_dir}/#{log_file_glob}.[0-9]*"].each do |logfile|
95
+ if File.mtime(logfile) < threshold
96
+ FileUtils.rm_f(logfile)
97
+ end
98
+ end
99
+ end
100
+
101
+
102
+ desc <<-DESC
103
+ Backup database to given backup directory
104
+ The following arguments affect behavior:
105
+ BACKUP_DIR (required): Directory where backups will be stored
106
+ BACKUP_NAME (required): What to name the backup
107
+ BACKUP_CMD (required): Command used to backup
108
+ BACKUP_AGE (3): Delete rotated logs older than this many days in the past
109
+ DESC
110
+ task :backup do
111
+ dir = get_env('BACKUP_DIR', true)
112
+ name = get_env('BACKUP_NAME', true)
113
+ cmd = get_env('BACKUP_CMD', true)
114
+ age = (get_env('BACKUP_AGE') || 3).to_i
115
+
116
+ time_stamp = Time.now.strftime("%Y-%m-%d_%H-%M")
117
+ FileUtils.mkdir_p(dir)
118
+
119
+ backup_cmd = cmd.gsub(/%([^%]+)%/, '#{\1}')
120
+ backup_cmd = eval('%Q{' + backup_cmd + '}')
121
+
122
+ puts "Backing up with command:"
123
+ sh backup_cmd
124
+ puts "Backup created"
125
+
126
+ s3_prefix = "#{name}/"
127
+ backup_bucket = cloud_provider.backup_bucket
128
+ if backup_bucket
129
+ init_s3
130
+ unless AWS::S3::Bucket.list.find { |b| b.name == backup_bucket }
131
+ AWS::S3::Bucket.create(backup_bucket)
132
+ end
133
+ newest = Dir.entries(dir).grep(/^[^.]/).sort_by {|f| File.mtime(File.join(dir,f))}.last
134
+ dest = "#{s3_prefix}#{newest}"
135
+ puts "Saving backup to S3: #{backup_bucket}:#{dest}"
136
+ AWS::S3::S3Object.store(dest, open(File.join(dir, newest)), backup_bucket)
137
+ end
138
+
139
+ tdate = Date.today - age
140
+ threshold = Time.local(tdate.year, tdate.month, tdate.day)
141
+ puts "Cleaning backups older than #{age} days"
142
+ Dir["#{dir}/*"].each do |file|
143
+ if File.mtime(file) < threshold
144
+ puts "Deleting #{file}"
145
+ FileUtils.rm_f(file)
146
+ end
147
+ end
148
+
149
+ if backup_bucket
150
+ puts "Cleaning S3 backups older than #{age} days from: #{backup_bucket}:#{s3_prefix}"
151
+ AWS::S3::Bucket.objects(backup_bucket, :prefix => s3_prefix).clone.each do |obj|
152
+ if Time.parse(obj.about["last-modified"]) < threshold
153
+ puts "Deleting #{obj.key}"
154
+ obj.delete
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ desc <<-DESC
161
+ Backup database to given backup directory
162
+ The following arguments affect behavior:
163
+ BACKUP_DIR (required): Directory where db backups will be stored
164
+ BACKUP_AGE (3): Delete rotated logs older than this many days in the past
165
+ DBUSER (required) User to connect to the db as
166
+ DBPASS (optional): Pass to connect to the db with
167
+ DBHOST (required): Host where the db is
168
+ DBNAME (required): Database name to backup
169
+ DESC
170
+ task :backup_db do
171
+ dir = get_env('BACKUP_DIR', true)
172
+ age = (get_env('BACKUP_AGE') || 3).to_i
173
+ time_stamp = Time.now.strftime("%Y-%m-%d_%H-%M")
174
+ backup_file = "#{dir}/#{RUBBER_ENV}_dump_#{time_stamp}.sql.gz"
175
+ FileUtils.mkdir_p(File.dirname(backup_file))
176
+
177
+ user = get_env('DBUSER', true)
178
+ pass = get_env('DBPASS')
179
+ pass = nil if pass.strip.size == 0
180
+ host = get_env('DBHOST', true)
181
+ name = get_env('DBNAME', true)
182
+
183
+ raise "No db_backup_cmd defined in rubber.yml, cannot backup!" unless rubber_env.db_backup_cmd
184
+ db_backup_cmd = rubber_env.db_backup_cmd.gsub(/%([^%]+)%/, '#{\1}')
185
+ db_backup_cmd = eval('%Q{' + db_backup_cmd + '}')
186
+
187
+ puts "Backing up database with command:"
188
+ sh db_backup_cmd
189
+ puts "Created backup: #{backup_file}"
190
+
191
+ s3_prefix = "db/"
192
+ backup_bucket = cloud_provider.backup_bucket
193
+ if backup_bucket
194
+ init_s3
195
+ unless AWS::S3::Bucket.list.find { |b| b.name == backup_bucket }
196
+ AWS::S3::Bucket.create(backup_bucket)
197
+ end
198
+ dest = "#{s3_prefix}#{File.basename(backup_file)}"
199
+ puts "Saving db backup to S3: #{backup_bucket}:#{dest}"
200
+ AWS::S3::S3Object.store(dest, open(backup_file), backup_bucket)
201
+ end
202
+
203
+ tdate = Date.today - age
204
+ threshold = Time.local(tdate.year, tdate.month, tdate.day)
205
+ puts "Cleaning backups older than #{age} days"
206
+ Dir["#{dir}/*"].each do |file|
207
+ if File.mtime(file) < threshold
208
+ puts "Deleting #{file}"
209
+ FileUtils.rm_f(file)
210
+ end
211
+ end
212
+
213
+ if backup_bucket
214
+ puts "Cleaning S3 backups older than #{age} days from: #{backup_bucket}:#{s3_prefix}"
215
+ AWS::S3::Bucket.objects(backup_bucket, :prefix => s3_prefix).clone.each do |obj|
216
+ if Time.parse(obj.about["last-modified"]) < threshold
217
+ puts "Deleting #{obj.key}"
218
+ obj.delete
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ desc <<-DESC
225
+ Restores a database backup from s3.
226
+ This tries to find the last backup made or the s3 object identified by the
227
+ key FILENAME
228
+ The following arguments affect behavior:
229
+ FILENAME (optional): key of S3 object to use
230
+ DBUSER (required) User to connect to the db as
231
+ DBPASS (optional): Pass to connect to the db with
232
+ DBHOST (required): Host where the db is
233
+ DBNAME (required): Database name to backup
234
+ DESC
235
+ task :restore_db_s3 do
236
+ file = get_env('FILENAME')
237
+ user = get_env('DBUSER', true)
238
+ pass = get_env('DBPASS')
239
+ pass = nil if pass && pass.strip.size == 0
240
+ host = get_env('DBHOST', true)
241
+ name = get_env('DBNAME', true)
242
+
243
+ raise "No db_restore_cmd defined in rubber.yml" unless rubber_env.db_restore_cmd
244
+ db_restore_cmd = rubber_env.db_restore_cmd.gsub(/%([^%]+)%/, '#{\1}')
245
+ db_restore_cmd = eval('%Q{' + db_restore_cmd + '}')
246
+
247
+ # try to fetch a matching file from s3 (if backup_bucket given)
248
+ backup_bucket = cloud_provider.backup_bucket
249
+ raise "No backup_bucket defined in rubber.yml" unless backup_bucket
250
+ if (init_s3 &&
251
+ AWS::S3::Bucket.list.find { |b| b.name == backup_bucket })
252
+ s3objects = AWS::S3::Bucket.find(backup_bucket,
253
+ :prefix => 'db/')
254
+ if file
255
+ puts "trying to fetch #{file} from s3"
256
+ data = s3objects.detect { |o| file == o.key }
257
+ else
258
+ puts "trying to fetch last modified s3 backup"
259
+ data = s3objects.max {|a,b| a.about["last-modified"] <=> b.about["last-modified"] }
260
+ end
261
+ end
262
+ raise "could not access backup file via s3" unless data
263
+
264
+ puts "piping restore data to command [#{db_restore_cmd}]"
265
+ IO.popen(db_restore_cmd, mode='w') do |p|
266
+ data.value do |segment|
267
+ p.write segment
268
+ end
269
+ end
270
+
271
+ end
272
+
273
+ def get_env(name, required=false)
274
+ value = ENV[name]
275
+ raise("#{name} is required, pass using environment") if required && ! value
276
+ return value
277
+ end
278
+
279
+ end
@@ -0,0 +1,37 @@
1
+
2
+
3
+ module Rubber
4
+ module Util
5
+
6
+ def self.symbolize_keys(map)
7
+ map.inject({}) do |options, (key, value)|
8
+ options[key.to_sym || key] = value
9
+ options
10
+ end
11
+ end
12
+
13
+ def self.stringify(val)
14
+ case val
15
+ when String
16
+ val
17
+ when Hash
18
+ val.inject({}) {|h, a| h[stringify(a[0])] = stringify(a[1]); h}
19
+ when Enumerable
20
+ val.collect {|v| stringify(v)}
21
+ else
22
+ val.to_s
23
+ end
24
+
25
+ end
26
+
27
+ # Opens the file for writing by root
28
+ def self.sudo_open(path, perms, &block)
29
+ open("|sudo tee #{path} > /dev/null", perms, &block)
30
+ end
31
+
32
+ def self.is_rails?
33
+ File.exist?(File.join(RUBBER_ROOT, 'config', 'environment.rb'))
34
+ end
35
+
36
+ end
37
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ # this file just makes it easy to refer to rubber config
2
+ # variables in your apps's config'
3
+ #
4
+
5
+ require "rubber"
6
+ Rubber::initialize(RAILS_ROOT, RAILS_ENV)
7
+
8
+ ::RUBBER_CONFIG = Rubber::Configuration.rubber_env
9
+ ::RUBBER_INSTANCES = Rubber::Configuration.rubber_instances
@@ -0,0 +1,133 @@
1
+ require 'test/unit'
2
+ require 'tempfile'
3
+ require 'test_helper'
4
+
5
+ class EnvironmentTest < Test::Unit::TestCase
6
+ include Rubber::Configuration
7
+
8
+ def test_known_roles
9
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/basic")
10
+ assert_equal ['role1', 'role2'], env.known_roles, "list of know roles not correct"
11
+ end
12
+
13
+ def test_env
14
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/basic")
15
+ e = env.bind()
16
+ assert_equal 'val1', e['var1'], 'env not retrieving right val'
17
+ assert_equal 'val2', e['var2'], 'env not retrieving right val'
18
+ assert_equal 'val1', e.var1, 'env not retrieving right val for method missing'
19
+ assert_equal 'val2', e.var2, 'env not retrieving right val for method missing'
20
+
21
+ assert_equal 'val3', e.var3, 'env not retrieving right val for config in supplemental file'
22
+
23
+ e = env.bind('role1', 'nohost')
24
+ assert_equal 'val1', e['var1'], 'env not retrieving right val'
25
+ assert_equal 'role1val2', e['var2'], 'env not retrieving right val'
26
+ assert_equal 'val1', e.var1, 'env not retrieving right val for method missing'
27
+ assert_equal 'role1val2', e.var2, 'env not retrieving right val for method missing'
28
+
29
+ e = env.bind('role1', 'host1')
30
+ assert_equal 'val1', e['var1'], 'env not retrieving right val'
31
+ assert_equal 'host1val2', e['var2'], 'env not retrieving right val'
32
+ assert_equal 'val1', e.var1, 'env not retrieving right val for method missing'
33
+ assert_equal 'host1val2', e.var2, 'env not retrieving right val for method missing'
34
+
35
+ e = env.bind('norole', 'host1')
36
+ assert_equal 'val1', e['var1'], 'env not retrieving right val'
37
+ assert_equal 'host1val2', e['var2'], 'env not retrieving right val'
38
+ assert_equal 'val1', e.var1, 'env not retrieving right val for method missing'
39
+ assert_equal 'host1val2', e.var2, 'env not retrieving right val for method missing'
40
+ end
41
+
42
+ def test_combine
43
+ env = Rubber::Configuration::Environment
44
+ assert_equal "new", env.combine("old", "new"), "Last should win for scalar combine"
45
+ assert_equal 5, env.combine(1, 5), "Last should win for scalar combine"
46
+ assert_equal [1, 2, 3, 4], env.combine([1, 2, 3], [3, 4]), "Arrays should be unioned when combined"
47
+ assert_equal({1 => "1", 2 => "2", 3 => "3", 4 => "4"}, env.combine({1 => "1", 2 => "2"}, {3 => "3", 4 => "4"}), "Maps should be unioned when combined")
48
+ assert_equal({1 => "2"}, env.combine({1 => "1"}, {1 => "2"}), "Last should win for scalars in maps when combined")
49
+ assert_equal({1 => {1 => "1", 2 => "2"}}, env.combine({1 => {1 => "1"}}, {1 => {2 => "2"}}), "Maps should be unioned recursively when combined")
50
+ end
51
+
52
+ def test_expansion
53
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/expansion")
54
+ e = env.bind()
55
+ assert_equal 'val1', e['var1']
56
+ assert_equal 'val2', e['var2']
57
+ assert_equal 'val1', e['var3']
58
+ assert_equal '4 is val2', e['var4']
59
+ assert_equal 'val1', e['var5']
60
+ assert_equal %w[lv1 lv2 val1], e['list1']
61
+ expected = {'mk1' => 'mv1', 'mk2' => 'mv2', 'mk3' => 'val2'}
62
+ e.map1.each do |k, v|
63
+ assert_equal expected[k], v
64
+ end
65
+
66
+ e = env.bind('role1', 'nohost')
67
+ assert_equal 'role1val1', e['var1']
68
+ assert_equal 'role1val1', e['var3']
69
+ assert_equal %w[lv1 lv2 role1val1 role1lv1 role1val2], e['list1']
70
+
71
+ e = env.bind('role1', 'host1')
72
+ assert_equal 'host1val1', e['var1']
73
+ assert_equal 'host1val1', e['var3']
74
+ assert_equal %w[lv1 lv2 host1val1 role1lv1 host1val2 host1lv1], e['list1'] # lists are additive
75
+
76
+ e = env.bind('norole', 'host1')
77
+ assert_equal 'host1val1', e['var1']
78
+ assert_equal 'host1val1', e['var3']
79
+ assert_equal %w[lv1 lv2 host1val1 host1lv1 host1val2], e['list1']
80
+ end
81
+
82
+ def test_bool_expansion
83
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/expansion")
84
+ e = env.bind()
85
+ assert_equal true, e['truevar']
86
+ assert_equal false, e['falsevar']
87
+ assert_equal true, e['truevar_exp']
88
+ assert 'true' != e['truevar_exp']
89
+ assert_equal false, e['falsevar_exp']
90
+ assert 'false' != e['falsevar_exp']
91
+ assert_equal 'true thing', e['faketruevar_exp']
92
+ end
93
+
94
+ def test_secret_env
95
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/basic")
96
+ e = env.bind()
97
+ assert_nil e['rubber_secret'], 'env should not have secret set'
98
+
99
+ fixture_dir = File.expand_path("#{File.dirname(__FILE__)}/fixtures/secret")
100
+ env = Rubber::Configuration::Environment.new(fixture_dir)
101
+ e = env.bind()
102
+ assert_equal "#{fixture_dir}/secret.yml", e['rubber_secret'], 'env should have secret set'
103
+ assert_equal "secret_val", e['secret_key'], 'env should have gotten setting from secret file'
104
+ end
105
+
106
+ def test_nested_ref
107
+ env = Rubber::Configuration::Environment.new("#{File.dirname(__FILE__)}/fixtures/nested")
108
+ e = env.bind()
109
+ assert_equal 'val1', e.var1, 'env not retrieving right val'
110
+ assert_equal 'val3', e.var2.var3, 'env not retrieving right val'
111
+ assert_equal({'var5' => 'val5'}, e.var2.var4, 'env not retrieving right val')
112
+ assert_equal ['val6a', 'val6b'], e.var2.var6, 'env not retrieving right val'
113
+ assert_equal 'val1', e.var2.var7, 'env not retrieving right val'
114
+ assert_equal 'val3', e.var2.var8, 'env not retrieving right val'
115
+ assert_equal 'val5', e.var2.var9, 'env not retrieving right val'
116
+ end
117
+
118
+ def test_instances_in_expansion
119
+ instance = InstanceItem.new('host1', 'domain.com', [RoleItem.new('role1')], '')
120
+ instance.external_ip = "1.2.3.4"
121
+ instances = Instance.new(Tempfile.new('testforinstanceexpansion').path)
122
+ instances.add(instance)
123
+
124
+ File.expects(:exist?).returns(true)
125
+ YAML.expects(:load_file).returns({'var1' =>'"#{rubber_instances.for_role("role1").first.external_ip}"'})
126
+ Rubber::Configuration.expects(:rubber_instances).returns(instances)
127
+ env = Rubber::Configuration::Environment.new(nil)
128
+ e = env.bind()
129
+
130
+ assert_equal "\"1.2.3.4\"", e['var1']
131
+ end
132
+
133
+ end