shelly 0.1.18 → 0.1.19

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.
@@ -0,0 +1,9 @@
1
+ class String
2
+ def dasherize
3
+ self.tr('_', '-')
4
+ end
5
+
6
+ def humanize
7
+ self.tr('_', ' ')
8
+ end
9
+ end
data/lib/shelly.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "rubygems"
2
2
  require "core_ext/object"
3
3
  require "core_ext/hash"
4
+ require "core_ext/string"
4
5
 
5
6
  require "yaml"
6
7
  if YAML.const_defined?(:ENGINE)
data/lib/shelly/app.rb CHANGED
@@ -92,8 +92,10 @@ module Shelly
92
92
  shelly.restore_backup(code_name, filename)
93
93
  end
94
94
 
95
- def request_backup(kind)
96
- shelly.request_backup(code_name, kind)
95
+ def request_backup(kinds)
96
+ Array(kinds).each do |kind|
97
+ shelly.request_backup(code_name, kind)
98
+ end
97
99
  end
98
100
 
99
101
  def logs
@@ -126,7 +128,7 @@ module Shelly
126
128
  end
127
129
  end
128
130
  end
129
- "#{File.basename(Dir.pwd)}-#{guessed || 'staging'}".downcase.tr('_','-')
131
+ "#{File.basename(Dir.pwd)}-#{guessed || 'staging'}".downcase.dasherize
130
132
  end
131
133
 
132
134
  def collaborations
data/lib/shelly/backup.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Shelly
2
2
  class Backup < Model
3
- attr_reader :filename, :size, :human_size, :code_name, :kind
3
+ attr_reader :filename, :size, :human_size, :code_name, :kind, :state
4
4
 
5
5
  def initialize(attributes = {})
6
6
  @filename = attributes["filename"]
@@ -8,6 +8,7 @@ module Shelly
8
8
  @human_size = attributes["human_size"]
9
9
  @code_name = attributes["code_name"]
10
10
  @kind = attributes["kind"]
11
+ @state = attributes["state"]
11
12
  end
12
13
 
13
14
  def download(callback)
@@ -17,9 +17,9 @@ module Shelly
17
17
  app = multiple_clouds(options[:cloud], "backup list")
18
18
  backups = app.database_backups
19
19
  if backups.present?
20
- to_display = [["Filename", "| Size"]]
20
+ to_display = [["Filename", "| Size", "| State"]]
21
21
  backups.each do |backup|
22
- to_display << [backup.filename, "| #{backup.human_size}"]
22
+ to_display << [backup.filename, "| #{backup.human_size}", "| #{backup.state.humanize}"]
23
23
  end
24
24
 
25
25
  say "Available backups:", :green
@@ -53,15 +53,22 @@ module Shelly
53
53
  desc "create [DB_KIND]", "Create backup of given database"
54
54
  long_desc %{
55
55
  Create backup of given database.
56
- If database kind is not specified, backup of all configured databases will be performed.
56
+ If database kind is not specified, Cloudfile must be present to backup all configured databases.
57
57
  }
58
58
  def create(kind = nil)
59
59
  app = multiple_clouds(options[:cloud], "backup create [DB_KIND]")
60
- app.request_backup(kind)
60
+ cloudfile = Cloudfile.new
61
+ unless kind || cloudfile.present?
62
+ say_error "Cloudfile must be present in current working directory or specify database kind with:", :with_exit => false
63
+ say_error "`shelly backup create DB_KIND`"
64
+ end
65
+ app.request_backup(kind || cloudfile.backup_databases(app))
61
66
  say "Backup requested. It can take up to several minutes for " +
62
- "the backup process to finish and the backup to show up in backups list.", :green
67
+ "the backup process to finish.", :green
63
68
  rescue Client::ValidationException => e
64
69
  say_error e[:message]
70
+ rescue Client::ConflictException => e
71
+ say_error e[:message]
65
72
  end
66
73
 
67
74
  desc "restore FILENAME", "Restore database to state from given backup"
@@ -78,6 +85,8 @@ module Shelly
78
85
  raise unless e.resource == :database_backup
