do_snapshot 0.3.0 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0c4e8fd9920e0fb822c5f84dadf54aa6cf0a90b5
4
- data.tar.gz: 26fa16b5c5e5a1ebb5d474e31467488fca1a3c07
3
+ metadata.gz: 4af572f41b36fbe4252628e2508404b789afca71
4
+ data.tar.gz: d31302ccbc40a5a24491ecefa788ea89b6f1881e
5
5
  SHA512:
6
- metadata.gz: 8368fd230ea50254df7456a01a7e20199b8ee0d7a6937b7e036c11a8902206b7c0034f79ea7cb2f0b80d4621d48b6715c2f02b62b254e5bc01978fb54ae07b8a
7
- data.tar.gz: 8139cdbee917477ecc0dea28a63c5d2fb07485e2f4f47781340959ba97fc94317b401c99f632685b8c37177cbaef35e585de39adad0818a5a4f0b12e996e1757
6
+ metadata.gz: dcffac80be5524e1e54a6d2754aec6bde8c991bafe84d93b830d52b984f2830df03399333c687c5bc88d27786339e91e1077987741080b953922a7eb10d15f27
7
+ data.tar.gz: 7983504785434f31b8169280923c506f1581b63ee6a34132edaab245a853061246fdbe6a3e6e0eef2eeff43e9810d62ad22283f27b93d57fd9163d4440594325
data/README.md CHANGED
@@ -185,6 +185,10 @@ For working mailer you need to set e-mail settings via run options.
185
185
 
186
186
  You can optionally specify parameters to select or exclude some droplets.
187
187
 
