do_snapshot 0.4.0 → 0.4.1

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: da57ad33d5179bc0f986121e76f31e3905da3e0c
4
- data.tar.gz: 0f5bcb0f0fcf7f3edffb692121630a04473680b8
3
+ metadata.gz: d2f557d0bd09889f074fdc153b9223a55f5866a3
4
+ data.tar.gz: 07e700c5e6e81e1b32a273204f6f25d4cd60a910
5
5
  SHA512:
6
- metadata.gz: 6b7c4642781f4436e2ea779208b36567b89c1a31cdc46bfedba882aa3e0f9d614d821d841dd8354c865da51d170eb333e87b10a36942f0b0338be0a56b07977d
7
- data.tar.gz: 52a00dd59bc60db77acfa037f98ba03cbfa7b7f1d7701a8d5c91ef8ab9725dd7b04e8f6187cbb182f72498a2348378f915f896aa9637fcdc74d2b13269d06ce3
6
+ metadata.gz: 70b662713abc68a487cabdd8cce90592b746e95e2067d45bd4a148da063456bc3756b1c40ec7d9f4689bc63627ffb3df775ea5a149e2856615f9e8a753ca401a
7
+ data.tar.gz: b75713e42882ff55dec16ab945dd2246447cde8fd9f9dcdb3abc4e24987b8bf9440a5326ea6bd1f5751f637bcfb4544b751b5307a06fd4fd5b0f3543e1240822
data/README.md CHANGED
@@ -172,6 +172,7 @@ For working mailer you need to set e-mail settings via run options.
172
172
  -l, [--log=/Users/someone/.do_snapshot/main.log] # Log file path. By default logging is disabled.
173
173
  -c, [--clean], [--no-clean] # Cleanup snapshots after create. If you have more images than you want to `keep`, older will be deleted.
174
174
  -s, [--stop], [--no-stop] # Stop creating snapshots if maximum is reached.
175
+ [--stop-by-power], [--no-stop-by-power] # Check if droplet stopped by its power status instead of waiting for event completed state.
175
176
  -v, [--trace], [--no-trace] # Verbose mode.
176
177
  -q, [--quiet], [--no-quiet] # Quiet mode. If don't need any messages in console.
177
178
  [--digital-ocean-access-token=YOURLONGAPITOKEN] # DIGITAL_OCEAN_ACCESS_TOKEN. if you can't use environment.
@@ -9,6 +9,7 @@ module DoSnapshot
9
9
  include DoSnapshot::Helpers
10
10
 
11
11
  attr_accessor :delay, :timeout
12
+ attr_writer :stop_by
12
13
 
13
14
  def initialize(options = {})
14
15
  check_keys
@@ -18,12 +19,27 @@ module DoSnapshot
18
19
  end
19
20
  end
20
21
 
22
+ # Power On request for Droplet
23
+ #
24
+ def start_droplet(id)
25
+ # noinspection RubyResolve
26
+ instance = droplet(id)
27
+
28
+ return power_on(id) unless instance.status.include?('active')
29
+
30
+ logger.error "Droplet #{id} is still running. Skipping."
31
+ end
32
+
21
33
  protected
22
34
 
23
35
  def set_id; end
24
36
 
25
37
  def check_keys; end
26
38
 
39
+ def stop_by
40
+ @stop_by ||= :event_status
41
+ end
42
+
27
43
  # Waiting wrapper
28
44
  def wait_wrap(id, message = "Event Id: #{id}", &status_block)
29
45
  logger.debug message
@@ -37,8 +53,15 @@ module DoSnapshot
37
53
  end
38
54
 
39
55
  # Waiting for droplet shutdown
40
- def wait_shutdown(droplet_id)
41
- wait_wrap(droplet_id, "Droplet Id: #{droplet_id} shutting down") { |id, time| get_shutdown_status(id, time) }
56
+ def wait_shutdown(droplet_id, event_id)
57
+ case stop_by
58
+ when :power_status
59
+ wait_wrap(droplet_id, "Droplet Id: #{droplet_id} shutting down") { |id, time| get_shutdown_status(id, time) }
60
+ when :event_status
61
+ wait_event(event_id)
62
+ else
63
+ fail 'Please define :stopper method (:droplet_status, :event_status'
64
+ end
42
65
  end
43
66
 
44
67
  def after_cleanup(droplet_id, droplet_name, snapshot, event)
@@ -29,17 +29,6 @@ module DoSnapshot
29
29
  instance.snapshots
30
30
  end
31
31
 