79
86
  say_error "Backup not found", :with_exit => false
80
87
  say "You can list available backups with `shelly backup list` command"
88
+ rescue Client::ConflictException => e
89
+ say_error e[:message]
81
90
  end
82
91
  end
83
92
  end
@@ -117,7 +117,7 @@ module Shelly
117
117
  e.each_error { |error| say_error error, :with_exit => false }
118
118
  say_new_line
119
119
  say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
120
- say_error "shelly add --code-name=#{app.code_name.downcase.tr('_','-')} --databases=#{app.databases.join(',')} --size=#{app.size}"
120
+ say_error "shelly add --code-name=#{app.code_name.downcase.dasherize} --databases=#{app.databases.join(',')} --size=#{app.size}"
121
121
  end
122
122
 
123
123
  map "status" => :list
@@ -132,7 +132,7 @@ module Shelly
132
132
  msg = if state == "deploy_failed" || state == "configuration_failed"
133
133
  " (deployment log: `shelly deploys show last -c #{app["code_name"]}`)"
134
134
  end
135
- [app["code_name"], "| #{state.gsub("_", " ")}#{msg}"]
135
+ [app["code_name"], "| #{state.humanize}#{msg}"]
136
136
  end
137
137
  print_table(apps_table, :ident => 2)
138
138
  else
@@ -35,6 +35,20 @@ module Shelly
35
35
  File.open(path, "a+") { |f| f << generate }
36
36
  end
37
37
 
38
+ # Public: Return databases for given Cloud in Cloudfile
39
+ # Returns Array of databases
40
+ def databases(cloud)
41
+ content[cloud.to_s]["servers"].map do |server, settings|
42
+ settings["databases"]
43
+ end.flatten.uniq
44
+ end
45
+
46
+ # Public: Return databases to backup for given Cloud in Cloudfile
47
+ # Returns Array of databases, except redis db
48
+ def backup_databases(cloud)
49
+ databases(cloud) - ['redis']
50
+ end
51
+
38
52
  private
39
53
 
40
54
  # Internal: Load and parse Cloudfile
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.1.18"
2
+ VERSION = "0.1.19"
3
3
  end
@@ -14,6 +14,7 @@ describe Shelly::Backup do
14
14
  backup.filename.should == "backup.tar.gz"
15
15
  backup.human_size.should == "2KB"
16
16
  backup.size.should == 2048
17
+ backup.state.should == "completed"
17
18
  end
18
19
 
19
20
  describe "#download" do
@@ -29,6 +30,7 @@ describe Shelly::Backup do
29
30
  {"code_name" => "foo",
30
31
  "filename" => "backup.tar.gz",
31
32
  "human_size" => "2KB",
32
- "size" => 2048}
33
+ "size" => 2048,
34
+ "state" => "completed"}
33
35
  end
34
36
  end
