netguru-safe 0.2.9
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.
- data/.autotest +42 -0
- data/.document +5 -0
- data/.gitignore +11 -0
- data/CHANGELOG +25 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +20 -0
- data/README.markdown +237 -0
- data/Rakefile +32 -0
- data/TODO +11 -0
- data/VERSION +1 -0
- data/astrails-safe.gemspec +37 -0
- data/bin/astrails-safe +53 -0
- data/examples/example_helper.rb +19 -0
- data/lib/astrails/safe.rb +73 -0
- data/lib/astrails/safe/archive.rb +24 -0
- data/lib/astrails/safe/backup.rb +20 -0
- data/lib/astrails/safe/cloudfiles.rb +77 -0
- data/lib/astrails/safe/config/builder.rb +60 -0
- data/lib/astrails/safe/config/node.rb +76 -0
- data/lib/astrails/safe/gpg.rb +46 -0
- data/lib/astrails/safe/gzip.rb +25 -0
- data/lib/astrails/safe/local.rb +51 -0
- data/lib/astrails/safe/mongodump.rb +23 -0
- data/lib/astrails/safe/mysqldump.rb +32 -0
- data/lib/astrails/safe/pgdump.rb +36 -0
- data/lib/astrails/safe/pipe.rb +17 -0
- data/lib/astrails/safe/s3.rb +75 -0
- data/lib/astrails/safe/sftp.rb +88 -0
- data/lib/astrails/safe/sink.rb +35 -0
- data/lib/astrails/safe/source.rb +47 -0
- data/lib/astrails/safe/stream.rb +20 -0
- data/lib/astrails/safe/svndump.rb +13 -0
- data/lib/astrails/safe/tmp_file.rb +48 -0
- data/lib/astrails/safe/version.rb +5 -0
- data/lib/extensions/mktmpdir.rb +45 -0
- data/spec/integration/airbrake_integration_spec.rb +76 -0
- data/spec/integration/archive_integration_spec.rb +88 -0
- data/spec/integration/cleanup_spec.rb +61 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit/archive_spec.rb +67 -0
- data/spec/unit/cloudfiles_spec.rb +177 -0
- data/spec/unit/config_spec.rb +234 -0
- data/spec/unit/gpg_spec.rb +148 -0
- data/spec/unit/gzip_spec.rb +64 -0
- data/spec/unit/local_spec.rb +110 -0
- data/spec/unit/mongodump_spec.rb +54 -0
- data/spec/unit/mysqldump_spec.rb +83 -0
- data/spec/unit/pgdump_spec.rb +45 -0
- data/spec/unit/s3_spec.rb +163 -0
- data/spec/unit/svndump_spec.rb +39 -0
- data/templates/script.rb +160 -0
- metadata +222 -0
data/.autotest
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'autotest'
|
2
|
+
|
3
|
+
Autotest.add_hook :initialize do |at|
|
4
|
+
at.clear_mappings
|
5
|
+
at.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
|
6
|
+
at.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m
|
7
|
+
|
8
|
+
at.add_mapping(%r%^examples/.*_example.rb$%) { |filename, _|
|
9
|
+
filename
|
10
|
+
}
|
11
|
+
|
12
|
+
at.add_mapping(%r%^lib/(.*)\.rb$%) { |filename, m|
|
13
|
+
["examples/lib/#{m[1]}_example.rb"]
|
14
|
+
}
|
15
|
+
|
16
|
+
at.add_mapping(%r%^examples/(example_helper|shared/.*)\.rb$%) {
|
17
|
+
at.files_matching %r%^examples/.*_example\.rb$%
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
class MicronautCommandError < StandardError; end
|
22
|
+
|
23
|
+
class Autotest::Micronaut < Autotest
|
24
|
+
#remove_method :consolidate_failures, :make_test_cmd
|
25
|
+
#remove_method :make_test_cmd
|
26
|
+
|
27
|
+
def consolidate_failures(failed)
|
28
|
+
filters = new_hash_of_arrays
|
29
|
+
failed.each do |spec, trace|
|
30
|
+
if trace =~ /\n(\.\/)?(.*example\.rb):[\d]+:\Z?/
|
31
|
+
filters[$2] << spec
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return filters
|
35
|
+
end
|
36
|
+
|
37
|
+
def make_test_cmd(files_to_test)
|
38
|
+
return '' if files_to_test.size == 0
|
39
|
+
"bin/micronaut #{files_to_test.keys.sort.join(' ')}"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/.document
ADDED
data/.gitignore
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
0.2.8
|
2
|
+
|
3
|
+
* ruby 1.9.2 compatibility (tests mostly)
|
4
|
+
* code review, and tons of small fixes
|
5
|
+
* check file size before attempting to upload to cloudfiles
|
6
|
+
* testing framework changed from micronaut to rspec
|
7
|
+
|
8
|
+
0.2.7
|
9
|
+
|
10
|
+
* default options for gpg now include '--no-use-agent'
|
11
|
+
* support for 'command' option for gpg
|
12
|
+
* quote values in mysql password file
|
13
|
+
* add 'lib' to $:
|
14
|
+
* [EXPERIMENTAL] Rackspace Cloud Files support
|
15
|
+
|
16
|
+
0.2.6
|
17
|
+
|
18
|
+
* fix typo in the template config file. (change option to options in pgdump)
|
19
|
+
* add example 'options' for tar in the template config file.
|
20
|
+
* do not try to upload more then 5G of data to S3. print error instead
|
21
|
+
|
22
|
+
0.2.5
|
23
|
+
|
24
|
+
* Safety mesure: Disable overwrite of existing configuration keys except for multi-value keys
|
25
|
+
supported multi-value keys: skip_tables, exclude, files
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
astrails-safe (0.2.9)
|
5
|
+
aws-sdk (~> 1.2.3)
|
6
|
+
cloudfiles (~> 1.4.7)
|
7
|
+
net-sftp (~> 2.0.4)
|
8
|
+
toadhopper (~> 2.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
aws-sdk (1.2.3)
|
14
|
+
httparty (~> 0.7)
|
15
|
+
json (~> 1.4)
|
16
|
+
nokogiri (>= 1.4.4)
|
17
|
+
uuidtools (~> 2.1)
|
18
|
+
cloudfiles (1.4.18)
|
19
|
+
mime-types (>= 1.16)
|
20
|
+
httparty (0.8.1)
|
21
|
+
multi_json
|
22
|
+
multi_xml
|
23
|
+
json (1.6.2)
|
24
|
+
mime-types (1.17.2)
|
25
|
+
multi_json (1.0.4)
|
26
|
+
multi_xml (0.4.1)
|
27
|
+
net-sftp (2.0.5)
|
28
|
+
net-ssh (>= 2.0.9)
|
29
|
+
net-ssh (2.2.1)
|
30
|
+
nokogiri (1.5.0)
|
31
|
+
rake (0.8.7)
|
32
|
+
rr (1.0.4)
|
33
|
+
rspec (1.3.2)
|
34
|
+
toadhopper (2.0)
|
35
|
+
uuidtools (2.1.2)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
astrails-safe!
|
42
|
+
rake (= 0.8.7)
|
43
|
+
rr (~> 1.0.4)
|
44
|
+
rspec (~> 1.3.2)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Astrails Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
astrails-safe
|
2
|
+
=============
|
3
|
+
|
4
|
+
Simple database and filesystem backups with S3 and Rackspace Cloud Files support (with optional encryption)
|
5
|
+
|
6
|
+
* Home: [http://astrails.com/opensource/astrails-safe](http://astrails.com/opensource/astrails-safe)
|
7
|
+
* Code: [http://github.com/astrails/safe](http://github.com/astrails/safe)
|
8
|
+
* Blog: [http://blog.astrails.com/astrails-safe](http://blog.astrails.com/astrails-safe)
|
9
|
+
|
10
|
+
|
11
|
+
Motivation
|
12
|
+
----------
|
13
|
+
|
14
|
+
We needed a backup solution that will satisfy the following requirements:
|
15
|
+
|
16
|
+
* opensource
|
17
|
+
* simple to install and configure
|
18
|
+
* support for simple ‘tar’ backups of directories (with includes/excludes)
|
19
|
+
* support for simple mysqldump of mysql databases
|
20
|
+
* support for symmetric or public key encryption
|
21
|
+
* support for local filesystem, Amazon S3, and Rackspace Cloud Files for storage
|
22
|
+
* support for backup rotation. we don’t want backups filling all the diskspace or cost a fortune on S3 or Cloud Files
|
23
|
+
|
24
|
+
And since we didn't find any, we wrote our own :)
|
25
|
+
|
26
|
+
Contributions
|
27
|
+
-------------
|
28
|
+
|
29
|
+
The following functionality was contributed by astrails-safe users:
|
30
|
+
|
31
|
+
* PostgreSQL dump using `pg_dump` (by Mark Mansour <mark@stateofflux.com>)
|
32
|
+
* Subversion dump using svndump (by Richard Luther <richard.luther@gmail.com>)
|
33
|
+
* SFTP remote storage (by Adam <adam@mediadrive.ca>)
|
34
|
+
* benchmarking output (By Neer)
|
35
|
+
* README fixes (by Bobby Wilson)
|
36
|
+
* improved config file parsing (by Fedor Kocherga <fkocherga@gmail.com>)
|
37
|
+
* mysql password file quoting (by Jonathan Sutherland <jonathan.sutherland@gmail.com>)
|
38
|
+
* Rackspace Cloud Files support (by H. Wade Minter <minter@lunenburg.org>)
|
39
|
+
|
40
|
+
Thanks to all :)
|
41
|
+
|
42
|
+
Installation
|
43
|
+
------------
|
44
|
+
|
45
|
+
sudo gem install astrails-safe --source http://gemcutter.org
|
46
|
+
|
47
|
+
Reporting problems
|
48
|
+
------------------
|
49
|
+
|
50
|
+
Please report problems at the [Issues tracker](http://github.com/astrails/safe/issues)
|
51
|
+
|
52
|
+
Usage
|
53
|
+
-----
|
54
|
+
|
55
|
+
Usage:
|
56
|
+
astrails-safe [OPTIONS] CONFIG_FILE
|
57
|
+
Options:
|
58
|
+
-h, --help This help screen
|
59
|
+
-v, --verbose be verbose, duh!
|
60
|
+
-n, --dry-run just pretend, don't do anything.
|
61
|
+
-L, --local skip remote storage, only do local backups
|
62
|
+
|
63
|
+
Note: CONFIG\_FILE will be created from template if missing
|
64
|
+
|
65
|
+
Encryption
|
66
|
+
----------
|
67
|
+
|
68
|
+
If you want to encrypt your backups you have 2 options:
|
69
|
+
* use simple password encryption
|
70
|
+
* use GPG public key encryption
|
71
|
+
|
72
|
+
> IMPORTANT: some gpg installations automatically set 'use-agent' option in the default
|
73
|
+
> configuration file that is created when you run gpg for the first time. This will cause
|
74
|
+
> gpg to fail on the 2nd run if you don't have the agent running. The result is that
|
75
|
+
> 'astrails-safe' will work ONCE when you manually test it and then fail on any subsequent run.
|
76
|
+
> The solution is to remove the 'use-agent' from the config file (usually /root/.gnupg/gpg.conf)
|
77
|
+
> To mitigate this problem for the gpg 1.x series '--no-use-agent' option is added by defaults
|
78
|
+
> to the autogenerated config file, but for gpg2 is doesn't work. as the manpage says it:
|
79
|
+
> "This is dummy option. gpg2 always requires the agent." :(
|
80
|
+
|
81
|
+
For simple password, just add password entry in gpg section.
|
82
|
+
For public key encryption you will need to create a public/secret keypair.
|
83
|
+
|
84
|
+
We recommend to create your GPG keys only on your local machine and then
|
85
|
+
transfer your public key to the server that will do the backups.
|
86
|
+
|
87
|
+
This way the server will only know how to encrypt the backups but only you
|
88
|
+
will be able to decrypt them using the secret key you have locally. Of course
|
89
|
+
you MUST backup your backup encryption key :)
|
90
|
+
We recommend also pringing the hard paper copy of your GPG key 'just in case'.
|
91
|
+
|
92
|
+
The procedure to create and transfer the key is as follows:
|
93
|
+
|
94
|
+
1. run 'gpg --gen-key' on your local machine and follow onscreen instructions to create the key
|
95
|
+
(you can accept all the defaults).
|
96
|
+
|
97
|
+
2. extract your public key into a file (assuming you used test@example.com as your key email):
|
98
|
+
`gpg -a --export test@example.com > test@example.com.pub`
|
99
|
+
|
100
|
+
3. transfer public key to the server
|
101
|
+
`scp test@example.com.pub root@example.com:`
|
102
|
+
|
103
|
+
4. import public key on the remote system:
|
104
|
+
|
105
|
+
$ gpg --import test@example.com.pub
|
106
|
+
gpg: key 45CA9403: public key "Test Backup <test@example.com>" imported
|
107
|
+
gpg: Total number processed: 1
|
108
|
+
gpg: imported: 1
|
109
|
+
|
110
|
+
5. since we don't keep the secret part of the key on the remote server, gpg has
|
111
|
+
no way to know its yours and can be trusted.
|
112
|
+
To fix that we can sign it with other trusted key, or just directly modify its
|
113
|
+
trust level in gpg (use level 5):
|
114
|
+
|
115
|
+
$ gpg --edit-key test@example.com
|
116
|
+
...
|
117
|
+
Command> trust
|
118
|
+
...
|
119
|
+
1 = I don't know or won't say
|
120
|
+
2 = I do NOT trust
|
121
|
+
3 = I trust marginally
|
122
|
+
4 = I trust fully
|
123
|
+
5 = I trust ultimately
|
124
|
+
m = back to the main menu
|
125
|
+
|
126
|
+
Your decision? 5
|
127
|
+
...
|
128
|
+
Command> quit
|
129
|
+
|
130
|
+
6. export your secret key for backup
|
131
|
+
(we recommend to print it on paper and burn to a CD/DVD and store in a safe place):
|
132
|
+
|
133
|
+
$ gpg -a --export-secret-key test@example.com > test@example.com.key
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
Example configuration
|
138
|
+
---------------------
|
139
|
+
|
140
|
+
safe do
|
141
|
+
local :path => "/backup/:kind/:id"
|
142
|
+
|
143
|
+
s3 do
|
144
|
+
key "...................."
|
145
|
+
secret "........................................"
|
146
|
+
bucket "backup.astrails.com"
|
147
|
+
path "servers/alpha/:kind/:id"
|
148
|
+
end
|
149
|
+
|
150
|
+
cloudfiles do
|
151
|
+
user "..........."
|
152
|
+
api_key "................................."
|
153
|
+
container "safe_backup"
|
154
|
+
path ":kind/" # this is default
|
155
|
+
service_net false
|
156
|
+
end
|
157
|
+
|
158
|
+
sftp do
|
159
|
+
host "sftp.astrails.com"
|
160
|
+
user "astrails"
|
161
|
+
# port 8023
|
162
|
+
password "ssh password for sftp"
|
163
|
+
end
|
164
|
+
|
165
|
+
gpg do
|
166
|
+
command "/usr/local/bin/gpg"
|
167
|
+
options "--no-use-agent"
|
168
|
+
# symmetric encryption key
|
169
|
+
# password "qwe"
|
170
|
+
|
171
|
+
# public GPG key (must be known to GPG, i.e. be on the keyring)
|
172
|
+
key "backup@astrails.com"
|
173
|
+
end
|
174
|
+
|
175
|
+
keep do
|
176
|
+
local 20
|
177
|
+
s3 100
|
178
|
+
cloudfiles 100
|
179
|
+
sftp 100
|
180
|
+
end
|
181
|
+
|
182
|
+
mysqldump do
|
183
|
+
options "-ceKq --single-transaction --create-options"
|
184
|
+
|
185
|
+
user "root"
|
186
|
+
password "............"
|
187
|
+
socket "/var/run/mysqld/mysqld.sock"
|
188
|
+
|
189
|
+
database :blog
|
190
|
+
database :servershape
|
191
|
+
database :astrails_com
|
192
|
+
database :secret_project_com do
|
193
|
+
skip_tables "foo"
|
194
|
+
skip_tables ["bar", "baz"]
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
svndump do
|
200
|
+
repo :my_repo do
|
201
|
+
repo_path "/home/svn/my_repo"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
pgdump do
|
206
|
+
options "-i -x -O" # -i => ignore version, -x => do not dump privileges (grant/revoke), -O => skip restoration of object ownership in plain text format
|
207
|
+
|
208
|
+
user "username"
|
209
|
+
password "............" # shouldn't be used, instead setup ident. Current functionality exports a password env to the shell which pg_dump uses - untested!
|
210
|
+
|
211
|
+
database :blog
|
212
|
+
database :stateofflux_com
|
213
|
+
end
|
214
|
+
|
215
|
+
tar do
|
216
|
+
options "-h" # dereference symlinks
|
217
|
+
archive "git-repositories", :files => "/home/git/repositories"
|
218
|
+
archive "dot-configs", :files => "/home/*/.[^.]*"
|
219
|
+
archive "etc", :files => "/etc", :exclude => "/etc/puppet/other"
|
220
|
+
|
221
|
+
archive "blog-astrails-com" do
|
222
|
+
files "/var/www/blog.astrails.com/"
|
223
|
+
exclude "/var/www/blog.astrails.com/log"
|
224
|
+
exclude "/var/www/blog.astrails.com/tmp"
|
225
|
+
end
|
226
|
+
|
227
|
+
archive "astrails-com" do
|
228
|
+
files "/var/www/astrails.com/"
|
229
|
+
exclude ["/var/www/astrails.com/log", "/var/www/astrails.com/tmp"]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
Copyright
|
235
|
+
---------
|
236
|
+
|
237
|
+
Copyright (c) 2010 Astrails Ltd. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
6
|
+
spec.libs << 'lib' << 'spec'
|
7
|
+
spec.spec_opts = ['--options', "\"spec/spec.opts\""]
|
8
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
12
|
+
spec.libs << 'lib' << 'spec'
|
13
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
14
|
+
spec.rcov = true
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :spec
|
18
|
+
|
19
|
+
require 'rake/rdoctask'
|
20
|
+
Rake::RDocTask.new do |rdoc|
|
21
|
+
if File.exist?('VERSION')
|
22
|
+
version = File.read('VERSION')
|
23
|
+
else
|
24
|
+
version = ""
|
25
|
+
end
|
26
|
+
|
27
|
+
rdoc.rdoc_dir = 'rdoc'
|
28
|
+
rdoc.title = "safe #{version}"
|
29
|
+
rdoc.rdoc_files.include('README*')
|
30
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
31
|
+
end
|
32
|
+
|
data/TODO
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
- add 'silent'
|
2
|
+
- handle errors from mysqldump
|
3
|
+
- check that gpg is installed
|
4
|
+
- support percona XtraBackup as an option instead of mysqldump [patches anyone :) ?]
|
5
|
+
- backup validation:
|
6
|
+
- support for 'minsize' opition in backup that will check that produced backup is at least the expected size
|
7
|
+
this should catch many backup failure scenarious (like broken mysql connection, insufficient disk space etc.
|
8
|
+
- support differencial backups
|
9
|
+
- it should be fairly easy for filesystem backups using tar's built in incremental functionality.
|
10
|
+
- for mysql need to use XtraBackup
|
11
|
+
- or we can keep the previous dump locally and store only diff with the latest dump
|