32
- # Power On request for Droplet
33
- #
34
- def start_droplet(id)
35
- # noinspection RubyResolve
36
- instance = droplet(id)
37
-
38
- return power_on(id) unless instance.status.include? 'active'
39
-
40
- logger.error "Droplet #{id} is still running. Skipping."
41
- end
42
-
43
32
  # Request Power On for droplet
44
33
  #
45
34
  def power_on(id)
@@ -62,7 +51,7 @@ module DoSnapshot
62
51
  fail event.message unless event.status.include? 'OK'
63
52
 
64
53
  # noinspection RubyResolve
65
- wait_event(event.event_id)
54
+ wait_shutdown(id, event.event_id)
66
55
  rescue => e
67
56
  raise DropletShutdownError.new(id), e.message, e.backtrace
68
57
  end
@@ -31,17 +31,6 @@ module DoSnapshot
31
31
  instance.snapshot_ids
32
32
  end
33
33
 
34
- # Power On request for Droplet
35
- #
36
- def start_droplet(id)
37
- # noinspection RubyResolve
38
- instance = droplet(id)
39
-
40
- return power_on(id) unless instance.status.include?('active')
41
-
42
- logger.error "Droplet #{id} is still running. Skipping."
43
- end
44
-
45
34
  # Request Power On for droplet
46
35
  #
47
36
  def power_on(id)
@@ -66,7 +55,7 @@ module DoSnapshot
66
55
  fail DropletShutdownError.new(id), response.message unless response.respond_to?(:action)
67
56
 
68
57
  # noinspection RubyResolve
69
- wait_event(response.action.id)
58
+ wait_shutdown(id, response.action.id)
70
59
  end
71
60
 
72
61
  # Sending event to create snapshot via DigitalOcean API and wait for success
@@ -14,7 +14,7 @@ module DoSnapshot
14
14
 
15
15
  default_task :snap
16
16
 
17
- map %w( c s create ) => :snap
17
+ map %w( c s create ) => :snap
18
18
  map %w( -V ) => :version
19
19
 
20
20
  # Overriding Thor method for custom initialization
@@ -135,6 +135,9 @@ module DoSnapshot
135
135
  type: :boolean,
136
136
  aliases: %w( -s),
137
137
  desc: 'Stop creating snapshots if maximum is reached.'
138
+ method_option :stop_by_power,
139
+ type: :boolean,
140
+ desc: 'Check if droplet stopped by its power status instead of waiting for event completed state.'
138
141
  method_option :trace,
139
142
  type: :boolean,
140
143
  aliases: %w( -v ),
@@ -92,7 +92,7 @@ module DoSnapshot
92
92
  # API launcher
93
93
  #
94
94
  def api
95
- @api ||= DoSnapshot::Adapter.api(protocol, delay: delay, timeout: timeout)
95
+ @api ||= DoSnapshot::Adapter.api(protocol, delay: delay, timeout: timeout, stop_by: stop_by)
96
96
  end
97
97
 
98
98
  # Processed droplets
@@ -104,7 +104,7 @@ module DoSnapshot
104
104
  protected
105
105
 
106
106
  attr_accessor :droplets, :exclude, :only
107
- attr_accessor :keep, :quiet, :stop, :clean, :timeout, :delay, :protocol
107
+ attr_accessor :keep, :quiet, :stop, :stop_by_power, :clean, :timeout, :delay, :protocol
108
108
 
109
109
  attr_writer :threads, :api
110
110
 
@@ -116,6 +116,10 @@ module DoSnapshot
116
116
  @threads ||= []
117
117
  end
118
118
 
119
+ def stop_by
120
+ stop_by_power ? :power_status : :event_status
121
+ end
122
+
119
123
  # Working with list of droplets.
120
124
  #
121
125
  def work_with_droplets
@@ -9,7 +9,7 @@ module DoSnapshot
9
9
  attr_accessor :mailer
10
10
 
11
11
  def initialize
12
- @logger = nil
12
+ @logger = nil
13
13
  @logger_level = Logger::INFO
14
14
  @verbose = false
15
15
  @quiet = false
@@ -5,7 +5,11 @@ module DoSnapshot
5
5
  #
6
6
  class Runner
7
7
  def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
8
- @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
8
+ @argv = argv
9
+ @stdin = stdin
10
+ @stdout = stdout
11
+ @stderr = stderr
12
+ @kernel = kernel
9
13
  end
10
14
 
11
15
  def execute! # rubocop:disable Metrics/MethodLength
@@ -2,5 +2,5 @@
2
2
  # Current version
3
3
  #
4
4
  module DoSnapshot
5
- VERSION = '0.4.0'
5
+ VERSION = '0.4.1'
6
6
  end
@@ -10,13 +10,13 @@ RSpec.describe DoSnapshot::Adapter::Abstract do
10
10
  describe '#delay' do
