sml-rubber 0.9.1
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/COPYING +339 -0
- data/README +6 -0
- data/TODO +9 -0
- data/VERSION +1 -0
- data/generators/vulcanize/USAGE +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/deploy-apache.rb +45 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web/deflate.conf +10 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web/expires.conf +9 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web/headers.conf +6 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web/setenvif.conf +52 -0
- data/generators/vulcanize/templates/apache/config/rubber/role/web/vhost.conf +27 -0
- data/generators/vulcanize/templates/apache/config/rubber/rubber-apache.yml +15 -0
- data/generators/vulcanize/templates/apache/templates.yml +1 -0
- data/generators/vulcanize/templates/base/Capfile +17 -0
- data/generators/vulcanize/templates/base/config/deploy.rb +77 -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 +56 -0
- data/generators/vulcanize/templates/base/config/rubber/rubber.yml +221 -0
- data/generators/vulcanize/templates/base/lib/tasks/rubber.rake +18 -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_mysql/templates.yml +6 -0
- data/generators/vulcanize/templates/complete_passenger_mysql/templates.yml +8 -0
- data/generators/vulcanize/templates/cruise/config/rubber/deploy-cruise.rb +74 -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-default.conf +8 -0
- data/generators/vulcanize/templates/haproxy/config/rubber/role/haproxy/haproxy.conf +44 -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 +12 -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/app/mongrel_cluster.yml +12 -0
- data/generators/vulcanize/templates/mongrel/config/rubber/role/app/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 +30 -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 +178 -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 +38 -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/web/crontab +9 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web/monit-nginx.conf +9 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web/nginx.conf +133 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/index.html +23 -0
- data/generators/vulcanize/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +74 -0
- data/generators/vulcanize/templates/nginx/config/rubber/rubber-nginx.yml +33 -0
- data/generators/vulcanize/templates/nginx/templates.yml +1 -0
- data/generators/vulcanize/templates/passenger/config/rubber/deploy-passenger.rb +27 -0
- data/generators/vulcanize/templates/passenger/config/rubber/role/web/passenger.conf +8 -0
- data/generators/vulcanize/templates/passenger/config/rubber/rubber-passenger.yml +4 -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 +37 -0
- data/lib/rubber/capistrano.rb +1 -0
- data/lib/rubber/cloud.rb +13 -0
- data/lib/rubber/cloud/aws.rb +261 -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 +56 -0
- data/lib/rubber/dns/zerigo.rb +121 -0
- data/lib/rubber/environment.rb +161 -0
- data/lib/rubber/generator.rb +197 -0
- data/lib/rubber/instance.rb +113 -0
- data/lib/rubber/recipes/rubber.rb +88 -0
- data/lib/rubber/recipes/rubber/bundles.rb +28 -0
- data/lib/rubber/recipes/rubber/deploy.rb +66 -0
- data/lib/rubber/recipes/rubber/instances.rb +298 -0
- data/lib/rubber/recipes/rubber/security_groups.rb +149 -0
- data/lib/rubber/recipes/rubber/setup.rb +285 -0
- data/lib/rubber/recipes/rubber/static_ips.rb +107 -0
- data/lib/rubber/recipes/rubber/utils.rb +195 -0
- data/lib/rubber/recipes/rubber/volumes.rb +263 -0
- data/lib/rubber/tasks/rubber.rb +218 -0
- data/lib/rubber/util.rb +33 -0
- data/test/environment_test.rb +118 -0
- data/test/generator_test.rb +323 -0
- data/test/instance_test.rb +38 -0
- data/test/test_helper.rb +4 -0
- data/test/util_test.rb +16 -0
- metadata +246 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
desc <<-DESC
|
|
4
|
+
Create a new EC2 instance with the given ALIAS and ROLES
|
|
5
|
+
DESC
|
|
6
|
+
required_task :create do
|
|
7
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
8
|
+
r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
|
|
9
|
+
if r == '*'
|
|
10
|
+
instance_roles = rubber_cfg.environment.known_roles
|
|
11
|
+
instance_roles = instance_roles.collect {|role| role == "db" ? "db:primary=true" : role }
|
|
12
|
+
else
|
|
13
|
+
instance_roles = r.split(",")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ir = []
|
|
17
|
+
instance_roles.each do |r|
|
|
18
|
+
data = r.split(':');
|
|
19
|
+
role = Rubber::Configuration::RoleItem.new(data[0])
|
|
20
|
+
if data[1]
|
|
21
|
+
data[1].split(';').each do |pair|
|
|
22
|
+
p = pair.split('=')
|
|
23
|
+
val = case p[1]
|
|
24
|
+
when 'true' then true
|
|
25
|
+
when 'false' then false
|
|
26
|
+
else p[1] end
|
|
27
|
+
role.options[p[0]] = val
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# If user doesn't setup a primary db, then be nice and do it
|
|
32
|
+
if role.name == "db" && role.options["primary"] == nil && rubber_cfg.instance.for_role("db").size == 0
|
|
33
|
+
value = Capistrano::CLI.ui.ask("You do not have a primary db role, should #{instance_alias} be it [y/n]?: ")
|
|
34
|
+
role.options["primary"] = true if value =~ /^y/
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
ir << role
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
create_instance(instance_alias, ir)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc <<-DESC
|
|
44
|
+
Refresh the host data for a EC2 instance with the given ALIAS.
|
|
45
|
+
This is useful to run when rubber:create fails after instance creation
|
|
46
|
+
DESC
|
|
47
|
+
task :refresh do
|
|
48
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
49
|
+
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
50
|
+
refresh_instance(instance_alias)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc <<-DESC
|
|
54
|
+
Destroy the EC2 instance for the given ALIAS
|
|
55
|
+
DESC
|
|
56
|
+
task :destroy do
|
|
57
|
+
instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
|
|
58
|
+
ENV.delete('ROLES') # so we don't get an error if people leave ROLES in env from :create CLI
|
|
59
|
+
destroy_instance(instance_alias)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
desc <<-DESC
|
|
63
|
+
Destroy ALL the EC2 instances for the current env
|
|
64
|
+
DESC
|
|
65
|
+
task :destroy_all do
|
|
66
|
+
rubber_cfg.instance.each do |ic|
|
|
67
|
+
destroy_instance(ic.name)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
desc <<-DESC
|
|
72
|
+
List all your EC2 instances
|
|
73
|
+
DESC
|
|
74
|
+
required_task :describe do
|
|
75
|
+
results = []
|
|
76
|
+
format = "%-10s %-10s %-10s %-15s %-30s"
|
|
77
|
+
results << format % %w[InstanceID State Zone IP Alias\ (*=unknown)]
|
|
78
|
+
|
|
79
|
+
instances = cloud.describe_instances()
|
|
80
|
+
instances.each do |instance|
|
|
81
|
+
local_alias = find_alias(instance[:external_ip], instance[:id], instance[:state] == 'running')
|
|
82
|
+
results << format % [instance[:id], instance[:state], instance[:zone], instance[:external_ip] || "NoIP", local_alias || "Unknown"]
|
|
83
|
+
end
|
|
84
|
+
results.each {|r| logger.info r}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
desc <<-DESC
|
|
88
|
+
Describes the availability zones
|
|
89
|
+
DESC
|
|
90
|
+
required_task :describe_zones do
|
|
91
|
+
results = []
|
|
92
|
+
format = "%-20s %-15s"
|
|
93
|
+
results << format % %w[Name State]
|
|
94
|
+
|
|
95
|
+
zones = cloud.describe_availability_zones()
|
|
96
|
+
zones.each do |zone|
|
|
97
|
+
results << format % [zone[:name], zone[:state]]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
results.each {|r| logger.info r}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
set :print_ip_command, "ifconfig eth0 | awk 'NR==2 {print $2}' | awk -F: '{print $2}'"
|
|
105
|
+
|
|
106
|
+
# Creates a new ec2 instance with the given alias and roles
|
|
107
|
+
# Configures aliases (/etc/hosts) on local and remote machines
|
|
108
|
+
def create_instance(instance_alias, instance_roles)
|
|
109
|
+
fatal "Instance already exists: #{instance_alias}" if rubber_cfg.instance[instance_alias]
|
|
110
|
+
|
|
111
|
+
role_names = instance_roles.collect{|x| x.name}
|
|
112
|
+
env = rubber_cfg.environment.bind(role_names, instance_alias)
|
|
113
|
+
|
|
114
|
+
# We need to use security_groups during create, so create them up front
|
|
115
|
+
security_groups = env.assigned_security_groups
|
|
116
|
+
security_group_defns = env.security_groups
|
|
117
|
+
if env.auto_security_groups
|
|
118
|
+
hosts = rubber_cfg.instance.collect{|ic| ic.name } + [instance_alias]
|
|
119
|
+
roles = (rubber_cfg.instance.all_roles + role_names).uniq
|
|
120
|
+
security_groups << instance_alias
|
|
121
|
+
security_groups += role_names
|
|
122
|
+
security_groups.uniq!
|
|
123
|
+
security_group_defns = inject_auto_security_groups(security_group_defns, hosts, roles)
|
|
124
|
+
sync_security_groups(security_group_defns)
|
|
125
|
+
else
|
|
126
|
+
sync_security_groups(security_group_defns)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
ami = env.cloud_providers[env.cloud_provider].image_id
|
|
130
|
+
ami_type = env.cloud_providers[env.cloud_provider].image_type
|
|
131
|
+
availability_zone = env.availability_zone
|
|
132
|
+
logger.info "Creating instance #{ami}/#{ami_type}/#{security_groups.join(',') rescue 'Default'}/#{availability_zone || 'Default'}"
|
|
133
|
+
instance_id = cloud.create_instance(ami, ami_type, security_groups, availability_zone)
|
|
134
|
+
|
|
135
|
+
logger.info "Instance #{instance_id} created"
|
|
136
|
+
|
|
137
|
+
instance_item = Rubber::Configuration::InstanceItem.new(instance_alias, env.domain, instance_roles, instance_id)
|
|
138
|
+
rubber_cfg.instance.add(instance_item)
|
|
139
|
+
rubber_cfg.instance.save()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
print "Waiting for instance to start"
|
|
143
|
+
while true do
|
|
144
|
+
print "."
|
|
145
|
+
sleep 2
|
|
146
|
+
instance = cloud.describe_instances(instance_id).first
|
|
147
|
+
|
|
148
|
+
if instance[:state] == "running"
|
|
149
|
+
print "\n"
|
|
150
|
+
logger.info "Instance running, fetching hostname/ip data"
|
|
151
|
+
instance_item.external_host = instance[:external_host]
|
|
152
|
+
instance_item.external_ip = instance[:external_ip]
|
|
153
|
+
instance_item.internal_host = instance[:internal_host]
|
|
154
|
+
rubber_cfg.instance.save()
|
|
155
|
+
|
|
156
|
+
# setup amazon elastic ips if configured to do so
|
|
157
|
+
setup_static_ips
|
|
158
|
+
|
|
159
|
+
# Need to setup aliases so ssh doesn't give us errors when we
|
|
160
|
+
# later try? to connect to same ip but using alias
|
|
161
|
+
setup_local_aliases
|
|
162
|
+
|
|
163
|
+
# re-load the roles since we may have just defined new ones
|
|
164
|
+
load_roles() unless env.disable_auto_roles
|
|
165
|
+
|
|
166
|
+
# Connect to newly created instance and grab its internal ip
|
|
167
|
+
# so that we can update all aliases
|
|
168
|
+
|
|
169
|
+
task :_get_ip, :hosts => instance_item.external_ip do
|
|
170
|
+
instance_item.internal_ip = capture(print_ip_command).strip
|
|
171
|
+
rubber_cfg.instance.save()
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# even though instance is running, sometimes ssh hasn't started yet,
|
|
175
|
+
# so retry on connect failure
|
|
176
|
+
begin
|
|
177
|
+
_get_ip
|
|
178
|
+
rescue ConnectionError
|
|
179
|
+
sleep 2
|
|
180
|
+
logger.info "Failed to connect to #{instance_alias} (#{instance_item.external_ip}), retrying"
|
|
181
|
+
retry
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Add the aliases for this instance to all other hosts
|
|
185
|
+
setup_remote_aliases
|
|
186
|
+
setup_dns_aliases
|
|
187
|
+
|
|
188
|
+
break
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Refreshes a ec2 instance with the given alias
|
|
194
|
+
# Configures aliases (/etc/hosts) on local and remote machines
|
|
195
|
+
def refresh_instance(instance_alias)
|
|
196
|
+
instance_item = rubber_cfg.instance[instance_alias]
|
|
197
|
+
|
|
198
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
199
|
+
|
|
200
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_alias)
|
|
201
|
+
|
|
202
|
+
instance = cloud.describe_instance(instance_item.instance_id).first
|
|
203
|
+
|
|
204
|
+
if instance[:state] == "running"
|
|
205
|
+
logger.info "\nInstance running, fetching hostname/ip data"
|
|
206
|
+
instance_item.external_host = instance[:external_host]
|
|
207
|
+
instance_item.external_ip = instance[:external_ip]
|
|
208
|
+
instance_item.internal_host = instance[:internal_host]
|
|
209
|
+
|
|
210
|
+
# Need to setup aliases so ssh doesn't give us errors when we
|
|
211
|
+
# later try to connect to same ip but using alias
|
|
212
|
+
setup_local_aliases
|
|
213
|
+
|
|
214
|
+
# re-load the roles since we may have just defined new ones
|
|
215
|
+
load_roles() unless env.disable_auto_roles
|
|
216
|
+
|
|
217
|
+
# Connect to newly created instance and grab its internal ip
|
|
218
|
+
# so that we can update all aliases
|
|
219
|
+
task :_get_ip, :hosts => instance_item.external_ip do
|
|
220
|
+
instance_item.internal_ip = capture(print_ip_command).strip
|
|
221
|
+
end
|
|
222
|
+
# even though instance is running, we need to give ssh a chance
|
|
223
|
+
# to get started
|
|
224
|
+
sleep 5
|
|
225
|
+
_get_ip
|
|
226
|
+
|
|
227
|
+
# Add the aliases for this instance to all other hosts
|
|
228
|
+
setup_remote_aliases
|
|
229
|
+
setup_dns_aliases
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
rubber_cfg.instance.save()
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
# Destroys the given ec2 instance
|
|
237
|
+
def destroy_instance(instance_alias)
|
|
238
|
+
instance_item = rubber_cfg.instance[instance_alias]
|
|
239
|
+
fatal "Instance does not exist: #{instance_alias}" if ! instance_item
|
|
240
|
+
|
|
241
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
242
|
+
|
|
243
|
+
value = Capistrano::CLI.ui.ask("About to DESTROY #{instance_alias} (#{instance_item.instance_id}) in mode #{RUBBER_ENV}. Are you SURE [yes/NO]?: ")
|
|
244
|
+
fatal("Exiting", 0) if value != "yes"
|
|
245
|
+
|
|
246
|
+
if instance_item.static_ip
|
|
247
|
+
value = Capistrano::CLI.ui.ask("Instance has a static ip, do you want to release it? [y/N]?: ")
|
|
248
|
+
destroy_static_ip(instance_item.static_ip) if value =~ /^y/
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
if instance_item.volumes
|
|
252
|
+
value = Capistrano::CLI.ui.ask("Instance has persistent volumes, do you want to destroy them? [y/N]?: ")
|
|
253
|
+
if value =~ /^y/
|
|
254
|
+
instance_item.volumes.clone.each do |volume_id|
|
|
255
|
+
destroy_volume(volume_id)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
logger.info "Destroying instance alias=#{instance_alias}, instance_id=#{instance_item.instance_id}"
|
|
261
|
+
|
|
262
|
+
cloud.destroy_instance(instance_item.instance_id)
|
|
263
|
+
|
|
264
|
+
rubber_cfg.instance.remove(instance_alias)
|
|
265
|
+
rubber_cfg.instance.save()
|
|
266
|
+
|
|
267
|
+
# re-load the roles since we just removed some and setup_remote_aliases
|
|
268
|
+
# shouldn't hit removed ones
|
|
269
|
+
load_roles() unless env.disable_auto_roles
|
|
270
|
+
|
|
271
|
+
setup_aliases
|
|
272
|
+
destroy_dyndns(instance_item)
|
|
273
|
+
cleanup_known_hosts(instance_item) unless env.disable_known_hosts_cleanup
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# delete from ~/.ssh/known_hosts all lines that begin with ec2- or instance_alias
|
|
278
|
+
def cleanup_known_hosts(instance_item)
|
|
279
|
+
logger.info "Cleaning ~/.ssh/known_hosts"
|
|
280
|
+
File.open(File.expand_path('~/.ssh/known_hosts'), 'r+') do |f|
|
|
281
|
+
out = ""
|
|
282
|
+
f.each do |line|
|
|
283
|
+
line = case line
|
|
284
|
+
when /^ec2-/; ''
|
|
285
|
+
when /#{instance_item.full_name}/; ''
|
|
286
|
+
when /#{instance_item.external_host}/; ''
|
|
287
|
+
when /#{instance_item.external_ip}/; ''
|
|
288
|
+
else line;
|
|
289
|
+
end
|
|
290
|
+
out << line
|
|
291
|
+
end
|
|
292
|
+
f.pos = 0
|
|
293
|
+
f.print out
|
|
294
|
+
f.truncate(f.pos)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
desc <<-DESC
|
|
4
|
+
Sets up the network security groups
|
|
5
|
+
All defined groups will be created, and any not defined will be removed.
|
|
6
|
+
Likewise, rules within a group will get created, and those not will be removed
|
|
7
|
+
DESC
|
|
8
|
+
required_task :setup_security_groups do
|
|
9
|
+
env = rubber_cfg.environment.bind()
|
|
10
|
+
security_group_defns = env.security_groups
|
|
11
|
+
if env.auto_security_groups
|
|
12
|
+
hosts = rubber_cfg.instance.collect{|ic| ic.name }
|
|
13
|
+
roles = rubber_cfg.instance.all_roles
|
|
14
|
+
security_group_defns = inject_auto_security_groups(security_group_defns, hosts, roles)
|
|
15
|
+
sync_security_groups(security_group_defns)
|
|
16
|
+
else
|
|
17
|
+
sync_security_groups(security_group_defns)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc <<-DESC
|
|
22
|
+
Describes the network security groups
|
|
23
|
+
DESC
|
|
24
|
+
required_task :describe_security_groups do
|
|
25
|
+
groups = cloud.describe_security_groups()
|
|
26
|
+
groups.each do |group|
|
|
27
|
+
puts "#{group[:name]}, #{group[:description]}"
|
|
28
|
+
group[:permissions].each do |perm|
|
|
29
|
+
puts " protocol: #{perm[:protocol]}"
|
|
30
|
+
puts " from_port: #{perm[:from_port]}"
|
|
31
|
+
puts " to_port: #{perm[:to_port]}"
|
|
32
|
+
puts " source_groups: #{perm[:source_groups].collect {|g| g[:name]}.join(", ") }" if perm[:source_groups]
|
|
33
|
+
puts " source_ips: #{perm[:source_ips].join(", ") }" if perm[:source_ips]
|
|
34
|
+
puts "\n"
|
|
35
|
+
end if group[:permissions]
|
|
36
|
+
puts "\n"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def inject_auto_security_groups(groups, hosts, roles)
|
|
42
|
+
hosts.each do |name|
|
|
43
|
+
group_name = name
|
|
44
|
+
groups[group_name] ||= {'description' => "Rubber automatic security group for host: #{name}", 'rules' => []}
|
|
45
|
+
end
|
|
46
|
+
roles.each do |name|
|
|
47
|
+
group_name = name
|
|
48
|
+
groups[group_name] ||= {'description' => "Rubber automatic security group for role: #{name}", 'rules' => []}
|
|
49
|
+
end
|
|
50
|
+
return groups
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def sync_security_groups(groups)
|
|
54
|
+
env = rubber_cfg.environment.bind()
|
|
55
|
+
return unless groups
|
|
56
|
+
|
|
57
|
+
groups = Rubber::Util::stringify(groups)
|
|
58
|
+
group_keys = groups.keys.clone()
|
|
59
|
+
|
|
60
|
+
# For each group that does already exist in ec2
|
|
61
|
+
cloud_groups = cloud.describe_security_groups()
|
|
62
|
+
cloud_groups.each do |cloud_group|
|
|
63
|
+
group_name = cloud_group[:name]
|
|
64
|
+
if group_keys.delete(group_name)
|
|
65
|
+
# sync rules
|
|
66
|
+
logger.debug "Security Group already in ec2, syncing rules: #{group_name}"
|
|
67
|
+
group = groups[group_name]
|
|
68
|
+
rules = group['rules'].clone
|
|
69
|
+
rule_maps = []
|
|
70
|
+
|
|
71
|
+
# first collect the rule maps from the request (group/user pairs are duplicated for tcp/udp/icmp,
|
|
72
|
+
# so we need to do this up frnot and remove duplicates before checking against the local rubber rules)
|
|
73
|
+
cloud_group[:permissions].each do |rule|
|
|
74
|
+
if rule[:source_groups]
|
|
75
|
+
rule.source_groups.each do |source_group|
|
|
76
|
+
rule_map = {:source_group_name => source_group[:name], :source_group_account => source_group[:account]}
|
|
77
|
+
rule_map = Rubber::Util::stringify(rule_map)
|
|
78
|
+
rule_maps << rule_map unless rule_maps.include?(rule_map)
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
rule_map = Rubber::Util::stringify(rule)
|
|
82
|
+
rule_maps << rule_map unless rule_maps.include?(rule_map)
|
|
83
|
+
end
|
|
84
|
+
end if cloud_group[:permissions]
|
|
85
|
+
# For each rule, if it exists, do nothing, otherwise remove it as its no longer defined locally
|
|
86
|
+
rule_maps.each do |rule_map|
|
|
87
|
+
if rules.delete(rule_map)
|
|
88
|
+
# rules match, don't need to do anything
|
|
89
|
+
# logger.debug "Rule in sync: #{rule_map.inspect}"
|
|
90
|
+
else
|
|
91
|
+
# rules don't match, remove them from ec2 and re-add below
|
|
92
|
+
answer = Capistrano::CLI.ui.ask("Rule '#{rule_map.inspect}' exists in ec2, but not locally, remove from ec2? [y/N]?: ")
|
|
93
|
+
rule_map = Rubber::Util::symbolize_keys(rule_map)
|
|
94
|
+
if rule_map[:source_group_name]
|
|
95
|
+
cloud.remove_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
|
|
96
|
+
else
|
|
97
|
+
rule_map[:source_ips].each do |source_ip|
|
|
98
|
+
cloud.remove_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
|
|
99
|
+
end if rule_map[:source_ips] && answer =~ /^y/
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
rules.each do |rule_map|
|
|
105
|
+
# create non-existing rules
|
|
106
|
+
logger.debug "Missing rule, creating: #{rule_map.inspect}"
|
|
107
|
+
rule_map = Rubber::Util::symbolize_keys(rule_map)
|
|
108
|
+
if rule_map[:source_group_name]
|
|
109
|
+
cloud.add_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
|
|
110
|
+
else
|
|
111
|
+
rule_map[:source_ips].each do |source_ip|
|
|
112
|
+
cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
|
|
113
|
+
end if rule_map[:source_ips]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
# when using auto groups, get prompted too much to delete when
|
|
118
|
+
# switching between production/staging since the hosts aren't shared
|
|
119
|
+
# between the two environments
|
|
120
|
+
if env.force_security_group_cleanup || ! env.auto_security_groups
|
|
121
|
+
# delete group
|
|
122
|
+
answer = Capistrano::CLI.ui.ask("Security group '#{group_name}' exists in ec2 but not locally, remove from ec2? [y/N]: ")
|
|
123
|
+
cloud.destroy_security_group(group_name) if answer =~ /^y/
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# For each group that didnt already exist in ec2
|
|
129
|
+
group_keys.each do |group_name|
|
|
130
|
+
group = groups[group_name]
|
|
131
|
+
logger.debug "Creating new security group: #{group_name}"
|
|
132
|
+
# create each group
|
|
133
|
+
cloud.create_security_group(group_name, group['description'])
|
|
134
|
+
# create rules for group
|
|
135
|
+
group['rules'].each do |rule_map|
|
|
136
|
+
logger.debug "Creating new rule: #{rule_map.inspect}"
|
|
137
|
+
rule_map = Rubber::Util::symbolize_keys(rule_map)
|
|
138
|
+
if rule_map[:source_group_name]
|
|
139
|
+
cloud.add_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
|
|
140
|
+
else
|
|
141
|
+
rule_map[:source_ips].each do |source_ip|
|
|
142
|
+
cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
|
|
143
|
+
end if rule_map[:source_ips]
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
namespace :rubber do
|
|
2
|
+
|
|
3
|
+
desc <<-DESC
|
|
4
|
+
Bootstraps instances by setting timezone, installing packages and gems
|
|
5
|
+
DESC
|
|
6
|
+
task :bootstrap do
|
|
7
|
+
set_timezone
|
|
8
|
+
link_bash
|
|
9
|
+
install_packages
|
|
10
|
+
setup_volumes
|
|
11
|
+
add_gem_sources
|
|
12
|
+
install_gems
|
|
13
|
+
deploy.setup
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc <<-DESC
|
|
17
|
+
Sets up aliases for instance hostnames based on contents of instance.yml.
|
|
18
|
+
Generates /etc/hosts for local/remote machines and sets hostname on
|
|
19
|
+
remote instances, and sets values in dynamic dns entries
|
|
20
|
+
DESC
|
|
21
|
+
required_task :setup_aliases do
|
|
22
|
+
setup_local_aliases
|
|
23
|
+
setup_remote_aliases
|
|
24
|
+
setup_dns_aliases
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc <<-DESC
|
|
28
|
+
Sets up local aliases for instance hostnames based on contents of instance.yml.
|
|
29
|
+
Generates/etc/hosts for local machine
|
|
30
|
+
DESC
|
|
31
|
+
required_task :setup_local_aliases do
|
|
32
|
+
hosts_file = '/etc/hosts'
|
|
33
|
+
|
|
34
|
+
# Generate /etc/hosts contents for the local machine from instance config
|
|
35
|
+
env = rubber_cfg.environment.bind()
|
|
36
|
+
delim = "## rubber config #{env.domain} #{RUBBER_ENV}"
|
|
37
|
+
local_hosts = delim + "\n"
|
|
38
|
+
rubber_cfg.instance.each do |ic|
|
|
39
|
+
# don't add unqualified hostname in local hosts file since user may be
|
|
40
|
+
# managing multiple domains with same aliases
|
|
41
|
+
hosts_data = [ic.full_name, ic.external_host, ic.internal_host].join(' ')
|
|
42
|
+
local_hosts << ic.external_ip << ' ' << hosts_data << "\n"
|
|
43
|
+
end
|
|
44
|
+
local_hosts << delim << "\n"
|
|
45
|
+
|
|
46
|
+
# Write out the hosts file for this machine, use sudo
|
|
47
|
+
filtered = File.read(hosts_file).gsub(/^#{delim}.*^#{delim}\n?/m, '')
|
|
48
|
+
logger.info "Writing out aliases into local machines #{hosts_file}, sudo access needed"
|
|
49
|
+
Rubber::Util::sudo_open(hosts_file, 'w') do |f|
|
|
50
|
+
f.write(filtered)
|
|
51
|
+
f.write(local_hosts)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
desc <<-DESC
|
|
56
|
+
Sets up aliases in dynamic dns provider for instance hostnames based on contents of instance.yml.
|
|
57
|
+
DESC
|
|
58
|
+
required_task :setup_dns_aliases do
|
|
59
|
+
rubber_cfg.instance.each do |ic|
|
|
60
|
+
update_dyndns(ic)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
desc <<-DESC
|
|
65
|
+
Sets up aliases for instance hostnames based on contents of instance.yml.
|
|
66
|
+
Generates /etc/hosts for remote machines and sets hostname on remote instances
|
|
67
|
+
DESC
|
|
68
|
+
task :setup_remote_aliases do
|
|
69
|
+
hosts_file = '/etc/hosts'
|
|
70
|
+
|
|
71
|
+
# Generate /etc/hosts contents for the remote instance from instance config
|
|
72
|
+
delim = "## rubber config"
|
|
73
|
+
delim = "#{delim} #{RUBBER_ENV}"
|
|
74
|
+
remote_hosts = delim + "\n"
|
|
75
|
+
rubber_cfg.instance.each do |ic|
|
|
76
|
+
hosts_data = [ic.name, ic.full_name, ic.external_host, ic.internal_host].join(' ')
|
|
77
|
+
remote_hosts << ic.internal_ip << ' ' << hosts_data << "\n"
|
|
78
|
+
end
|
|
79
|
+
remote_hosts << delim << "\n"
|
|
80
|
+
if rubber_cfg.instance.size > 0
|
|
81
|
+
# write out the hosts file for the remote instances
|
|
82
|
+
# NOTE that we use "capture" to get the existing hosts
|
|
83
|
+
# file, which only grabs the hosts file from the first host
|
|
84
|
+
filtered = (capture "cat #{hosts_file}").gsub(/^#{delim}.*^#{delim}\n?/m, '')
|
|
85
|
+
filtered = filtered + remote_hosts
|
|
86
|
+
# Put the generated hosts back on remote instance
|
|
87
|
+
put filtered, hosts_file
|
|
88
|
+
|
|
89
|
+
# Setup hostname on instance so shell, etcs have nice display
|
|
90
|
+
sudo "echo $CAPISTRANO:HOST$ > /etc/hostname && hostname $CAPISTRANO:HOST$"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# TODO
|
|
94
|
+
# /etc/resolv.conf to add search domain
|
|
95
|
+
# ~/.ssh/options to setup user/host/key aliases
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
desc <<-DESC
|
|
99
|
+
Update to the newest versions of all packages/gems.
|
|
100
|
+
DESC
|
|
101
|
+
task :update do
|
|
102
|
+
upgrade_packages
|
|
103
|
+
update_gems
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
desc <<-DESC
|
|
107
|
+
Upgrade to the newest versions of all Ubuntu packages.
|
|
108
|
+
DESC
|
|
109
|
+
task :upgrade_packages do
|
|
110
|
+
package_helper(true)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
desc <<-DESC
|
|
114
|
+
Upgrade to the newest versions of all rubygems.
|
|
115
|
+
DESC
|
|
116
|
+
task :update_gems do
|
|
117
|
+
gem_helper(true)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
desc <<-DESC
|
|
121
|
+
Install extra packages and gems.
|
|
122
|
+
DESC
|
|
123
|
+
task :install do
|
|
124
|
+
install_packages
|
|
125
|
+
install_gems
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
desc <<-DESC
|
|
129
|
+
Install extra Ubuntu packages. Set 'packages' in rubber.yml to \
|
|
130
|
+
be an array of strings.
|
|
131
|
+
DESC
|
|
132
|
+
task :install_packages do
|
|
133
|
+
package_helper(false)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
desc <<-DESC
|
|
137
|
+
Install extra ruby gems. Set 'gems' in rubber.yml to \
|
|
138
|
+
be an array of strings.
|
|
139
|
+
DESC
|
|
140
|
+
task :install_gems do
|
|
141
|
+
gem_helper(false)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
desc <<-DESC
|
|
145
|
+
Add extra ruby gems sources. Set 'gemsources' in rubber.yml to \
|
|
146
|
+
be an array of URI strings.
|
|
147
|
+
DESC
|
|
148
|
+
task :add_gem_sources do
|
|
149
|
+
env = rubber_cfg.environment.bind()
|
|
150
|
+
if env.gemsources
|
|
151
|
+
env.gemsources.each { |source| sudo "gem sources -a #{source}"}
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
desc <<-DESC
|
|
156
|
+
The ubuntu has /bin/sh linking to dash instead of bash, fix this
|
|
157
|
+
You can override this task if you don't want this to happen
|
|
158
|
+
DESC
|
|
159
|
+
task :link_bash do
|
|
160
|
+
sudo("ln -sf /bin/bash /bin/sh")
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
desc <<-DESC
|
|
164
|
+
Set the timezone using the value of the variable named timezone. \
|
|
165
|
+
Valid options for timezone can be determined by the contents of \
|
|
166
|
+
/usr/share/zoneinfo, which can be seen here: \
|
|
167
|
+
http://packages.ubuntu.com/cgi-bin/search_contents.pl?searchmode=filelist&word=tzdata&version=gutsy&arch=all&page=1&number=all \
|
|
168
|
+
Remove 'usr/share/zoneinfo/' from the filename, and use the last \
|
|
169
|
+
directory and file as the value. For example 'Africa/Abidjan' or \
|
|
170
|
+
'posix/GMT' or 'Canada/Eastern'.
|
|
171
|
+
DESC
|
|
172
|
+
task :set_timezone do
|
|
173
|
+
opts = get_host_options('timezone')
|
|
174
|
+
sudo "bash -c 'echo $CAPISTRANO:VAR$ > /etc/timezone'", opts
|
|
175
|
+
sudo "cp /usr/share/zoneinfo/$CAPISTRANO:VAR$ /etc/localtime", opts
|
|
176
|
+
# restart syslog so that times match timezone
|
|
177
|
+
sudo "/etc/init.d/sysklogd restart"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def update_dyndns(instance_item)
|
|
181
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
182
|
+
if env.dns_provider
|
|
183
|
+
provider = Rubber::Dns::get_provider(env.dns_provider, env)
|
|
184
|
+
provider.update(instance_item.name, instance_item.external_ip)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def destroy_dyndns(instance_item)
|
|
189
|
+
env = rubber_cfg.environment.bind(instance_item.role_names, instance_item.name)
|
|
190
|
+
if env.dns_provider
|
|
191
|
+
provider = Rubber::Dns::get_provider(env.dns_provider, env)
|
|
192
|
+
provider.destroy(instance_item.name)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def package_helper(upgrade=false)
|
|
197
|
+
opts = get_host_options('packages') do |pkg_list|
|
|
198
|
+
expanded_pkg_list = []
|
|
199
|
+
pkg_list.each do |pkg_spec|
|
|
200
|
+
if pkg_spec.is_a?(Array)
|
|
201
|
+
expanded_pkg_list << "#{pkg_spec[0]}=#{pkg_spec[1]}"
|
|
202
|
+
else
|
|
203
|
+
expanded_pkg_list << pkg_spec
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
expanded_pkg_list.join(' ')
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
sudo "apt-get -q update"
|
|
210
|
+
if upgrade
|
|
211
|
+
sudo "/bin/sh -c 'export DEBIAN_FRONTEND=noninteractive; apt-get -q -y --force-yes dist-upgrade'"
|
|
212
|
+
else
|
|
213
|
+
sudo "/bin/sh -c 'export DEBIAN_FRONTEND=noninteractive; apt-get -q -y --force-yes install $CAPISTRANO:VAR$'", opts
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def custom_package(url_base, name, ver, install_test)
|
|
218
|
+
rubber.run_script "install_#{name}", <<-ENDSCRIPT
|
|
219
|
+
if [[ #{install_test} ]]; then
|
|
220
|
+
arch=`uname -m`
|
|
221
|
+
if [ "$arch" = "x86_64" ]; then
|
|
222
|
+
src="#{url_base}/#{name}_#{ver}_amd64.deb"
|
|
223
|
+
else
|
|
224
|
+
src="#{url_base}/#{name}_#{ver}_i386.deb"
|
|
225
|
+
fi
|
|
226
|
+
src_file="${src##*/}"
|
|
227
|
+
wget -qP /tmp ${src}
|
|
228
|
+
dpkg -i /tmp/${src_file}
|
|
229
|
+
fi
|
|
230
|
+
ENDSCRIPT
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def handle_gem_prompt(ch, data, str)
|
|
234
|
+
ch[:data] ||= ""
|
|
235
|
+
ch[:data] << data
|
|
236
|
+
if data =~ />\s*$/
|
|
237
|
+
logger.info data
|
|
238
|
+
logger.info "The gem command is asking for a number:"
|
|
239
|
+
choice = STDIN.gets
|
|
240
|
+
ch.send_data(choice)
|
|
241
|
+
else
|
|
242
|
+
logger.info data
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Helper for installing gems,allows one to respond to prompts
|
|
247
|
+
def gem_helper(update=false)
|
|
248
|
+
cmd = update ? "update" : "install"
|
|
249
|
+
|
|
250
|
+
# when versions are provided for a gem, rubygems fails unless versions ae provided for all gems
|
|
251
|
+
#
|
|
252
|
+
# first do the gems that the user specified versions for
|
|
253
|
+
opts = get_host_options('gems') do |gem_list|
|
|
254
|
+
expanded_gem_list = []
|
|
255
|
+
gem_list.each do |gem_spec|
|
|
256
|
+
if gem_spec.is_a?(Array)
|
|
257
|
+
expanded_gem_list << "#{gem_spec[0]} -v #{gem_spec[1]}"
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
expanded_gem_list.join(' ')
|
|
261
|
+
end
|
|
262
|
+
if opts.size > 0
|
|
263
|
+
sudo "gem #{cmd} $CAPISTRANO:VAR$ --no-rdoc --no-ri", opts do |ch, str, data|
|
|
264
|
+
handle_gem_prompt(ch, data, str)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# then do the gems without versions
|
|
269
|
+
opts = get_host_options('gems') do |gem_list|
|
|
270
|
+
expanded_gem_list = []
|
|
271
|
+
gem_list.each do |gem_spec|
|
|
272
|
+
if ! gem_spec.is_a?(Array)
|
|
273
|
+
expanded_gem_list << gem_spec
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
expanded_gem_list.join(' ')
|
|
277
|
+
end
|
|
278
|
+
if opts.size > 0
|
|
279
|
+
sudo "gem #{cmd} $CAPISTRANO:VAR$ --no-rdoc --no-ri", opts do |ch, str, data|
|
|
280
|
+
handle_gem_prompt(ch, data, str)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
end
|