shelly 0.1.21 → 0.1.22
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/lib/shelly/app.rb +5 -1
- data/lib/shelly/backup.rb +1 -0
- data/lib/shelly/cli/backup.rb +9 -1
- data/lib/shelly/cli/main.rb +10 -1
- data/lib/shelly/client.rb +6 -3
- data/lib/shelly/version.rb +1 -1
- data/lib/thor/thor.rb +1 -0
- data/shelly.gemspec +1 -1
- data/spec/shelly/app_spec.rb +19 -2
- data/spec/shelly/cli/backup_spec.rb +18 -2
- data/spec/shelly/cli/main_spec.rb +44 -48
- metadata +4 -9
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
## 0.1.22 / 2012-08-06
|
2
|
+
|
3
|
+
* [feature] Add dbconsole to access 'rails dbconsole' on Shelly Cloud.
|
4
|
+
|
5
|
+
* [feature] Limit backups list to 10 backups, --all option to list all backups.
|
6
|
+
|
7
|
+
Usage: ```shelly backup list --all```
|
8
|
+
|
9
|
+
## 0.1.21 / 2012-08-06
|
10
|
+
|
11
|
+
* [refactoring] Adjusted shelly console to match new API.
|
data/lib/shelly/app.rb
CHANGED
@@ -176,6 +176,10 @@ module Shelly
|
|
176
176
|
ssh_command("rake_runner \"#{task}\"")
|
177
177
|
end
|
178
178
|
|
179
|
+
def dbconsole
|
180
|
+
ssh_command("dbconsole")
|
181
|
+
end
|
182
|
+
|
179
183
|
def attributes
|
180
184
|
@attributes ||= shelly.app(code_name)
|
181
185
|
end
|
@@ -244,7 +248,7 @@ module Shelly
|
|
244
248
|
end
|
245
249
|
|
246
250
|
def ssh_command(command = "")
|
247
|
-
exec "ssh #{ssh_options} #{ssh['host']} #{command}"
|
251
|
+
exec "ssh #{ssh_options} -t #{ssh['host']} #{command}"
|
248
252
|
end
|
249
253
|
|
250
254
|
def ssh_options
|
data/lib/shelly/backup.rb
CHANGED
data/lib/shelly/cli/backup.rb
CHANGED
@@ -12,13 +12,21 @@ module Shelly
|
|
12
12
|
|
13
13
|
class_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
14
14
|
|
15
|
+
method_option :all, :type => :boolean, :aliases => "-a",
|
16
|
+
:desc => "Show all backups"
|
15
17
|
desc "list", "List available database backups"
|
16
18
|
def list
|
17
19
|
app = multiple_clouds(options[:cloud], "backup list")
|
18
20
|
backups = app.database_backups
|
19
21
|
if backups.present?
|
22
|
+
limit = -1
|
23
|
+
unless options[:all] || backups.count < (Shelly::Backup::LIMIT + 1)
|
24
|
+
limit = Shelly::Backup::LIMIT - 1
|
25
|
+
say "Limiting the number of backups to #{Shelly::Backup::LIMIT}."
|
26
|
+
say "Use --all or -a option to list all backups."
|
27
|
+
end
|
20
28
|
to_display = [["Filename", "| Size", "| State"]]
|
21
|
-
backups.each do |backup|
|
29
|
+
backups[0..limit].each do |backup|
|
22
30
|
to_display << [backup.filename, "| #{backup.human_size}", "| #{backup.state.humanize}"]
|
23
31
|
end
|
24
32
|
|
data/lib/shelly/cli/main.rb
CHANGED
@@ -20,7 +20,7 @@ module Shelly
|
|
20
20
|
check_unknown_options!(:except => :rake)
|
21
21
|
|
22
22
|
# FIXME: it should be possible to pass single symbol, instead of one element array
|
23
|
-
before_hook :logged_in?, :only => [:add, :status, :list, :start, :stop, :logs, :delete, :info, :ip, :logout, :execute, :rake, :setup, :console]
|
23
|
+
before_hook :logged_in?, :only => [:add, :status, :list, :start, :stop, :logs, :delete, :info, :ip, :logout, :execute, :rake, :setup, :console, :dbconsole]
|
24
24
|
before_hook :inside_git_repository?, :only => [:add, :setup, :check]
|
25
25
|
|
26
26
|
map %w(-v --version) => :version
|
@@ -318,6 +318,15 @@ We have been notified about it. We will be adding new resources shortly}
|
|
318
318
|
say_error "Cloud #{app} is not running. Cannot run rake task."
|
319
319
|
end
|
320
320
|
|
321
|
+
desc "dbconsole", "Run rails dbconsole"
|
322
|
+
method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
323
|
+
def dbconsole(task = nil)
|
324
|
+
app = multiple_clouds(options[:cloud], "dbconsole")
|
325
|
+
app.dbconsole
|
326
|
+
rescue Client::ConflictException
|
327
|
+
say_error "Cloud #{app} is not running. Cannot run dbconsole."
|
328
|
+
end
|
329
|
+
|
321
330
|
desc "redeploy", "Redeploy application"
|
322
331
|
method_option :cloud, :type => :string, :aliases => "-c",
|
323
332
|
:desc => "Specify which cloud to redeploy application for"
|
data/lib/shelly/client.rb
CHANGED
@@ -147,9 +147,7 @@ module Shelly
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def application_logs(cloud, options = {})
|
150
|
-
query
|
151
|
-
URI.escape(k.to_s) + "=" + URI.escape(v.to_s) }.join("&")
|
152
|
-
get("/apps/#{cloud}/application_logs#{query}")
|
150
|
+
get("/apps/#{cloud}/application_logs#{query(options)}")
|
153
151
|
end
|
154
152
|
|
155
153
|
def database_backups(code_name)
|
@@ -176,6 +174,11 @@ module Shelly
|
|
176
174
|
post("/apps/#{cloud}/deploys")
|
177
175
|
end
|
178
176
|
|
177
|
+
def query(options = {})
|
178
|
+
"?" + options.map { |k, v|
|
179
|
+
URI.escape(k.to_s) + "=" + URI.escape(v.to_s) }.join("&")
|
180
|
+
end
|
181
|
+
|
179
182
|
def post(path, params = {})
|
180
183
|
request(path, :post, params)
|
181
184
|
end
|
data/lib/shelly/version.rb
CHANGED
data/lib/thor/thor.rb
CHANGED
data/shelly.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.description = %q{Tool for managing applications and clouds at shellycloud.com}
|
13
13
|
|
14
14
|
s.rubyforge_project = "shelly"
|
15
|
-
s.add_development_dependency "rspec", "~> 2.
|
15
|
+
s.add_development_dependency "rspec", "~> 2.11.0"
|
16
16
|
s.add_development_dependency "rake"
|
17
17
|
s.add_development_dependency "guard"
|
18
18
|
s.add_development_dependency "guard-rspec"
|
data/spec/shelly/app_spec.rb
CHANGED
@@ -253,6 +253,14 @@ describe Shelly::App do
|
|
253
253
|
end
|
254
254
|
end
|
255
255
|
|
256
|
+
describe "#database_backups" do
|
257
|
+
it "should add limit parameter" do
|
258
|
+
@client.stub_chain(:database_backups, :map)
|
259
|
+
@client.should_receive(:database_backups).with("foo-staging")
|
260
|
+
@app.database_backups
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
256
264
|
describe "#database_backup" do
|
257
265
|
before do
|
258
266
|
@description = {
|
@@ -312,11 +320,20 @@ describe Shelly::App do
|
|
312
320
|
it "should return result of rake task" do
|
313
321
|
@client.stub(:console).and_return(
|
314
322
|
{"host" => "console.example.com", "port" => "40010", "user" => "foo"})
|
315
|
-
@app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo console.example.com rake_runner \"test\"")
|
323
|
+
@app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com rake_runner \"test\"")
|
316
324
|
@app.rake("test")
|
317
325
|
end
|
318
326
|
end
|
319
327
|
|
328
|
+
describe "#dbconsole" do
|
329
|
+
it "should return result of dbconsole" do
|
330
|
+
@client.stub(:console).and_return(
|
331
|
+
{"host" => "console.example.com", "port" => "40010", "user" => "foo"})
|
332
|
+
@app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com dbconsole")
|
333
|
+
@app.dbconsole
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
320
337
|
describe "#to_s" do
|
321
338
|
it "should return code_name" do
|
322
339
|
@app.to_s.should == "foo-staging"
|
@@ -342,7 +359,7 @@ describe Shelly::App do
|
|
342
359
|
it "should run ssh with all parameters" do
|
343
360
|
@client.stub(:console).and_return(
|
344
361
|
{"host" => "console.example.com", "port" => "40010", "user" => "foo"})
|
345
|
-
@app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo console.example.com ")
|
362
|
+
@app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com ")
|
346
363
|
@app.console
|
347
364
|
end
|
348
365
|
end
|
@@ -31,23 +31,39 @@ describe Shelly::CLI::Backup do
|
|
31
31
|
|
32
32
|
# multiple_clouds is tested in main_spec.rb in describe "#start" block
|
33
33
|
it "should ensure multiple_clouds check" do
|
34
|
-
@client.should_receive(:database_backups).with("foo-staging").and_return(
|
34
|
+
@client.should_receive(:database_backups).with("foo-staging").and_return(
|
35
|
+
[{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb",
|
36
|
+
"size" => 12345, "state" => "completed"}])
|
35
37
|
@backup.should_receive(:multiple_clouds).and_return(@app)
|
36
38
|
invoke(@backup, :list)
|
37
39
|
end
|
38
40
|
|
39
41
|
it "should take cloud from command line for which to show backups" do
|
42
|
+
stub_const("Shelly::Backup::LIMIT", 1)
|
40
43
|
@client.should_receive(:database_backups).with("foo-staging").and_return(
|
41
44
|
[{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb",
|
42
45
|
"size" => 12345, "state" => "completed"},
|
43
46
|
{"filename" => "backup.mongo.tar.gz", "human_size" => "22kb",
|
44
47
|
"size" => 333, "state" => "in_progress"}])
|
48
|
+
$stdout.should_not_receive(:puts).with("Limiting the number of backups to 1.")
|
45
49
|
$stdout.should_receive(:puts).with(green "Available backups:")
|
46
50
|
$stdout.should_receive(:puts).with("\n")
|
47
51
|
$stdout.should_receive(:puts).with(" Filename | Size | State")
|
48
52
|
$stdout.should_receive(:puts).with(" backup.postgre.tar.gz | 10kb | completed")
|
49
53
|
$stdout.should_receive(:puts).with(" backup.mongo.tar.gz | 22kb | in progress")
|
50
|
-
@backup.options = {:cloud => "foo-staging"}
|
54
|
+
@backup.options = {:cloud => "foo-staging", :all => true}
|
55
|
+
invoke(@backup, :list)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should show --all option if not present" do
|
59
|
+
stub_const("Shelly::Backup::LIMIT", 1)
|
60
|
+
$stdout.should_receive(:puts).with("Limiting the number of backups to 1.")
|
61
|
+
$stdout.should_receive(:puts).with("Use --all or -a option to list all backups.")
|
62
|
+
@client.should_receive(:database_backups).with("foo-staging").and_return(
|
63
|
+
[{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb",
|
64
|
+
"size" => 12345, "state" => "completed"},
|
65
|
+
{"filename" => "backup.mongo.tar.gz", "human_size" => "22kb",
|
66
|
+
"size" => 333, "state" => "in_progress"}])
|
51
67
|
invoke(@backup, :list)
|
52
68
|
end
|
53
69
|
|
@@ -9,6 +9,7 @@ describe Shelly::CLI::Main do
|
|
9
9
|
@main = Shelly::CLI::Main.new
|
10
10
|
Shelly::CLI::Main.stub(:new).and_return(@main)
|
11
11
|
@client = mock
|
12
|
+
@client.stub(:token).and_return("abc")
|
12
13
|
Shelly::Client.stub(:new).and_return(@client)
|
13
14
|
Shelly::User.stub(:guess_email).and_return("")
|
14
15
|
$stdout.stub(:puts)
|
@@ -31,6 +32,7 @@ Tasks:
|
|
31
32
|
shelly check # Check if application fulfills Shelly Cloud requirements
|
32
33
|
shelly config <command> # Manage application configuration files
|
33
34
|
shelly console # Open application console
|
35
|
+
shelly dbconsole # Run rails dbconsole
|
34
36
|
shelly delete # Delete the cloud
|
35
37
|
shelly deploys <command> # View deploy logs
|
36
38
|
shelly execute CODE # Run code on one of application servers
|
@@ -563,16 +565,10 @@ OUT
|
|
563
565
|
|
564
566
|
describe "#start" do
|
565
567
|
before do
|
566
|
-
|
567
|
-
@client.stub(:
|
568
|
-
|
569
|
-
|
570
|
-
File.open("Cloudfile", 'w') {|f| f.write("foo-production:\n") }
|
571
|
-
Shelly::User.stub(:new).and_return(@user)
|
572
|
-
@client.stub(:apps).and_return([{"code_name" => "foo-production", "state" => "running"},
|
573
|
-
{"code_name" => "foo-staging", "state" => "no_code"}])
|
574
|
-
@app = Shelly::App.new
|
575
|
-
Shelly::App.stub(:new).and_return(@app)
|
568
|
+
setup_project
|
569
|
+
@client.stub(:apps).and_return([
|
570
|
+
{"code_name" => "foo-production", "state" => "running"},
|
571
|
+
{"code_name" => "foo-staging", "state" => "no_code"}])
|
576
572
|
end
|
577
573
|
|
578
574
|
it "should ensure user has logged in" do
|
@@ -1074,16 +1070,7 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1074
1070
|
|
1075
1071
|
describe "#logs" do
|
1076
1072
|
before do
|
1077
|
-
|
1078
|
-
@client.stub(:token).and_return("abc")
|
1079
|
-
FileUtils.mkdir_p("/projects/foo")
|
1080
|
-
Dir.chdir("/projects/foo")
|
1081
|
-
File.open("Cloudfile", 'w') { |f| f.write("foo-production:\n") }
|
1082
|
-
Shelly::User.stub(:new).and_return(@user)
|
1083
|
-
@client.stub(:apps).and_return([{"code_name" => "foo-production"},
|
1084
|
-
{"code_name" => "foo-staging"}])
|
1085
|
-
@app = Shelly::App.new
|
1086
|
-
Shelly::App.stub(:new).and_return(@app)
|
1073
|
+
setup_project
|
1087
1074
|
@sample_logs = {"entries" => [['app1', 'log1'], ['app1', 'log2']]}
|
1088
1075
|
end
|
1089
1076
|
|
@@ -1123,14 +1110,7 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1123
1110
|
|
1124
1111
|
describe "#rake" do
|
1125
1112
|
before do
|
1126
|
-
|
1127
|
-
Dir.chdir("/projects/foo")
|
1128
|
-
File.open("Cloudfile", 'w') {|f| f.write("foo-production:\n") }
|
1129
|
-
@user = Shelly::User.new
|
1130
|
-
@user.stub(:token)
|
1131
|
-
Shelly::User.stub(:new).and_return(@user)
|
1132
|
-
@app = Shelly::App.new("foo-production")
|
1133
|
-
Shelly::App.stub(:new).and_return(@app)
|
1113
|
+
setup_project
|
1134
1114
|
@main.stub(:rake_args).and_return(%w(db:migrate))
|
1135
1115
|
end
|
1136
1116
|
|
@@ -1167,13 +1147,7 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1167
1147
|
|
1168
1148
|
describe "#redeploy" do
|
1169
1149
|
before do
|
1170
|
-
|
1171
|
-
@client.stub(:token).and_return("abc")
|
1172
|
-
@app = Shelly::App.new("foo-production")
|
1173
|
-
Shelly::App.stub(:new).and_return(@app)
|
1174
|
-
FileUtils.mkdir_p("/projects/foo")
|
1175
|
-
Dir.chdir("/projects/foo")
|
1176
|
-
File.open("Cloudfile", 'w') { |f| f.write("foo-production:\n") }
|
1150
|
+
setup_project
|
1177
1151
|
end
|
1178
1152
|
|
1179
1153
|
# multiple_clouds is tested in main_spec.rb in describe "#start" block
|
@@ -1229,14 +1203,8 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1229
1203
|
|
1230
1204
|
describe "#open" do
|
1231
1205
|
before do
|
1232
|
-
|
1233
|
-
@client.stub(:token).and_return("abc")
|
1234
|
-
@app = Shelly::App.new("foo-production")
|
1206
|
+
setup_project
|
1235
1207
|
@app.stub(:open)
|
1236
|
-
Shelly::App.stub(:new).and_return(@app)
|
1237
|
-
FileUtils.mkdir_p("/projects/foo")
|
1238
|
-
Dir.chdir("/projects/foo")
|
1239
|
-
File.open("Cloudfile", 'w') { |f| f.write("foo-production:\n") }
|
1240
1208
|
end
|
1241
1209
|
|
1242
1210
|
# multiple_clouds is tested in main_spec.rb in describe "#start" block
|
@@ -1254,12 +1222,7 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1254
1222
|
|
1255
1223
|
describe "#console" do
|
1256
1224
|
before do
|
1257
|
-
|
1258
|
-
@app = Shelly::App.new("foo-production")
|
1259
|
-
Shelly::App.stub(:new).and_return(@app)
|
1260
|
-
FileUtils.mkdir_p("/projects/foo")
|
1261
|
-
Dir.chdir("/projects/foo")
|
1262
|
-
File.open("Cloudfile", 'w') { |f| f.write("foo-production:\n") }
|
1225
|
+
setup_project
|
1263
1226
|
end
|
1264
1227
|
|
1265
1228
|
it "should ensure user has logged in" do
|
@@ -1282,6 +1245,31 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1282
1245
|
end
|
1283
1246
|
end
|
1284
1247
|
|
1248
|
+
describe "#dbconsole" do
|
1249
|
+
before do
|
1250
|
+
setup_project
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
it "should ensure user has logged in" do
|
1254
|
+
hooks(@main, :dbconsole).should include(:logged_in?)
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
it "should execute ssh command" do
|
1258
|
+
@app.should_receive(:dbconsole)
|
1259
|
+
invoke(@main, :dbconsole)
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
context "Instances are not running" do
|
1263
|
+
it "should display error" do
|
1264
|
+
@client.stub(:console).and_raise(Shelly::Client::ConflictException)
|
1265
|
+
$stdout.should_receive(:puts).with(red "Cloud foo-production is not running. Cannot run dbconsole.")
|
1266
|
+
lambda {
|
1267
|
+
invoke(@main, :dbconsole)
|
1268
|
+
}.should raise_error(SystemExit)
|
1269
|
+
end
|
1270
|
+
end
|
1271
|
+
end
|
1272
|
+
|
1285
1273
|
describe "#check" do
|
1286
1274
|
before do
|
1287
1275
|
Shelly::App.stub(:inside_git_repository?).and_return(true)
|
@@ -1390,4 +1378,12 @@ We have been notified about it. We will be adding new resources shortly")
|
|
1390
1378
|
@main.check(false)
|
1391
1379
|
end
|
1392
1380
|
end
|
1381
|
+
|
1382
|
+
def setup_project(code_name = "foo")
|
1383
|
+
@app = Shelly::App.new("#{code_name}-production")
|
1384
|
+
Shelly::App.stub(:new).and_return(@app)
|
1385
|
+
FileUtils.mkdir_p("/projects/#{code_name}")
|
1386
|
+
Dir.chdir("/projects/#{code_name}")
|
1387
|
+
File.open("Cloudfile", 'w') { |f| f.write("#{code_name}-production:\n") }
|
1388
|
+
end
|
1393
1389
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shelly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.22
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 2.
|
21
|
+
version: 2.11.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 2.
|
29
|
+
version: 2.11.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -277,6 +277,7 @@ extra_rdoc_files: []
|
|
277
277
|
files:
|
278
278
|
- .gitignore
|
279
279
|
- .travis.yml
|
280
|
+
- CHANGELOG.md
|
280
281
|
- Gemfile
|
281
282
|
- Guardfile
|
282
283
|
- README.md
|
@@ -342,18 +343,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
342
343
|
- - ! '>='
|
343
344
|
- !ruby/object:Gem::Version
|
344
345
|
version: '0'
|
345
|
-
segments:
|
346
|
-
- 0
|
347
|
-
hash: 2910498490410578861
|
348
346
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
349
347
|
none: false
|
350
348
|
requirements:
|
351
349
|
- - ! '>='
|
352
350
|
- !ruby/object:Gem::Version
|
353
351
|
version: '0'
|
354
|
-
segments:
|
355
|
-
- 0
|
356
|
-
hash: 2910498490410578861
|
357
352
|
requirements: []
|
358
353
|
rubyforge_project: shelly
|
359
354
|
rubygems_version: 1.8.24
|