188
+ ## Donating:
189
+ Support this project and others by [merqlove](https://gratipay.com/~merqlove/) via [gratipay](https://gratipay.com/~merqlove/).
190
+ [![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.3.0/dist/gratipay.png)](https://gratipay.com/merqlove/)
191
+
188
192
  ## Dependencies:
189
193
 
190
194
  - [Thor](https://github.com/erikhuda/thor) for CLI.
@@ -25,10 +25,20 @@ module DoSnapshot
25
25
  def check_keys; end
26
26
 
27
27
  # Waiting for event exit
28
- def wait_event(id)
29
- logger.debug "Event Id: #{id}"
28
+ def wait_wrap(id, message = "Event Id: #{id}", &status_block)
29
+ logger.debug message
30
30
  time = Time.now
31
- sleep(delay) until get_event_status(id, time)
31
+ sleep(delay) until status_block.call(id, time)
32
+ end
33
+
34
+ # Waiting for event exit
35
+ def wait_event(event_id)
36
+ wait_wrap(event_id) { |id, time| get_event_status(id, time) }
37
+ end
38
+
39
+ # Waiting for event exit
40
+ def wait_shutdown(droplet_id)
41
+ wait_wrap(droplet_id, "Droplet Id: #{droplet_id} shutting down") { |id, time| get_shutdown_status(id, time) }
32
42
  end
33
43
 
34
44
  def after_cleanup(droplet_id, droplet_name, snapshot, event)
@@ -40,6 +50,25 @@ module DoSnapshot
40
50
  logger.debug "Snapshot name: #{snapshot.name} delete requested."
41
51
  end
42
52
  end
53
+
54
+ def timeout?(id, time, message = "Event #{id} finished by timeout #{time}")
55
+ return false unless (Time.now - time) > @timeout
56
+ logger.debug message
57
+ true
58
+ end
59
+
60
+ def droplet_timeout?(id, time)
61
+ timeout? id, time, "Droplet id: #{id} shutdown event closed by timeout #{time}"
62
+ end
63
+
64
+ # Looking for event status.
65
+ # Before snapshot we to know that machine has powered off.
66
+ #
67
+ def get_shutdown_status(id, time)
68
+ fail "Droplet #{id} not responding for shutdown!" if droplet_timeout?(id, time)
69
+
70
+ inactive?(id)
71
+ end
43
72
  end
44
73
  end
45
74
  end
@@ -35,11 +35,9 @@ module DoSnapshot
35
35
  # noinspection RubyResolve
36
36
  instance = droplet(id)
37
37
 
38
- if instance.status.include? 'active'
39
- logger.error 'Droplet is still running.'
40
- else
41
- power_on id
42
- end
38
+ return power_on(id) unless instance.status.include? 'active'
39
+
40
+ logger.error "Droplet #{id} is still running. Skipping."
43
41
  end
44
42
 
45
43
  # Power Off request for Droplet
@@ -51,7 +49,7 @@ module DoSnapshot
51
49
  fail event.message unless event.status.include? 'OK'
52
50
 
53
51
  # noinspection RubyResolve
54
- wait_event(event.event_id)
52
+ wait_shutdown(id)
55
53
  rescue => e
56
54
  raise DropletShutdownError.new(id), e.message, e.backtrace
57
55
  end
@@ -63,15 +61,23 @@ module DoSnapshot
63
61
  event = ::DigitaloceanC::Droplet.snapshot(id, name: name)
64
62
 
65
63
  if !event
66
- fail 'Something wrong with DigitalOcean or with your connection :)'
64
+ fail DoSnapshot::SnapshotCreateError.new(id), 'Something wrong with DigitalOcean or with your connection :)'
67
65
  elsif event && !event.status.include?('OK')
68
- fail event.message
66
+ fail DoSnapshot::SnapshotCreateError.new(id), event.message
69
67
  end
70
68
 
71
69
  # noinspection RubyResolve
72
70
  wait_event(event.event_id)
73
71
  end
74
72
 
73
+ # Checking if droplet is powered off.
74
+ #
75
+ def inactive?(id)
76
+ instance = droplet(id)
77
+
78
+ instance.status.include?('off')
79
+ end
80
+
75
81
  # Cleanup our snapshots.
76
82
  #
77
83
  def cleanup_snapshots(instance, size)
@@ -107,17 +113,11 @@ module DoSnapshot
107
113
  return true if timeout?(id, time)
108
114
 
109
115
  event = ::DigitaloceanC::Event.find(id)
110
- fail event.message unless event.status.include?('OK')
116
+ fail DoSnapshot::EventError.new(id), event.message unless event.status.include?('OK')
111
117
  # noinspection RubyResolve,RubyResolve
112
118
  event.event.percentage && event.event.percentage.include?('100') ? true : false
113
119
  end
114
120
 
115
- def timeout?(id, time)
116
- return false unless (Time.now - time) > @timeout
117
- logger.debug "Event #{id} finished by timeout #{time}"
118
- true
119
- end
120
-
121
121
  # Request Power On for droplet
122
122
  #
123
123
  def power_on(id)
@@ -41,21 +41,19 @@ module DoSnapshot
41
41
  # noinspection RubyResolve
42
42
  instance = droplet(id)
43
43
 
44
- if instance.status && instance.status.include?('active')
45
- logger.error 'Droplet is still running.'
46
- else
47
- power_on id
48
- end
44
+ return power_on(id) unless instance.status && instance.status.include?('active')
45
+
46
+ logger.error "Droplet #{id} is still running. Skipping."
49
47
  end
50
48
 
51
49
  # Power Off request for Droplet
52
50
  #
53
51
  def stop_droplet(id)
54
52
  # noinspection RubyResolve,RubyResolve
55
- event = client.droplet_actions.power_off(droplet_id: id)
53
+ client.droplet_actions.power_off(droplet_id: id)
56
54
 
57
55
  # noinspection RubyResolve
58
- wait_event(event.id)
56
+ wait_shutdown(id)
59
57
  rescue => e
60
58
  raise DropletShutdownError.new(id), e.message, e.backtrace
61
59
  end
@@ -66,10 +64,18 @@ module DoSnapshot
66
64
  # noinspection RubyResolve,RubyResolve
67
65
  event = client.droplet_actions.snapshot(droplet_id: id, name: name)
68
66
 
67
+ fail DoSnapshot::SnapshotCreateError.new(id), name unless event && event.respond_to?(:id)
68
+
69
69
  # noinspection RubyResolve
70
70
  wait_event(event.id)
71
- rescue => e
72
- raise e.message, e.backtrace
71
+ end
72
+
73
+ # Checking if droplet is powered off.
74
+ #
75
+ def inactive?(id)
76
+ instance = droplet(id)
77
+
78
+ instance.status.include?('off')
73
79
  end
74
80
 
75
81
  # Cleanup our snapshots.
@@ -117,16 +123,14 @@ module DoSnapshot
117
123
  # Before snapshot we to know that machine has powered off.
118
124
  #
119
125
  def get_event_status(id, time)
120
- if (Time.now - time) > @timeout
121
- logger.debug "Event #{id} finished by timeout #{time}"
122
- return true
123
- end
126
+ return true if timeout?(id, time)
124
127
 
125
128
  action = client.actions.find(id: id)
129
+
130
+ fail DoSnapshot::EventError.new(id), 'Check your connection' unless action && action.respond_to?(:status)
131
+
126
132
  # noinspection RubyResolve,RubyResolve
127
133
  action.status.include?('completed') ? true : false
128
- rescue => e
129
- raise e.message, e.backtrace
130
134
  end
131
135
 
132
136
  # Request Power On for droplet
@@ -203,7 +203,7 @@ module DoSnapshot
203
203
  config.logger_level = Logger::DEBUG if config.verbose
204
204
  config.verbose = options['trace']
205
205
  config.quiet = options['quiet']
206
- config.mailer = Mail.new(opts: options['mail'], smtp: options['smtp'])
206
+ config.mailer = Mail.new(opts: options['mail'], smtp: options['smtp']) if options['mail']
207
207
  end
208
208
  end
209
209
 
@@ -42,11 +42,17 @@ module DoSnapshot
42
42
  def stop_droplet(droplet)
43
43
  logger.debug 'Shutting down droplet.'
44
44
  api.stop_droplet(droplet.id) unless droplet.status.include? 'off'
45
+ true
46
+ rescue => e
47
+ logger.error e.message
48
+ false
45
49
  end
46
50
 
47
51
  # Trying to create a snapshot.
48
52
  #
49
53
  def create_snapshot(droplet) # rubocop:disable MethodLength,Metrics/AbcSize
54
+ fail DropletPowerError.new(droplet.id), droplet.name unless api.inactive?(droplet.id)
55
+
50
56
  logger.info "Start creating snapshot for droplet id: #{droplet.id} name: #{droplet.name}."
51
57
 
52
58
  today = DateTime.now
@@ -69,6 +75,8 @@ module DoSnapshot
69
75
  case e.class.to_s
70
76
  when 'DoSnapshot::SnapshotCleanupError'
71
77
  raise e.class, e.message, e.backtrace
78
+ when 'DoSnapshot::DropletPowerError'
79
+ return
72
80
  else
73
81
  raise SnapshotCreateError.new(droplet.id), e.message, e.backtrace
74
82
  end
@@ -132,8 +140,7 @@ module DoSnapshot
132
140
  #
133
141
  def thread_runner(droplet)
134
142
  threads << Thread.new do
135
- stop_droplet droplet
136
- create_snapshot droplet
143
+ create_snapshot droplet if stop_droplet(droplet)
137
144
  end
138
145
  end
139
146
 
@@ -141,7 +148,7 @@ module DoSnapshot
141
148
  # Droplet instance must be powered off first!
142
149
  #
143
150
  def prepare_droplet(id, name)
144
- logger.debug "Droplet id: #{id} name: #{name} "
151
+ logger.debug "Droplet id: #{id} name: #{name}\n"
145
152
  droplet = api.droplet id
146
153
 
147
154
  return unless droplet
@@ -2,5 +2,5 @@
2
2
  # Current version
3
3
  #
4
4
  module DoSnapshot
5
- VERSION = '0.3.0'
5
+ VERSION = '0.3.4'
6
6
  end
data/lib/do_snapshot.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'active_support/multibyte' # ActiveSupport 3.2 & Mail gem fix to work together.
3
+
2
4
  require_relative 'do_snapshot/version'
3
5
  require_relative 'do_snapshot/configuration'
4
6
 
@@ -80,6 +82,24 @@ module DoSnapshot
80
82
  end
81
83
  end
82
84
 
85
+ # When Droplet not Powered Off!
86
+ #
87
+ class DropletPowerError < RequestError
88
+ def initialize(*args)
89
+ DoSnapshot.logger.error "Droplet id: #{args[0]} must be Powered Off!"
90
+ super
91
+ end
92
+ end
93
+
94
+ # When Event is failed!
95
+ #
96
+ class EventError < RequestError
97
+ def initialize(*args)
98
+ DoSnapshot.logger.error "Event id: #{args[0]} is failed!"
99
+ super
100
+ end
101
+ end
102
+
83
103
  # When Digital Ocean API cannot retrieve list of droplets.
84
104
  # Sometimes it connection problem or DigitalOcean API maintenance.
85
105
  #
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Adapter::Abstract do
4
+ RSpec.describe DoSnapshot::Adapter::Abstract do
5
5
  include_context 'spec'
6
6
 
7
7
  subject(:api) { described_class }
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Adapter::Digitalocean do
4
+ RSpec.describe DoSnapshot::Adapter::Digitalocean do
5
5
  include_context 'spec'
6
6
  include_context 'api_v1_helpers'
7
7
 
@@ -40,7 +40,7 @@ describe DoSnapshot::Adapter::Digitalocean do
40
40
  stub_droplet_fail(droplet_id)
41
41
 
42
42
  expect { instance.droplet(droplet_id) }
43
- .to raise_error
43
+ .to raise_error(DoSnapshot::DropletFindError)
44
44
  expect(DoSnapshot.logger.buffer)
45
45
  .to include 'Droplet Not Found'
46
46
 
@@ -62,7 +62,7 @@ describe DoSnapshot::Adapter::Digitalocean do
62
62
  it 'with error' do
63
63
  stub_droplets_fail
64
64
 
65
- expect { instance.droplets }.to raise_error
65
+ expect { instance.droplets }.to raise_error(DoSnapshot::DropletListError)
66
66
  expect(DoSnapshot.logger.buffer)
67
67
  .to include 'Droplet Listing is failed to retrieve'
68
68
 
@@ -91,7 +91,7 @@ describe DoSnapshot::Adapter::Digitalocean do
91
91
  expect { instance.start_droplet(droplet_id) }
92
92
  .not_to raise_error
93
93
  expect(DoSnapshot.logger.buffer)
94
- .to include 'Droplet is still running.'
94
+ .to include "Droplet #{droplet_id} is still running. Skipping."
95
95
 
96
96
  expect(a_request(:get, droplet_url))
97
97
  .to have_been_made
@@ -101,7 +101,7 @@ describe DoSnapshot::Adapter::Digitalocean do
101
101
  stub_droplet_fail(droplet_id)
102
102
 
103
103
  expect { instance.start_droplet(droplet_id) }
104
- .to raise_error
104
+ .to raise_error(DoSnapshot::DropletFindError)
105
105
 
106
106
  expect(a_request(:get, droplet_url))
107
107
  .to have_been_made
@@ -109,23 +109,27 @@ describe DoSnapshot::Adapter::Digitalocean do
109
109
  end
110
110
 
111
111
  describe '.stop_droplet' do
112
- it 'with event' do
112
+ it 'with success' do
113
113
  stub_event_done(event_id)
114
114
  stub_droplet_stop(droplet_id)
115
+ stub_droplet_inactive(droplet_id)
115
116
 
116
117
  instance.stop_droplet(droplet_id)
117
118
 
118
119
  expect(a_request(:get, droplet_stop_url))
119
120
  .to have_been_made
120
- expect(a_request(:get, event_find_url))
121
+ expect(a_request(:get, droplet_url))
121
122
  .to have_been_made
122
123
  end
123
124
 
124
125
  it 'with error' do
125
126
  stub_droplet_stop_fail(droplet_id)
127
+ stub_droplet(droplet_id)
126
128
 
129
+ instance.timeout = 1
127
130
  expect { instance.stop_droplet(droplet_id) }
128
- .to raise_error
131
+ .to raise_error(DoSnapshot::DropletShutdownError)
132
+ instance.timeout = timeout
129
133
  expect(DoSnapshot.logger.buffer)
130
134
  .to include 'Droplet id: 100823 is Failed to Power Off.'
131
135
 
@@ -152,7 +156,7 @@ describe DoSnapshot::Adapter::Digitalocean do
152
156
  stub_droplet_snapshot_fail(droplet_id, snapshot_name)
153
157
 
154
158
  expect { instance.create_snapshot(droplet_id, snapshot_name) }
155
- .to raise_error
159
+ .to raise_error(DoSnapshot::SnapshotCreateError)
156
160
 
157
161
  expect(a_request(:get, droplet_snapshot_url))
158
162
  .to have_been_made
@@ -163,7 +167,7 @@ describe DoSnapshot::Adapter::Digitalocean do
163
167
  stub_event_fail(event_id)
164
168
 
165
169
  expect { instance.create_snapshot(droplet_id, snapshot_name) }
166
- .to raise_error
170
+ .to raise_error(DoSnapshot::EventError)
167
171
 
168
172
  expect(a_request(:get, droplet_snapshot_url))
169
173
  .to have_been_made
@@ -172,6 +176,22 @@ describe DoSnapshot::Adapter::Digitalocean do
172
176
  end
173
177
  end
174
178
 
179
+ describe '.inactive?' do
180
+ it 'when inactive' do
181
+ stub_droplet_inactive(droplet_id)
182
+
183
+ expect(instance.inactive?(droplet_id))
184
+ .to be_truthy
185
+ end
186
+
187
+ it 'when active' do
188
+ stub_droplet(droplet_id)
189
+
190
+ expect(instance.inactive?(droplet_id))
191
+ .to be_falsey
192
+ end
193
+ end
194
+
175
195
  describe '.cleanup_snapshots' do
176
196
  it 'with success' do
177
197
  stub_droplet(droplet_id)
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Adapter::DigitaloceanV2 do
4
+ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
5
5
  include_context 'spec'
6
6
  include_context 'api_v2_helpers'
7
7
 
@@ -42,7 +42,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
42
42
  stub_droplet_fail(droplet_id)
43
43
 
44
44
  expect { instance.droplet(droplet_id) }
45
- .to raise_error
45
+ .to raise_error(DoSnapshot::DropletFindError)
46
46
  expect(DoSnapshot.logger.buffer)
47
47
  .to include 'Droplet Not Found'
48
48
 
@@ -64,7 +64,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
64
64
  it 'with error' do
65
65
  stub_droplets_fail
66
66
 
67
- expect { instance.droplets }.to raise_error
67
+ expect { instance.droplets }.to raise_error(DoSnapshot::DropletListError)
68
68
  expect(DoSnapshot.logger.buffer)
69
69
  .to include 'Droplet Listing is failed to retrieve'
70
70
 
@@ -93,7 +93,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
93
93
  expect { instance.start_droplet(droplet_id) }
94
94
  .not_to raise_error
95
95
  expect(DoSnapshot.logger.buffer)
96
- .to include 'Droplet is still running.'
96
+ .to include "Droplet #{droplet_id} is still running. Skipping."
97
97
 
98
98
  expect(a_request(:get, droplet_url))
99
99
  .to have_been_made
@@ -103,7 +103,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
103
103
  stub_droplet_fail(droplet_id)
104
104
 
105
105
  expect { instance.start_droplet(droplet_id) }
106
- .to raise_error
106
+ .to raise_error(DoSnapshot::DropletFindError)
107
107
 
108
108
  expect(a_request(:get, droplet_url))
109
109
  .to have_been_made
@@ -111,23 +111,26 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
111
111
  end
112
112
 
113
113
  describe '.stop_droplet' do
114
- it 'with event' do
114
+ it 'with success' do
115
115
  stub_event_done(event_id)
116
116
  stub_droplet_stop(droplet_id)
117
+ stub_droplet_inactive(droplet_id)
117
118
 
118
119
  instance.stop_droplet(droplet_id)
119
120
 
120
121
  expect(a_request(:post, droplet_stop_url))
121
122
  .to have_been_made
122
- expect(a_request(:get, action_find_url))
123
+ expect(a_request(:get, droplet_url))
123
124
  .to have_been_made
124
125
  end
125
126
 
126
127
  it 'with error' do
127
128
  stub_droplet_stop_fail(droplet_id)
128
-
129
+ stub_droplet(droplet_id)
130
+ instance.timeout = 1
129
131
  expect { instance.stop_droplet(droplet_id) }
130
- .to raise_error
132
+ .to raise_error(DoSnapshot::DropletShutdownError)
133
+ instance.timeout = timeout
131
134
  expect(DoSnapshot.logger.buffer)
132
135
  .to include 'Droplet id: 100823 is Failed to Power Off.'
133
136
 
@@ -154,7 +157,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
154
157
  stub_droplet_snapshot_fail(droplet_id, snapshot_name)
155
158
 
156
159
  expect { instance.create_snapshot(droplet_id, snapshot_name) }
157
- .to raise_error
160
+ .to raise_error(DoSnapshot::SnapshotCreateError)
158
161
 
159
162
  expect(a_request(:post, droplet_snapshot_url))
160
163
  .to have_been_made
@@ -165,7 +168,7 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
165
168
  stub_event_fail(event_id)
166
169
 
167
170
  expect { instance.create_snapshot(droplet_id, snapshot_name) }
168
- .to raise_error
171
+ .to raise_error(DoSnapshot::EventError)
169
172
 
170
173
  expect(a_request(:post, droplet_snapshot_url))
171
174
  .to have_been_made
@@ -174,6 +177,22 @@ describe DoSnapshot::Adapter::DigitaloceanV2 do
174
177
  end
175
178
  end
176
179
 
180
+ describe '.inactive?' do
181
+ it 'when inactive' do
182
+ stub_droplet_inactive(droplet_id)
183
+
184
+ expect(instance.inactive?(droplet_id))
185
+ .to be_truthy
186
+ end
187
+
188
+ it 'when active' do
189
+ stub_droplet(droplet_id)
190
+
191
+ expect(instance.inactive?(droplet_id))
192
+ .to be_falsey
193
+ end
194
+ end
195
+
177
196
  describe '.cleanup_snapshots' do
178
197
  it 'with success' do
179
198
  stub_droplet(droplet_id)
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::CLI do
4
+ RSpec.describe DoSnapshot::CLI do
5
5
  include_context 'spec'
6
6
  include_context 'api_v1_helpers'
7
7
 
@@ -1,137 +1,179 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Command do
4
+ RSpec.describe DoSnapshot::Command do
5
5
  include_context 'spec'
6
6
  include_context 'uri_helpers'
7
- include_context 'api_v1_helpers'
8
7
 
9
8
  subject(:cmd) { DoSnapshot::Command.new }
10
9
  subject(:log) { DoSnapshot::Log }
11
10
 
12
- describe '.snap' do
13
- context 'when success' do
14
- it 'sends message' do
15
- expect { snap_runner }
16
- .not_to raise_error
17
- expect(DoSnapshot.logger.buffer)
18
- .to include 'All operations has been finished.'
11
+ describe 'V2' do
12
+ include_context 'api_v2_helpers'
13
+ end
14
+
15
+ describe 'V1' do
16
+ include_context 'api_v1_helpers'
17
+
18
+ describe '.snap' do
19
+ context 'when success' do
20
+ it 'sends message' do
21
+ stub_droplet_inactive(droplet_id)
22
+ expect { snap_runner }
23
+ .not_to raise_error
24
+ expect(DoSnapshot.logger.buffer)
25
+ .to include 'All operations has been finished.'
26
+ end
19
27
  end
20
- end
21
28
 
22
- context 'when snapshot not cleanup' do
23
- it 'sends message' do
24
- stub_image_destroy_fail(image_id)
25
- stub_image_destroy_fail(image_id2)
29
+ context 'when snapshot not cleanup' do
30
+ it 'sends message' do
31
+ stub_droplet_inactive(droplet_id)
32
+ stub_image_destroy_fail(image_id)
33
+ stub_image_destroy_fail(image_id2)
26
34
 
27
- expect { snap_runner }
28
- .not_to raise_error
35
+ expect { snap_runner }
36
+ .not_to raise_error
37
+ end
29
38
  end
30
- end
31
39
 
32
- context 'when droplet not found' do
33
- it 'raised by exception' do
34
- stub_droplet_fail(droplet_id)
40
+ context 'when droplet not found' do
41
+ it 'raised by exception' do
42
+ stub_droplet_fail(droplet_id)
35
43
 
36
- expect { snap_runner }
37
- .to raise_error(DoSnapshot::DropletFindError)
44
+ expect { snap_runner }
45
+ .to raise_error(DoSnapshot::DropletFindError)
46
+ end
38
47
  end
39
- end
40
48
 
41
- context 'when failed to list droplets' do
42
- it 'raised with error' do
43
- stub_droplets_fail
49
+ context 'when failed to list droplets' do
50
+ it 'raised with error' do
51
+ stub_droplets_fail
44
52
 
45
- expect { snap_runner }
46
- .to raise_error(DoSnapshot::DropletListError)
53
+ expect { snap_runner }
54
+ .to raise_error(DoSnapshot::DropletListError)
55
+ end
47
56
  end
48
- end
49
57
 
50
- context 'when droplet failed for shutdown' do
51
- it 'raised with error' do
52
- stub_droplet_stop_fail(droplet_id)
58
+ context 'when droplet failed for shutdown' do
59
+ it 'raised with error' do
60
+ stub_droplet_stop_fail(droplet_id)
53
61
 
54
- expect { snap_runner }
55
- .to raise_error(DoSnapshot::DropletShutdownError)
62
+ expect { snap_runner }
63
+ .not_to raise_error
64
+ expect(DoSnapshot.logger.buffer)
65
+ .to include "Droplet id: #{droplet_id} is Failed to Power Off."
66
+ end
56
67
  end
57
- end
58
68
 
59
- context 'when no snapshot created' do
60
- it 'raised with error' do
61
- stub_droplet_snapshot_fail(droplet_id, snapshot_name)
69
+ context 'when no snapshot created' do
70
+ it 'raised with error' do
71
+ stub_droplet_inactive(droplet_id)
72
+ stub_droplet_snapshot_fail(droplet_id, snapshot_name)
62
73
 
63
- expect { snap_runner }
64
- .to raise_error(DoSnapshot::SnapshotCreateError)
74
+ expect { snap_runner }
75
+ .to raise_error(DoSnapshot::SnapshotCreateError)
76
+ end
65
77
  end
66
- end
67
- end
68
78
 
69
- describe '.stop_droplet' do
70
- it 'when raised with error' do
71
- stub_droplet_stop_fail(droplet_id)
72
- load_options
73
- droplet = cmd.api.droplet droplet_id
74
- expect { cmd.stop_droplet(droplet) }
75
- .to raise_error(DoSnapshot::DropletShutdownError)
76
- end
79
+ context 'when droplet not stopped' do
80
+ it 'skipped droplet' do
81
+ stub_droplet_stop_fail(droplet_id)
77
82
 
78
- it 'when stopped' do
79
- stub_droplet_stop(droplet_id)
80
- load_options
81
- droplet = cmd.api.droplet droplet_id
82
- expect { cmd.stop_droplet(droplet) }
83
- .not_to raise_error
83
+ expect { snap_runner }
84
+ .not_to raise_error
85
+ expect(DoSnapshot.logger.buffer)
86
+ .to include "Droplet id: #{droplet_id} is Failed to Power Off."
87
+ end
88
+ end
84
89
  end
85
- end
86
90
 
87
- describe '.create_snapshot' do
88
- it 'when raised with error' do
89
- stub_droplet_snapshot_fail(droplet_id, snapshot_name)
90
- load_options
91
- droplet = cmd.api.droplet droplet_id
92
- expect { cmd.create_snapshot(droplet) }
93
- .to raise_error(DoSnapshot::SnapshotCreateError)
94
- end
91
+ describe '.stop_droplet' do
92
+ it 'when raised with error' do
93
+ stub_droplet_stop_fail(droplet_id)
94
+ load_options
95
+ droplet = cmd.api.droplet droplet_id
96
+ expect { cmd.stop_droplet(droplet) }
97
+ .not_to raise_error
98
+ expect(cmd.stop_droplet(droplet))
99
+ .to be_falsey
100
+ end
95
101
 
96
- it 'when snapshot is created' do
97
- stub_droplet_snapshot(droplet_id, snapshot_name)
98
- load_options
99
- droplet = cmd.api.droplet droplet_id
100
- expect { cmd.create_snapshot(droplet) }
101
- .not_to raise_error
102
+ it 'when stopped' do
103
+ stub_droplet_inactive(droplet_id)
104
+ stub_droplet_stop(droplet_id)
105
+ load_options
106
+ droplet = cmd.api.droplet droplet_id
107
+ expect { cmd.stop_droplet(droplet) }
108
+ .not_to raise_error
109
+ expect(cmd.stop_droplet(droplet))
110
+ .to be_truthy
111
+ end
102
112
  end
103
- end
104
113
 
105
- describe '.fail_power_off' do
106
- it 'when success' do
107
- stub_droplet_inactive(droplet_id)
114
+ describe '.create_snapshot' do
115
+ it 'when raised with error' do
116
+ stub_droplet_inactive(droplet_id)
117
+ stub_droplet_snapshot_fail(droplet_id, snapshot_name)
118
+ load_options
119
+ droplet = cmd.api.droplet droplet_id
120
+ expect { cmd.create_snapshot(droplet) }
121
+ .to raise_error(DoSnapshot::SnapshotCreateError)
122
+ end
108
123
 
109
- expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
110
- .not_to raise_error
111
- expect(DoSnapshot.logger.buffer)
112
- .to include 'Power On has been requested.'
124
+ it 'when snapshot is created' do
125
+ stub_droplet_inactive(droplet_id)
126
+ stub_droplet_snapshot(droplet_id, snapshot_name)
127
+ load_options
128
+ droplet = cmd.api.droplet droplet_id
129
+ cmd.create_snapshot(droplet)
130
+ expect { cmd.create_snapshot(droplet) }
131
+ .not_to raise_error
132
+ end
133
+
134
+ it 'when droplet is running' do
135
+ stub_droplet(droplet_id)
136
+ load_options
137
+ droplet = cmd.api.droplet droplet_id
138
+ cmd.create_snapshot(droplet)
139
+ expect { cmd.create_snapshot(droplet) }
140
+ .not_to raise_error
141
+ expect(DoSnapshot.logger.buffer)
142
+ .to include "Droplet id: #{droplet_id} must be Powered Off!"
143
+ end
113
144
  end
114
145
 
115
- it 'with request error' do
116
- stub_droplet_fail(droplet_id)
146
+ describe '.fail_power_off' do
147
+ it 'when success' do
148
+ stub_droplet_inactive(droplet_id)
117
149
 
118
- expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
119
- .to raise_error
120
- expect(DoSnapshot.logger.buffer)
121
- .to include 'Droplet id: 100823 is Failed to Power Off.'
122
- expect(DoSnapshot.logger.buffer)
123
- .to include 'Droplet Not Found'
124
- end
150
+ expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
151
+ .not_to raise_error
152
+ expect(DoSnapshot.logger.buffer)
153
+ .to include 'Power On has been requested.'
154
+ end
155
+
156
+ it 'with request error' do
157
+ stub_droplet_fail(droplet_id)
158
+
159
+ expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
160
+ .to raise_error(DoSnapshot::DropletFindError)
161
+ expect(DoSnapshot.logger.buffer)
162
+ .to include 'Droplet id: 100823 is Failed to Power Off.'
163
+ expect(DoSnapshot.logger.buffer)
164
+ .to include 'Droplet Not Found'
165
+ end
125
166
 
126
- it 'with start error' do
127
- stub_droplet_inactive(droplet_id)
128
- stub_droplet_start_fail(droplet_id)
129
- stub_event_fail(event_id)
167
+ it 'with start error' do
168
+ stub_droplet_inactive(droplet_id)
169
+ stub_droplet_start_fail(droplet_id)
170
+ stub_event_fail(event_id)
130
171
 
131
- expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
132
- .not_to raise_error
133
- expect(DoSnapshot.logger.buffer)
134
- .to include 'Power On failed to request.'
172
+ expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
173
+ .not_to raise_error
174
+ expect(DoSnapshot.logger.buffer)
175
+ .to include 'Power On failed to request.'
176
+ end
135
177
  end
136
178
  end
137
179
 
@@ -143,7 +185,7 @@ describe DoSnapshot::Command do
143
185
  end
144
186
 
145
187
  def load_options(options = nil)
146
- options ||= default_options
188
+ options ||= default_options.merge(protocol: 1)
147
189
  cmd.load_options(options, [:log, :mail, :smtp, :trace, :digital_ocean_client_id, :digital_ocean_api_key])
148
190
  end
149
191
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DoSnapshot::Configuration do
3
+ RSpec.describe DoSnapshot::Configuration do
4
4
  subject(:cli) { described_class }
5
5
 
6
6
  it { expect(cli.new).to respond_to(:logger) }
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Log do
4
+ RSpec.describe DoSnapshot::Log do
5
5
  include_context 'spec'
6
6
 
7
7
  subject(:log) { described_class }
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot::Mail do
4
+ RSpec.describe DoSnapshot::Mail do
5
5
  include_context 'spec'
6
6
 
7
7
  subject(:mail) { described_class }
@@ -134,7 +134,7 @@ RSpec.describe DoSnapshot::Runner, type: :aruba do
134
134
  hash_attribute_eq
135
135
 
136
136
  expect(last_command).to have_exit_status(0)
137
- expect(all_stdout).to include(t_sending_email)
137
+ expect(all_stdout).not_to include(t_sending_email)
138
138
  end
139
139
 
140
140
  it 'with smtp' do
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe DoSnapshot do
4
+ RSpec.describe DoSnapshot do
5
5
  include_context 'spec'
6
6
 
7
7
  describe DoSnapshot::DropletFindError do
@@ -14,6 +14,26 @@ describe DoSnapshot do
14
14
  end
15
15
  end
16
16
 
17
+ describe DoSnapshot::DropletPowerError do
18
+ subject(:error) { described_class }
19
+
20
+ it 'should work' do
21
+ error.new(droplet_id)
22
+ expect(DoSnapshot.logger.buffer)
23
+ .to include "Droplet id: #{droplet_id} must be Powered Off!"
24
+ end
25
+ end
26
+
27
+ describe DoSnapshot::EventError do
28
+ subject(:error) { described_class }
29
+
30
+ it 'should work' do
31
+ error.new(event_id)
32
+ expect(DoSnapshot.logger.buffer)
33
+ .to include "Event id: #{event_id} is failed!"
34
+ end
35
+ end
36
+
17
37
  describe DoSnapshot::DropletListError do
18
38
  subject(:error) { described_class }
19
39
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: do_snapshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Merkulov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-19 00:00:00.000000000 Z
11
+ date: 2015-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 4.0.0
19
+ version: '3.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 4.0.0
26
+ version: '3.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: digitalocean_c
29
29
  requirement: !ruby/object:Gem::Requirement