shelly 0.2.24 → 0.2.25

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 CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.2.25 / 2013-06-06
2
+
3
+ * [feature] It's possible to import PostgreSQL and MongoDB database from a dump file with `shelly backup import KIND FILENAME`. See our documentation for more info https://shellycloud.com/documentation/database_backups#import_database
4
+
1
5
  ## 0.2.24 / 2013-06-04
2
6
 
3
7
  * [bug] exit gracefully when downloaded or restored database backup doesn't exist
data/lib/shelly/app.rb CHANGED
@@ -120,6 +120,10 @@ module Shelly
120
120
  shelly.restore_backup(code_name, filename)
121
121
  end
122
122
 
123
+ def import_database(kind, filename)
124
+ ssh(:command => "import_database #{kind} #{filename}")
125
+ end
126
+
123
127
  def request_backup(kinds)
124
128
  Array(kinds).each do |kind|
125
129
  shelly.request_backup(code_name, kind)
@@ -342,7 +346,7 @@ module Shelly
342
346
 
343
347
  def ssh(options = {})
344
348
  conn = console_connection(options[:server])
345
- exec "ssh #{ssh_options(conn)} -t #{conn['host']} #{options[:command]}"
349
+ system "ssh #{ssh_options(conn)} -t #{conn['host']} #{options[:command]}"
346
350
  end
347
351
 
348
352
  def ssh_options(conn = console_connection)
@@ -350,7 +354,7 @@ module Shelly
350
354
  end
351
355
 
352
356
  def rsync(source, destination)
353
- exec "rsync -avz -e 'ssh #{ssh_options}' --progress #{source} #{destination}"
357
+ system "rsync -avz -e 'ssh #{ssh_options}' --progress #{source} #{destination}"
354
358
  end
355
359
  end
356
360
  end
@@ -9,7 +9,7 @@ module Shelly
9
9
  namespace :backup
10
10
  include Helpers
11
11
 
12
- before_hook :logged_in?, :only => [:list, :get, :create, :restore]
12
+ before_hook :logged_in?, :only => [:list, :get, :create, :restore, :import]
13
13
 
14
14
  class_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
15
15
 
@@ -85,7 +85,7 @@ module Shelly
85
85
  def restore(filename)
86
86
  app = multiple_clouds(options[:cloud], "backup restore FILENAME")
87
87
  backup = app.database_backup(filename)
88
- say "You are about restore database #{backup.kind} for cloud #{backup.code_name} to state from #{backup.filename}"
88
+ say "You are about restore #{backup.kind} database for cloud #{backup.code_name} to state from #{backup.filename}"
89
89
  say_new_line
90
90
  ask_to_restore_database
91
91
  app.restore_backup(filename)
@@ -98,6 +98,37 @@ module Shelly
98
98
  rescue Client::ConflictException => e
99
99
  say_error e[:message]
100
100
  end
101
+
102
+ desc "import KIND FILENAME", "Import database from dump file"
103
+ long_desc %{
104
+ Import database from local dump file to your cloud
105
+ KIND - Database kind. Possible values are: postgresql or mongodb
106
+ FILENAME - Database dump file or directory (mongodb), it has to be in current working directory.
107
+ }
108
+ def import(kind, filename)
109
+ app = multiple_clouds(options[:cloud], "backup import KIND FILENAME")
110
+ unless ::File.exist?(filename)
111
+ say_error "File #{filename} doesn't exist"
112
+ end
113
+ say "You are about import #{kind} database for cloud #{app} to state from file #{filename}"
114
+ ask_to_import_database
115
+ archive = compress(filename)
116
+ say "Uploading #{archive}", :green
117
+ app.upload(archive)
118
+ say "Uploading done", :green
119
+ say "Importing database", :green
120
+ app.import_database(kind, archive)
121
+ say "Database imported successfully", :green
122
+ end
123
+
124
+ no_tasks do
125
+ def compress(filename)
126
+ archive_name = "#{::File.basename(filename)}.tar"
127
+ say "Compressing #{filename} into #{archive_name}", :green
128
+ system("tar -cf #{archive_name} #{filename}")
129
+ archive_name
130
+ end
131
+ end
101
132
  end