@@ -31,18 +31,22 @@ 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}])
34
+ @client.should_receive(:database_backups).with("foo-staging").and_return([{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb", "size" => 12345, "state" => "completed"}])
35
35
  @backup.should_receive(:multiple_clouds).and_return(@app)
36
36
  invoke(@backup, :list)
37
37
  end
38
38
 
39
39
  it "should take cloud from command line for which to show backups" do
40
- @client.should_receive(:database_backups).with("foo-staging").and_return([{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb", "size" => 12345},{"filename" => "backup.mongo.tar.gz", "human_size" => "22kb", "size" => 333}])
40
+ @client.should_receive(:database_backups).with("foo-staging").and_return(
41
+ [{"filename" => "backup.postgre.tar.gz", "human_size" => "10kb",
42
+ "size" => 12345, "state" => "completed"},
43
+ {"filename" => "backup.mongo.tar.gz", "human_size" => "22kb",
44
+ "size" => 333, "state" => "in_progress"}])
41
45
  $stdout.should_receive(:puts).with(green "Available backups:")
42
46
  $stdout.should_receive(:puts).with("\n")
43
- $stdout.should_receive(:puts).with(" Filename | Size")
44
- $stdout.should_receive(:puts).with(" backup.postgre.tar.gz | 10kb")
45
- $stdout.should_receive(:puts).with(" backup.mongo.tar.gz | 22kb")
47
+ $stdout.should_receive(:puts).with(" Filename | Size | State")
48
+ $stdout.should_receive(:puts).with(" backup.postgre.tar.gz | 10kb | completed")
49
+ $stdout.should_receive(:puts).with(" backup.mongo.tar.gz | 22kb | in progress")
46
50
  @backup.options = {:cloud => "foo-staging"}
47
51
  invoke(@backup, :list)
48
52
  end
@@ -114,8 +118,9 @@ describe Shelly::CLI::Backup do
114
118
  before do
115
119
  FileUtils.mkdir_p("/projects/foo")
116
120
  Dir.chdir("/projects/foo")
117
- File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\n") }
118
121
  $stdout.stub(:puts)
122
+ @cloudfile = mock(:backup_databases => ['postgresql', 'mongodb'], :clouds => ['foo-staging'])
123
+ Shelly::Cloudfile.stub(:new).and_return(@cloudfile)
119
124
  end
120
125
 
121
126
  it "should ensure user has logged in" do
@@ -137,12 +142,31 @@ describe Shelly::CLI::Backup do
137
142
  lambda { invoke(@backup, :create) }.should raise_error(SystemExit)
138
143
  end
139
144
 
145
+ it "should backup db specified by cli" do
146
+ @app.should_receive(:request_backup).with('postgresql')
147
+ invoke(@backup, :create, "postgresql")
148
+ end
149
+
150
+ it "should backup all dbs in cloudfile" do
151
+ @app.should_receive(:request_backup).with(['postgresql', 'mongodb'])
152
+ invoke(@backup, :create)
153
+ end
154
+
140
155
  it "should display information about request backup" do
141
156
  @client.stub(:request_backup)
142
157
  $stdout.should_receive(:puts).with(green "Backup requested. It can take up to several minutes for " +
143
- "the backup process to finish and the backup to show up in backups list.")
158
+ "the backup process to finish.")
144
159
  invoke(@backup, :create)
145
160
  end
161
+
162
+ it "should display information about missing kind or Cloudfile" do
163
+ @cloudfile.stub(:present?).and_return(false)
164
+ $stdout.should_receive(:puts).with(red "Cloudfile must be present in current working directory or specify database kind with:")
165
+ $stdout.should_receive(:puts).with(red "`shelly backup create DB_KIND`")
166
+
167
+ @backup.options = {:cloud => "foo-production"}
168
+ lambda { invoke(@backup, :create) }.should raise_error(SystemExit)
169
+ end
146
170
  end
147
171
 
148
172
  describe "restore" do
@@ -88,6 +88,31 @@ config
88
88
  end
89
89
  end
90
90
 
91
+ describe "#databases" do
92
+ before do
93
+ content = <<-config
94
+ foo-staging:
95
+ servers:
96
+ app1:
97
+ databases:
98
+ - postgresql
99
+ - redis
100
+ app2:
101
+ databases:
102
+ - mongodb
103
+ config
104
+ File.open("Cloudfile", 'w') {|f| f.write(content) }
105
+ end
106
+
107
+ it "should return databases in cloudfile" do
108
+ @cloudfile.databases("foo-staging").should =~ ['redis', 'mongodb', 'postgresql']
109
+ end
110
+
111
+ it "should return databases except for redis" do
112
+ @cloudfile.backup_databases("foo-staging").should =~ ['postgresql', 'mongodb']
113
+ end
114
+ end
115
+
91
116
  describe "#create" do
92
117
  before do
93
118
  @cloudfile.stub(:generate).and_return("foo-staging:")
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.18
4
+ version: 0.1.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-23 00:00:00.000000000 Z
12
+ date: 2012-07-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -284,6 +284,7 @@ files:
284
284
  - bin/shelly
285
285
  - lib/core_ext/hash.rb
286
286
  - lib/core_ext/object.rb
287
+ - lib/core_ext/string.rb
287
288
  - lib/shelly.rb
288
289
  - lib/shelly/app.rb
289
290
  - lib/shelly/backup.rb