shelly 0.1.21 → 0.1.22

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.
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
@@ -1,5 +1,6 @@
1
1
  module Shelly
2
2
  class Backup < Model
3
+ LIMIT = 10
3
4
  attr_reader :filename, :size, :human_size, :code_name, :kind, :state
4
5
 
5
6
  def initialize(attributes = {})
@@ -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
 
@@ -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 = "?" + options.map { |k, v|
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
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.1.21"
2
+ VERSION = "0.1.22"
3
3
  end
data/lib/thor/thor.rb CHANGED
@@ -12,6 +12,7 @@ class Thor
12
12
  def send(*args)
13
13
  if args.first == :dispatch && !args[2].empty?
14
14
  running_task = args[2].first
15
+
15
16
  @hook.each do |method, options|
16
17
  if options[:only].include?(running_task.to_sym)
17
18
  new.send(method)
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.8.0"
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"
@@ -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([{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb", "size" => 12345, "state" => "completed"}])
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
- @user = Shelly::User.new
567
- @client.stub(:token).and_return("abc")
568
- FileUtils.mkdir_p("/projects/foo")
569
- Dir.chdir("/projects/foo")
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
- @user = Shelly::User.new
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
- FileUtils.mkdir_p("/projects/foo")
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
- @user = Shelly::User.new
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
- @user = Shelly::User.new
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
- @client.stub(:token).and_return("abc")
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.21
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.8.0
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.8.0
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