do_snapshot 0.6.2 → 0.6.3

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: d4b1d0886088780b79e06c589eba381d8152ac73
4
- data.tar.gz: d5bd6e4651f3265200457d0ffb107d8093325b71
3
+ metadata.gz: 5ee1fb26e08febbd07bd95db15ede7e27288c6ac
4
+ data.tar.gz: e94d18d396f7afe4a2746b7d5f26ab4bf162cc1e
5
5
  SHA512:
6
- metadata.gz: 36e0890a6ea0f126053fad03b94211b9f8d7453c2318be21a32f241dd18d2dbfede194c279d1f19c20c9c59f566c888356579c8c4d4e9f55798e62da62e90cdd
7
- data.tar.gz: 09884729d366d5effb5b2ce263e82bb113a0afb4c1c21aead12502beea9d38728a5f612a55487b0b7efd3657f8fc3c43a607b15ce4ed7277bdcce2117eba8a9e
6
+ metadata.gz: d9222fbba54f8d23156befea3fbe36aebb173e566f29710d09a84c9ab4915ad177e8800818744c54c02ece99fd167b30a013054ff526fc749ce128358cd66e6c
7
+ data.tar.gz: bc3c05e81971b6a62e217785035361179e2832c9b52f8cab5371d64655eedf57dded6bbc9f5064aa340fbfa1584adc0028c00307f6ff951ffcfdba732fe991c0
data/README.md CHANGED
@@ -13,6 +13,10 @@
13
13
  Use this tool to backup DigitalOcean droplet's via snapshot method, on the fly!
14
14
 
15
15
  ## API Changes:
16
+ - 03.08.16: DO now automagically keeps our droplets running when snapshot is processing, so:
17
+ Added options `--shutdown`, `--no-shutdown`.
18
+ `shutdown` now disabled by default, no downtime anymore, `YES`!
19
+ If you want `shutdown` back use `--shutdown` option.
16
20
  - 08.01.16: now we have to use DO API V2 only, because V1 is not work anymore.
17
21
  - 17.10.15: now we use DO API V2 by default, due V1 deprecation at 11.2015.
18
22
 
@@ -87,8 +91,9 @@ If you want to set keys without environment, than set it via options when you ru
87
91
  ### How-To
88
92
 
89
93
  ##### Tutorials:
