netguru-safe 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.autotest +42 -0
  2. data/.document +5 -0
  3. data/.gitignore +11 -0
  4. data/CHANGELOG +25 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +44 -0
  7. data/LICENSE +20 -0
  8. data/README.markdown +237 -0
  9. data/Rakefile +32 -0
  10. data/TODO +11 -0
  11. data/VERSION +1 -0
  12. data/astrails-safe.gemspec +37 -0
  13. data/bin/astrails-safe +53 -0
  14. data/examples/example_helper.rb +19 -0
  15. data/lib/astrails/safe.rb +73 -0
  16. data/lib/astrails/safe/archive.rb +24 -0
  17. data/lib/astrails/safe/backup.rb +20 -0
  18. data/lib/astrails/safe/cloudfiles.rb +77 -0
  19. data/lib/astrails/safe/config/builder.rb +60 -0
  20. data/lib/astrails/safe/config/node.rb +76 -0
  21. data/lib/astrails/safe/gpg.rb +46 -0
  22. data/lib/astrails/safe/gzip.rb +25 -0
  23. data/lib/astrails/safe/local.rb +51 -0
  24. data/lib/astrails/safe/mongodump.rb +23 -0
  25. data/lib/astrails/safe/mysqldump.rb +32 -0
  26. data/lib/astrails/safe/pgdump.rb +36 -0
  27. data/lib/astrails/safe/pipe.rb +17 -0
  28. data/lib/astrails/safe/s3.rb +75 -0
  29. data/lib/astrails/safe/sftp.rb +88 -0
  30. data/lib/astrails/safe/sink.rb +35 -0
  31. data/lib/astrails/safe/source.rb +47 -0
  32. data/lib/astrails/safe/stream.rb +20 -0
  33. data/lib/astrails/safe/svndump.rb +13 -0
  34. data/lib/astrails/safe/tmp_file.rb +48 -0
  35. data/lib/astrails/safe/version.rb +5 -0
  36. data/lib/extensions/mktmpdir.rb +45 -0
  37. data/spec/integration/airbrake_integration_spec.rb +76 -0
  38. data/spec/integration/archive_integration_spec.rb +88 -0
  39. data/spec/integration/cleanup_spec.rb +61 -0
  40. data/spec/spec.opts +5 -0
  41. data/spec/spec_helper.rb +13 -0
  42. data/spec/unit/archive_spec.rb +67 -0
  43. data/spec/unit/cloudfiles_spec.rb +177 -0
  44. data/spec/unit/config_spec.rb +234 -0
  45. data/spec/unit/gpg_spec.rb +148 -0
  46. data/spec/unit/gzip_spec.rb +64 -0
  47. data/spec/unit/local_spec.rb +110 -0
  48. data/spec/unit/mongodump_spec.rb +54 -0
  49. data/spec/unit/mysqldump_spec.rb +83 -0
  50. data/spec/unit/pgdump_spec.rb +45 -0
  51. data/spec/unit/s3_spec.rb +163 -0
  52. data/spec/unit/svndump_spec.rb +39 -0
  53. data/templates/script.rb +160 -0
  54. 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
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ tmp
7
+ *~
8
+ tags
9
+ log/
10
+ .bundle/
11
+ vendor/bundle
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
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'rake', '0.8.7'
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