rubber 2.0.8 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/.travis.yml +7 -3
  2. data/CHANGELOG +28 -0
  3. data/README.md +1 -1
  4. data/lib/rubber/cloud/fog.rb +12 -2
  5. data/lib/rubber/commands/config.rb +1 -1
  6. data/lib/rubber/dns/aws.rb +1 -1
  7. data/lib/rubber/dns/nettica.rb +1 -1
  8. data/lib/rubber/recipes/rubber/instances.rb +4 -4
  9. data/lib/rubber/recipes/rubber/security_groups.rb +37 -13
  10. data/lib/rubber/recipes/rubber/volumes.rb +2 -0
  11. data/lib/rubber/util.rb +1 -1
  12. data/lib/rubber/version.rb +1 -1
  13. data/rubber.gemspec +1 -1
  14. data/templates/base/config/rubber/rubber.yml +14 -0
  15. data/templates/complete_unicorn_nginx/config/rubber/role/haproxy/haproxy-unicorn.conf +21 -0
  16. data/templates/complete_unicorn_nginx/config/rubber/rubber-complete.yml +39 -0
  17. data/templates/complete_unicorn_nginx/templates.rb +8 -0
  18. data/templates/complete_unicorn_nginx/templates.yml +9 -0
  19. data/templates/complete_unicorn_nginx_mysql/templates.yml +4 -0
  20. data/templates/complete_unicorn_nginx_postgresql/templates.yml +4 -0
  21. data/templates/monit/config/rubber/role/unicorn/monit-unicorn.conf +7 -0
  22. data/templates/nginx/config/rubber/role/web_tools/nginx-tools.conf +41 -0
  23. data/templates/nginx/config/rubber/role/web_tools/tools-index.html +18 -16
  24. data/templates/passenger_nginx/config/rubber/role/web_tools/nginx-tools.conf +41 -0
  25. data/templates/passenger_nginx/config/rubber/role/web_tools/tools-index.html +18 -20
  26. data/templates/postgresql/config/rubber/deploy-postgresql.rb +3 -4
  27. data/templates/redis/config/rubber/rubber-redis.yml +1 -1
  28. data/templates/resque/templates.yml +2 -1
  29. data/templates/unicorn/config/rubber/role/unicorn/unicorn-upstart.conf +13 -0
  30. data/templates/unicorn/config/rubber/role/unicorn/unicorn.rb +8 -0
  31. data/templates/zookeeper/config/rubber/rubber-zookeeper.yml +1 -1
  32. data/test/dns/aws_test.rb +6 -0
  33. data/test/dns/zerigo_test.rb +6 -0
  34. data/test/instance_test.rb +3 -0
  35. metadata +14 -6
data/.travis.yml CHANGED
@@ -3,9 +3,13 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
- # - jruby-18mode
7
- # - jruby-19mode
8
- # - jruby-head
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - jruby-head
9
9
  # - rbx-18mode
10
10
  # - rbx-19mode
11
11
  # script: bundle exec rspec spec
12
+ env:
13
+ - JAVA_OPTS="-server -Djruby.cext.enabled=false -Djruby.compile.invokedynamic=false"
14
+ jdk:
15
+ - oraclejdk7
data/CHANGELOG CHANGED
@@ -1,3 +1,31 @@
1
+ 2.1.0 (08/20/2012)
2
+ ------------------
3
+
4
+ New Features:
5
+ ============
6
+
7
+ [unicorn] Added unicorn, complete_unicorn template, thanks messick!
8
+
9
+ Improvements:
10
+ ============
11
+
12
+ [redis] Bumped the redis version from 2.4.12 to 2.4.16. <ab6923e>
13
+ [zookeeper] bumped up zookeeper to 3.3.6 <409dbac>
14
+ [nginx, passenger_nginx, resque] Add nginx web_tools proxies with same strategy as apache, thanks messick!
15
+ [core] updated fog ~> 1.5
16
+
17
+ Bug Fixes:
18
+ =========
19
+
20
+ [base] allow port specific source_group rules in security_groups, allow source_groups to refer to groups in other projects <b6dba33>
21
+ [postgresql] Added sudo flag to change $HOME when running Postgresql commands, thanks infamouse <b3ff1ff>
22
+ [core] Handle finding a host for an empty domain, fixes #199 <6ba2181>
23
+ [core] with stopping exec queue, mdadm will not be able to create RAID array, thanks messick! <5662653>
24
+ [core] more friendly split for arguments, fixes #196 <5af6777>
25
+ [core] We need to close a file before we can unlink it in JRuby >= 1.7. <beb7bf0>
26
+ [core] call fatal, not fail method - fixes #204 <56fb7dd>
27
+
28
+
1
29
  2.0.8 (08/01/2012)
2
30
  ------------------
3
31
 
data/README.md CHANGED
@@ -2,6 +2,6 @@ The rubber plugin enables relatively complex multi-instance deployments of
2
2
  RubyOnRails applications to Amazon's Elastic Compute Cloud (EC2).
3
3
 
4
4
  See the documentation in the github wiki for more details:
5
- http://github.com/wr0ngway/rubber/wikis
5
+ http://github.com/wr0ngway/rubber/wiki
6
6
 
7
7
  [![Build Status](https://secure.travis-ci.org/wr0ngway/rubber.png)](http://travis-ci.org/wr0ngway/rubber)
@@ -172,7 +172,12 @@ module Rubber
172
172
  def add_security_group_rule(group_name, protocol, from_port, to_port, source)
173
173
  group = @compute_provider.security_groups.get(group_name)
174
174
  if source.instance_of? Hash
175
- group.authorize_group_and_owner(source[:name], source[:account])
175
+ if protocol
176
+ groupstr = "#{source[:account]}:#{source[:name]}"
177
+ group.authorize_port_range(from_port.to_i..to_port.to_i, :ip_protocol => protocol, :group => groupstr)
178
+ else
179
+ group.authorize_group_and_owner(source[:name], source[:account])
180
+ end
176
181
  else
177
182
  group.authorize_port_range(from_port.to_i..to_port.to_i, :ip_protocol => protocol, :cidr_ip => source)
178
183
  end
@@ -181,7 +186,12 @@ module Rubber
181
186
  def remove_security_group_rule(group_name, protocol, from_port, to_port, source)
182
187
  group = @compute_provider.security_groups.get(group_name)
183
188
  if source.instance_of? Hash
184
- group.revoke_group_and_owner(source[:name], source[:account])
189
+ if protocol
190
+ groupstr = "#{source[:account]}:#{source[:name]}"
191
+ group.revoke_port_range(from_port.to_i..to_port.to_i, :ip_protocol => protocol, :group => groupstr)
192
+ else
193
+ group.revoke_group_and_owner(source[:name], source[:account])
194
+ end
185
195
  else
186
196
  group.revoke_port_range(from_port.to_i..to_port.to_i, :ip_protocol => protocol, :cidr_ip => source)
187
197
  end
@@ -18,7 +18,7 @@ module Rubber
18
18
 
19
19
  option ["--host", "-h"], "HOST", "Override the instance's host for generation"
20
20
  option ["--roles", "-r"], "ROLES", "Override the instance's roles for generation" do |str|
21
- str.split(",")
21
+ str.split(/\s*,\s*/)
22
22
  end
23
23
  option ["--file", "-p"], "FILE", "Only generate files matching the given pattern"
24
24
  option ["--no_post", "-n"], :flag, "Skip running post commands"
@@ -133,7 +133,7 @@ module Rubber
133
133
 
134
134
  if opts[:host] && opts[:host] != '*'
135
135
  found_host = zone.records.all(:name => host[:name], :type => host[:type], :max_items => 1).first
136
- found_host = nil if found_host.name != "#{host[:name]}." && found_host.type != host[:type]
136
+ found_host = nil if found_host && found_host.name != "#{host[:name]}." && found_host.type != host[:type]
137
137
  hosts = Array(found_host)
138
138
  else
139
139
  hosts = all_hosts(zone)
@@ -1,7 +1,7 @@
1
1
  begin
2
2
  require 'nettica/client'
3
3
  rescue LoadError
4
- Rubber::Util.fail "Missing the nettica gem. Install or add it to your Gemfile."
4
+ Rubber::Util.fatal "Missing the nettica gem. Install or add it to your Gemfile."
5
5
  end
6
6
 
7
7
  module Rubber
@@ -23,7 +23,7 @@ namespace :rubber do
23
23
  if r == '*'
24
24
  instance_roles = rubber_cfg.environment.known_roles.reject {|r| r =~ /slave/ || r =~ /^db$/ }
25
25
  else
26
- instance_roles = r.split(",")
26
+ instance_roles = r.split(/\s*,\s*/)
27
27
  end
28
28
 
29
29
  create_instances(aliases, instance_roles, create_spot_instance)
@@ -100,7 +100,7 @@ namespace :rubber do
100
100
  instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
101
101
  r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
102
102
 
103
- instance_roles = r.split(",")
103
+ instance_roles = r.split(/\s*,\s*/)
104
104
 
105
105
  ir = []
106
106
  instance_roles.each do |r|
@@ -129,7 +129,7 @@ namespace :rubber do
129
129
  instance_alias = get_env('ALIAS', "Instance alias (e.g. web01)", true)
130
130
  r = get_env('ROLES', "Instance roles (e.g. web,app,db:primary=true)", true)
131
131
 
132
- instance_roles = r.split(",")
132
+ instance_roles = r.split(/\s*,\s*/)
133
133
 
134
134
  ir = []
135
135
  instance_roles.each do |r|
@@ -199,7 +199,7 @@ namespace :rubber do
199
199
  roles = instance_roles
200
200
  if roles.size == 0
201
201
  env = rubber_cfg.environment.bind(nil, instance_alias)
202
- roles = env.instance_roles.split(",") rescue []
202
+ roles = env.instance_roles.split(/\s*,\s*/) rescue []
203
203
  end
204
204
 
205
205
  # If user doesn't setup a primary db, then be nice and do it
@@ -37,7 +37,7 @@ namespace :rubber do
37
37
  security_groups += roles
38
38
  end
39
39
  security_groups = security_groups.uniq.compact.reject {|x| x.empty? }
40
- security_groups = security_groups.collect {|x| isolate_group_name(x) } if env.isolate_security_groups
40
+ security_groups = security_groups.collect {|x| isolate_group_name(x) }
41
41
  return security_groups
42
42
  end
43
43
 
@@ -71,19 +71,27 @@ namespace :rubber do
71
71
  end
72
72
 
73
73
  def isolate_group_name(group_name)
74
- new_name = "#{isolate_prefix}#{group_name}"
75
- return new_name
74
+ if rubber_env.isolate_security_groups
75
+ group_name =~ /^#{isolate_prefix}/ ? group_name : "#{isolate_prefix}#{group_name}"
76
+ else
77
+ group_name
78
+ end
76
79
  end
77
80
 
78
81
  def isolate_groups(groups)
79
82
  renamed = {}
80
83
  groups.each do |name, group|
81
- new_name = name =~ /^#{isolate_prefix}/ ? name : isolate_group_name(name)
84
+ new_name = isolate_group_name(name)
82
85
  new_group = Marshal.load(Marshal.dump(group))
83
86
  new_group['rules'].each do |rule|
84
87
  old_ref_name = rule['source_group_name']
85
- if old_ref_name && old_ref_name !~ /^#{isolate_prefix}/
86
- rule['source_group_name'] = isolate_group_name(old_ref_name)
88
+ if old_ref_name
89
+ # don't mangle names if the user specifies this is an external group they are giving access to.
90
+ # remove the external_group key to allow this to match with groups retrieved from cloud
91
+ is_external = rule.delete('external_group')
92
+ if ! is_external && old_ref_name !~ /^#{isolate_prefix}/
93
+ rule['source_group_name'] = isolate_group_name(old_ref_name)
94
+ end
87
95
  end
88
96
  end
89
97
  renamed[new_name] = new_group
@@ -95,7 +103,7 @@ namespace :rubber do
95
103
  return unless groups
96
104
 
97
105
  groups = Rubber::Util::stringify(groups)
98
- groups = isolate_groups(groups) if rubber_env.isolate_security_groups
106
+ groups = isolate_groups(groups)
99
107
  group_keys = groups.keys.clone()
100
108
 
101
109
  # For each group that does already exist in cloud
@@ -110,15 +118,31 @@ namespace :rubber do
110
118
  # sync rules
111
119
  logger.debug "Security Group already in cloud, syncing rules: #{group_name}"
112
120
  group = groups[group_name]
121
+
122
+ # convert the special case default rule into what it actually looks like when
123
+ # we query ec2 so that we can match things up when syncing
113
124
  rules = group['rules'].clone
125
+ group['rules'].each do |rule|
126
+ if [2, 3].include?(rule.size) && rule['source_group_name'] && rule['source_group_account']
127
+ rules << rule.merge({'protocol' => 'tcp', 'from_port' => '1', 'to_port' => '65535' })
128
+ rules << rule.merge({'protocol' => 'udp', 'from_port' => '1', 'to_port' => '65535' })
129
+ rules << rule.merge({'protocol' => 'icmp', 'from_port' => '-1', 'to_port' => '-1' })
130
+ rules.delete(rule)
131
+ end
132
+ end
133
+
114
134
  rule_maps = []
115
135
 
116
136
  # first collect the rule maps from the request (group/user pairs are duplicated for tcp/udp/icmp,
117
137
  # so we need to do this up frnot and remove duplicates before checking against the local rubber rules)
118
138
  cloud_group[:permissions].each do |rule|
119
- if rule[:source_groups]
120
- rule[:source_groups].each do |source_group|
121
- rule_map = {:source_group_name => source_group[:name], :source_group_account => source_group[:account]}
139
+ source_groups = rule.delete(:source_groups)
140
+ if source_groups
141
+ source_groups.each do |source_group|
142
+ rule_map = rule.clone
143
+ rule_map.delete(:source_ips)
144
+ rule_map[:source_group_name] = source_group[:name]
145
+ rule_map[:source_group_account] = source_group[:account]
122
146
  rule_map = Rubber::Util::stringify(rule_map)
123
147
  rule_maps << rule_map unless rule_maps.include?(rule_map)
124
148
  end
@@ -145,7 +169,7 @@ namespace :rubber do
145
169
  if answer =~ /^y/
146
170
  rule_map = Rubber::Util::symbolize_keys(rule_map)
147
171
  if rule_map[:source_group_name]
148
- cloud.remove_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
172
+ cloud.remove_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
149
173
  else
150
174
  rule_map[:source_ips].each do |source_ip|
151
175
  cloud.remove_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
@@ -160,7 +184,7 @@ namespace :rubber do
160
184
  logger.debug "Missing rule, creating: #{rule_map.inspect}"
161
185
  rule_map = Rubber::Util::symbolize_keys(rule_map)
162
186
  if rule_map[:source_group_name]
163
- cloud.add_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
187
+ cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
164
188
  else
165
189
  rule_map[:source_ips].each do |source_ip|
166
190
  cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
@@ -191,7 +215,7 @@ namespace :rubber do
191
215
  logger.debug "Creating new rule: #{rule_map.inspect}"
192
216
  rule_map = Rubber::Util::symbolize_keys(rule_map)
193
217
  if rule_map[:source_group_name]
194
- cloud.add_security_group_rule(group_name, nil, nil, nil, {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
218
+ cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], {:name => rule_map[:source_group_name], :account => rule_map[:source_group_account]})
195
219
  else
196
220
  rule_map[:source_ips].each do |source_ip|
197
221
  cloud.add_security_group_rule(group_name, rule_map[:protocol], rule_map[:from_port], rule_map[:to_port], source_ip)
@@ -258,7 +258,9 @@ namespace :rubber do
258
258
  done
259
259
  echo 'Devices ready'
260
260
 
261
+ udevadm control --stop-exec-queue
261
262
  #{mdadm_init}
263
+ udevadm control --start-exec-queue
262
264
 
263
265
  # set reconstruction speed
264
266
  echo $((30*1024)) > /proc/sys/dev/raid/speed_limit_min
data/lib/rubber/util.rb CHANGED
@@ -36,7 +36,7 @@ module Rubber
36
36
  alias_patterns = instance_aliases.to_s.strip.split(/\s*,\s*/)
37
37
  alias_patterns.each do |a|
38
38
  if a =~ /~/
39
- range = a.split(/~/)
39
+ range = a.split(/\s*~\s*/)
40
40
  range_items = (range.first..range.last).to_a
41
41
  raise "Invalid range, '#{a}', sequence generated no items" if range_items.size == 0
42
42
  aliases.concat(range_items)
@@ -1,4 +1,4 @@
1
1
  module Rubber
2
- VERSION = "2.0.8"
2
+ VERSION = "2.1.0"
3
3
  end
4
4
 
data/rubber.gemspec CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_dependency 'thor'
35
35
  s.add_dependency 'clamp'
36
36
  s.add_dependency 'open4'
37
- s.add_dependency 'fog', '~> 1.2'
37
+ s.add_dependency 'fog', '~> 1.5'
38
38
  s.add_dependency 'json'
39
39
 
40
40
  s.add_development_dependency('rake')
@@ -136,6 +136,20 @@ cloud_provider: aws
136
136
  # keys are the parameters to the ec2 AuthorizeSecurityGroupIngress API
137
137
  # source_security_group_name, source_security_group_owner_id
138
138
  # ip_protocol, from_port, to_port, cidr_ip
139
+ # If you want to use a source_group outside of this project, add "external_group: true"
140
+ # to prevent group_isolation from mangling its name, e.g. to give access to graphite
141
+ # server to other projects
142
+ #
143
+ # security_groups:
144
+ # graphite_server:
145
+ # description: The graphite_server security group to allow projects to send graphite data
146
+ # rules:
147
+ # - source_group_name: yourappname_production_collectd
148
+ # source_group_account: 123456
149
+ # external_group: true
150
+ # protocol: tcp
151
+ # from_port: "#{graphite_server_port}"
152
+ # to_port: "#{graphite_server_port}"
139
153
  #
140
154
  security_groups:
141
155
  default:
@@ -0,0 +1,21 @@
1
+ <%
2
+ @path = "/etc/haproxy/haproxy.cfg"
3
+ @additive = ["# start haproxy unicorn", "# end haproxy unicorn"]
4
+ %>
5
+
6
+ <%
7
+ backend_hosts = rubber_instances.for_role('app').collect { |i| i.name }
8
+ %>
9
+
10
+ listen unicorn_proxy 0.0.0.0:<%= rubber_env.web_port %>
11
+ option forwardfor
12
+ <% backend_hosts.each do |server| %>
13
+ server <%= server %> <%= server %>:<%= rubber_env.unicorn_listen_port %> maxconn <%= rubber_env.max_app_connections %> check
14
+ <% end %>
15
+
16
+ listen unicorn_proxy_ssl 0.0.0.0:<%= rubber_env.web_ssl_port %>
17
+ mode tcp
18
+ option forwardfor
19
+ <% backend_hosts.each do |server| %>
20
+ server <%= server %> <%= server %>:<%= rubber_env.unicorn_listen_ssl_port %> maxconn <%= rubber_env.max_app_connections %> check
21
+ <% end %>
@@ -0,0 +1,39 @@
1
+ role_dependencies:
2
+ web: [haproxy]
3
+ app: [unicorn_nginx]
4
+ web_tools: [unicorn_nginx]
5
+
6
+ web_port: 80
7
+ web_ssl_port: 443
8
+ web_tools_port: 8080
9
+ web_tools_ssl_port: 8443
10
+
11
+ security_groups:
12
+ web:
13
+ description: "To open up port #{web_port}/#{web_ssl_port} for http server on web role"
14
+ rules:
15
+ - protocol: tcp
16
+ from_port: "#{web_port}"
17
+ to_port: "#{web_port}"
18
+ source_ips: [0.0.0.0/0]
19
+ - protocol: tcp
20
+ from_port: "#{web_ssl_port}"
21
+ to_port: "#{web_ssl_port}"
22
+ source_ips: [0.0.0.0/0]
23
+ web_tools:
24
+ description: "To open up port #{web_tools_port}/#{web_tools_ssl_port} for internal/tools http server"
25
+ rules:
26
+ - protocol: tcp
27
+ from_port: "#{web_tools_port}"
28
+ to_port: "#{web_tools_port}"
29
+ source_ips: [0.0.0.0/0]
30
+ - protocol: tcp
31
+ from_port: "#{web_tools_ssl_port}"
32
+ to_port: "#{web_tools_ssl_port}"
33
+ source_ips: [0.0.0.0/0]
34
+
35
+ roles:
36
+ web:
37
+ assigned_security_groups: [web]
38
+ web_tools:
39
+ assigned_security_groups: [web_tools]
@@ -0,0 +1,8 @@
1
+ database_engines = ['mysql', 'postgresql']
2
+ if ! database_engines.any? {|d| @template_dependencies.include?(d)}
3
+ db = Rubber::Util::prompt("DATABASE",
4
+ "The database engine to use (#{database_engines.join(', ')})",
5
+ true,
6
+ 'mysql')
7
+ template_dependencies << db
8
+ end
@@ -0,0 +1,9 @@
1
+ description: A fairly complete and scalable deployment setup using unicorn and nginx
2
+ dependent_templates:
3
+ - base
4
+ - haproxy
5
+ - nginx
6
+ - unicorn
7
+ - monit
8
+ - collectd
9
+ - graphite
@@ -0,0 +1,4 @@
1
+ description: A fairly complete and scalable mysql deployment setup using unicorn/nginx
2
+ dependent_templates:
3
+ - complete_unicorn_nginx
4
+ - mysql
@@ -0,0 +1,4 @@
1
+ description: A fairly complete and scalable postgresql deployment setup using unicorn/nginx
2
+ dependent_templates:
3
+ - complete_unicorn_nginx
4
+ - postgresql
@@ -0,0 +1,7 @@
1
+ <%
2
+ @path = '/etc/monit/monit.d/monit-unicorn.conf'
3
+ %>
4
+ check process unicorn with pidfile /var/run/unicorn.pid
5
+ group unicorn-<%= Rubber.env %>
6
+ start program = "/usr/bin/env service unicorn start"
7
+ stop program = "/usr/bin/env service unicorn stop"
@@ -13,6 +13,47 @@ server
13
13
  rewrite (.*) https://$host:<%= rubber_env.web_tools_ssl_port %>$1 break;
14
14
  }
15
15
 
16
+ # Web Tools Proxies
17
+ <%
18
+ Array(rubber_env.web_tools_proxies).each do |name, settings|
19
+ proxy_host = rubber_instances.for_role(settings.role).first.full_name rescue nil
20
+ next unless proxy_host
21
+
22
+ host = "#{name}-#{rubber_env.full_host}"
23
+ host_and_port = "#{host}:#{rubber_env.web_tools_ssl_port}"
24
+
25
+ # don't use settings.path here - mapping the host/port is sufficient,
26
+ # and path can be done in tools-index.html. This allows admin sites
27
+ # that hit other paths on same host/port to still function, e.g. elasticsearch
28
+ proxy_url = "http://#{proxy_host}:#{settings.port}/"
29
+ %>
30
+ server
31
+ {
32
+ listen <%= rubber_env.web_tools_ssl_port %>;
33
+ server_name <%= host %>;
34
+
35
+ ssl on;
36
+ <% if rubber_env.use_ssl_key %>
37
+ ssl_certificate <%= Rubber.root %>/config/<%= rubber_env.domain %>.crt;
38
+ ssl_certificate_key <%= Rubber.root %>/config/<%= rubber_env.domain %>.key;
39
+ <% else %>
40
+ ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
41
+ ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
42
+ <% end %>
43
+
44
+ auth_basic "Rubber Admin Tools";
45
+ auth_basic_user_file <%= Rubber.root %>/config/<%= rubber_env.app_name %>.auth;
46
+
47
+ client_max_body_size 10M;
48
+ root /var/www;
49
+
50
+ location /
51
+ {
52
+ proxy_pass <%= proxy_url %>;
53
+ }
54
+ }
55
+ <% end %>
56
+
16
57
  # This server is setup to serve https.
17
58
  server
18
59
  {
@@ -1,5 +1,6 @@
1
1
  <%
2
2
  @path = "/var/www/index.html"
3
+ tools_host = rubber_instances.for_role('web_tools').first
3
4
  %>
4
5
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
5
6
  <html>
@@ -11,24 +12,25 @@
11
12
  <h1>Rubber Admin Tools</h1>
12
13
  <ul>
13
14
 
14
- <% if File.exist?("/var/www/munin") %>
15
- <li><a href="/munin/">Munin</a></li>
15
+ <%
16
+ tools_html_path = "/var/www"
17
+ tools_html_prefix = "#{tools_html_path}/rubber-web-tools-"
18
+ Dir["#{tools_html_prefix}*.html"].each do |tools_file|
19
+ tool_path = tools_file.gsub(tools_html_path, '')
20
+ tool_name = tools_file.gsub(tools_html_prefix, '').split('.').first
21
+ tool_name = tool_name.capitalize
22
+ %>
23
+ <li><a href="<%= tool_path %>"><%= tool_name %></a></li>
16
24
  <% end %>
17
25
 
18
- <% if cruise_host = rubber_instances.for_role('cruise').first %>
19
- <li><a href="http://<%= cruise_host %>/cruise/">CruiseControl</a></li>
20
- <% end %>
21
-
22
- <% rubber_instances.for_role('haproxy').each do |ic| %>
23
- <li><a href="/haproxy_<%= ic.name %>/">HAProxy <%= ic.name %></a></li>
24
- <% end %>
25
-
26
- <% rubber_instances.each do |ic| %>
27
- <li><a href="/monit_<%= ic.name %>/">Monit <%= ic.name %></a></li>
28
- <% end %>
29
-
30
- <% if graphite_host = rubber_instances.for_role('graphite_web').first %>
31
- <li><a href="/graphite/">Graphite</a></li>
26
+ <%
27
+ # add the ip aliases for web tools hosts so we can map internal tools
28
+ # to their own vhost to make proxying easier (rewriting url paths for
29
+ # proxy is a real pain, e.g. '/graphite/' externally to '/' on the
30
+ # graphite web app)
31
+ Array(rubber_env.web_tools_proxies).each do |name, settings|
32
+ %>
33
+ <li><a href="https://<%= name %>-<%= tools_host.full_name %>:<%= rubber_env.web_tools_ssl_port %><%= settings.path || '/' %>"><%= name.capitalize %></a></li>
32
34
  <% end %>
33
35
 
34
36
  </ul>
@@ -13,6 +13,47 @@ server
13
13
  rewrite (.*) https://$host:<%= rubber_env.web_tools_ssl_port %>$1 break;
14
14
  }
15
15
 
16
+ # Web Tools Proxies
17
+ <%
18
+ Array(rubber_env.web_tools_proxies).each do |name, settings|
19
+ proxy_host = rubber_instances.for_role(settings.role).first.full_name rescue nil
20
+ next unless proxy_host
21
+
22
+ host = "#{name}-#{rubber_env.full_host}"
23
+ host_and_port = "#{host}:#{rubber_env.web_tools_ssl_port}"
24
+
25
+ # don't use settings.path here - mapping the host/port is sufficient,
26
+ # and path can be done in tools-index.html. This allows admin sites
27
+ # that hit other paths on same host/port to still function, e.g. elasticsearch
28
+ proxy_url = "http://#{proxy_host}:#{settings.port}/"
29
+ %>
30
+ server
31
+ {
32
+ listen <%= rubber_env.web_tools_ssl_port %>;
33
+ server_name <%= host %>;
34
+
35
+ ssl on;
36
+ <% if rubber_env.use_ssl_key %>
37
+ ssl_certificate <%= Rubber.root %>/config/<%= rubber_env.domain %>.crt;
38
+ ssl_certificate_key <%= Rubber.root %>/config/<%= rubber_env.domain %>.key;
39
+ <% else %>
40
+ ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
41
+ ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
42
+ <% end %>
43
+
44
+ auth_basic "Rubber Admin Tools";
45
+ auth_basic_user_file <%= Rubber.root %>/config/<%= rubber_env.app_name %>.auth;
46
+
47
+ client_max_body_size 10M;
48
+ root /var/www;
49
+
50
+ location /
51
+ {
52
+ proxy_pass <%= proxy_url %>;
53
+ }
54
+ }
55
+ <% end %>
56
+
16
57
  # This server is setup to serve https.
17
58
  server
18
59
  {
@@ -1,5 +1,6 @@
1
1
  <%
2
2
  @path = "/var/www/index.html"
3
+ tools_host = rubber_instances.for_role('web_tools').first
3
4
  %>
4
5
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
5
6
  <html>
@@ -10,29 +11,26 @@
10
11
  <body>
11
12
  <h1>Rubber Admin Tools</h1>
12
13
  <ul>
13
-
14
- <% if File.exist?("/var/www/munin") %>
15
- <li><a href="/munin/">Munin</a></li>
16
- <% end %>
17
-
18
- <% if cruise_host = rubber_instances.for_role('cruise').first %>
19
- <li><a href="http://<%= cruise_host %>/cruise/">CruiseControl</a></li>
20
- <% end %>
21
-
22
- <% rubber_instances.for_role('haproxy').sort {|a,b| a.name <=> b.name }.each do |ic| %>
23
- <li><a href="/haproxy_<%= ic.name %>/">HAProxy <%= ic.name %></a></li>
24
- <% end %>
25
-
26
- <% rubber_instances.sort {|a,b| a.name <=> b.name }.each do |ic| %>
27
- <li><a href="/monit_<%= ic.name %>/">Monit <%= ic.name %></a></li>
28
- <% end %>
29
14
 
30
- <% if resque_host = rubber_instances.for_role('resque_web').first %>
31
- <li><a href="/resque/">Resque</a></li>
15
+ <%
16
+ tools_html_path = "/var/www"
17
+ tools_html_prefix = "#{tools_html_path}/rubber-web-tools-"
18
+ Dir["#{tools_html_prefix}*.html"].each do |tools_file|
19
+ tool_path = tools_file.gsub(tools_html_path, '')
20
+ tool_name = tools_file.gsub(tools_html_prefix, '').split('.').first
21
+ tool_name = tool_name.capitalize
22
+ %>
23
+ <li><a href="<%= tool_path %>"><%= tool_name %></a></li>
32
24
  <% end %>
33
25
 
34
- <% if graphite_host = rubber_instances.for_role('graphite_web').first %>
35
- <li><a href="/graphite/">Graphite</a></li>
26
+ <%
27
+ # add the ip aliases for web tools hosts so we can map internal tools
28
+ # to their own vhost to make proxying easier (rewriting url paths for
29
+ # proxy is a real pain, e.g. '/graphite/' externally to '/' on the
30
+ # graphite web app)
31
+ Array(rubber_env.web_tools_proxies).each do |name, settings|
32
+ %>
33
+ <li><a href="https://<%= name %>-<%= tools_host.full_name %>:<%= rubber_env.web_tools_ssl_port %><%= settings.path || '/' %>"><%= name.capitalize %></a></li>
36
34
  <% end %>
37
35
 
38
36
  </ul>
@@ -1,4 +1,3 @@
1
-
2
1
  namespace :rubber do
3
2
 
4
3
  namespace :postgresql do
@@ -58,9 +57,9 @@ namespace :rubber do
58
57
  create_replication_user_cmd << " PASSWORD '#{env.db_replication_pass}'" if env.db_replication_pass
59
58
 
60
59
  rubber.sudo_script "create_master_db", <<-ENDSCRIPT
61
- sudo -u postgres psql -c "#{create_user_cmd}"
62
- sudo -u postgres psql -c "#{create_replication_user_cmd}"
63
- sudo -u postgres psql -c "CREATE DATABASE #{env.db_name} WITH OWNER #{env.db_user}"
60
+ sudo -i -u postgres psql -c "#{create_user_cmd}"
61
+ sudo -i -u postgres psql -c "#{create_replication_user_cmd}"
62
+ sudo -i -u postgres psql -c "CREATE DATABASE #{env.db_name} WITH OWNER #{env.db_user}"
64
63
  ENDSCRIPT
65
64
  end
66
65
  end
@@ -1,4 +1,4 @@
1
- redis_server_version: 2.4.12
1
+ redis_server_version: 2.4.16
2
2
  redis_server_pid_file: /var/run/redis-server.pid
3
3
  redis_server_conf_file: /etc/redis.conf
4
4
  redis_server_log_file: /var/log/redis-server.log
@@ -1,3 +1,4 @@
1
1
  description: The resque background queue system
2
2
  dependent_templates:
3
- - redis
3
+ - redis
4
+ skip_unknown_roles: true
@@ -0,0 +1,13 @@
1
+ <%
2
+ @path = "/etc/init/unicorn.conf"
3
+ current_path = "/mnt/#{rubber_env.app_name}-#{Rubber.env}/current"
4
+ @backup = false
5
+ %>
6
+ description "unicorn daemon"
7
+
8
+ start on runlevel [2345]
9
+ stop on runlevel [016]
10
+
11
+ script
12
+ exec /bin/bash -l -c 'cd <%= current_path %> && exec bundle exec unicorn_rails -c <%= current_path %>/config/unicorn.rb -E <%= Rubber.env %> -D >> log/unicorn_upstart.log 2>&1'
13
+ end script
@@ -1,5 +1,6 @@
1
1
  <%
2
2
  @path = "#{Rubber.root}/config/unicorn.rb"
3
+ current_path = "/mnt/#{rubber_env.app_name}-#{Rubber.env}/current"
3
4
  %>
4
5
  worker_processes 2
5
6
  working_directory "<%= Rubber.root %>"
@@ -22,6 +23,13 @@ pid "/var/run/unicorn.pid"
22
23
  stderr_path "<%= Rubber.root %>/log/unicorn.stderr.log"
23
24
  stdout_path "<%= Rubber.root %>/log/unicorn.stdout.log"
24
25
 
26
+ # Because of Capistano, we need to tell unicorn where find the current Gemfile
27
+ # Read about Unicorn, Capistrano, and Bundler here:
28
+ # http://unicorn.bogomips.org/Sandbox.html
29
+ before_exec do |server|
30
+ ENV['BUNDLE_GEMFILE'] = "<%= current_path %>/Gemfile"
31
+ end
32
+
25
33
  before_fork do |server, worker|
26
34
  ##
27
35
  # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
@@ -1,4 +1,4 @@
1
- zookeeper_version: 3.3.5
1
+ zookeeper_version: 3.3.6
2
2
  zookeeper_package_url: "http://www.ecoficial.com/am/zookeeper/stable/zookeeper-#{zookeeper_version}.tar.gz"
3
3
  zookeeper_install_dir: "/usr/local/zookeeper-#{zookeeper_version}"
4
4
  zookeeper_data_dir: /mnt/zookeeper/data
data/test/dns/aws_test.rb CHANGED
@@ -123,6 +123,12 @@ class AwsTest < Test::Unit::TestCase
123
123
  assert_equal ['1.1.1.2'], attributes[:data]
124
124
  end
125
125
 
126
+ should "find no records" do
127
+ # Wildcard search.
128
+ records = @dns.find_host_records(:host => 'foo', :domain => @domain)
129
+ assert_equal 0, records.size
130
+ end
131
+
126
132
  should "find_records" do
127
133
  # Set up some sample records.
128
134
  created = []
@@ -121,6 +121,12 @@ class ZerigoTest < Test::Unit::TestCase
121
121
  assert_equal ['1.1.1.2'], attributes[:data]
122
122
  end
123
123
 
124
+ should "find no records" do
125
+ # Wildcard search.
126
+ records = @dns.find_host_records(:host => 'foo', :domain => @domain)
127
+ assert_equal 0, records.size
128
+ end
129
+
124
130
  should "find_records" do
125
131
  # Set up some sample records.
126
132
  created = []
@@ -226,7 +226,10 @@ class InstanceTest < Test::Unit::TestCase
226
226
  should "create new instance in filesystem when instance file doesn't exist" do
227
227
  tempfile = Tempfile.new('instancestorage')
228
228
  location = "file:#{tempfile.path}"
229
+
230
+ tempfile.close
229
231
  tempfile.unlink
232
+
230
233
  Instance.any_instance.expects(:load_from_file).never
231
234
  Instance.any_instance.expects(:save_to_file)
232
235
  Instance.new(location).save
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.8
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-01 00:00:00.000000000 Z
13
+ date: 2012-08-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: capistrano
@@ -99,7 +99,7 @@ dependencies:
99
99
  requirements:
100
100
  - - ~>
101
101
  - !ruby/object:Gem::Version
102
- version: '1.2'
102
+ version: '1.5'
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
@@ -107,7 +107,7 @@ dependencies:
107
107
  requirements:
108
108
  - - ~>
109
109
  - !ruby/object:Gem::Version
110
- version: '1.2'
110
+ version: '1.5'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: json
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -345,6 +345,12 @@ files:
345
345
  - templates/complete_passenger_nginx_mysql/templates.yml
346
346
  - templates/complete_passenger_nginx_postgresql/templates.yml
347
347
  - templates/complete_passenger_postgresql/templates.yml
348
+ - templates/complete_unicorn_nginx/config/rubber/role/haproxy/haproxy-unicorn.conf
349
+ - templates/complete_unicorn_nginx/config/rubber/rubber-complete.yml
350
+ - templates/complete_unicorn_nginx/templates.rb
351
+ - templates/complete_unicorn_nginx/templates.yml
352
+ - templates/complete_unicorn_nginx_mysql/templates.yml
353
+ - templates/complete_unicorn_nginx_postgresql/templates.yml
348
354
  - templates/cruise/config/rubber/deploy-cruise.rb
349
355
  - templates/cruise/config/rubber/role/cruise/cruise
350
356
  - templates/cruise/config/rubber/role/cruise/my.cnf
@@ -450,6 +456,7 @@ files:
450
456
  - templates/monit/config/rubber/role/resque_web/monit-resque_web.conf
451
457
  - templates/monit/config/rubber/role/resque_worker/monit-resque_pool.conf
452
458
  - templates/monit/config/rubber/role/sphinx/monit-sphinx.conf
459
+ - templates/monit/config/rubber/role/unicorn/monit-unicorn.conf
453
460
  - templates/monit/config/rubber/role/web_tools/monit-admin-nginx.conf
454
461
  - templates/monit/config/rubber/role/web_tools/rubber-web-tools-monit.html
455
462
  - templates/monit/config/rubber/rubber-monit.yml
@@ -581,6 +588,7 @@ files:
581
588
  - templates/torquebox/templates.yml
582
589
  - templates/unicorn/config/rubber/deploy-unicorn.rb
583
590
  - templates/unicorn/config/rubber/role/nginx/unicorn_nginx.conf
591
+ - templates/unicorn/config/rubber/role/unicorn/unicorn-upstart.conf
584
592
  - templates/unicorn/config/rubber/role/unicorn/unicorn.rb
585
593
  - templates/unicorn/config/rubber/rubber-unicorn.yml
586
594
  - templates/unicorn/templates.yml
@@ -648,7 +656,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
648
656
  version: '0'
649
657
  segments:
650
658
  - 0
651
- hash: 4060872164563619130
659
+ hash: -230817372791926441
652
660
  required_rubygems_version: !ruby/object:Gem::Requirement
653
661
  none: false
654
662
  requirements:
@@ -657,7 +665,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
657
665
  version: '0'
658
666
  segments:
659
667
  - 0
660
- hash: 4060872164563619130
668
+ hash: -230817372791926441
661
669
  requirements: []
662
670
  rubyforge_project: rubber
663
671
  rubygems_version: 1.8.24