90
- - [Longren Tutorial](https://longren.io/automate-making-snapshots-of-your-digitalocean-droplets/)
91
- - [Arun Kumar Tutorial](http://www.ashout.com/automate-digital-ocean-droplet-snaphot/)
94
+ - [Automate Taking Snapshots of Your DigitalOcean Droplets with DOSnapshot
95
+ , Tyler Longren](https://longren.io/automate-making-snapshots-of-your-digitalocean-droplets/)
96
+ - [How to Automate Taking Digital Ocean Droplet Snaphot with DoSnapShot Script, Arun Kumar](http://www.ashout.com/automate-digital-ocean-droplet-snaphot/)
92
97
 
93
98
  Here we `keeping` only 5 **latest** snapshots and cleanup older after new one is created. If creation of snapshots failed no one will be deleted. By default we keeping `10` droplets.
94
99
 
@@ -147,6 +152,7 @@ For working mailer you need to set e-mail settings via run options.
147
152
  Options:
148
153
  -p, [--protocol=1] # Select api version.
149
154
  # Default: 2
155
+ [--shutdown], [--no-shutdown] # Check if you want to stop your droplet before the snapshot.
150
156
  -o, [--only=123456 123456 123456] # Select some droplets.
151
157
  -e, [--exclude=123456 123456 123456] # Except some droplets.
152
158
  -k, [--keep=5] # How much snapshots you want to keep?
@@ -160,7 +166,7 @@ For working mailer you need to set e-mail settings via run options.
160
166
  -l, [--log=/Users/someone/.do_snapshot/main.log] # Log file path. By default logging is disabled.
161
167
  -c, [--clean], [--no-clean] # Cleanup snapshots after create. If you have more images than you want to `keep`, older will be deleted.
162
168
  -s, [--stop], [--no-stop] # Stop creating snapshots if maximum is reached.
163
- [--stop-by-power], [--no-stop-by-power] # Check if droplet stopped by its power status instead of waiting for event completed state.
169
+ [--stop-by-power], [--no-stop-by-power] # Droplet stop method, by it's power status (instead of waiting for event completed state).
164
170
  -v, [--trace], [--no-trace] # Verbose mode.
165
171
  -q, [--quiet], [--no-quiet] # Quiet mode. If don't need any messages in console.
166
172
  [--digital-ocean-access-token=YOURLONGAPITOKEN] # DIGITAL_OCEAN_ACCESS_TOKEN. if you can't use environment.
@@ -189,7 +195,6 @@ Support this project and others by [merqlove](https://gratipay.com/~merqlove/) v
189
195
  ## Dependencies:
190
196
 
191
197
  - [Thor](https://github.com/erikhuda/thor) for CLI.
192
- - [Digitalocean](https://github.com/scottmotte/digitalocean) for API V1 requests.
193
198
  - [Barge](https://github.com/blom/barge) for API V2 requests.
194
199
  - [Pony](https://github.com/benprew/pony) for mail notifications.
195
200
 
@@ -95,7 +95,7 @@ module DoSnapshot
95
95
  def check_keys
96
96
  logger.debug 'Checking DigitalOcean Access Token.'
97
97
  %w( DIGITAL_OCEAN_ACCESS_TOKEN ).each do |key|
98
- fail DoSnapshot::NoTokenError, "You must have #{key} in environment or set it via options." if ENV[key].blank?
98
+ fail DoSnapshot::NoTokenError, "You must have #{key} in environment or set it via options." if ENV[key].nil? || ENV[key].empty?
99
99
  end
100
100
  end
101
101
 
@@ -82,6 +82,10 @@ module DoSnapshot
82
82
  aliases: %w( -p ),
83
83
  banner: '1',
84
84
  desc: 'Select api version.'
85
+ method_option :shutdown,
86
+ default: false,
87
+ type: :boolean,
88
+ desc: 'Check if you want to stop droplet before the snapshot.'
85
89
  method_option :only,
86
90
  type: :array,
87
91
  default: [],
@@ -137,7 +141,7 @@ module DoSnapshot
137
141
  desc: 'Stop creating snapshots if maximum is reached.'
138
142
  method_option :stop_by_power,
139
143
  type: :boolean,
140
- desc: 'Check if droplet stopped by its power status instead of waiting for event completed state.'
144
+ desc: "Droplet stop method, by it's power status (instead of waiting for event completed state)."
141
145
  method_option :trace,
142
146
  type: :boolean,
143
147
  aliases: %w( -v ),
@@ -7,6 +7,10 @@ module DoSnapshot
7
7
  class Command # rubocop:disable ClassLength
8
8
  include DoSnapshot::Helpers
9
9
 
10
+ RESET_OPTIONS = [:droplets, :exclude, :only, :keep, :quiet,
11
+ :stop, :clean, :timeout, :shutdown, :delay,
12
+ :protocol, :threads, :api]
13
+
10
14
  def initialize(*args)
11
15
  load_options(*args)
12
16
  end
@@ -21,6 +25,7 @@ module DoSnapshot
21
25
  end
22
26
 
23
27
  def fail_power_off(e)
28
+ return unless shutdown
24
29
  return unless e && e.id
25
30
  api.start_droplet(e.id)
26
31
  rescue
@@ -35,12 +40,13 @@ module DoSnapshot
35
40
  end
36
41
 
37
42
  def reset_options
38
- [:droplets, :exclude, :only, :keep, :quiet, :stop, :clean, :timeout, :delay, :protocol, :threads, :api].each do |key|
43
+ RESET_OPTIONS.each do |key|
39
44
  send("#{key}=", nil)
40
45
  end
41
46
  end
42
47
 
43
48
  def stop_droplet(droplet)
49
+ return true unless shutdown
44
50
  logger.debug 'Shutting down droplet.'
45
51
  api.stop_droplet(droplet.id) unless droplet.status.include? 'off'
46
52
  true
@@ -49,10 +55,15 @@ module DoSnapshot
49
55
  false
50
56
  end
51
57
 
58
+ def fail_if_shutdown(droplet)
59
+ return unless shutdown
60
+ fail DropletPowerError.new(droplet.id), droplet.name unless api.inactive?(droplet.id)
61
+ end
62
+
52
63
  # Trying to create a snapshot.
53
64
  #
54
65
  def create_snapshot(droplet) # rubocop:disable MethodLength,Metrics/AbcSize
55
- fail DropletPowerError.new(droplet.id), droplet.name unless api.inactive?(droplet.id)
66
+ fail_if_shutdown(droplet)
56
67
 
57
68
  logger.info "Start creating snapshot for droplet id: #{droplet.id} name: #{droplet.name}."
58
69
 
@@ -104,7 +115,7 @@ module DoSnapshot
104
115
  protected
105
116
 
106
117
  attr_accessor :droplets, :exclude, :only
107
- attr_accessor :keep, :quiet, :stop, :stop_by_power, :clean, :timeout, :delay, :protocol
118
+ attr_accessor :keep, :quiet, :shutdown, :stop, :stop_by_power, :clean, :timeout, :delay, :protocol
108
119
 
109
120
  attr_writer :threads, :api
110
121
 
@@ -2,5 +2,5 @@
2
2
  # Current version
3
3
  #
4
4
  module DoSnapshot
5
- VERSION = '0.6.2'
5
+ VERSION = '0.6.3'
6
6
  end
@@ -75,6 +75,14 @@ RSpec.describe DoSnapshot::CLI do
75
75
  attribute_eq 'stop', false
76
76
  end
77
77
 
78
+ it 'with shutdown' do
79
+ attribute_eq 'shutdown', true
80
+ end
81
+
82
+ it 'with no shutdown' do
83
+ attribute_eq 'shutdown', false
84
+ end
85
+
78
86
  it 'with stop by power' do
79
87
  attribute_eq 'stop_by_power', true
80
88
  end
@@ -113,7 +113,7 @@ RSpec.describe DoSnapshot::Command do
113
113
  describe '.stop_droplet by power status' do
114
114
  it 'when raised with error' do
115
115
  stub_droplet_stop_fail(droplet_id)
116
- load_options(stop_by_power: true)
116
+ load_options(stop_by_power: true, shutdown: true)
117
117
  droplet = cmd.api.droplet droplet_id
118
118
  expect { cmd.stop_droplet(droplet) }
119
119
  .not_to raise_error
@@ -124,7 +124,17 @@ RSpec.describe DoSnapshot::Command do
124
124
  it 'when stopped' do
125
125
  stub_droplet_inactive(droplet_id)
126
126
  stub_droplet_stop(droplet_id)
127
- load_options(stop_by_power: true)
127
+ load_options(stop_by_power: true, shutdown: true)
128
+ droplet = cmd.api.droplet droplet_id
129
+ expect { cmd.stop_droplet(droplet) }
130
+ .not_to raise_error
131
+ expect(cmd.stop_droplet(droplet))
132
+ .to be_truthy
133
+ end
134
+
135
+ it 'when nothing' do
136
+ stub_droplet(droplet_id)
137
+ load_options(stop_by_power: true, shutdown: false)
128
138
  droplet = cmd.api.droplet droplet_id
129
139
  expect { cmd.stop_droplet(droplet) }
130
140
  .not_to raise_error
@@ -154,6 +164,16 @@ RSpec.describe DoSnapshot::Command do
154
164
  expect(cmd.stop_droplet(droplet))
155
165
  .to be_truthy
156
166
  end
167
+
168
+ it 'when nothing' do
169
+ stub_droplet(droplet_id)
170
+ load_options(shutdown: false)
171
+ droplet = cmd.api.droplet droplet_id
172
+ expect { cmd.stop_droplet(droplet) }
173
+ .not_to raise_error
174
+ expect(cmd.stop_droplet(droplet))
175
+ .to be_truthy
176
+ end
157
177
  end
158
178
 
159
179
  describe '.create_snapshot' do
@@ -176,6 +196,18 @@ RSpec.describe DoSnapshot::Command do
176
196
  .not_to raise_error
177
197
  end
178
198
 
199
+ it 'when snapshot is created with no shutdown' do
200
+ stub_droplet(droplet_id)
201
+ stub_droplet_snapshot(droplet_id, snapshot_name)
202
+ load_options(shutdown: false)
203
+ droplet = cmd.api.droplet droplet_id
204
+ cmd.create_snapshot(droplet)
205
+ expect(DoSnapshot.logger.buffer)
206
+ .not_to include "Droplet id: #{droplet_id} must be Powered Off!"
207
+ expect { cmd.create_snapshot(droplet) }
208
+ .not_to raise_error
209
+ end
210
+
179
211
  it 'when droplet is running' do
180
212
  stub_droplet(droplet_id)
181
213
  load_options
@@ -191,16 +223,25 @@ RSpec.describe DoSnapshot::Command do
191
223
  describe '.fail_power_off' do
192
224
  it 'when success' do
193
225
  stub_droplet_inactive(droplet_id)
194
-
226
+ load_options(shutdown: true)
195
227
  expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
196
228
  .not_to raise_error
197
229
  expect(DoSnapshot.logger.buffer)
198
230
  .to include "Droplet id: #{droplet_id} is requested for Power On."
199
231
  end
200
232
 
201
- it 'with request error' do
233
+ it 'not rescue when shutdown is true' do
202
234
  stub_droplet_fail(droplet_id)
235
+ load_options(shutdown: false)
236
+ expect { cmd.fail_power_off(DoSnapshot::SnapshotCreateError.new(droplet_id)) }
237
+ .not_to raise_error
238
+ expect(DoSnapshot.logger.buffer)
239
+ .to include "Droplet id: #{droplet_id} is Failed to Snapshot."
240
+ end
203
241
 
242
+ it 'with request error' do
243
+ stub_droplet_fail(droplet_id)
244
+ load_options(shutdown: true)
204
245
  expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
205
246
  .to raise_error(DoSnapshot::DropletFindError)
206
247
  expect(DoSnapshot.logger.buffer)
@@ -212,7 +253,7 @@ RSpec.describe DoSnapshot::Command do
212
253
  it 'with start error' do
213
254
  stub_droplet_inactive(droplet_id)
214
255
  stub_droplet_start_done(droplet_id)
215
-
256
+ load_options(shutdown: true)
216
257
  expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
217
258
  .not_to raise_error
218
259
  expect(DoSnapshot.logger.buffer)
@@ -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 shutdown' do
113
+ attribute_eq 'shutdown', 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 no shutdown' do
122
+ attribute_eq 'shutdown', false
123
+
124
+ expect(last_command).to have_exit_status(0)
125
+ expect(all_stdout).not_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 stop by power' do
113
131
  attribute_eq 'stop_by_power', true
114
132
 
@@ -19,7 +19,7 @@ RSpec.shared_context 'environment' do
19
19
  let(:cli_keys) { Thor::CoreExt::HashWithIndifferentAccess.new(digital_ocean_access_token: access_token) }
20
20
  let(:cli_keys_other) { Thor::CoreExt::HashWithIndifferentAccess.new(digital_ocean_access_token: 'NOTTOK') }
21
21
  let(:snapshot_name) { "example.com_#{DateTime.now.strftime('%Y_%m_%d')}" }
22
- let(:default_options) { Hash[protocol: 2, only: %w( 100823 ), exclude: %w(), keep: 3, stop: false, trace: true, clean: true, delay: 0, timeout: 600] }
22
+ let(:default_options) { Hash[protocol: 2, only: %w( 100823 ), exclude: %w(), keep: 3, stop: false, trace: true, clean: true, delay: 0, shutdown: true, timeout: 600] }
23
23
  let(:default_options_cli) { default_options.reject { |key, _| %w( droplets threads ).include?(key.to_s) } }
24
24
  let(:no_exclude) { [] }
25
25
  let(:exclude) { %w( 100824 100825 ) }
@@ -31,6 +31,7 @@ RSpec.shared_context 'environment' do
31
31
  let(:no_quiet) { false }
32
32
  let(:clean) { true }
33
33
  let(:no_clean) { false }
34
+ let(:shutdown) { true }
34
35
  let(:timeout) { 600 }
35
36
  let(:delay) { 0 }
36
37
  let(:log_path) { "#{project_path}/log/test.log" }
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.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Merkulov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-09 00:00:00.000000000 Z
11
+ date: 2016-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: barge