do_snapshot 0.0.12 → 0.0.13

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: 1832957a7416c15f2755720be734b7153dc19856
4
- data.tar.gz: 4cd6ea976f4bbbe26051e10b538e4e213f7cd87c
3
+ metadata.gz: fd8a67c728fd77180645b3ea87ee37db50ab627e
4
+ data.tar.gz: e3196ed56ad208a890c3be2f55bb02cb7499a06f
5
5
  SHA512:
6
- metadata.gz: 2c988328d3c25992b45336a37e34ff535f5db6e4545ae9946c77b24dd9866517734bf27653e4e170451463ae94580053c88a968f2f9acda141b00ccbb66a0b12
7
- data.tar.gz: 10532b1d32445a9cd7c28d84119524cd6a8399103295639dcabfe308dd6eddb2aa2c2a1fb4c95e2eecd36a7d026574d33d4693e745a5a00b93d89662272fc471
6
+ metadata.gz: 1f91dd0dc2e68e03eb59a48e7e2077893d2d4574d6f2fc2900070adcaa1c9c580b9d001ece9283d34da67fdbe4ec93e0ed8894d0f74e446b774f3837ed4f1a44
7
+ data.tar.gz: 7a27ff1d46bc31ffd257ae77f0e474408172d4dc6dd755615215dedf280e842f88c1fe543b099ca522bf552a8ec070744d4d7ee661a712638e9d0211495aafbb
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- # DoSnapshot CLI
1
+ # DoSnapshot CLI
2
+ [Project Page at Digital Ocean](https://www.digitalocean.com/community/projects/dosnapshot), comment or vote for this project.
2
3
 
3
4
  [![Gem Version](https://badge.fury.io/rb/do_snapshot.svg)](http://badge.fury.io/rb/do_snapshot)
4
5
  [![Build Status](https://travis-ci.org/merqlove/do_snapshot.svg?branch=master)](https://travis-ci.org/merqlove/do_snapshot)
@@ -183,4 +184,4 @@ For working mailer you need to set e-mail settings via run options.
183
184
 
184
185
  Copyright (c) 2014 Alexander Merkulov
185
186
 
186
- MIT License
187
+ MIT License
@@ -87,13 +87,7 @@ module DoSnapshot
87
87
  snapshot = instance.snapshots[i]
88
88
  event = Digitalocean::Image.destroy(snapshot.id)
89
89
 
90
- if !event
91
- Log.error "Destroy of snapshot #{snapshot.name} for droplet id: #{instance.id} name: #{instance.name} is failed."
92
- elsif event && !event.status.include?('OK')
93
- Log.error event.message
94
- else
95
- Log.debug "Snapshot name: #{snapshot.name} delete requested."
96
- end
90
+ after_cleanup(instance.id, instance.name, snapshot, event)
97
91
  end
98
92
  end
99
93
 
@@ -136,5 +130,15 @@ module DoSnapshot
136
130
  Log.error 'Power On failed to request.'
137
131
  end
138
132
  end
133
+
134
+ def after_cleanup(droplet_id, droplet_name, snapshot, event)
135
+ if !event
136
+ Log.error "Destroy of snapshot #{snapshot.name} for droplet id: #{droplet_id} name: #{droplet_name} is failed."
137
+ elsif event && !event.status.include?('OK')
138
+ Log.error event.message
139
+ else
140
+ Log.debug "Snapshot name: #{snapshot.name} delete requested."
141
+ end
142
+ end
139
143
  end
140
144
  end
@@ -1,9 +1,9 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'thor'
3
3
  require 'do_snapshot'
4
- require 'do_snapshot/command'
5
- require 'do_snapshot/mail'
6
- require 'do_snapshot/log'
4
+ require_relative 'command'
5
+ require_relative 'mail'
6
+ require_relative 'log'
7
7
 
8
8
  module DoSnapshot
9
9
  # CLI is here
@@ -137,16 +137,13 @@ module DoSnapshot
137
137
  desc: 'DIGITAL_OCEAN_API_KEY. if you can\'t use environment.'
138
138
 
139
139
  def snap
140
- Command.snap options, %w( log mail smtp trace digital_ocean_client_id digital_ocean_api_key )
140
+ Command.load_options options, %w( log mail smtp trace digital_ocean_client_id digital_ocean_api_key )
141
+ Command.snap
141
142
  rescue => e
142
143
  Command.fail_power_off(e) if [SnapshotCreateError, DropletShutdownError].include?(e.class)
143
144
  Log.error e.message
144
145
  backtrace(e) if options.include? 'trace'
145
- if Mail.opts
146
- Mail.opts[:subject] = 'Digital Ocean: Error.'
147
- Mail.opts[:body] = 'Please check your droplets.'
148
- Mail.notify
149
- end
146
+ send_error
150
147
  end
151
148
 
152
149
  desc 'version, -V', 'Shows the version of the currently installed DoSnapshot gem'
@@ -160,6 +157,14 @@ module DoSnapshot
160
157
  Mail.smtp = options['smtp']
161
158
  end
162
159
 
160
+ def send_error
161
+ return unless Mail.opts
162
+
163
+ Mail.opts[:subject] = 'Digital Ocean: Error.'
164
+ Mail.opts[:body] = 'Please check your droplets.'
165
+ Mail.notify
166
+ end
167
+
163
168
  def set_logger
164
169
  Log.quiet = options['quiet']
165
170
  Log.verbose = options['trace']
@@ -1,18 +1,12 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'do_snapshot/api'
2
+ require_relative 'api'
3
3
 
4
4
  module DoSnapshot
5
5
  # Our commands live here :)
6
6
  #
7
7
  class Command # rubocop:disable ClassLength
8
8
  class << self
9
- def snap(options, skip)
10
- return unless options
11
-
12
- options.each_pair do |key, option|
13
- send("#{key}=", option) unless skip.include?(key)
14
- end
15
-
9
+ def snap
16
10
  Log.info 'Start performing operations'
17
11
  work_with_droplets
18
12
  Log.info 'All operations has been finished.'
@@ -20,6 +14,12 @@ module DoSnapshot
20
14
  Mail.notify if notify && !quiet
21
15
  end
22
16
 
17
+ def load_options(options = {}, skip = %w())
18
+ options.each_pair do |key, option|
19
+ send("#{key}=", option) unless skip.include?(key)
20
+ end if options
21
+ end
22
+
23
23
  def fail_power_off(e)
24
24
  return unless e && e.id
25
25
  api.start_droplet(e.id)
@@ -27,17 +27,52 @@ module DoSnapshot
27
27
  raise DropletFindError, e.message, e.backtrace
28
28
  end
29
29
 
30
- protected
30
+ def stop_droplet(droplet)
31
+ Log.debug 'Shutting down droplet.'
32
+ api.stop_droplet(droplet.id) unless droplet.status.include? 'off'
33
+ end
31
34
 
32
- attr_accessor :droplets, :exclude, :only
33
- attr_accessor :keep, :quiet, :stop, :clean, :timeout, :delay
35
+ # Trying to create a snapshot.
36
+ #
37
+ def create_snapshot(droplet) # rubocop:disable MethodLength,Metrics/AbcSize
38
+ Log.info "Start creating snapshot for droplet id: #{droplet.id} name: #{droplet.name}."
34
39
 
35
- attr_writer :notify, :threads, :api
40
+ today = DateTime.now
41
+ name = "#{droplet.name}_#{today.strftime('%Y_%m_%d')}"
42
+ # noinspection RubyResolve
43
+ snapshot_size = droplet.snapshots.size
44
+
45
+ Log.debug 'Wait until snapshot will be created.'
46
+
47
+ api.create_snapshot droplet.id, name
48
+
49
+ snapshot_size += 1
50
+
51
+ Log.info "Snapshot name: #{name} created successfully."
52
+ Log.info "Droplet id: #{droplet.id} name: #{droplet.name} snapshots: #{snapshot_size}."
53
+
54
+ # Cleanup snapshots.
55
+ cleanup_snapshots droplet, snapshot_size if clean
56
+ rescue => e
57
+ case e.class.to_s
58
+ when 'DoSnapshot::SnapshotCleanupError'
59
+ raise e.class, e.message, e.backtrace
60
+ else
61
+ raise SnapshotCreateError.new(droplet.id), e.message, e.backtrace
62
+ end
63
+ end
36
64
 
37
65
  def api
38
66
  @api ||= API.new(delay: delay, timeout: timeout)
39
67
  end
40
68
 
69
+ protected
70
+
71
+ attr_accessor :droplets, :exclude, :only
72
+ attr_accessor :keep, :quiet, :stop, :clean, :timeout, :delay
73
+
74
+ attr_writer :notify, :threads, :api
75
+
41
76
  def notify
42
77
  @notify ||= false
43
78
  end
@@ -69,12 +104,9 @@ module DoSnapshot
69
104
  droplets.each do |droplet|
70
105
  id = droplet.id.to_s
71
106
  next if exclude.include? id
72
- next if !only.empty? && !only.include?(id)
73
-
74
- Log.debug "Droplet id: #{id} name: #{droplet.name} "
75
- instance = api.droplet id
107
+ next unless only.empty? || only.include?(id)
76
108
 
77
- prepare_instance instance.droplet
109
+ prepare_droplet id, droplet.name
78
110
  end
79
111
  end
80
112
 
@@ -86,81 +118,50 @@ module DoSnapshot
86
118
 
87
119
  # Run threads
88
120
  #
89
- def thread_runner(instance)
121
+ def thread_runner(droplet)
90
122
  threads << Thread.new do
91
- Log.debug 'Shutting down droplet.'
92
- stop_droplet instance
93
- create_snapshot instance
123
+ stop_droplet droplet
124
+ create_snapshot droplet
94
125
  end
95
126
  end
96
127
 
97
- # Preparing instance to take snapshot.
98
- # Instance must be powered off first!
128
+ # Preparing droplet to take a snapshot.
129
+ # Droplet instance must be powered off first!
99
130
  #
100
- def prepare_instance(instance)
101
- return unless instance
102
- Log.info "Preparing droplet id: #{instance.id} name: #{instance.name} to take snapshot."
103
- return if too_much_snapshots(instance)
104
- thread_runner(instance)
105
- end
131
+ def prepare_droplet(id, name)
132
+ Log.debug "Droplet id: #{id} name: #{name} "
133
+ instance = api.droplet id
134
+ droplet = instance.droplet
106
135
 
107
- def too_much_snapshots(instance)
108
- # noinspection RubyResolve
109
- if instance.snapshots.size >= keep
110
- warning_size(instance.id, instance.name, keep)
111
- return true if stop
112
- end
113
- false
114
- end
115
-
116
- def stop_droplet(instance)
117
- api.stop_droplet(instance.id) unless instance.status.include? 'off'
136
+ return unless droplet
137
+ Log.info "Preparing droplet id: #{droplet.id} name: #{droplet.name} to take snapshot."
138
+ return if too_much_snapshots(droplet)
139
+ thread_runner(droplet)
118
140
  end
119
141
 
120
- # Trying to create a snapshot.
121
- #
122
- def create_snapshot(instance) # rubocop:disable MethodLength
123
- Log.info "Start creating snapshot for droplet id: #{instance.id} name: #{instance.name}."
124
-
125
- today = DateTime.now
126
- name = "#{instance.name}_#{today.strftime('%Y_%m_%d')}"
142
+ def too_much_snapshots(instance)
127
143
  # noinspection RubyResolve
128
- snapshot_size = instance.snapshots.size
129
-
130
- Log.debug 'Wait until snapshot will be created.'
131
-
132
- api.create_snapshot instance.id, name
133
-
134
- snapshot_size += 1
135
-
136
- Log.info "Snapshot name: #{name} created successfully."
137
- Log.info "Droplet id: #{instance.id} name: #{instance.name} snapshots: #{snapshot_size}."
138
-
139
- # Cleanup snapshots.
140
- cleanup_snapshots instance, snapshot_size if clean
141
- rescue => e
142
- case e.class.to_s
143
- when 'DoSnapshot::SnapshotCleanupError'
144
- raise e.class, e.message, e.backtrace
145
- else
146
- raise SnapshotCreateError.new(instance.id), e.message, e.backtrace
147
- end
144
+ return false unless instance.snapshots.size >= keep
145
+ warning_size(instance.id, instance.name, keep)
146
+ stop ? true : false
148
147
  end
149
148
 
150
149
  # Cleanup our snapshots.
151
150
  #
152
- def cleanup_snapshots(instance, size)
151
+ def cleanup_snapshots(droplet, size) # rubocop:disable Metrics/AbcSize
153
152
  return unless size > keep
154
153
 
155
- warning_size(instance.id, instance.name, size)
154
+ warning_size(droplet.id, droplet.name, size)
156
155
 
157
- Log.debug "Cleaning up snapshots for droplet id: #{instance.id} name: #{instance.name}."
156
+ Log.debug "Cleaning up snapshots for droplet id: #{droplet.id} name: #{droplet.name}."
158
157
 
159
- api.cleanup_snapshots(instance, size - keep - 1)
158
+ api.cleanup_snapshots(droplet, size - keep - 1)
160
159
  rescue => e
161
160
  raise SnapshotCleanupError, e.message, e.backtrace
162
161
  end
163
162
 
163
+ # Helpers
164
+ #
164
165
  def warning_size(id, name, keep)
165
166
  message = "For droplet with id: #{id} and name: #{name} the maximum number #{keep} of snapshots is reached."
166
167
  Log.warning message
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'date'
3
3
  require 'pony'
4
- require 'do_snapshot/core_ext/hash'
4
+ require_relative 'core_ext/hash'
5
5
 
6
6
  module DoSnapshot
7
7
  # Shared mailer.
@@ -2,5 +2,5 @@
2
2
  # Current version
3
3
  #
4
4
  module DoSnapshot
5
- VERSION = '0.0.12'
5
+ VERSION = '0.0.13'
6
6
  end
data/lib/do_snapshot.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'do_snapshot/version'
2
+ require_relative 'do_snapshot/version'
3
3
 
4
4
  # Used primary for creating snapshot's as backups for DigitalOcean
5
5
  #
@@ -207,7 +207,7 @@ describe DoSnapshot::API do
207
207
  expect(a_request(:get, image_destroy_url))
208
208
  .to have_been_made
209
209
  expect(a_request(:get, image_destroy2_url))
210
- .to have_been_made
210
+ .to have_been_made
211
211
  end
212
212
  end
213
213
  end
@@ -9,7 +9,6 @@ describe DoSnapshot::CLI do
9
9
  subject(:api) { DoSnapshot::API }
10
10
 
11
11
  describe '.snap' do
12
-
13
12
  it 'with exclude' do
14
13
  excluded_droplets = %w( 100824 )
15
14
  stub_all_api(%w(100825 100823))
@@ -65,7 +65,47 @@ describe DoSnapshot::Command do
65
65
  end
66
66
  end
67
67
 
68
- describe '.fail_power_off' do
68
+ describe '.stop_droplet' do
69
+ it 'when raised with error' do
70
+ stub_droplet_stop_fail(droplet_id)
71
+ load_options
72
+ instance = cmd.api.droplet droplet_id
73
+ droplet = instance.droplet
74
+ expect { cmd.stop_droplet(droplet) }
75
+ .to raise_error(DoSnapshot::DropletShutdownError)
76
+ end
77
+
78
+ it 'when stopped' do
79
+ stub_droplet_stop(droplet_id)
80
+ load_options
81
+ instance = cmd.api.droplet droplet_id
82
+ droplet = instance.droplet
83
+ expect { cmd.stop_droplet(droplet) }
84
+ .not_to raise_error
85
+ end
86
+ end
87
+
88
+ describe '.create_snapshot' do
89
+ it 'when raised with error' do
90
+ stub_droplet_snapshot_fail(droplet_id, snapshot_name)
91
+ load_options
92
+ instance = cmd.api.droplet droplet_id
93
+ droplet = instance.droplet
94
+ expect { cmd.create_snapshot(droplet) }
95
+ .to raise_error(DoSnapshot::SnapshotCreateError)
96
+ end
97
+
98
+ it 'when snapshot is created' do
99
+ stub_droplet_snapshot(droplet_id, snapshot_name)
100
+ load_options
101
+ instance = cmd.api.droplet droplet_id
102
+ droplet = instance.droplet
103
+ expect { cmd.create_snapshot(droplet) }
104
+ .not_to raise_error
105
+ end
106
+ end
107
+
108
+ describe '.fail_power_off' do
69
109
  it 'when success' do
70
110
  stub_droplet_inactive(droplet_id)
71
111
 
@@ -83,7 +123,7 @@ describe DoSnapshot::Command do
83
123
  expect(log.buffer)
84
124
  .to include 'Droplet id: 100823 is Failed to Power Off.'
85
125
  expect(log.buffer)
86
- .to include 'Droplet Not Found'
126
+ .to include 'Droplet Not Found'
87
127
  end
88
128
 
89
129
  it 'with start error' do
@@ -105,9 +145,14 @@ describe DoSnapshot::Command do
105
145
  log.quiet = true
106
146
  end
107
147
 
108
- def snap_runner(options = nil)
148
+ def load_options(options = nil)
109
149
  options ||= default_options
110
150
  cmd.send('api=', nil)
111
- cmd.snap(options, [:log, :mail, :smtp, :trace, :digital_ocean_client_id, :digital_ocean_api_key])
151
+ cmd.load_options(options, [:log, :mail, :smtp, :trace, :digital_ocean_client_id, :digital_ocean_api_key])
152
+ end
153
+
154
+ def snap_runner
155
+ load_options
156
+ cmd.snap
112
157
  end
113
158
  end
@@ -30,7 +30,6 @@ describe DoSnapshot do
30
30
  subject(:error) { described_class }
31
31
 
32
32
  it 'should be' do
33
-
34
33
  expect { error.new }
35
34
  .not_to raise_error
36
35
  end
@@ -2,7 +2,6 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  shared_context 'api_helpers' do
5
-
6
5
  # List of droplets
7
6
  #
8
7
  def stub_droplets
data/spec/spec_helper.rb CHANGED
@@ -8,10 +8,9 @@ end
8
8
  require 'do_snapshot/cli'
9
9
  require 'webmock/rspec'
10
10
  require 'digitalocean'
11
- require 'shared/api_helpers'
12
- require 'shared/uri_helpers'
13
- require 'shared/environment'
14
- require 'shared/uri_helpers'
11
+ require_relative 'shared/api_helpers'
12
+ require_relative 'shared/uri_helpers'
13
+ require_relative 'shared/environment'
15
14
  require 'do_snapshot/core_ext/hash'
16
15
 
17
16
  WebMock.disable_net_connect!(allow_localhost: true)
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.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Merkulov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-24 00:00:00.000000000 Z
11
+ date: 2015-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: digitalocean
@@ -263,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
263
  version: '0'
264
264
  requirements: []
265
265
  rubyforge_project:
266
- rubygems_version: 2.2.2
266
+ rubygems_version: 2.4.5
267
267
  signing_key:
268
268
  specification_version: 4
269
269
  summary: A command-line snapshot maker for your DigitalOcean droplets. Fully Automated.