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.
- data/CHANGELOG +146 -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 +66 -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 +34 -0
- data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +6 -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 +17 -0
- data/generators/vulcanize/templates/base/config/rubber/common/monit-postfix.conf +8 -0
- data/generators/vulcanize/templates/base/config/rubber/common/rubber.profile +14 -0
- data/generators/vulcanize/templates/base/config/rubber/deploy-setup.rb +84 -0
- data/generators/vulcanize/templates/base/config/rubber/rubber-dns.yml +79 -0
- data/generators/vulcanize/templates/base/config/rubber/rubber.yml +227 -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 +21 -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/jetty/config/rubber/deploy-jetty.rb +59 -0
- data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/jetty.sh +589 -0
- data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/jetty.xml +199 -0
- data/generators/vulcanize/templates/jetty/config/rubber/role/jetty/monit-jetty.conf +9 -0
- data/generators/vulcanize/templates/jetty/config/rubber/rubber-jetty.yml +10 -0
- data/generators/vulcanize/templates/jetty/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/common/munin-plugins.conf +9 -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-memory.conf +34 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/passenger/munin-passenger-sudoers.conf +7 -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 +15 -0
- data/generators/vulcanize/templates/passenger/templates.yml +3 -0
- data/generators/vulcanize/templates/redis/config/rubber/deploy-redis.rb +36 -0
- data/generators/vulcanize/templates/redis/config/rubber/role/redis/crontab +8 -0
- data/generators/vulcanize/templates/redis/config/rubber/role/redis/monit-redis.conf +9 -0
- data/generators/vulcanize/templates/redis/config/rubber/role/redis/redis.conf +141 -0
- data/generators/vulcanize/templates/redis/config/rubber/rubber-redis.yml +4 -0
- data/generators/vulcanize/templates/redis/templates.yml +1 -0
- data/generators/vulcanize/templates/resque/config/rubber/deploy-resque-worker-default.rb +38 -0
- data/generators/vulcanize/templates/resque/config/rubber/deploy-resque.rb +39 -0
- data/generators/vulcanize/templates/resque/config/rubber/role/resque_worker_default/monit-resque_worker_default.conf +19 -0
- data/generators/vulcanize/templates/resque/config/rubber/rubber-resque.yml +10 -0
- data/generators/vulcanize/templates/resque/templates.yml +3 -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 +334 -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 +84 -0
- data/lib/rubber/dns/dyndns.rb +78 -0
- data/lib/rubber/dns/nettica.rb +117 -0
- data/lib/rubber/dns/zerigo.rb +174 -0
- data/lib/rubber/environment.rb +169 -0
- data/lib/rubber/generator.rb +197 -0
- data/lib/rubber/instance.rb +166 -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 +393 -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 +457 -0
- data/lib/rubber/recipes/rubber/spot_requests.rb +17 -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 +279 -0
- data/lib/rubber/util.rb +37 -0
- data/rails/init.rb +9 -0
- data/test/environment_test.rb +133 -0
- data/test/generator_test.rb +323 -0
- data/test/instance_test.rb +93 -0
- data/test/test_helper.rb +8 -0
- data/test/util_test.rb +16 -0
- 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
|
data/lib/rubber/util.rb
ADDED
|
@@ -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
|