do_snapshot 0.3.6 → 0.3.7

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: 21efe1c089acf9072715fbb30f61344f0cd7f5df
4
- data.tar.gz: 9f4fce0343830350f4c5e5305274ef9d7ac9903c
3
+ metadata.gz: 06606ebf6e8df99c994ce845c7f5fa63996f53e1
4
+ data.tar.gz: 42f86fa15f04f5e5d43e7785b0fcd46b6c0875e1
5
5
  SHA512:
6
- metadata.gz: 2c97b328614cf2d9154c972862aaea983b1e9bf3087a90ea18679bc8f6d18f5a0119b924d24d1b055aa658954ca1a085ddcd5318f75c8fd6f7afa053c6910352
7
- data.tar.gz: 9c917c20fdd446c6161b69f339d907453dc3ccb639ff9017ed9aee8f7ea580ee67a8e1acfb3f75d9981b7c342082aa227e5a9c90553c0b72d6620a7a4ae26c0e
6
+ metadata.gz: cbaea0198b09721b86e4419b5fb1aba1c1935469be3a7fb0fe16d9be044857767150fa7b5e5cc4da3b546b6e5ee353ce5466ca3cd096ba5fa8156f067d8ce499
7
+ data.tar.gz: f04fe0b3897ca82876cbc33b7b952017bcd9e569953c101486eae2a34304c73fffb90d3b56deb63bfa78931a8576a2a83ede049087586405f78286cac6d4d93f
data/README.md CHANGED
@@ -193,7 +193,7 @@ Support this project and others by [merqlove](https://gratipay.com/~merqlove/) v
193
193
 
194
194
  - [Thor](https://github.com/erikhuda/thor) for CLI.
195
195
  - [Digitalocean](https://github.com/scottmotte/digitalocean) for API V1 requests.
196
- - [DropletKit](https://github.com/digitalocean/droplet_kit) for API V2 requests.
196
+ - [Barge](https://github.com/blom/barge) for API V2 requests.
197
197
  - [Pony](https://github.com/benprew/pony) for mail notifications.
198
198
 
199
199
  ## Contributing
@@ -1,6 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_support/multibyte' # ActiveSupport 3.2 & Mail gem fix to work together.
3
-
4
2
  require_relative 'do_snapshot/version'
5
3
  require_relative 'do_snapshot/configuration'
6
4
 
@@ -77,7 +75,7 @@ module DoSnapshot
77
75
  #
78
76
  class DropletFindError < RequestError
79
77
  def initialize(*args)
80
- DoSnapshot.logger.error 'Droplet Not Found'
78
+ DoSnapshot.logger.error "Droplet id: #{args[0]} Not Found"
81
79
  super
82
80
  end
83
81
  end
@@ -12,7 +12,7 @@ module DoSnapshot
12
12
  def droplet(id)
13
13
  # noinspection RubyResolve
14
14
  response = ::DigitaloceanC::Droplet.find(id)
15
- fail DropletFindError, response.message unless response.status.include? 'OK'
15
+ fail DropletFindError.new(id), response.message unless response.status.include? 'OK'
16
16
  response.droplet
17
17
  end
18
18
 
@@ -124,9 +124,9 @@ module DoSnapshot
124
124
  event = ::DigitaloceanC::Droplet.power_on(id)
125
125
  case event && event.status
126
126
  when 'OK'
127
- logger.info 'Power On has been requested.'
127
+ logger.info "Droplet id: #{id} is requested for Power On."
128
128
  else
129
- logger.error 'Power On failed to request.'
129
+ logger.error "Droplet id: #{id} is failed to request for Power On."
130
130
  end
131
131
  end
132
132
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'droplet_kit' unless defined?(::DropletKit)
2
+ require 'barge' unless defined?(::Barge)
3
3
 
4
4
  module DoSnapshot
5
5
  module Adapter
@@ -13,22 +13,18 @@ module DoSnapshot
13
13
  #
14
14
  def droplet(id)
15
15
  # noinspection RubyResolve
16
- response = client.droplets.find(id: id)
17
- fail DropletFindError unless response
18
- response
19
- rescue => e
20
- raise DropletFindError, e.message
16
+ response = client.droplet.show(id)
17
+ fail DropletFindError.new(id), response.message unless response.respond_to?(:droplet)
18
+ response.droplet
21
19
  end
22
20
 
23
21
  # Get droplets list from DigitalOcean
24
22
  #
25
23
  def droplets
26
24
  # noinspection RubyResolve
27
- response = client.droplets.all
28
- fail DropletListError unless response
29
- response.each
30
- rescue => e
31
- raise DropletListError, e.message
25
+ response = client.droplet.all
26
+ fail DropletListError, response.message unless response.respond_to?(:droplets)
27
+ response.droplets
32
28
  end
33
29
 
34
30
  def snapshots(instance)
@@ -41,7 +37,7 @@ module DoSnapshot
41
37
  # noinspection RubyResolve
42
38
  instance = droplet(id)
43
39
 
44
- return power_on(id) unless instance.status && instance.status.include?('active')
40
+ return power_on(id) unless instance.status.include?('active')
45
41
 
46
42
  logger.error "Droplet #{id} is still running. Skipping."
47
43
  end
@@ -50,24 +46,24 @@ module DoSnapshot
50
46
  #
51
47
  def stop_droplet(id)
52
48
  # noinspection RubyResolve,RubyResolve
53
- client.droplet_actions.power_off(droplet_id: id)
49
+ response = client.droplet.power_off(id)
50
+
51
+ fail DropletShutdownError.new(id), response.message unless response.respond_to?(:action)
54
52
 
55
53
  # noinspection RubyResolve
56
- wait_shutdown(id)
57
- rescue => e
58
- raise DropletShutdownError.new(id), e.message, e.backtrace
54
+ wait_event(response.action.id)
59
55
  end
60
56
 
61
57
  # Sending event to create snapshot via DigitalOcean API and wait for success
62
58
  #
63
59
  def create_snapshot(id, name)
64
60
  # noinspection RubyResolve,RubyResolve
65
- event = client.droplet_actions.snapshot(droplet_id: id, name: name)
61
+ response = client.droplet.snapshot(id, name: name)
66
62
 
67
- fail DoSnapshot::SnapshotCreateError.new(id), name unless event && event.respond_to?(:id)
63
+ fail DoSnapshot::SnapshotCreateError.new(id), response.message unless response.respond_to?(:action)
68
64
 
69
65
  # noinspection RubyResolve
70
- wait_event(event.id)
66
+ wait_event(response.action.id)
71
67
  end
72
68
 
73
69
  # Checking if droplet is powered off.
@@ -84,14 +80,11 @@ module DoSnapshot
84
80
  (0..size).each do |i|
85
81
  # noinspection RubyResolve
86
82
  snapshot = instance.snapshot_ids[i]
87
- event = client.images.delete(id: snapshot)
83
+ action = client.image.destroy(snapshot)
88
84
 
89
- unless event.is_a?(TrueClass)
90
- logger.debug event
91
- event = false
92
- end
85
+ logger.debug action unless action.success?
93
86
 
94
- after_cleanup(instance.id, instance.name, snapshot, event)
87
+ after_cleanup(instance.id, instance.name, snapshot, action)
95
88
  end
96
89
  end
97
90
 
@@ -106,13 +99,13 @@ module DoSnapshot
106
99
  #
107
100
  def set_id
108
101
  logger.debug 'Setting DigitalOcean Access Token.'
109
- @client = ::DropletKit::Client.new(access_token: ENV['DIGITAL_OCEAN_ACCESS_TOKEN'])
102
+ @client = ::Barge::Client.new(access_token: ENV['DIGITAL_OCEAN_ACCESS_TOKEN'], timeout: 15, open_timeout: 15)
110
103
  end
111
104
 
112
105
  protected
113
106
 
114
- def after_cleanup(droplet_id, droplet_name, snapshot, event)
115
- if !event
107
+ def after_cleanup(droplet_id, droplet_name, snapshot, action)
108
+ if !action.success?
116
109
  logger.error "Destroy of snapshot #{snapshot} for droplet id: #{droplet_id} name: #{droplet_name} is failed."
117
110
  else
118
111
  logger.debug "Snapshot: #{snapshot} delete requested."
@@ -124,23 +117,26 @@ module DoSnapshot
124
117
  def get_event_status(id, time)
125
118
  return true if timeout?(id, time)
126
119
 
127
- action = client.actions.find(id: id)
120
+ response = client.action.show(id)
128
121
 
129
- fail DoSnapshot::EventError.new(id), 'Check your connection' unless action && action.respond_to?(:status)
122
+ fail DoSnapshot::EventError.new(id), response.message unless response.respond_to?(:action)
130
123
 
131
124
  # noinspection RubyResolve,RubyResolve
132
- action.status.include?('completed') ? true : false
125
+ response.action.status.include?('completed') ? true : false
133
126
  end
134
127
 
135
128
  # Request Power On for droplet
136
129
  #
137
130
  def power_on(id)
138
131
  # noinspection RubyResolve
139
- event = client.droplet_actions.power_on(droplet_id: id)
140
- if event.status.include?('in-progress')
141
- logger.info 'Power On has been requested.'
132
+ response = client.droplet.power_on(id)
133
+
134
+ fail DoSnapshot::EventError.new(id), response.message unless response.respond_to?(:action)
135
+
136
+ if response.action.status.include?('in-progress')
137
+ logger.info "Droplet id: #{id} is requested for Power On."
142
138
  else
143
- logger.error 'Power On failed to request.'
139
+ logger.error "Droplet id: #{id} is failed to request for Power On."
144
140
  end
145
141
  end
146
142
  end
@@ -14,6 +14,7 @@ module DoSnapshot
14
14
  def snap
15
15
  logger.info 'Start performing operations'
16
16
  work_with_droplets
17
+ power_on_failed_droplets
17
18
  logger.info 'All operations has been finished.'
18
19
 
19
20
  mailer.notify if mailer && notify && !quiet
@@ -82,10 +83,24 @@ module DoSnapshot
82
83
  end
83
84
  end
84
85
 
86
+ def power_on_failed_droplets
87
+ processed_droplet_ids
88
+ .select { |id| api.inactive?(id) }
89
+ .each { |id| api.start_droplet(id) }
90
+ end
91
+
92
+ # API launcher
93
+ #
85
94
  def api
86
95
  @api ||= DoSnapshot::Adapter.api(protocol, delay: delay, timeout: timeout)
87
96
  end
88
97
 
98
+ # Processed droplets
99
+ #
100
+ def processed_droplet_ids
101
+ @droplet_ids ||= %w()
102
+ end
103
+
89
104
  protected
90
105
 
91
106
  attr_accessor :droplets, :exclude, :only
@@ -154,6 +169,7 @@ module DoSnapshot
154
169
  return unless droplet
155
170
  logger.info "Preparing droplet id: #{droplet.id} name: #{droplet.name} to take snapshot."
156
171
  return if too_much_snapshots(droplet)
172
+ processed_droplet_ids << droplet.id
157
173
  thread_runner(droplet)
158
174
  end
159
175
 
@@ -2,5 +2,5 @@
2
2
  # Current version
3
3
  #
4
4
  module DoSnapshot
5
- VERSION = '0.3.6'
5
+ VERSION = '0.3.7'
6
6
  end
@@ -42,7 +42,7 @@ RSpec.describe DoSnapshot::Adapter::Digitalocean do
42
42
  expect { instance.droplet(droplet_id) }
43
43
  .to raise_error(DoSnapshot::DropletFindError)
44
44
  expect(DoSnapshot.logger.buffer)
45
- .to include 'Droplet Not Found'
45
+ .to include "Droplet id: #{droplet_id} Not Found"
46
46
 
47
47
  expect(a_request(:get, droplet_url))
48
48
  .to have_been_made
@@ -77,7 +77,7 @@ RSpec.describe DoSnapshot::Adapter::Digitalocean do
77
77
  stub_droplet_start(droplet_id)
78
78
 
79
79
  instance.start_droplet(droplet_id)
80
- expect(DoSnapshot.logger.buffer).to include 'Power On has been requested.'
80
+ expect(DoSnapshot.logger.buffer).to include "Droplet id: #{droplet_id} is requested for Power On."
81
81
 
82
82
  expect(a_request(:get, droplet_start_url))
83
83
  .to have_been_made
@@ -44,7 +44,7 @@ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
44
44
  expect { instance.droplet(droplet_id) }
45
45
  .to raise_error(DoSnapshot::DropletFindError)
46
46
  expect(DoSnapshot.logger.buffer)
47
- .to include 'Droplet Not Found'
47
+ .to include "Droplet id: #{droplet_id} Not Found"
48
48
 
49
49
  expect(a_request(:get, droplet_url))
50
50
  .to have_been_made
@@ -79,7 +79,7 @@ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
79
79
  stub_droplet_start(droplet_id)
80
80
 
81
81
  instance.start_droplet(droplet_id)
82
- expect(DoSnapshot.logger.buffer).to include 'Power On has been requested.'
82
+ expect(DoSnapshot.logger.buffer).to include "Droplet id: #{droplet_id} is requested for Power On."
83
83
 
84
84
  expect(a_request(:post, droplet_start_url))
85
85
  .to have_been_made
@@ -114,23 +114,20 @@ RSpec.describe DoSnapshot::Adapter::DigitaloceanV2 do
114
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)
118
117
 
119
118
  instance.stop_droplet(droplet_id)
120
119
 
121
120
  expect(a_request(:post, droplet_stop_url))
122
121
  .to have_been_made
123
- expect(a_request(:get, droplet_url))
122
+ expect(a_request(:get, action_find_url))
124
123
  .to have_been_made
125
124
  end
126
125
 
127
126
  it 'with error' do
128
127
  stub_droplet_stop_fail(droplet_id)
129
- stub_droplet(droplet_id)
130
- instance.timeout = 1
128
+
131
129
  expect { instance.stop_droplet(droplet_id) }
132
130
  .to raise_error(DoSnapshot::DropletShutdownError)
133
- instance.timeout = timeout
134
131
  expect(DoSnapshot.logger.buffer)
135
132
  .to include 'Droplet id: 100823 is Failed to Power Off.'
136
133
 
@@ -88,6 +88,32 @@ RSpec.describe DoSnapshot::Command do
88
88
  end
89
89
  end
90
90
 
91
+ describe '.power_on_failed_droplets' do
92
+ it 'when nothing' do
93
+ stub_droplet_start(droplet_id)
94
+ stub_droplet(droplet_id)
95
+
96
+ load_options
97
+ cmd.processed_droplet_ids << droplet_id
98
+ expect { cmd.power_on_failed_droplets }
99
+ .not_to raise_error
100
+ expect(DoSnapshot.logger.buffer)
101
+ .not_to include "Droplet id: #{droplet_id} is requested for Power On."
102
+ end
103
+
104
+ it 'when one' do
105
+ stub_droplet_start(droplet_id)
106
+ stub_droplet_inactive(droplet_id)
107
+
108
+ load_options
109
+ cmd.processed_droplet_ids << droplet_id
110
+ expect { cmd.power_on_failed_droplets }
111
+ .not_to raise_error
112
+ expect(DoSnapshot.logger.buffer)
113
+ .to include "Droplet id: #{droplet_id} is requested for Power On."
114
+ end
115
+ end
116
+
91
117
  describe '.stop_droplet' do
92
118
  it 'when raised with error' do
93
119
  stub_droplet_stop_fail(droplet_id)
@@ -150,7 +176,7 @@ RSpec.describe DoSnapshot::Command do
150
176
  expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
151
177
  .not_to raise_error
152
178
  expect(DoSnapshot.logger.buffer)
153
- .to include 'Power On has been requested.'
179
+ .to include "Droplet id: #{droplet_id} is requested for Power On."
154
180
  end
155
181
 
156
182
  it 'with request error' do
@@ -161,7 +187,7 @@ RSpec.describe DoSnapshot::Command do
161
187
  expect(DoSnapshot.logger.buffer)
162
188
  .to include 'Droplet id: 100823 is Failed to Power Off.'
163
189
  expect(DoSnapshot.logger.buffer)
164
- .to include 'Droplet Not Found'
190
+ .to include "Droplet id: #{droplet_id} Not Found"
165
191
  end
166
192
 
167
193
  it 'with start error' do
@@ -172,7 +198,7 @@ RSpec.describe DoSnapshot::Command do
172
198
  expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
173
199
  .not_to raise_error
174
200
  expect(DoSnapshot.logger.buffer)
175
- .to include 'Power On failed to request.'
201
+ .to include "Droplet id: #{droplet_id} is failed to request for Power On."
176
202
  end
177
203
  end
178
204
  end
@@ -8,9 +8,9 @@ RSpec.describe DoSnapshot do
8
8
  subject(:error) { described_class }
9
9
 
10
10
  it 'should work' do
11
- error.new
11
+ error.new(droplet_id)
12
12
  expect(DoSnapshot.logger.buffer)
13
- .to include 'Droplet Not Found'
13
+ .to include "Droplet id: #{droplet_id} Not Found"
14
14
  end
15
15
  end
16
16
 
@@ -9,13 +9,13 @@ shared_context 'api_v2_helpers' do
9
9
  let(:actions_api_base) { "#{api_base}/actions" }
10
10
  let(:images_api_base) { "#{api_base}/images" }
11
11
  let(:image_destroy_uri) { "#{images_api_base}/[id]" }
12
- let(:droplets_uri) { "#{droplets_api_base}?page=1&per_page=20" }
13
- let(:droplet_find_uri) { "#{droplets_api_base}/[id]" }
12
+ let(:droplets_uri) { "#{droplets_api_base}?per_page=200" }
13
+ let(:droplet_find_uri) { "#{droplets_api_base}/[id]?per_page=200" }
14
14
  let(:droplet_stop_uri) { "#{droplets_api_base}/[id]/actions" }
15
15
  let(:droplet_start_uri) { "#{droplets_api_base}/[id]/actions" }
16
16
  let(:snapshot_uri) { "#{droplets_api_base}/[id]/actions" }
17
17
  let(:event_find_uri) { "#{events_api_base}/[id]" }
18
- let(:action_find_uri) { "#{actions_api_base}/[id]" }
18
+ let(:action_find_uri) { "#{actions_api_base}/[id]?per_page=200" }
19
19
 
20
20
  # List of droplets
21
21
  #
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: do_snapshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
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-30 00:00:00.000000000 Z
11
+ date: 2015-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '3.2'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '3.2'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: digitalocean_c
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +25,19 @@ dependencies:
39
25
  - !ruby/object:Gem::Version
40
26
  version: '1.2'
41
27
  - !ruby/object:Gem::Dependency
42
- name: droplet_kit
28
+ name: barge
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: '1.2'
33
+ version: '0.11'
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: '1.2'
40
+ version: '0.11'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: thor
57
43
  requirement: !ruby/object:Gem::Requirement