rubber 2.0.8 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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