11
11
  let(:delay) { 5 }
12
12
  let(:instance) { api.new(delay: delay) }
13
- it('with custom delay') { expect(instance.delay).to eq delay }
13
+ it('with custom delay') { expect(instance.delay).to eq delay }
14
14
  end
15
15
 
16
16
  describe '#timeout' do
17
17
  let(:timeout) { 5 }
18
18
  let(:instance) { api.new(timeout: timeout) }
19
- it('with custom timeout') { expect(instance.timeout).to eq timeout }
19
+ it('with custom timeout') { expect(instance.timeout).to eq timeout }
20
20
  end
21
21
  end
22
22
  end
@@ -12,13 +12,13 @@ RSpec.describe DoSnapshot::Adapter::Digitalocean do
12
12
  describe '#delay' do
13
13
  let(:delay) { 5 }
14
14
  let(:instance) { api.new(delay: delay) }
15
- it('with custom delay') { expect(instance.delay).to eq delay }
15
+ it('with custom delay') { expect(instance.delay).to eq delay }
16
16
  end
17
17
 
18
18
  describe '#timeout' do
19
19
  let(:timeout) { 5 }
20
20
  let(:instance) { api.new(timeout: timeout) }
21
- it('with custom timeout') { expect(instance.timeout).to eq timeout }
21
+ it('with custom timeout') { expect(instance.timeout).to eq timeout }
22
22
  end
23
23
  end
24
24
 
@@ -108,7 +108,39 @@ RSpec.describe DoSnapshot::Adapter::Digitalocean do
108
108
  end
109
109
  end
110
110
 
111
- describe '.stop_droplet' do
111
+ describe '.stop_droplet by power status' do
112
+ let(:instance) { api.new(delay: delay, timeout: timeout, stop_by: :power_status) }
113
+
114
+ it 'with success' do
115
+ stub_event_done(event_id)
116
+ stub_droplet_stop(droplet_id)
117
+ stub_droplet_inactive(droplet_id)
118
+
119
+ instance.stop_droplet(droplet_id)
120
+
121
+ expect(a_request(:get, droplet_stop_url))
122
+ .to have_been_made
123
+ expect(a_request(:get, droplet_url))
124
+ .to have_been_made
125
+ end
126
+
127
+ it 'with error' do
128
+ stub_droplet_stop_fail(droplet_id)
129
+ stub_droplet(droplet_id)
130
+
131
+ instance.timeout = 1
132
+ expect { instance.stop_droplet(droplet_id) }
133
+ .to raise_error(DoSnapshot::DropletShutdownError)
134
+ instance.timeout = timeout
135
+ expect(DoSnapshot.logger.buffer)
136
+ .to include 'Droplet id: 100823 is Failed to Power Off.'
137
+
138
+ expect(a_request(:get, droplet_stop_url))
139
+ .to have_been_made
140
+ end
141
+ end
142
+
143
+ describe '.stop_droplet by event' do
112
144
  it 'with success' do
113
145
  stub_event_done(event_id)
114
146
  stub_droplet_stop(droplet_id)
@@ -14,13 +14,13 @@ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
14
14
  describe '#delay' do
15
15
  let(:delay) { 5 }
16
16
  let(:instance) { api.new(delay: delay) }
17
- it('with custom delay') { expect(instance.delay).to eq delay }
17
+ it('with custom delay') { expect(instance.delay).to eq delay }
18
18
  end
19
19
 
20
20
  describe '#timeout' do
21
21
  let(:timeout) { 5 }
22
22
  let(:instance) { api.new(timeout: timeout) }
23
- it('with custom timeout') { expect(instance.timeout).to eq timeout }
23
+ it('with custom timeout') { expect(instance.timeout).to eq timeout }
24
24
  end
25
25
  end
26
26
 
@@ -110,7 +110,38 @@ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
110
110
  end
111
111
  end
112
112
 
113
- describe '.stop_droplet' do
113
+ describe '.stop_droplet by power status' do
114
+ let(:instance) { api.new(delay: delay, timeout: timeout, stop_by: :power_status) }
115
+
116
+ it 'with success' do
117
+ stub_event_done(event_id)
118
+ stub_droplet_stop(droplet_id)
119
+ stub_droplet_inactive(droplet_id)
120
+
121
+ instance.stop_droplet(droplet_id)
122
+
123
+ expect(a_request(:post, droplet_stop_url))
124
+ .to have_been_made
125
+ expect(a_request(:get, droplet_url))
126
+ .to have_been_made
127
+ end
128
+
129
+ it 'with error' do
130
+ stub_droplet_stop_fail(droplet_id)
131
+ stub_droplet(droplet_id)
132
+ instance.timeout = 1
133
+ expect { instance.stop_droplet(droplet_id) }
134
+ .to raise_error(DoSnapshot::DropletShutdownError)
135
+ instance.timeout = timeout
136
+ expect(DoSnapshot.logger.buffer)
137
+ .to include 'Droplet id: 100823 is Failed to Power Off.'
138
+
139
+ expect(a_request(:post, droplet_stop_url))
140
+ .to have_been_made
141
+ end
142
+ end
143
+
144
+ describe '.stop_droplet by event' do
114
145
  it 'with success' do
