heroku-rails-saas 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +15 -4
- data/heroku-rails.gemspec +1 -1
- data/lib/generators/templates/heroku.yml +9 -0
- data/lib/heroku-rails-saas/config.rb +20 -0
- data/lib/heroku-rails-saas/runner.rb +16 -0
- data/lib/heroku/rails/tasks.rb +34 -10
- data/spec/fixtures/awesomeapp.yml +9 -1
- data/spec/fixtures/heroku-config.yml +1 -1
- data/spec/fixtures/mediocreapp.yml +1 -1
- data/spec/heroku/rails/saas/heroku_config_spec.rb +32 -0
- metadata +8 -8
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,9 +3,8 @@ Heroku Rails SaaS
|
|
3
3
|
|
4
4
|
Easier configuration and deployment of Rails apps on Heroku
|
5
5
|
|
6
|
-
Configure all your Heroku
|
7
|
-
Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, and
|
8
|
-
environment variables for awesomeapp.
|
6
|
+
Configure all your Heroku environments via a YML file (config/heroku.yml) that defines all your environments, addons, scaling settings and environment variables.
|
7
|
+
Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, scaling settings and environment variables for awesomeapp.
|
9
8
|
|
10
9
|
## Install
|
11
10
|
|
@@ -44,6 +43,10 @@ For all configuration settings
|
|
44
43
|
- scheduler:standard
|
45
44
|
# add any other addons here
|
46
45
|
|
46
|
+
scale:
|
47
|
+
web: 1
|
48
|
+
worker: 0
|
49
|
+
|
47
50
|
For an app specific settings awesomeapp
|
48
51
|
|
49
52
|
apps:
|
@@ -70,6 +73,13 @@ For an app specific settings awesomeapp
|
|
70
73
|
- cron:daily
|
71
74
|
- newrelic:bronze
|
72
75
|
|
76
|
+
scale:
|
77
|
+
production:
|
78
|
+
web: 3
|
79
|
+
worker: 2
|
80
|
+
staging:
|
81
|
+
web: 2
|
82
|
+
worker: 1
|
73
83
|
|
74
84
|
### Setting up Heroku
|
75
85
|
|
@@ -99,7 +109,7 @@ A special rake task 'all' is created that causes any further commands to
|
|
99
109
|
execute on all heroku apps (Note: Any environment labeled `production` will not
|
100
110
|
be included, you must explicitly state it).
|
101
111
|
|
102
|
-
|
112
|
+
Furthermore there are rake task 'environments' created from environments in configs
|
103
113
|
that causes any further commands to execute on all heroku apps.
|
104
114
|
|
105
115
|
rake all:production heroku:info
|
@@ -120,6 +130,7 @@ A full list of tasks provided:
|
|
120
130
|
rake heroku:remotes # Add git remotes for all apps in this project
|
121
131
|
rake heroku:migrate # Migrates and restarts remote servers
|
122
132
|
rake heroku:restart # Restarts remote servers
|
133
|
+
rake heroku:scale # Scales heroku processes
|
123
134
|
|
124
135
|
rake heroku:setup # runs all heroku setup scripts
|
125
136
|
rake heroku:setup:addons # sets up the heroku addons
|
data/heroku-rails.gemspec
CHANGED
@@ -33,6 +33,11 @@
|
|
33
33
|
# - cron:daily
|
34
34
|
# - newrelic:bronze
|
35
35
|
|
36
|
+
# scale:
|
37
|
+
# production:
|
38
|
+
# web: 2
|
39
|
+
# worker: 1
|
40
|
+
|
36
41
|
|
37
42
|
# The following are configuration settings formally under the :all key
|
38
43
|
# for all apps and thier environments
|
@@ -50,3 +55,7 @@ collaborators:
|
|
50
55
|
addons:
|
51
56
|
- scheduler:standard
|
52
57
|
# add any other addons here
|
58
|
+
|
59
|
+
scale:
|
60
|
+
web: 1
|
61
|
+
worker: 0
|
@@ -22,6 +22,12 @@ module HerokuRailsSaas
|
|
22
22
|
name, env = app_env.split(SEPERATOR)
|
23
23
|
env
|
24
24
|
end
|
25
|
+
|
26
|
+
def extract_name_from(app_env)
|
27
|
+
name, env = app_env.split(SEPERATOR)
|
28
|
+
name
|
29
|
+
end
|
30
|
+
|
25
31
|
end
|
26
32
|
|
27
33
|
attr_accessor :settings
|
@@ -89,6 +95,20 @@ module HerokuRailsSaas
|
|
89
95
|
all.merge(merged_environment_configs)
|
90
96
|
end
|
91
97
|
|
98
|
+
# pull out the scaling setting hash for a particular app environment
|
99
|
+
def scale(app_env)
|
100
|
+
name, env = app_env.split(SEPERATOR)
|
101
|
+
scaling = self.settings['scale'] || {}
|
102
|
+
all = scaling['all'] || {}
|
103
|
+
|
104
|
+
app_scaling = (scaling[name] && scaling[name].reject { |k,v| v.class == Hash }) || {}
|
105
|
+
# overwrite app scaling with the environment specific ones
|
106
|
+
merged_environment_scaling = app_scaling.merge((scaling[name] && scaling[name][env]) || {})
|
107
|
+
|
108
|
+
# overwrite all scaling with the environment specific ones
|
109
|
+
all.merge(merged_environment_scaling)
|
110
|
+
end
|
111
|
+
|
92
112
|
# return a list of domains for a particular app environment
|
93
113
|
def domains(app_env)
|
94
114
|
name, env = app_env.split(SEPERATOR)
|
@@ -204,6 +204,22 @@ module HerokuRailsSaas
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
+
def scale
|
208
|
+
authorize unless @heroku
|
209
|
+
each_heroku_app do |heroku_env, app_name, repo|
|
210
|
+
scaling = @config.scale(heroku_env)
|
211
|
+
scaling.each do |process_name, instance_count|
|
212
|
+
begin
|
213
|
+
puts "Scaling app #{app_name} process #{process_name} to #{instance_count}"
|
214
|
+
response = @heroku.ps_scale(app_name, {:type => process_name, :qty => instance_count })
|
215
|
+
puts "Response: #{response}"
|
216
|
+
rescue => e
|
217
|
+
puts "Failed to scale #{app_name}. Error: #{e.inspect}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
207
223
|
# cycles through each configured heroku app
|
208
224
|
# yields the environment name, the app name, and the repo url
|
209
225
|
def each_heroku_app
|
data/lib/heroku/rails/tasks.rb
CHANGED
@@ -141,13 +141,6 @@ namespace :heroku do
|
|
141
141
|
task :switch_environment do
|
142
142
|
end
|
143
143
|
|
144
|
-
desc "Force deploys, migrates and restarts latest code"
|
145
|
-
task :force_deploy do
|
146
|
-
@git_push_arguments ||= []
|
147
|
-
@git_push_arguments << '--force'
|
148
|
-
Rake::Task["heroku:deploy"].execute
|
149
|
-
end
|
150
|
-
|
151
144
|
desc "Captures a bundle on Heroku"
|
152
145
|
task :capture do
|
153
146
|
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
@@ -177,6 +170,11 @@ namespace :heroku do
|
|
177
170
|
end
|
178
171
|
end
|
179
172
|
|
173
|
+
desc "Scales heroku processes"
|
174
|
+
task :scale do
|
175
|
+
HEROKU_RUNNER.scale
|
176
|
+
end
|
177
|
+
|
180
178
|
namespace :setup do
|
181
179
|
|
182
180
|
desc "Creates the apps on Heroku"
|
@@ -232,11 +230,11 @@ namespace :heroku do
|
|
232
230
|
desc "Pulls the database from heroku and stores it into db/dumps/"
|
233
231
|
task :pull do
|
234
232
|
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
235
|
-
system_with_echo "heroku
|
236
|
-
dump = `heroku
|
233
|
+
system_with_echo "heroku pgbackups:capture --app #{app_name}"
|
234
|
+
dump = `heroku pgbackups --app #{app_name}`.split("\n").last.split(" ").first
|
237
235
|
system_with_echo "mkdir -p #{HerokuRailsSaas::Config.root}/db/dumps"
|
238
236
|
file = "#{HerokuRailsSaas::Config.root}/db/dumps/#{dump}.sql.gz"
|
239
|
-
url = `heroku
|
237
|
+
url = `heroku pgbackups:url --app #{app_name} #{dump}`.chomp
|
240
238
|
system_with_echo "wget", url, "-O", file
|
241
239
|
|
242
240
|
# TODO: these are a bit distructive...
|
@@ -245,5 +243,31 @@ namespace :heroku do
|
|
245
243
|
# system_with_echo "rake jobs:clear"
|
246
244
|
end
|
247
245
|
end
|
246
|
+
|
247
|
+
desc "Resets a Non Production database"
|
248
|
+
task :reset do
|
249
|
+
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
250
|
+
unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
|
251
|
+
system_with_echo "heroku pg:reset DATABASE_URL --app #{app_name} --confirm #{app_name}"
|
252
|
+
else
|
253
|
+
puts "Will not reset the Production database"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
desc "Copies a database over a Non Production database"
|
259
|
+
task :copy,[ :source] => :reset do |t, args|
|
260
|
+
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
261
|
+
raise "missing source" unless HEROKU_CONFIG.app_name_on_heroku(args.source)
|
262
|
+
|
263
|
+
unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
|
264
|
+
source_app_name = HEROKU_CONFIG.app_name_on_heroku(args.source)
|
265
|
+
system_with_echo "heroku pgbackups:restore DATABASE_URL `heroku pgbackups:url --app #{source_app_name}` --app #{app_name} --confirm #{app_name}"
|
266
|
+
else
|
267
|
+
puts "Will not overwrite the Production database"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
248
272
|
end
|
249
273
|
end
|
@@ -153,5 +153,37 @@ module HerokuRailsSaas
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
describe "#scale" do
|
157
|
+
context "mediocrapp" do
|
158
|
+
it "should include the scaling settings defined in 'all'" do
|
159
|
+
@scale = @config.scale('mediocreapp')
|
160
|
+
@scale['web'].should_not be_nil
|
161
|
+
@scale['worker'].should_not be_nil
|
162
|
+
@scale['web'].should eql 1
|
163
|
+
@scale['worker'].should eql 0
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "staging environment" do
|
168
|
+
it "should include the scaling settings defined in 'staging'" do
|
169
|
+
@scale = @config.scale('awesomeapp:staging')
|
170
|
+
@scale['web'].should_not be_nil
|
171
|
+
@scale['worker'].should_not be_nil
|
172
|
+
@scale['web'].should eql 2
|
173
|
+
@scale['worker'].should eql 1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context "production environment" do
|
178
|
+
it "should include the scaling settings defined in 'production'" do
|
179
|
+
@scale = @config.scale('awesomeapp:production')
|
180
|
+
@scale['web'].should_not be_nil
|
181
|
+
@scale['worker'].should_not be_nil
|
182
|
+
@scale['web'].should eql 3
|
183
|
+
@scale['worker'].should eql 2
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
156
188
|
end
|
157
189
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-rails-saas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,11 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-05-
|
15
|
+
date: 2012-05-04 00:00:00.000000000Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: heroku
|
19
|
-
requirement: &
|
19
|
+
requirement: &2156355220 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
@@ -24,10 +24,10 @@ dependencies:
|
|
24
24
|
version: 2.24.1
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2156355220
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
|
-
requirement: &
|
30
|
+
requirement: &2156354200 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
version: '2.0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2156354200
|
39
39
|
description: Manage multiple Heroku instances/apps for a single Rails app using Rake.
|
40
40
|
email: lance.sanchez@gmail.com
|
41
41
|
executables: []
|
@@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
84
|
version: '0'
|
85
85
|
segments:
|
86
86
|
- 0
|
87
|
-
hash:
|
87
|
+
hash: 3808687770431151887
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: '0'
|
94
94
|
segments:
|
95
95
|
- 0
|
96
|
-
hash:
|
96
|
+
hash: 3808687770431151887
|
97
97
|
requirements: []
|
98
98
|
rubyforge_project: none
|
99
99
|
rubygems_version: 1.8.6
|