do_snapshot 0.0.7 → 0.0.8
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 +5 -13
- data/README.md +51 -21
- data/lib/do_snapshot/api.rb +3 -3
- data/lib/do_snapshot/cli.rb +2 -2
- data/lib/do_snapshot/command.rb +12 -4
- data/lib/do_snapshot/distribution.rb +13 -0
- data/lib/do_snapshot/log.rb +1 -1
- data/lib/do_snapshot/version.rb +1 -1
- data/spec/do_snapshot/api_spec.rb +6 -0
- data/spec/do_snapshot/cli_spec.rb +18 -1
- data/spec/do_snapshot/command_spec.rb +17 -18
- data/spec/do_snapshots_spec.rb +7 -1
- data/spec/shared/environment.rb +12 -26
- data/spec/spec_helper.rb +2 -0
- metadata +76 -57
- data/.gitignore +0 -28
- data/.rubocop.yml +0 -14
- data/.ruby-version +0 -1
- data/.travis.yml +0 -10
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -7
- data/do_snapshot.gemspec +0 -33
- data/log/.keep +0 -0
- data/tmp/.keep +0 -0
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YmVmZGFjMzIwNjZmZDY1NjA3M2QzMDI0OGFmZDJkYTk3NzM0NmE2ZA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 95ce0ffdfe696ae7a5cce1b334dd49a5d250f1bc
|
4
|
+
data.tar.gz: cbebe31ada54228fcd5b7f0cb642b7e37cccf0bd
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
Mzc0MTUxZWUzODFkYjBkMGIyNGIwOWU3MGY2Y2EzNzJmNDgwNzQ1M2E2NWYx
|
11
|
-
MjBkYWY2MTIxNTNmMWZmN2U1MDMzNjBkNGIxODQwOWNiZGI5MmQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTY2YmI2NWQ1ZWYxZWYwMGNjMjYzMzk1NjU5M2Q2YjM0NGNjNjU4ZGVjOTc2
|
14
|
-
YWZjZWEzMDYzZDE0Yjk4Njg3ZWEyNDQwZDVmODEzN2UwNjk1OTYyZmI4NGJj
|
15
|
-
MGQ4NGQzMGZhNjJhYTZiMzcyOGZhNjNlNWZmNTJjNjNiNDQwMTg=
|
6
|
+
metadata.gz: f4b1a3c9f608d28cf411cbed0dad3929eaabb65f43f6030e071d6e952f3323ab6d4edb5dac99e44fdccae8a3cdacc71958a7f831f8c65a9b1e1eecd1d1445347
|
7
|
+
data.tar.gz: cec0fd4b44bd7dad64e9f038947bdbd3f14641169f5152ef07fef1ead965f1e1d082f6f81eea6c69900bd32ecb9e04028f9b76bb802d48750100f83bab561a7d
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# DoSnapshot
|
1
|
+
# DoSnapshot CLI
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/do_snapshot)
|
4
4
|
[](https://travis-ci.org/merqlove/do_snapshot)
|
@@ -7,45 +7,67 @@
|
|
7
7
|
[](http://inch-ci.org/github/merqlove/do_snapshot)
|
8
8
|
[](https://codeclimate.com/github/merqlove/do_snapshot)
|
9
9
|
|
10
|
-
|
10
|
+
Use this tool to backup DigitalOcean droplet's via snapshot method, on the fly!
|
11
11
|
|
12
12
|
Here some features:
|
13
13
|
|
14
14
|
- Multiple threads out of the box. No matter how much droplet's you have.
|
15
|
-
- Auto-
|
16
|
-
-
|
15
|
+
- Snapshots Auto-Cleanup.
|
16
|
+
- Auto-Boot Droplet back if Snapshot Event is failed or bad connection exception.
|
17
|
+
- Binary special for cron and command-line. Homebrew, Standalone installers.
|
17
18
|
- Mail notifications when fail or maximum of snapshots is reached for one or multiple droplets.
|
18
19
|
- Custom mail settings (You can set [Pony](https://github.com/benprew/pony) mail settings).
|
19
20
|
- Stop mode (when you don't want to create new snapshots when maximum is reached).
|
20
|
-
- Timeout for
|
21
|
+
- Timeout option for long requests or uncaught loops. By default it 600 seconds, but you can change it by hand.
|
21
22
|
- Logging into selected directory.
|
22
23
|
- Verbose mode for research.
|
23
24
|
- Quiet mode for silence.
|
24
25
|
|
25
|
-
|
26
|
+
## Compatibility
|
26
27
|
|
27
|
-
|
28
|
-
- `Thor` for CLI.
|
29
|
-
- `Pony` for mail notifications.
|
28
|
+
Ruby versions: 1.9.3 and higher. JRuby in 1.9 mode is also supported.
|
30
29
|
|
31
|
-
|
30
|
+

|
31
|
+
|
32
|
+
### You can ask me, "Why you made this tool?"
|
32
33
|
|
33
|
-
|
34
|
+
- First. I needed stable tool, which can provide for me automatic Snapshot feature for all of my Droplets via Cron planner.
|
35
|
+
- I don't want to think how much snapshots for each droplet i have.
|
36
|
+
- I don't wont to sleep when my droplets Offline!!! And i wanted tool which can Staryt
|
37
|
+
- Also i want to understand what's going on if there some error. Mail is my choice. But logs also good.
|
38
|
+
- And ... sure ;) We want to do it fast as rocket! :)
|
39
|
+
- more more more...
|
40
|
+
- So this tool can save a lot of time for people.
|
34
41
|
|
35
42
|
## Installation
|
36
43
|
|
37
|
-
|
44
|
+
Install it yourself as:
|
38
45
|
|
39
|
-
gem
|
46
|
+
$ gem install do_snapshot
|
47
|
+
|
48
|
+
For **OSX** users ([Homebrew Tap](http://github.com/merqlove/do_snapshot/tap)):
|
40
49
|
|
41
|
-
|
50
|
+
$ brew tap merqlove/do_snapshot/tap && brew install do_snapshot
|
51
|
+
|
52
|
+
$ do_snapshot -V
|
53
|
+
|
54
|
+
Standalone pack for **Unix/Linux** users: [Download](https://assets.merqlove.ru.s3.amazonaws.com/do_snapshot/dosnapshot.tgz)
|
55
|
+
|
56
|
+
$ wget https://assets.merqlove.ru.s3.amazonaws.com/do_snapshot/do_snapshot.tgz # if not done.
|
57
|
+
|
58
|
+
# Example Install into /usr/local
|
59
|
+
|
60
|
+
$ tar -xzf do_snapshot.tgz /usr/local/ && ln -s /usr/local/do_snapshot/bin/do_snapshot /usr/local/bin/do_snapshot
|
61
|
+
$ do_snapshot help
|
42
62
|
|
43
|
-
|
63
|
+
Or add this line to Gemfile:
|
44
64
|
|
45
|
-
|
65
|
+
gem 'do_snapshot'
|
46
66
|
|
47
|
-
|
67
|
+
And then execute:
|
48
68
|
|
69
|
+
$ bundle
|
70
|
+
|
49
71
|
## Usage
|
50
72
|
|
51
73
|
First you may need to set DigitalOcean API keys:
|
@@ -57,7 +79,7 @@ If you want to set keys without environment, than set it via options when you ru
|
|
57
79
|
|
58
80
|
$ do_snapshot --digital-ocean-client-id YOURLONGAPICLIENTID --digital-ocean-api-key YOURLONGAPIKEY
|
59
81
|
|
60
|
-
|
82
|
+
### How-To
|
61
83
|
|
62
84
|
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.
|
63
85
|
|
@@ -75,16 +97,18 @@ Keep latest 5 snapshots, send mail notification instead of creating new one:
|
|
75
97
|
|
76
98
|
$ do_snapshot --keep 10 --stop --mail to:yourmail@example.com
|
77
99
|
|
100
|
+

|
101
|
+
|
78
102
|
E-mail notifications disabled out of the box.
|
79
103
|
For working mailer you need to set e-mail settings via run options.
|
80
104
|
|
81
105
|
--mail to:mail@somehost.com from:from@host.com --smtp address:smtp.gmail.com port:25 user_name:someuser password:somepassword
|
82
106
|
|
83
|
-
|
107
|
+
### Cron example
|
84
108
|
|
85
109
|
0 4 * * 7 /.../bin/do_snapshot -k 5 -m to:TO from:FROM -t address:HOST user_name:LOGIN password:PASSWORD port:2525 -q -c
|
86
110
|
|
87
|
-
|
111
|
+
### Real world example
|
88
112
|
|
89
113
|
$ bin/do_snapshot --only 123456 -k 3 -c -m to:TO from:FROM -t address:HOST user_name:LOGIN password:PASSWORD port:2525 -v
|
90
114
|
|
@@ -119,7 +143,7 @@ For working mailer you need to set e-mail settings via run options.
|
|
119
143
|
-d, [--delay=5] # Delay between snapshot operation status requests.
|
120
144
|
# Default: 10
|
121
145
|
[--timeout=250] # Timeout in sec's for events like Power Off or Create Snapshot.
|
122
|
-
# Default:
|
146
|
+
# Default: 600
|
123
147
|
-m, [--mail=to:yourmail@example.com] # Receive mail if fail or maximum is reached.
|
124
148
|
-t, [--smtp=user_name:yourmail@example.com password:password] # SMTP options.
|
125
149
|
-l, [--log=/Users/someone/.do_snapshot/main.log] # Log file path. By default logging is disabled.
|
@@ -135,6 +159,12 @@ For working mailer you need to set e-mail settings via run options.
|
|
135
159
|
|
136
160
|
You can optionally specify parameters to select or exclude some droplets.
|
137
161
|
|
162
|
+
## Dependencies:
|
163
|
+
|
164
|
+
- [Thor](https://github.com/erikhuda/thor) for CLI.
|
165
|
+
- [Digitalocean](https://github.com/scottmotte/digitalocean) for API requests.
|
166
|
+
- [Pony](https://github.com/benprew/pony) for mail notifications.
|
167
|
+
|
138
168
|
## Contributing
|
139
169
|
|
140
170
|
1. Fork it ( https://github.com/merqlove/do_snapshot/fork )
|
data/lib/do_snapshot/api.rb
CHANGED
@@ -109,15 +109,15 @@ module DoSnapshot
|
|
109
109
|
|
110
110
|
# Waiting for event exit
|
111
111
|
def wait_event(id)
|
112
|
-
time = Time.now
|
113
|
-
sleep
|
112
|
+
time = Time.now
|
113
|
+
sleep(delay) until get_event_status(id, time)
|
114
114
|
end
|
115
115
|
|
116
116
|
# Looking for event status.
|
117
117
|
# Before snapshot we to know that machine has powered off.
|
118
118
|
#
|
119
119
|
def get_event_status(id, time)
|
120
|
-
return true if (Time.now.to_f - time) > timeout
|
120
|
+
return true if (Time.now.to_f - time.to_f) > timeout
|
121
121
|
event = Digitalocean::Event.find(id)
|
122
122
|
fail event.message unless event.status.include?('OK')
|
123
123
|
# noinspection RubyResolve,RubyResolve
|
data/lib/do_snapshot/cli.rb
CHANGED
@@ -92,7 +92,7 @@ module DoSnapshot
|
|
92
92
|
desc: 'Delay between snapshot operation status requests.'
|
93
93
|
method_option :timeout,
|
94
94
|
type: :numeric,
|
95
|
-
default:
|
95
|
+
default: 600,
|
96
96
|
banner: '250',
|
97
97
|
desc: 'Timeout in sec\'s for events like Power Off or Create Snapshot.'
|
98
98
|
method_option :mail,
|
@@ -137,7 +137,7 @@ 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 trace digital_ocean_client_id digital_ocean_api_key )
|
140
|
+
Command.snap options, %w( log mail smtp trace digital_ocean_client_id digital_ocean_api_key )
|
141
141
|
rescue => e
|
142
142
|
Command.fail_power_off(e) if [SnapshotCreateError, DropletShutdownError].include?(e.class)
|
143
143
|
Log.error e.message
|
data/lib/do_snapshot/command.rb
CHANGED
@@ -11,7 +11,7 @@ module DoSnapshot
|
|
11
11
|
return unless options
|
12
12
|
|
13
13
|
options.each_pair do |key, option|
|
14
|
-
send("#{key}=", option) unless skip.include?
|
14
|
+
send("#{key}=", option) unless skip.include?(key)
|
15
15
|
end
|
16
16
|
|
17
17
|
Log.info 'Start performing operations'
|
@@ -30,10 +30,10 @@ module DoSnapshot
|
|
30
30
|
|
31
31
|
protected
|
32
32
|
|
33
|
-
attr_accessor :droplets, :
|
34
|
-
attr_accessor :
|
33
|
+
attr_accessor :droplets, :exclude, :only
|
34
|
+
attr_accessor :keep, :quiet, :stop, :clean
|
35
35
|
|
36
|
-
attr_writer :notify, :threads, :api
|
36
|
+
attr_writer :notify, :delay, :timeout, :threads, :api
|
37
37
|
|
38
38
|
def api
|
39
39
|
@api ||= API.new(delay: delay, timeout: timeout)
|
@@ -47,6 +47,14 @@ module DoSnapshot
|
|
47
47
|
@threads ||= []
|
48
48
|
end
|
49
49
|
|
50
|
+
def timeout
|
51
|
+
@timeout ||= 600
|
52
|
+
end
|
53
|
+
|
54
|
+
def delay
|
55
|
+
@delay ||= 10
|
56
|
+
end
|
57
|
+
|
50
58
|
# Working with list of droplets.
|
51
59
|
#
|
52
60
|
def work_with_droplets
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module DoSnapshot
|
3
|
+
# Distributive files
|
4
|
+
# Used part of Heroku script https://github.com/heroku/heroku
|
5
|
+
#
|
6
|
+
module Distribution
|
7
|
+
def self.files
|
8
|
+
Dir[File.expand_path('../../../{bin,lib}/**/*', __FILE__)].select do |file|
|
9
|
+
File.file?(file)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/do_snapshot/log.rb
CHANGED
data/lib/do_snapshot/version.rb
CHANGED
@@ -210,9 +210,15 @@ describe DoSnapshot::API do
|
|
210
210
|
.to have_been_made
|
211
211
|
end
|
212
212
|
end
|
213
|
+
|
214
|
+
after(:all) do
|
215
|
+
WebMock.reset!
|
216
|
+
end
|
213
217
|
end
|
214
218
|
|
215
219
|
before(:each) do
|
216
220
|
log.buffer = %w()
|
221
|
+
log.verbose = false
|
222
|
+
log.quiet = true
|
217
223
|
end
|
218
224
|
end
|
@@ -167,7 +167,24 @@ describe DoSnapshot::CLI do
|
|
167
167
|
command.send('api=', api.new(options))
|
168
168
|
end
|
169
169
|
|
170
|
+
before(:each) do
|
171
|
+
$stdout.sync = true
|
172
|
+
$stderr.sync = true
|
173
|
+
|
174
|
+
@cli = cli.new
|
175
|
+
|
176
|
+
# Keep track of the old stderr / out
|
177
|
+
@orig_stderr = $stderr
|
178
|
+
@orig_stdout = $stdout
|
179
|
+
|
180
|
+
# Make them strings so we can manipulate and compare.
|
181
|
+
$stderr = StringIO.new
|
182
|
+
$stdout = StringIO.new
|
183
|
+
end
|
184
|
+
|
170
185
|
after(:each) do
|
171
|
-
#
|
186
|
+
# Reassign the stderr / out so rspec can have it back.
|
187
|
+
$stderr = @orig_stderr
|
188
|
+
$stdout = @orig_stdout
|
172
189
|
end
|
173
190
|
end
|
@@ -5,11 +5,12 @@ describe DoSnapshot::Command do
|
|
5
5
|
include_context 'spec'
|
6
6
|
include_context 'uri_helpers'
|
7
7
|
|
8
|
+
subject(:cmd) { DoSnapshot::Command }
|
8
9
|
subject(:log) { DoSnapshot::Log }
|
9
10
|
|
10
11
|
describe '.snap' do
|
11
12
|
context 'when success' do
|
12
|
-
it 'sends
|
13
|
+
it 'sends message' do
|
13
14
|
expect { snap_runner }
|
14
15
|
.not_to raise_error
|
15
16
|
expect(log.buffer)
|
@@ -18,7 +19,7 @@ describe DoSnapshot::Command do
|
|
18
19
|
end
|
19
20
|
|
20
21
|
context 'when snapshot not cleanup' do
|
21
|
-
it 'sends
|
22
|
+
it 'sends message' do
|
22
23
|
stub_image_destroy_fail(image_id)
|
23
24
|
stub_image_destroy_fail(image_id2)
|
24
25
|
|
@@ -37,7 +38,7 @@ describe DoSnapshot::Command do
|
|
37
38
|
end
|
38
39
|
|
39
40
|
context 'when failed to list droplets' do
|
40
|
-
it 'raised with
|
41
|
+
it 'raised with error' do
|
41
42
|
stub_droplets_fail
|
42
43
|
|
43
44
|
expect { snap_runner }
|
@@ -46,8 +47,9 @@ describe DoSnapshot::Command do
|
|
46
47
|
end
|
47
48
|
|
48
49
|
# TODO: MUST HAVE! Now when this two works others can fail...
|
50
|
+
# I think it's threading problem with RSpec
|
49
51
|
# context 'when droplet failed for shutdown' do
|
50
|
-
# it 'raised with
|
52
|
+
# it 'raised with error' do
|
51
53
|
# fail = stub_droplet_stop_fail(droplet_id)
|
52
54
|
#
|
53
55
|
# expect { snap_runner }
|
@@ -56,15 +58,16 @@ describe DoSnapshot::Command do
|
|
56
58
|
# remove_request_stub(fail)
|
57
59
|
# end
|
58
60
|
# end
|
59
|
-
|
61
|
+
|
60
62
|
# context 'when no snapshot created' do
|
61
|
-
# it 'raised with
|
62
|
-
# no_snapshot =
|
63
|
+
# it 'raised with error' do
|
64
|
+
# # no_snapshot =
|
65
|
+
# stub_droplet_snapshot_fail(droplet_id, snapshot_name)
|
63
66
|
#
|
64
67
|
# expect { snap_runner }
|
65
68
|
# .to raise_error(DoSnapshot::SnapshotCreateError)
|
66
69
|
#
|
67
|
-
# remove_request_stub(no_snapshot)
|
70
|
+
# # remove_request_stub(no_snapshot)
|
68
71
|
# end
|
69
72
|
# end
|
70
73
|
end
|
@@ -73,7 +76,7 @@ describe DoSnapshot::Command do
|
|
73
76
|
it 'when success' do
|
74
77
|
stub_droplet_inactive(droplet_id)
|
75
78
|
|
76
|
-
expect {
|
79
|
+
expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
77
80
|
.not_to raise_error
|
78
81
|
expect(log.buffer)
|
79
82
|
.to include 'Power On has been requested.'
|
@@ -82,7 +85,7 @@ describe DoSnapshot::Command do
|
|
82
85
|
it 'with request error' do
|
83
86
|
stub_droplet_fail(droplet_id)
|
84
87
|
|
85
|
-
expect {
|
88
|
+
expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
86
89
|
.to raise_error
|
87
90
|
expect(log.buffer)
|
88
91
|
.to include 'Droplet id: 100823 is Failed to Power Off.'
|
@@ -95,27 +98,23 @@ describe DoSnapshot::Command do
|
|
95
98
|
stub_droplet_start_fail(droplet_id)
|
96
99
|
stub_event_fail(event_id)
|
97
100
|
|
98
|
-
expect {
|
101
|
+
expect { cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
99
102
|
.not_to raise_error
|
100
103
|
expect(log.buffer)
|
101
104
|
.to include 'Power On failed to request.'
|
102
105
|
end
|
103
106
|
end
|
104
107
|
|
105
|
-
after(:each) do
|
106
|
-
# WebMock.reset!
|
107
|
-
stub_cleanup
|
108
|
-
end
|
109
|
-
|
110
108
|
before(:each) do
|
111
|
-
@cmd = DoSnapshot::Command
|
109
|
+
# @cmd = DoSnapshot::Command
|
112
110
|
stub_all_api(nil, true)
|
113
111
|
log.buffer = %w()
|
112
|
+
log.verbose = false
|
114
113
|
log.quiet = true
|
115
114
|
end
|
116
115
|
|
117
116
|
def snap_runner(options = nil)
|
118
117
|
options ||= default_options
|
119
|
-
|
118
|
+
cmd.snap(options, [:log, :mail, :smtp, :trace, :digital_ocean_client_id, :digital_ocean_api_key])
|
120
119
|
end
|
121
120
|
end
|
data/spec/do_snapshots_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
describe DoSnapshot do
|
5
5
|
include_context 'spec'
|
6
6
|
|
7
|
-
subject(:log)
|
7
|
+
subject(:log) { DoSnapshot::Log }
|
8
8
|
|
9
9
|
describe DoSnapshot::DropletFindError do
|
10
10
|
subject(:error) { described_class }
|
@@ -55,4 +55,10 @@ describe DoSnapshot do
|
|
55
55
|
.to include "Droplet id: #{droplet_id} is Failed to Snapshot."
|
56
56
|
end
|
57
57
|
end
|
58
|
+
|
59
|
+
before(:each) do
|
60
|
+
log.buffer = %w()
|
61
|
+
log.verbose = false
|
62
|
+
log.quiet = true
|
63
|
+
end
|
58
64
|
end
|
data/spec/shared/environment.rb
CHANGED
@@ -12,7 +12,7 @@ shared_context 'spec' do
|
|
12
12
|
let(:image_id2) { '5019903' }
|
13
13
|
let(:cli_keys) { Thor::CoreExt::HashWithIndifferentAccess.new(digital_ocean_client_id: 'NOTFOO', digital_ocean_client_bar: 'NOTBAR') }
|
14
14
|
let(:snapshot_name) { "foo_#{DateTime.now.strftime('%Y_%m_%d')}" }
|
15
|
-
let(:default_options) { Hash[only: %w( 100823 ), exclude: %w(), keep: 3, trace: true, clean: true, delay: 0, timeout:
|
15
|
+
let(:default_options) { Hash[only: %w( 100823 ), exclude: %w(), keep: 3, trace: true, clean: true, delay: 0, timeout: 600, droplets: nil, threads: []] }
|
16
16
|
let(:no_exclude) { [] }
|
17
17
|
let(:exclude) { %w( 100824 100825 ) }
|
18
18
|
let(:no_only) { [] }
|
@@ -23,7 +23,7 @@ shared_context 'spec' do
|
|
23
23
|
let(:no_quiet) { false }
|
24
24
|
let(:clean) { true }
|
25
25
|
let(:no_clean) { false }
|
26
|
-
let(:timeout) {
|
26
|
+
let(:timeout) { 600 }
|
27
27
|
let(:delay) { 0 }
|
28
28
|
let(:mail_options) { Thor::CoreExt::HashWithIndifferentAccess.new(to: 'mail@somehost.com', from: 'from@host.com') }
|
29
29
|
let(:smtp_options) { Thor::CoreExt::HashWithIndifferentAccess.new(address: 'smtp.gmail.com', port: '25', user_name: 'someuser', password: 'somepassword') }
|
@@ -41,30 +41,6 @@ shared_context 'spec' do
|
|
41
41
|
let(:snapshot_uri) { "#{droplets_api_base}/[id]/snapshot/?name=[name]&#{keys_uri}" }
|
42
42
|
let(:event_find_uri) { "#{events_api_base}/[id]/?#{keys_uri}" }
|
43
43
|
|
44
|
-
before(:each) do
|
45
|
-
$stdout.sync = true
|
46
|
-
$stderr.sync = true
|
47
|
-
|
48
|
-
ENV['DIGITAL_OCEAN_API_KEY'] = api_key
|
49
|
-
ENV['DIGITAL_OCEAN_CLIENT_ID'] = client_key
|
50
|
-
|
51
|
-
@cli = DoSnapshot::CLI.new
|
52
|
-
|
53
|
-
# Keep track of the old stderr / out
|
54
|
-
@orig_stderr = $stderr
|
55
|
-
@orig_stdout = $stdout
|
56
|
-
|
57
|
-
# Make them strings so we can manipulate and compare.
|
58
|
-
$stderr = StringIO.new
|
59
|
-
$stdout = StringIO.new
|
60
|
-
end
|
61
|
-
|
62
|
-
after(:each) do
|
63
|
-
# Reassign the stderr / out so rspec can have it back.
|
64
|
-
$stderr = @orig_stderr
|
65
|
-
$stdout = @orig_stdout
|
66
|
-
end
|
67
|
-
|
68
44
|
def stub_all_api(droplets = nil, active = false) # rubocop:disable MethodLength
|
69
45
|
drops = []
|
70
46
|
droplets ||= [droplet_id]
|
@@ -111,4 +87,14 @@ shared_context 'spec' do
|
|
111
87
|
before(:all) do
|
112
88
|
WebMock.reset!
|
113
89
|
end
|
90
|
+
|
91
|
+
after(:all) do
|
92
|
+
# sleep(1)
|
93
|
+
end
|
94
|
+
|
95
|
+
before(:each) do
|
96
|
+
# stub_cleanup
|
97
|
+
ENV['DIGITAL_OCEAN_API_KEY'] = api_key
|
98
|
+
ENV['DIGITAL_OCEAN_CLIENT_ID'] = client_key
|
99
|
+
end
|
114
100
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,169 +1,197 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: do_snapshot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
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-07-
|
11
|
+
date: 2014-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digitalocean
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.19
|
33
|
+
version: '0.19'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.19
|
40
|
+
version: '0.19'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pony
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.1
|
47
|
+
version: '1.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.1
|
54
|
+
version: '1.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.8.7
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.8.7
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: json
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '0.24'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
96
|
+
version: '0.24'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec-core
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 3.0
|
103
|
+
version: '3.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 3.0
|
110
|
+
version: '3.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rspec-expectations
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 3.0
|
117
|
+
version: '3.0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 3.0
|
124
|
+
version: '3.0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rspec-mocks
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 3.0
|
131
|
+
version: '3.0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 3.0
|
138
|
+
version: '3.0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: webmock
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 1.18
|
145
|
+
version: '1.18'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 1.18
|
152
|
+
version: '1.18'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: coveralls
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.7'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.7'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubyzip
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0
|
173
|
+
version: '0'
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
|
-
- -
|
178
|
+
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: 0
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: aws-s3
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
167
195
|
description: Snapshot creator for Digital Ocean droplets. Multi-threading inside.
|
168
196
|
Auto-cleanup feature. No matter how much droplets you have. Cron optimized.
|
169
197
|
email:
|
@@ -173,25 +201,17 @@ executables:
|
|
173
201
|
extensions: []
|
174
202
|
extra_rdoc_files: []
|
175
203
|
files:
|
176
|
-
- .gitignore
|
177
|
-
- .rubocop.yml
|
178
|
-
- .ruby-version
|
179
|
-
- .travis.yml
|
180
|
-
- Gemfile
|
181
|
-
- LICENSE.txt
|
182
204
|
- README.md
|
183
|
-
- Rakefile
|
184
205
|
- bin/do_snapshot
|
185
|
-
- do_snapshot.gemspec
|
186
206
|
- lib/do_snapshot.rb
|
187
207
|
- lib/do_snapshot/api.rb
|
188
208
|
- lib/do_snapshot/cli.rb
|
189
209
|
- lib/do_snapshot/command.rb
|
190
210
|
- lib/do_snapshot/core_ext/hash.rb
|
211
|
+
- lib/do_snapshot/distribution.rb
|
191
212
|
- lib/do_snapshot/log.rb
|
192
213
|
- lib/do_snapshot/mail.rb
|
193
214
|
- lib/do_snapshot/version.rb
|
194
|
-
- log/.keep
|
195
215
|
- spec/.keep
|
196
216
|
- spec/do_snapshot/api_spec.rb
|
197
217
|
- spec/do_snapshot/cli_spec.rb
|
@@ -209,8 +229,7 @@ files:
|
|
209
229
|
- spec/shared/environment.rb
|
210
230
|
- spec/shared/uri_helpers.rb
|
211
231
|
- spec/spec_helper.rb
|
212
|
-
|
213
|
-
homepage: http://github.com/merqlove/do_snapshot
|
232
|
+
homepage: http://dosnapshot.merqlove.ru/
|
214
233
|
licenses:
|
215
234
|
- MIT
|
216
235
|
metadata: {}
|
@@ -220,12 +239,12 @@ require_paths:
|
|
220
239
|
- lib
|
221
240
|
required_ruby_version: !ruby/object:Gem::Requirement
|
222
241
|
requirements:
|
223
|
-
- -
|
242
|
+
- - ">="
|
224
243
|
- !ruby/object:Gem::Version
|
225
244
|
version: '0'
|
226
245
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
246
|
requirements:
|
228
|
-
- -
|
247
|
+
- - ">="
|
229
248
|
- !ruby/object:Gem::Version
|
230
249
|
version: '0'
|
231
250
|
requirements: []
|
data/.gitignore
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
log/*
|
18
|
-
!log/.keep
|
19
|
-
tmp/*
|
20
|
-
!tmp/.keep
|
21
|
-
*.bundle
|
22
|
-
*.so
|
23
|
-
*.o
|
24
|
-
*.a
|
25
|
-
mkmf.log
|
26
|
-
.idea
|
27
|
-
.irb_history
|
28
|
-
.ruby-version
|
data/.rubocop.yml
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.2
|
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2014 Alexander Merkulov
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
data/do_snapshot.gemspec
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'do_snapshot/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'do_snapshot'
|
8
|
-
spec.version = DoSnapshot::VERSION
|
9
|
-
spec.authors = ['Alexander Merkulov']
|
10
|
-
spec.email = ['sasha@merqlove.ru']
|
11
|
-
spec.summary = 'Snapshot creator for Digital Ocean droplets. Multi-threading. Auto-cleanup. Cron optimized.'
|
12
|
-
spec.description = 'Snapshot creator for Digital Ocean droplets. Multi-threading inside. Auto-cleanup feature. No matter how much droplets you have. Cron optimized.'
|
13
|
-
spec.homepage = 'http://github.com/merqlove/do_snapshot'
|
14
|
-
spec.license = 'MIT'
|
15
|
-
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ['lib']
|
20
|
-
|
21
|
-
spec.add_dependency 'digitalocean', '~> 1.2'
|
22
|
-
spec.add_dependency 'thor', '~> 0.19.1'
|
23
|
-
spec.add_dependency 'pony', '~> 1.1.0'
|
24
|
-
|
25
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
26
|
-
spec.add_development_dependency 'rake'
|
27
|
-
spec.add_development_dependency 'rubocop'
|
28
|
-
spec.add_development_dependency 'rspec-core', '~> 3.0.2'
|
29
|
-
spec.add_development_dependency 'rspec-expectations', '~> 3.0.2'
|
30
|
-
spec.add_development_dependency 'rspec-mocks', '~> 3.0.2'
|
31
|
-
spec.add_development_dependency 'webmock', '~> 1.18.0'
|
32
|
-
spec.add_development_dependency 'coveralls', '~> 0.7.0'
|
33
|
-
end
|
data/log/.keep
DELETED
File without changes
|
data/tmp/.keep
DELETED
File without changes
|