115
146
  stub_event_done(event_id)
116
147
  stub_droplet_stop(droplet_id)
@@ -75,6 +75,14 @@ RSpec.describe DoSnapshot::CLI do
75
75
  attribute_eq 'stop', false
76
76
  end
77
77
 
78
+ it 'with stop by power' do
79
+ attribute_eq 'stop_by_power', true
80
+ end
81
+
82
+ it 'with stop by event' do
83
+ attribute_eq 'stop_by_power', false
84
+ end
85
+
78
86
  it 'with clean' do
79
87
  attribute_eq 'clean', true
80
88
  end
@@ -114,7 +114,30 @@ RSpec.describe DoSnapshot::Command do
114
114
  end
115
115
  end
116
116
 
117
- describe '.stop_droplet' do
117
+ describe '.stop_droplet by power status' do
118
+ it 'when raised with error' do
119
+ stub_droplet_stop_fail(droplet_id)
120
+ load_options(stop_by_power: true)
121
+ droplet = cmd.api.droplet droplet_id
122
+ expect { cmd.stop_droplet(droplet) }
123
+ .not_to raise_error
124
+ expect(cmd.stop_droplet(droplet))
125
+ .to be_falsey
126
+ end
127
+
128
+ it 'when stopped' do
129
+ stub_droplet_inactive(droplet_id)
130
+ stub_droplet_stop(droplet_id)
131
+ load_options(stop_by_power: true)
132
+ droplet = cmd.api.droplet droplet_id
133
+ expect { cmd.stop_droplet(droplet) }
134
+ .not_to raise_error
135
+ expect(cmd.stop_droplet(droplet))
136
+ .to be_truthy
137
+ end
138
+ end
139
+
140
+ describe '.stop_droplet by event' do
118
141
  it 'when raised with error' do
119
142
  stub_droplet_stop_fail(droplet_id)
120
143
  load_options
@@ -109,6 +109,24 @@ RSpec.describe DoSnapshot::Runner, type: :aruba do
109
109
  expect(all_stdout).to include(t_snapshot_created(snapshot_name))
110
110
  end
111
111
 
112
+ it 'with stop by power' do
113
+ attribute_eq 'stop_by_power', true
114
+
115
+ expect(last_command).to have_exit_status(0)
116
+ expect(all_stdout).to include(t_droplet_shutdown)
117
+ expect(all_stdout).to include(t_wait_until_create)
118
+ expect(all_stdout).to include(t_snapshot_created(snapshot_name))
119
+ end
120
+
121
+ it 'with stop by event' do
122
+ attribute_eq 'stop_by_power', false
123
+
124
+ expect(last_command).to have_exit_status(0)
125
+ expect(all_stdout).to include(t_droplet_shutdown)
126
+ expect(all_stdout).to include(t_wait_until_create)
127
+ expect(all_stdout).to include(t_snapshot_created(snapshot_name))
128
+ end
129
+
112
130
  it 'with clean' do
113
131
  attribute_eq 'clean', true
114
132
 
@@ -314,18 +332,12 @@ RSpec.describe DoSnapshot::Runner, type: :aruba do
314
332
  elsif value.is_a?(Numeric)
315
333
  "--#{key}=#{value}"
316
334
  elsif value.is_a?(Array)
317
- if value.size > 0
318
- "--#{key}=#{value.join(' ')}"
319
- else
320
- nil
321
- end
335
+ next unless value.size > 0
336
+ "--#{key}=#{value.join(' ')}"
322
337
  elsif value.is_a?(Hash)
323
- if value.size > 0
324
- items = value.map { |param, setting| "#{param}:#{setting}" }.join(' ')
325
- "--#{key}=#{items}"
326
- else
327
- nil
328
- end
338
+ next unless value.size > 0
339
+ items = value.map { |param, setting| "#{param}:#{setting}" }.join(' ')
340
+ "--#{key}=#{items}"
329
341
  else
330
342
  "--#{key}"
331
343
  end
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.4.0
4
+ version: 0.4.1
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-08-02 00:00:00.000000000 Z
11
+ date: 2015-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: digitalocean_c