102
133
  end
103
134
  end
@@ -72,6 +72,11 @@ More info at http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository}
72
72
  say_new_line say_error "Canceled" unless delete_application == "yes"
73
73
  end
74
74
 
75
+ def ask_to_import_database
76
+ import_database = ask("I want to import the database (yes/no):")
77
+ say_new_line say_error "Canceled" unless import_database == "yes"
78
+ end
79
+
75
80
  def logged_in?
76
81
  user = Shelly::User.new
77
82
  user.token
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.2.24"
2
+ VERSION = "0.2.25"
3
3
  end
@@ -293,7 +293,7 @@ describe Shelly::App do
293
293
  it "should return result of rake task" do
294
294
  @client.stub(:console).and_return(
295
295
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
296
- @app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com rake_runner \"test\"")
296
+ @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com rake_runner \"test\"")
297
297
  @app.rake("test")
298
298
  end
299
299
  end
@@ -302,7 +302,7 @@ describe Shelly::App do
302
302
  it "should return result of dbconsole" do
303
303
  @client.stub(:console).and_return(
304
304
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
305
- @app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com dbconsole")
305
+ @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com dbconsole")
306
306
  @app.dbconsole
307
307
  end
308
308
  end
@@ -333,14 +333,14 @@ describe Shelly::App do
333
333
  it "should run ssh with all parameters" do
334
334
  @client.stub(:console).and_return(
335
335
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
336
- @app.should_receive(:exec).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com ")
336
+ @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com ")
337
337
  @app.console
338
338
  end
339
339
 
340
340
  context "when server passed" do
341
341
  it "should request console on given server" do
342
342
  @client.should_receive(:console).with("foo-staging", "app1").and_return({})
343
- @app.stub(:exec)
343
+ @app.stub(:system)
344
344
  @app.console("app1")
345
345
  end
346
346
  end
@@ -357,7 +357,7 @@ describe Shelly::App do
357
357
  it "should run rsync with proper parameters" do
358
358
  @client.stub(:console).and_return(
359
359
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
360
- @app.should_receive(:exec).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress /path console.example.com:/srv/glusterfs/disk")
360
+ @app.should_receive(:system).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress /path console.example.com:/srv/glusterfs/disk")
361
361
  @app.upload("/path")
362
362
  end
363
363
  end
@@ -366,7 +366,7 @@ describe Shelly::App do
366
366
  it "should run rsync with proper parameters" do
367
367
  @client.stub(:console).and_return(
368
368
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
369
- @app.should_receive(:exec).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress console.example.com:/srv/glusterfs/disk/. /tmp")
369
+ @app.should_receive(:system).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress console.example.com:/srv/glusterfs/disk/. /tmp")
370
370
  @app.download(".", "/tmp")
371
371
  end
372
372
  end
@@ -193,8 +193,8 @@ describe Shelly::CLI::Backup do
193
193
 
194
194
  describe "restore" do
195
195
  before do
196
- @client.stub(:database_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgre"})
197
- @client.stub(:restore_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgre"})
196
+ @client.stub(:database_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgresql"})
197
+ @client.stub(:restore_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgresql"})
198
198
  $stdout.stub(:puts)
199
199
  $stdout.stub(:print)
200
200
  end
@@ -213,7 +213,7 @@ describe Shelly::CLI::Backup do
213
213
  end
214
214
 
215
215
  it "should restore database" do
216
- $stdout.should_receive(:puts).with("You are about restore database postgre for cloud foo-staging to state from better.tar.gz")
216
+ $stdout.should_receive(:puts).with("You are about restore postgresql database for cloud foo-staging to state from better.tar.gz")
217
217
  $stdout.should_receive(:print).with("I want to restore the database (yes/no): ")
218
218
  $stdout.should_receive(:puts).with("\n")
219
219
  @client.stub(:restore_backup).with("todo-list-test","better.tar.gz")
@@ -227,7 +227,7 @@ describe Shelly::CLI::Backup do
227
227
 
228
228
  context "when answering no" do
229
229
  it "should cancel restore database" do
230
- $stdout.should_receive(:puts).with("You are about restore database postgre for cloud foo-staging to state from better.tar.gz")
230
+ $stdout.should_receive(:puts).with("You are about restore postgresql database for cloud foo-staging to state from better.tar.gz")
231
231
  $stdout.should_receive(:print).with("I want to restore the database (yes/no): ")
232
232
  $stdout.should_receive(:puts).with("\n")
233
233
  $stdout.should_receive(:puts).with(red "Canceled")
@@ -251,4 +251,67 @@ describe Shelly::CLI::Backup do
251
251
  end
252
252
  end
253
253
  end
254
+
255
+ describe "#import" do
256
+ before do
257
+ FileUtils.touch("dump.sql")
258
+ @app.stub(:upload => nil, :ssh => nil)
259
+ @backup.stub(:system)
260
+ $stdout.stub(:puts)
261
+ $stdout.stub(:print)
262
+ end
263
+
264
+ it "should ensure user has logged in" do
265
+ hooks(@backup, :import).should include(:logged_in?)
266
+ end
267
+
268
+ it "should compress file" do
269
+ @backup.should_receive(:system).with("tar -cf dump.sql.tar dump.sql")
270
+ $stdout.should_receive(:puts).with(green "Compressing dump.sql into dump.sql.tar")
271
+ fake_stdin(["yes"]) do
272
+ invoke(@backup, :import, "postgresql", "dump.sql")
273
+ end
274
+ end
275
+
276
+ it "should upload compressed file" do
277
+ @app.should_receive(:upload).with("dump.sql.tar")
278
+ $stdout.should_receive(:puts).with(green "Uploading dump.sql.tar")
279
+ fake_stdin(["yes"]) do
280
+ invoke(@backup, :import, "postgresql", "dump.sql")
281
+ end
282
+ end
283
+
284
+ it "should import given database from uploaded file" do
285
+ @app.should_receive(:ssh).with(:command => "import_database postgresql dump.sql.tar")
286
+ $stdout.should_receive(:puts).with(green "Importing database")
287
+ fake_stdin(["yes"]) do
288
+ invoke(@backup, :import, "postgresql", "dump.sql")
289
+ end
290
+ end
291
+
292
+ context "on answering no" do
293
+ it "should cancel database import" do
294
+ $stdout.should_receive(:puts).with("You are about import postgresql database for cloud foo-staging to state from file dump.sql")
295
+ $stdout.should_receive(:print).with("I want to import the database (yes/no): ")
296
+ $stdout.should_receive(:puts).with(red "Canceled")
297
+ lambda {
298
+ fake_stdin(["no"]) do
299
+ invoke(@backup, :import, "postgresql", "dump.sql")
300
+ end
301
+ }.should raise_error(SystemExit)
302
+ end
303
+ end
304
+
305
+ context "file doesn't exist" do
306
+ it "should exit with error" do
307
+ FileUtils.rm("dump.sql")
308
+ $stdout.should_receive(:puts).with(red "File dump.sql doesn't exist")
309
+ lambda {
310
+ fake_stdin(["yes"]) do
311
+ invoke(@backup, :import, "postgresql", "dump.sql")
312
+ end
313
+ }.should raise_error(SystemExit)
314
+ end
315
+ end
316
+ end
254
317
  end
metadata CHANGED
@@ -1,207 +1,236 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.24
4
+ prerelease:
5
+ version: 0.2.25
5
6
  platform: ruby
6
7
  authors:
7
8
  - Shelly Cloud team
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-06-04 00:00:00.000000000 Z
12
+ date: 2013-06-06 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rspec
16
+ type: :development
15
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
16
19
  requirements:
17
20
  - - ~>
18
21
  - !ruby/object:Gem::Version
19
22
  version: 2.11.0
20
- type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: 2.11.0
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rake
32
+ type: :development
29
33
  requirement: !ruby/object:Gem::Requirement
34
+ none: false
30
35
  requirements:
31
36
  - - ! '>='
32
37
  - !ruby/object:Gem::Version
33
38
  version: '0'
34
- type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: guard
48
+ type: :development
43
49
  requirement: !ruby/object:Gem::Requirement
50
+ none: false
44
51
  requirements:
45
52
  - - ! '>='
46
53
  - !ruby/object:Gem::Version
47
54
  version: '0'
48
- type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: guard-rspec
64
+ type: :development
57
65
  requirement: !ruby/object:Gem::Requirement
66
+ none: false
58
67
  requirements:
59
68
  - - ! '>='
60
69
  - !ruby/object:Gem::Version
61
70
  version: '0'
62
- type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ! '>='
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0'
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: simplecov
80
+ type: :development
71
81
  requirement: !ruby/object:Gem::Requirement
82
+ none: false
72
83
  requirements:
73
84
  - - ! '>='
74
85
  - !ruby/object:Gem::Version
75
86
  version: '0'
76
- type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ! '>='
81
92
  - !ruby/object:Gem::Version
82
93
  version: '0'
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: ruby_gntp
96
+ type: :development
85
97
  requirement: !ruby/object:Gem::Requirement
98
+ none: false
86
99
  requirements:
87
100
  - - ! '>='
88
101
  - !ruby/object:Gem::Version
89
102
  version: '0'
90
- type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
107
  - - ! '>='
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0'
97
110
  - !ruby/object:Gem::Dependency
98
111
  name: rb-fsevent
112
+ type: :development
99
113
  requirement: !ruby/object:Gem::Requirement
114
+ none: false
100
115
  requirements:
101
116
  - - ! '>='
102
117
  - !ruby/object:Gem::Version
103
118
  version: '0'
104
- type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
107
122
  requirements:
108
123
  - - ! '>='
109
124
  - !ruby/object:Gem::Version
110
125
  version: '0'
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: fakefs
128
+ type: :development
113
129
  requirement: !ruby/object:Gem::Requirement
130
+ none: false
114
131
  requirements:
115
132
  - - ! '>='
116
133
  - !ruby/object:Gem::Version
117
134
  version: '0'
118
- type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
121
138
  requirements:
122
139
  - - ! '>='
123
140
  - !ruby/object:Gem::Version
124
141
  version: '0'
125
142
  - !ruby/object:Gem::Dependency
126
143
  name: fakeweb
144
+ type: :development
127
145
  requirement: !ruby/object:Gem::Requirement
146
+ none: false
128
147
  requirements:
129
148
  - - ! '>='
130
149
  - !ruby/object:Gem::Version
131
150
  version: '0'
132
- type: :development
133
151
  prerelease: false
134
152
  version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
135
154
  requirements:
136
155
  - - ! '>='
137
156
  - !ruby/object:Gem::Version
138
157
  version: '0'
139
158
  - !ruby/object:Gem::Dependency
140
159
  name: wijet-thor
160
+ type: :runtime
141
161
  requirement: !ruby/object:Gem::Requirement
162
+ none: false
142
163
  requirements:
143
164
  - - ~>
144
165
  - !ruby/object:Gem::Version
145
166
  version: 0.14.9
146
- type: :runtime
147
167
  prerelease: false
148
168
  version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
149
170
  requirements:
150
171
  - - ~>
151
172
  - !ruby/object:Gem::Version
152
173
  version: 0.14.9
153
174
  - !ruby/object:Gem::Dependency
154
175
  name: rest-client
176
+ type: :runtime
155
177
  requirement: !ruby/object:Gem::Requirement
178
+ none: false
156
179
  requirements:
157
180
  - - ! '>='
158
181
  - !ruby/object:Gem::Version
159
182
  version: '0'
160
- type: :runtime
161
183
  prerelease: false
162
184
  version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
163
186
  requirements:
164
187
  - - ! '>='
165
188
  - !ruby/object:Gem::Version
166
189
  version: '0'
167
190
  - !ruby/object:Gem::Dependency
168
191
  name: json
192
+ type: :runtime
169
193
  requirement: !ruby/object:Gem::Requirement
194
+ none: false
170
195
  requirements:
171
196
  - - ! '>='
172
197
  - !ruby/object:Gem::Version
173
198
  version: '0'
174
- type: :runtime
175
199
  prerelease: false
176
200
  version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
177
202
  requirements:
178
203
  - - ! '>='
179
204
  - !ruby/object:Gem::Version
180
205
  version: '0'
181
206
  - !ruby/object:Gem::Dependency
182
207
  name: progressbar
208
+ type: :runtime
183
209
  requirement: !ruby/object:Gem::Requirement
210
+ none: false
184
211
  requirements:
185
212
  - - ! '>='
186
213
  - !ruby/object:Gem::Version
187
214
  version: '0'
188
- type: :runtime
189
215
  prerelease: false
190
216
  version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
191
218
  requirements:
192
219
  - - ! '>='
193
220
  - !ruby/object:Gem::Version
194
221
  version: '0'
195
222
  - !ruby/object:Gem::Dependency
196
223
  name: launchy
224
+ type: :runtime
197
225
  requirement: !ruby/object:Gem::Requirement
226
+ none: false
198
227
  requirements:
199
228
  - - ! '>='
200
229
  - !ruby/object:Gem::Version
201
230
  version: '0'
202
- type: :runtime
203
231
  prerelease: false
204
232
  version_requirements: !ruby/object:Gem::Requirement
233
+ none: false
205
234
  requirements:
206
235
  - - ! '>='
207
236
  - !ruby/object:Gem::Version
@@ -276,26 +305,27 @@ files:
276
305
  - spec/thor/options_spec.rb
277
306
  homepage: http://shellycloud.com
278
307
  licenses: []
279
- metadata: {}
280
308
  post_install_message:
281
309
  rdoc_options: []
282
310
  require_paths:
283
311
  - lib
284
312
  required_ruby_version: !ruby/object:Gem::Requirement
313
+ none: false
285
314
  requirements:
286
315
  - - ! '>='
287
316
  - !ruby/object:Gem::Version
288
317
  version: '0'
289
318
  required_rubygems_version: !ruby/object:Gem::Requirement
319
+ none: false
290
320
  requirements:
291
321
  - - ! '>='
292
322
  - !ruby/object:Gem::Version
293
323
  version: '0'
294
324
  requirements: []
295
325
  rubyforge_project: shelly
296
- rubygems_version: 2.0.3
326
+ rubygems_version: 1.8.23
297
327
  signing_key:
298
- specification_version: 4
328
+ specification_version: 3
299
329
  summary: Shelly Cloud command line tool
300
330
  test_files:
301
331
  - spec/helpers.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MWM5MmE2NjRhNGJmMjM1YzBjYzEzNWQwMzMxODlmZjlkZWZmZDU1YQ==
5
- data.tar.gz: !binary |-
6
- MTQwNDM4OTY5NGU4NDI2MWY1MmUyN2JmZTNmOGZkZTFkZDc4OTljMA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NTJhMTU1ZWQ5ZjgyNGEzNWRkYjBhZjAyYzUwN2VmMThiN2NlNDVmYmI3YTdk
10
- MjQ1ZjI0OTA3Zjk3MjE5NjJiNmZkMmUyODdmOTU5ODBiNWJhMTQ3MTgxZTVm
11
- ZDMzMWI0Zjk2NjQzNjY1YjQxZmU0YWZhMzcyNTdlMmQ3ZWFlYjg=
12
- data.tar.gz: !binary |-
13
- NzNhZTEzMjljOWYyNmEyOTQ2MDE0ZDYyZjkxZGIyMzkyYjJhMDE2ZGZkNGZk
14
- NmUwZjE3Y2VlNTI2MWU2MGY4NTlkYzgzOTU3ODA1ZmFhMDIyZDA4OTdhYzFh
15
- NjMyNzhlOTBmMjYzN2ZmNjRkZGU4OTcyNmM4Y2U4NTFjMzQzN2Y=