pogo 2.32.14 → 2.39.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -2
- data/lib/heroku/auth.rb +3 -1
- data/lib/heroku/client.rb +8 -5
- data/lib/heroku/client/cisaurus.rb +25 -0
- data/lib/heroku/client/heroku_postgresql.rb +0 -3
- data/lib/heroku/client/rendezvous.rb +2 -1
- data/lib/heroku/command.rb +1 -1
- data/lib/heroku/command/addons.rb +11 -2
- data/lib/heroku/command/apps.rb +105 -20
- data/lib/heroku/command/base.rb +1 -1
- data/lib/heroku/command/certs.rb +95 -34
- data/lib/heroku/command/config.rb +5 -5
- data/lib/heroku/command/domains.rb +4 -4
- data/lib/heroku/command/fork.rb +160 -0
- data/lib/heroku/command/git.rb +19 -20
- data/lib/heroku/command/help.rb +18 -2
- data/lib/heroku/command/keys.rb +1 -1
- data/lib/heroku/command/labs.rb +1 -1
- data/lib/heroku/command/logs.rb +3 -56
- data/lib/heroku/command/maintenance.rb +2 -2
- data/lib/heroku/command/pg.rb +7 -16
- data/lib/heroku/command/pgbackups.rb +37 -17
- data/lib/heroku/command/ps.rb +82 -35
- data/lib/heroku/command/regions.rb +23 -0
- data/lib/heroku/command/releases.rb +3 -3
- data/lib/heroku/command/run.rb +40 -27
- data/lib/heroku/command/sharing.rb +4 -4
- data/lib/heroku/command/ssl.rb +7 -25
- data/lib/heroku/command/stack.rb +1 -1
- data/lib/heroku/helpers/heroku_postgresql.rb +13 -17
- data/lib/heroku/helpers/log_displayer.rb +70 -0
- data/lib/heroku/plugin.rb +3 -0
- data/lib/heroku/updater.rb +11 -2
- data/lib/heroku/version.rb +1 -1
- data/spec/heroku/auth_spec.rb +10 -0
- data/spec/heroku/client/ssl_endpoint_spec.rb +12 -12
- data/spec/heroku/client_spec.rb +100 -100
- data/spec/heroku/command/addons_spec.rb +63 -59
- data/spec/heroku/command/apps_spec.rb +68 -65
- data/spec/heroku/command/base_spec.rb +21 -21
- data/spec/heroku/command/certs_spec.rb +31 -31
- data/spec/heroku/command/config_spec.rb +18 -18
- data/spec/heroku/command/db_spec.rb +3 -3
- data/spec/heroku/command/domains_spec.rb +13 -13
- data/spec/heroku/command/drains_spec.rb +3 -3
- data/spec/heroku/command/fork_spec.rb +56 -0
- data/spec/heroku/command/git_spec.rb +57 -29
- data/spec/heroku/command/labs_spec.rb +8 -8
- data/spec/heroku/command/logs_spec.rb +3 -3
- data/spec/heroku/command/maintenance_spec.rb +5 -5
- data/spec/heroku/command/pg_spec.rb +11 -25
- data/spec/heroku/command/pgbackups_spec.rb +13 -8
- data/spec/heroku/command/ps_spec.rb +23 -23
- data/spec/heroku/command/releases_spec.rb +22 -24
- data/spec/heroku/command/run_spec.rb +12 -15
- data/spec/heroku/command/sharing_spec.rb +9 -9
- data/spec/heroku/command/stack_spec.rb +4 -4
- data/spec/heroku/command_spec.rb +12 -12
- data/spec/heroku/helpers/heroku_postgresql_spec.rb +35 -14
- data/spec/spec_helper.rb +17 -2
- data/spec/support/openssl_mock_helper.rb +1 -1
- metadata +11 -6
- data/spec/heroku/command/ssl_spec.rb +0 -32
data/lib/heroku/command/pg.rb
CHANGED
@@ -93,15 +93,11 @@ class Heroku::Command::Pg < Heroku::Command::Base
|
|
93
93
|
end
|
94
94
|
validate_arguments!
|
95
95
|
|
96
|
-
attachment = hpg_resolve(db)
|
96
|
+
attachment = hpg_resolve(db)
|
97
97
|
return unless confirm_command
|
98
98
|
|
99
|
-
|
100
|
-
|
101
|
-
else
|
102
|
-
action("Resetting #{attachment.display_name}") do
|
103
|
-
hpg_client(attachment).reset
|
104
|
-
end
|
99
|
+
action("Resetting #{attachment.display_name}") do
|
100
|
+
hpg_client(attachment).reset
|
105
101
|
end
|
106
102
|
end
|
107
103
|
|
@@ -181,6 +177,9 @@ class Heroku::Command::Pg < Heroku::Command::Base
|
|
181
177
|
uri = URI.parse( attachment.url )
|
182
178
|
display "Connection info string:"
|
183
179
|
display " \"dbname=#{uri.path[1..-1]} host=#{uri.host} port=#{uri.port || 5432} user=#{uri.user} password=#{uri.password} sslmode=require\""
|
180
|
+
display "Connection URL:"
|
181
|
+
display " " + attachment.url
|
182
|
+
|
184
183
|
end
|
185
184
|
end
|
186
185
|
|
@@ -218,15 +217,7 @@ private
|
|
218
217
|
end
|
219
218
|
|
220
219
|
def hpg_info(attachment, extended=false)
|
221
|
-
|
222
|
-
data = api.get_app(app).body
|
223
|
-
{:info => [{
|
224
|
-
'name' => 'Data Size',
|
225
|
-
'values' => [format_bytes(data['database_size'])]
|
226
|
-
}]}
|
227
|
-
else
|
228
|
-
hpg_client(attachment).get_database(extended)
|
229
|
-
end
|
220
|
+
hpg_client(attachment).get_database(extended)
|
230
221
|
end
|
231
222
|
|
232
223
|
def hpg_info_display(item)
|
@@ -20,10 +20,11 @@ module Heroku::Command
|
|
20
20
|
pgbackup_client.get_transfers.each { |t|
|
21
21
|
next unless backup_types.member?(t['to_name']) && !t['error_at'] && !t['destroyed_at']
|
22
22
|
backups << {
|
23
|
-
'id'
|
24
|
-
'created_at'
|
25
|
-
'
|
26
|
-
'
|
23
|
+
'id' => backup_name(t['to_url']),
|
24
|
+
'created_at' => t['created_at'],
|
25
|
+
'status' => transfer_status(t),
|
26
|
+
'size' => t['size'],
|
27
|
+
'database' => t['from_name']
|
27
28
|
}
|
28
29
|
}
|
29
30
|
|
@@ -32,8 +33,8 @@ module Heroku::Command
|
|
32
33
|
else
|
33
34
|
display_table(
|
34
35
|
backups,
|
35
|
-
%w{ id created_at size database },
|
36
|
-
["ID", "Backup Time", "Size", "Database"]
|
36
|
+
%w{ id created_at status size database },
|
37
|
+
["ID", "Backup Time", "Status", "Size", "Database"]
|
37
38
|
)
|
38
39
|
end
|
39
40
|
end
|
@@ -90,6 +91,7 @@ module Heroku::Command
|
|
90
91
|
|
91
92
|
if backup["error_at"]
|
92
93
|
message = "An error occurred and your backup did not finish."
|
94
|
+
message += "\nPlease run `heroku logs --ps pgbackups` for details."
|
93
95
|
message += "\nThe database is not yet online. Please try again." if backup['log'] =~ /Name or service not known/
|
94
96
|
message += "\nThe database credentials are incorrect." if backup['log'] =~ /psql: FATAL:/
|
95
97
|
error(message)
|
@@ -157,7 +159,11 @@ module Heroku::Command
|
|
157
159
|
|
158
160
|
if restore["error_at"]
|
159
161
|
message = "An error occurred and your restore did not finish."
|
160
|
-
|
162
|
+
if restore['log'] =~ /Invalid dump format: .*: XML document text/
|
163
|
+
message += "\nThe backup url is invalid. Use `pgbackups:url` to generate a new temporary URL."
|
164
|
+
else
|
165
|
+
message += "\nPlease run `heroku logs --ps pgbackups` for details."
|
166
|
+
end
|
161
167
|
error(message)
|
162
168
|
end
|
163
169
|
end
|
@@ -183,6 +189,17 @@ module Heroku::Command
|
|
183
189
|
|
184
190
|
protected
|
185
191
|
|
192
|
+
def transfer_status(t)
|
193
|
+
if t['finished_at']
|
194
|
+
"Finished @ #{t["finished_at"]}"
|
195
|
+
elsif t['started_at']
|
196
|
+
step = t['progress'] && t['progress'].split[0]
|
197
|
+
step.nil? ? 'Unknown' : step_map[step]
|
198
|
+
else
|
199
|
+
"Unknown"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
186
203
|
def config_vars
|
187
204
|
@config_vars ||= api.get_config_vars(app).body
|
188
205
|
end
|
@@ -207,6 +224,7 @@ module Heroku::Command
|
|
207
224
|
error <<-EOM
|
208
225
|
Failed to query the PGBackups status API. Your backup may still be running.
|
209
226
|
Verify the status of your backup with `heroku pgbackups -a #{app}`
|
227
|
+
You can also watch progress with `heroku logs --tail --ps pgbackups -a #{app}`
|
210
228
|
EOM
|
211
229
|
end
|
212
230
|
|
@@ -228,7 +246,7 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
|
|
228
246
|
begin
|
229
247
|
sleep(sleep_time)
|
230
248
|
transfer = pgbackup_client.get_transfer(transfer["id"])
|
231
|
-
rescue
|
249
|
+
rescue
|
232
250
|
if sleep_time > 300
|
233
251
|
poll_error(app)
|
234
252
|
else
|
@@ -243,15 +261,8 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
|
|
243
261
|
return transfer
|
244
262
|
end
|
245
263
|
|
246
|
-
def
|
247
|
-
@
|
248
|
-
@last_updated_at ||= 0
|
249
|
-
@last_logs ||= []
|
250
|
-
@last_progress ||= ["", 0]
|
251
|
-
|
252
|
-
@ticks += 1
|
253
|
-
|
254
|
-
step_map = {
|
264
|
+
def step_map
|
265
|
+
@step_map ||= {
|
255
266
|
"dump" => "Capturing",
|
256
267
|
"upload" => "Storing",
|
257
268
|
"download" => "Retrieving",
|
@@ -259,6 +270,15 @@ Verify the status of your backup with `heroku pgbackups -a #{app}`
|
|
259
270
|
"gunzip" => "Uncompressing",
|
260
271
|
"load" => "Restoring",
|
261
272
|
}
|
273
|
+
end
|
274
|
+
|
275
|
+
def update_display(transfer)
|
276
|
+
@ticks ||= 0
|
277
|
+
@last_updated_at ||= 0
|
278
|
+
@last_logs ||= []
|
279
|
+
@last_progress ||= ["", 0]
|
280
|
+
|
281
|
+
@ticks += 1
|
262
282
|
|
263
283
|
if !transfer["log"]
|
264
284
|
@last_progress = ['pending', nil]
|
data/lib/heroku/command/ps.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "heroku/command/base"
|
2
2
|
|
3
|
-
# manage
|
3
|
+
# manage dynos (dynos, workers)
|
4
4
|
#
|
5
5
|
class Heroku::Command::Ps < Heroku::Command::Base
|
6
6
|
|
@@ -80,12 +80,12 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
80
80
|
|
81
81
|
# ps
|
82
82
|
#
|
83
|
-
# list
|
83
|
+
# list dynos for an app
|
84
84
|
#
|
85
85
|
#Example:
|
86
86
|
#
|
87
87
|
# $ heroku ps
|
88
|
-
# === run: one-off
|
88
|
+
# === run: one-off dyno
|
89
89
|
# run.1: up for 5m: `bash`
|
90
90
|
#
|
91
91
|
# === web: `bundle exec thin start -p $PORT`
|
@@ -99,21 +99,23 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
99
99
|
processes.each do |process|
|
100
100
|
name = process["process"].split(".").first
|
101
101
|
elapsed = time_ago(Time.now - process['elapsed'])
|
102
|
+
size = process.fetch("size", 1)
|
102
103
|
|
103
104
|
if name == "run"
|
104
105
|
key = "run: one-off processes"
|
105
|
-
item = "%s: %s %s: `%s`" % [ process["process"], process["state"], elapsed, process["command"] ]
|
106
|
+
item = "%s (%sX): %s %s: `%s`" % [ process["process"], size, process["state"], elapsed, process["command"] ]
|
106
107
|
else
|
107
|
-
key = "#{name}: `#{process["command"]}`"
|
108
|
+
key = "#{name} (#{size}X): `#{process["command"]}`"
|
108
109
|
item = "%s: %s %s" % [ process["process"], process["state"], elapsed ]
|
109
110
|
end
|
110
111
|
|
111
112
|
processes_by_command[key] << item
|
112
113
|
end
|
113
114
|
|
115
|
+
extract_run_id = /\.(\d+).*:/
|
114
116
|
processes_by_command.keys.each do |key|
|
115
117
|
processes_by_command[key] = processes_by_command[key].sort do |x,y|
|
116
|
-
x.match(
|
118
|
+
x.match(extract_run_id).captures.first.to_i <=> y.match(extract_run_id).captures.first.to_i
|
117
119
|
end
|
118
120
|
end
|
119
121
|
|
@@ -123,36 +125,36 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
126
|
-
# ps:restart [
|
128
|
+
# ps:restart [DYNO]
|
127
129
|
#
|
128
|
-
# restart an app
|
130
|
+
# restart an app dyno
|
129
131
|
#
|
130
|
-
# if
|
132
|
+
# if DYNO is not specified, restarts all dynos on the app
|
131
133
|
#
|
132
134
|
#Examples:
|
133
135
|
#
|
134
136
|
# $ heroku ps:restart web.1
|
135
|
-
# Restarting web.1
|
137
|
+
# Restarting web.1 dyno... done
|
136
138
|
#
|
137
139
|
# $ heroku ps:restart web
|
138
|
-
# Restarting web
|
140
|
+
# Restarting web dyno... done
|
139
141
|
#
|
140
142
|
# $ heroku ps:restart
|
141
|
-
# Restarting
|
143
|
+
# Restarting dynos... done
|
142
144
|
#
|
143
145
|
def restart
|
144
|
-
|
146
|
+
dyno = shift_argument
|
145
147
|
validate_arguments!
|
146
148
|
|
147
|
-
message, options = case
|
149
|
+
message, options = case dyno
|
148
150
|
when NilClass
|
149
|
-
["Restarting
|
151
|
+
["Restarting dynos", {}]
|
150
152
|
when /.+\..+/
|
151
153
|
ps = args.first
|
152
|
-
["Restarting #{ps}
|
154
|
+
["Restarting #{ps} dyno", { :ps => ps }]
|
153
155
|
else
|
154
156
|
type = args.first
|
155
|
-
["Restarting #{type}
|
157
|
+
["Restarting #{type} dynos", { :type => type }]
|
156
158
|
end
|
157
159
|
|
158
160
|
action(message) do
|
@@ -162,15 +164,15 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
162
164
|
|
163
165
|
alias_command "restart", "ps:restart"
|
164
166
|
|
165
|
-
# ps:scale
|
167
|
+
# ps:scale DYNO1=AMOUNT1 [DYNO2=AMOUNT2 ...]
|
166
168
|
#
|
167
|
-
# scale
|
169
|
+
# scale dynos by the given amount
|
168
170
|
#
|
169
171
|
#Examples:
|
170
172
|
#
|
171
173
|
# $ heroku ps:scale web=3 worker+1
|
172
|
-
# Scaling web
|
173
|
-
# Scaling worker
|
174
|
+
# Scaling web dynos... done, now running 3
|
175
|
+
# Scaling worker dynos... done, now running 1
|
174
176
|
#
|
175
177
|
def scale
|
176
178
|
changes = {}
|
@@ -181,14 +183,14 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
181
183
|
end
|
182
184
|
|
183
185
|
if changes.empty?
|
184
|
-
error("Usage: heroku ps:scale
|
186
|
+
error("Usage: heroku ps:scale DYNO1=AMOUNT1 [DYNO2=AMOUNT2 ...]\nMust specify DYNO and AMOUNT to scale.")
|
185
187
|
end
|
186
188
|
|
187
|
-
changes.keys.sort.each do |
|
188
|
-
amount = changes[
|
189
|
-
action("Scaling #{
|
189
|
+
changes.keys.sort.each do |dyno|
|
190
|
+
amount = changes[dyno]
|
191
|
+
action("Scaling #{dyno} dynos") do
|
190
192
|
amount.gsub!("=", "")
|
191
|
-
new_qty = api.post_ps_scale(app,
|
193
|
+
new_qty = api.post_ps_scale(app, dyno, amount).body
|
192
194
|
status("now running #{new_qty}")
|
193
195
|
end
|
194
196
|
end
|
@@ -196,31 +198,31 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
196
198
|
|
197
199
|
alias_command "scale", "ps:scale"
|
198
200
|
|
199
|
-
# ps:stop
|
201
|
+
# ps:stop DYNOS
|
200
202
|
#
|
201
|
-
# stop an app
|
203
|
+
# stop an app dyno
|
202
204
|
#
|
203
205
|
# Examples:
|
204
206
|
#
|
205
207
|
# $ heroku stop run.3
|
206
|
-
# Stopping run.3
|
208
|
+
# Stopping run.3 dyno... done
|
207
209
|
#
|
208
210
|
# $ heroku stop run
|
209
|
-
# Stopping run
|
211
|
+
# Stopping run dynos... done
|
210
212
|
#
|
211
213
|
def stop
|
212
|
-
|
214
|
+
dyno = shift_argument
|
213
215
|
validate_arguments!
|
214
216
|
|
215
|
-
message, options = case
|
217
|
+
message, options = case dyno
|
216
218
|
when NilClass
|
217
|
-
error("Usage: heroku ps:stop
|
219
|
+
error("Usage: heroku ps:stop DYNO\nMust specify DYNO to stop.")
|
218
220
|
when /.+\..+/
|
219
221
|
ps = args.first
|
220
|
-
["Stopping #{ps}
|
222
|
+
["Stopping #{ps} dyno", { :ps => ps }]
|
221
223
|
else
|
222
224
|
type = args.first
|
223
|
-
["Stopping #{type}
|
225
|
+
["Stopping #{type} dynos", { :type => type }]
|
224
226
|
end
|
225
227
|
|
226
228
|
action(message) do
|
@@ -229,4 +231,49 @@ class Heroku::Command::Ps < Heroku::Command::Base
|
|
229
231
|
end
|
230
232
|
|
231
233
|
alias_command "stop", "ps:stop"
|
234
|
+
|
235
|
+
# ps:resize DYNO1=1X|2X [DYNO2=1X|2X ...]
|
236
|
+
#
|
237
|
+
# resize dynos to the given size
|
238
|
+
#
|
239
|
+
# Example:
|
240
|
+
#
|
241
|
+
# $ heroku ps:resize web=2X worker=1X
|
242
|
+
# Resizing and restarting the specified dynos... done
|
243
|
+
# web dynos now 2X ($0.10/dyno-hour)
|
244
|
+
# worker dynos now 1X ($0.05/dyno-hour)
|
245
|
+
#
|
246
|
+
def resize
|
247
|
+
app
|
248
|
+
changes = {}
|
249
|
+
args.each do |arg|
|
250
|
+
if arg =~ /^([a-zA-Z0-9_]+)=(\d+)([xX]?)$/
|
251
|
+
changes[$1] = { "size" => $2.to_i }
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
if changes.empty?
|
256
|
+
message = [
|
257
|
+
"Usage: heroku ps:resize DYNO1=1X|2X [DYNO2=1X|2X ...]",
|
258
|
+
"Must specify DYNO and SIZE to resize."
|
259
|
+
]
|
260
|
+
error(message.join("\n"))
|
261
|
+
end
|
262
|
+
|
263
|
+
action("Resizing and restarting the specified dynos") do
|
264
|
+
api.request(
|
265
|
+
:expects => 200,
|
266
|
+
:method => :put,
|
267
|
+
:path => "/apps/#{app}/formation",
|
268
|
+
:body => json_encode(changes)
|
269
|
+
)
|
270
|
+
end
|
271
|
+
changes.each do |type, options|
|
272
|
+
size = options["size"]
|
273
|
+
price = sprintf("%.2f", 0.05 * size)
|
274
|
+
display "#{type} dynos now #{size}X ($#{price}/dyno-hour)"
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
alias_command "resize", "ps:resize"
|
232
279
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "heroku/command/base"
|
2
|
+
|
3
|
+
# list available regions
|
4
|
+
#
|
5
|
+
class Heroku::Command::Regions < Heroku::Command::Base
|
6
|
+
|
7
|
+
# regions
|
8
|
+
#
|
9
|
+
# List available regions for deployment
|
10
|
+
#
|
11
|
+
#Example:
|
12
|
+
#
|
13
|
+
# $ heroku regions
|
14
|
+
# === Regions
|
15
|
+
# us
|
16
|
+
# eu
|
17
|
+
def index
|
18
|
+
regions = json_decode(heroku.get("/regions"))
|
19
|
+
styled_header("Regions")
|
20
|
+
styled_array(regions.map { |region| [region["slug"], region["name"]] })
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -11,7 +11,7 @@ class Heroku::Command::Releases < Heroku::Command::Base
|
|
11
11
|
#Example:
|
12
12
|
#
|
13
13
|
# $ heroku releases
|
14
|
-
# ===
|
14
|
+
# === example Releases
|
15
15
|
# v1 Config add FOO_BAR by email@example.com 0s ago
|
16
16
|
# v2 Config add BAR_BAZ by email@example.com 0s ago
|
17
17
|
# v3 Config add BAZ_QUX by email@example.com 0s ago
|
@@ -105,10 +105,10 @@ class Heroku::Command::Releases < Heroku::Command::Base
|
|
105
105
|
#Example:
|
106
106
|
#
|
107
107
|
# $ heroku releases:rollback
|
108
|
-
# Rolling back
|
108
|
+
# Rolling back example... done, v122
|
109
109
|
#
|
110
110
|
# $ heroku releases:rollback v42
|
111
|
-
# Rolling back
|
111
|
+
# Rolling back example to v42... done
|
112
112
|
#
|
113
113
|
def rollback
|
114
114
|
release = shift_argument
|
data/lib/heroku/command/run.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "readline"
|
2
2
|
require "heroku/command/base"
|
3
|
+
require "heroku/helpers/log_displayer"
|
3
4
|
|
4
5
|
# run one-off commands (console, rake)
|
5
6
|
#
|
@@ -7,7 +8,9 @@ class Heroku::Command::Run < Heroku::Command::Base
|
|
7
8
|
|
8
9
|
# run COMMAND
|
9
10
|
#
|
10
|
-
# run an attached
|
11
|
+
# run an attached dyno
|
12
|
+
#
|
13
|
+
# -s, --size SIZE # specify dyno size
|
11
14
|
#
|
12
15
|
#Example:
|
13
16
|
#
|
@@ -17,13 +20,16 @@ class Heroku::Command::Run < Heroku::Command::Base
|
|
17
20
|
#
|
18
21
|
def index
|
19
22
|
command = args.join(" ")
|
20
|
-
error("Usage: heroku run COMMAND")if command.empty?
|
23
|
+
error("Usage: heroku run COMMAND") if command.empty?
|
21
24
|
run_attached(command)
|
22
25
|
end
|
23
26
|
|
24
27
|
# run:detached COMMAND
|
25
28
|
#
|
26
|
-
# run a detached
|
29
|
+
# run a detached dyno, where output is sent to your logs
|
30
|
+
#
|
31
|
+
# -s, --size SIZE # specify dyno size
|
32
|
+
# -t, --tail # stream logs for the dyno
|
27
33
|
#
|
28
34
|
#Example:
|
29
35
|
#
|
@@ -33,14 +39,25 @@ class Heroku::Command::Run < Heroku::Command::Base
|
|
33
39
|
#
|
34
40
|
def detached
|
35
41
|
command = args.join(" ")
|
36
|
-
error("Usage: heroku run COMMAND")if command.empty?
|
42
|
+
error("Usage: heroku run COMMAND") if command.empty?
|
37
43
|
opts = { :attach => false, :command => command }
|
44
|
+
opts[:size] = get_size if options[:size]
|
45
|
+
|
46
|
+
app_name = app
|
38
47
|
process_data = action("Running `#{command}` detached", :success => "up") do
|
39
|
-
process_data = api.post_ps(
|
48
|
+
process_data = api.post_ps(app_name, command, opts).body
|
40
49
|
status(process_data['process'])
|
41
50
|
process_data
|
42
51
|
end
|
43
|
-
|
52
|
+
if options[:tail]
|
53
|
+
opts = []
|
54
|
+
opts << "tail=1"
|
55
|
+
opts << "ps=#{process_data['process']}"
|
56
|
+
log_displayer = ::Heroku::Helpers::LogDisplayer.new(heroku, app, opts)
|
57
|
+
log_displayer.display_logs
|
58
|
+
else
|
59
|
+
display("Use `heroku logs -p #{process_data['process']}` to view the output.")
|
60
|
+
end
|
44
61
|
end
|
45
62
|
|
46
63
|
# run:rake COMMAND
|
@@ -75,37 +92,27 @@ class Heroku::Command::Run < Heroku::Command::Base
|
|
75
92
|
#Examples:
|
76
93
|
#
|
77
94
|
# $ heroku console
|
78
|
-
# Ruby console for
|
95
|
+
# Ruby console for example.heroku.com
|
79
96
|
# >>
|
80
97
|
#
|
81
98
|
def console
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
rescue RestClient::RequestFailed => e
|
89
|
-
if e.http_body =~ /For Cedar apps, use: `heroku run console`/
|
90
|
-
deprecate("`heroku #{current_command}` has been deprecated for Cedar apps. Please use: `heroku run console` instead.")
|
91
|
-
command = "console #{args.join(' ')}"
|
92
|
-
run_attached(command)
|
93
|
-
else
|
94
|
-
raise(e)
|
95
|
-
end
|
96
|
-
rescue RestClient::RequestTimeout
|
97
|
-
error("Timed out. Long running requests are not supported on the console.\nPlease consider creating a rake task instead.")
|
98
|
-
rescue Heroku::Client::AppCrashed => e
|
99
|
-
error(e.message)
|
99
|
+
puts "`heroku #{current_command}` has been removed. Please use: `heroku run` instead."
|
100
|
+
puts "For more information, please see:"
|
101
|
+
puts " * https://devcenter.heroku.com/articles/one-off-dynos"
|
102
|
+
puts " * https://devcenter.heroku.com/articles/rails3#console"
|
103
|
+
puts " * https://devcenter.heroku.com/articles/console-bamboo"
|
100
104
|
end
|
101
|
-
|
102
105
|
alias_command "console", "run:console"
|
103
106
|
|
104
107
|
protected
|
105
108
|
|
106
109
|
def run_attached(command)
|
110
|
+
app_name = app
|
111
|
+
opts = { :attach => true, :ps_env => get_terminal_environment }
|
112
|
+
opts[:size] = get_size if options[:size]
|
113
|
+
|
107
114
|
process_data = action("Running `#{command}` attached to terminal", :success => "up") do
|
108
|
-
process_data = api.post_ps(
|
115
|
+
process_data = api.post_ps(app_name, command, opts).body
|
109
116
|
status(process_data["process"])
|
110
117
|
process_data
|
111
118
|
end
|
@@ -178,4 +185,10 @@ protected
|
|
178
185
|
Readline::HISTORY.push(cmd)
|
179
186
|
File.open(console_history_file(app), "a") { |f| f.puts cmd + "\n" }
|
180
187
|
end
|
188
|
+
|
189
|
+
def get_size
|
190
|
+
size = options[:size].to_i
|
191
|
+
error("Must specify SIZE in format '1X' or '2X'.") if size <= 0
|
192
|
+
size
|
193
|
+
end
|
181
194
|
end
|