do_snapshot 0.4.0 → 0.4.1

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.
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