webtranslateit-safe 0.4.0 → 0.4.1

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +445 -32
  3. data/CHANGELOG +4 -5
  4. data/Gemfile.lock +1 -1
  5. data/bin/webtranslateit-safe +16 -16
  6. data/lib/webtranslateit/safe/archive.rb +4 -9
  7. data/lib/webtranslateit/safe/backup.rb +2 -9
  8. data/lib/webtranslateit/safe/cloudfiles.rb +1 -1
  9. data/lib/webtranslateit/safe/config/builder.rb +6 -16
  10. data/lib/webtranslateit/safe/config/node.rb +14 -21
  11. data/lib/webtranslateit/safe/ftp.rb +26 -26
  12. data/lib/webtranslateit/safe/gpg.rb +2 -8
  13. data/lib/webtranslateit/safe/gzip.rb +1 -5
  14. data/lib/webtranslateit/safe/local.rb +12 -16
  15. data/lib/webtranslateit/safe/mongodump.rb +6 -13
  16. data/lib/webtranslateit/safe/mysqldump.rb +5 -9
  17. data/lib/webtranslateit/safe/pgdump.rb +9 -9
  18. data/lib/webtranslateit/safe/pipe.rb +0 -6
  19. data/lib/webtranslateit/safe/s3.rb +1 -1
  20. data/lib/webtranslateit/safe/sftp.rb +25 -33
  21. data/lib/webtranslateit/safe/sink.rb +4 -9
  22. data/lib/webtranslateit/safe/source.rb +9 -13
  23. data/lib/webtranslateit/safe/stream.rb +6 -14
  24. data/lib/webtranslateit/safe/svndump.rb +1 -5
  25. data/lib/webtranslateit/safe/tmp_file.rb +11 -16
  26. data/lib/webtranslateit/safe/version.rb +1 -5
  27. data/lib/webtranslateit/safe.rb +9 -11
  28. data/spec/webtranslateit/safe/archive_spec.rb +20 -20
  29. data/spec/webtranslateit/safe/cloudfiles_spec.rb +1 -1
  30. data/spec/webtranslateit/safe/config_spec.rb +31 -31
  31. data/spec/webtranslateit/safe/gpg_spec.rb +35 -35
  32. data/spec/webtranslateit/safe/gzip_spec.rb +11 -11
  33. data/spec/webtranslateit/safe/local_spec.rb +27 -27
  34. data/spec/webtranslateit/safe/mongodump_spec.rb +23 -23
  35. data/spec/webtranslateit/safe/mysqldump_spec.rb +30 -30
  36. data/spec/webtranslateit/safe/pgdump_spec.rb +13 -13
  37. data/spec/webtranslateit/safe/s3_spec.rb +1 -1
  38. data/spec/webtranslateit/safe/svndump_spec.rb +9 -9
  39. data/webtranslateit-safe.gemspec +6 -7
  40. metadata +2 -2
@@ -1,7 +1,5 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
3
  class Sftp < Sink
6
4
 
7
5
  protected
@@ -15,42 +13,38 @@ module WebTranslateIt
15
13
  end
16
14
 
17
15
  def save
18
- raise 'pipe-streaming not supported for SFTP.' unless @backup.path
16
+ raise RuntimeError, 'pipe-streaming not supported for SFTP.' unless @backup.path
19
17
 
20
18
  puts "Uploading #{host}:#{full_path} via SFTP" if verbose? || dry_run?
21
19
 
22
- return if dry_run? || local_only?
23
-
24
- opts = {}
25
- opts[:password] = password if password
26
- opts[:port] = port if port
27
- Net::SFTP.start(host, user, opts) do |sftp|
28
- puts "Sending #{@backup.path} to #{full_path}" if verbose?
29
- begin
30
- sftp.upload! @backup.path, full_path
31
- rescue Net::SFTP::StatusException
32
- puts "Ensuring remote path (#{path}) exists" if verbose?
33
- # mkdir -p
34
- folders = path.split('/')
35
- folders.each_index do |i|
36
- folder = folders[0..i].join('/')
37
- puts "Creating #{folder} on remote" if verbose?
38
- begin
39
- sftp.mkdir!(folder)
40
- rescue StandardError
41
- Net::SFTP::StatusException
20
+ unless dry_run? || local_only?
21
+ opts = {}
22
+ opts[:password] = password if password
23
+ opts[:port] = port if port
24
+ Net::SFTP.start(host, user, opts) do |sftp|
25
+ puts "Sending #{@backup.path} to #{full_path}" if verbose?
26
+ begin
27
+ sftp.upload! @backup.path, full_path
28
+ rescue Net::SFTP::StatusException
29
+ puts "Ensuring remote path (#{path}) exists" if verbose?
30
+ # mkdir -p
31
+ folders = path.split('/')
32
+ folders.each_index do |i|
33
+ folder = folders[0..i].join('/')
34
+ puts "Creating #{folder} on remote" if verbose?
35
+ sftp.mkdir!(folder) rescue Net::SFTP::StatusException
42
36
  end
37
+ retry
43
38
  end
44
- retry
45
39
  end
40
+ puts '...done' if verbose?
46
41
  end
47
- puts '...done' if verbose?
48
42
  end
49
43
 
50
44
  def cleanup
51
45
  return if local_only? || dry_run?
52
46
 
53
- return unless (keep = config[:keep, :sftp])
47
+ return unless keep = config[:keep, :sftp]
54
48
 
55
49
  puts "listing files: #{host}:#{base}*" if verbose?
56
50
  opts = {}
@@ -59,11 +53,11 @@ module WebTranslateIt
59
53
  Net::SFTP.start(host, user, opts) do |sftp|
60
54
  files = sftp.dir.glob(path, File.basename("#{base}*"))
61
55
 
62
- puts(files.collect(&:name)) if verbose?
56
+ puts files.collect {|x| x.name } if verbose?
63
57
 
64
- files = files
65
- .collect(&:name)
66
- .sort
58
+ files = files.
59
+ collect {|x| x.name }.
60
+ sort
67
61
 
68
62
  cleanup_with_limit(files, keep) do |f|
69
63
  file = File.join(path, f)
@@ -90,7 +84,5 @@ module WebTranslateIt
90
84
  end
91
85
 
92
86
  end
93
-
94
87
  end
95
-
96
- end
88
+ end
@@ -1,7 +1,5 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
3
  class Sink < Stream
6
4
 
7
5
  def process
@@ -17,7 +15,7 @@ module WebTranslateIt
17
15
  # base is used in 'cleanup' to find all files that begin with base. the '.'
18
16
  # at the end is essential to distinguish b/w foo.* and foobar.* archives for example
19
17
  def base
20
- @base ||= File.join(path, "#{File.basename(@backup.filename).split('.').first}.")
18
+ @base ||= File.join(path, File.basename(@backup.filename).split('.').first + '.')
21
19
  end
22
20
 
23
21
  def full_path
@@ -25,16 +23,13 @@ module WebTranslateIt
25
23
  end
26
24
 
27
25
  # call block on files to be removed (all except for the LAST 'limit' files
28
- def cleanup_with_limit(files, limit, &)
26
+ def cleanup_with_limit(files, limit, &block)
29
27
  return unless files.size > limit
30
28
 
31
29
  to_remove = files[0..(files.size - limit - 1)]
32
30
  # TODO: validate here
33
- to_remove.each(&)
31
+ to_remove.each(&block)
34
32
  end
35
-
36
33
  end
37
-
38
34
  end
39
-
40
- end
35
+ end
@@ -1,14 +1,10 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
3
  class Source < Stream
6
4
 
7
5
  attr_accessor :id
8
-
9
6
  def initialize(id, config)
10
- @id = id.to_s
11
- @config = config
7
+ @id, @config = id.to_s, config
12
8
  end
13
9
 
14
10
  def timestamp
@@ -25,13 +21,12 @@ module WebTranslateIt
25
21
 
26
22
  def backup
27
23
  return @backup if @backup
28
-
29
24
  @backup = Backup.new(
30
- id: @id,
31
- kind: kind,
32
- extension: extension,
33
- command: command,
34
- timestamp: timestamp
25
+ :id => @id,
26
+ :kind => kind,
27
+ :extension => extension,
28
+ :command => command,
29
+ :timestamp => timestamp
35
30
  )
36
31
  # can't do this in the initializer hash above since
37
32
  # filename() calls expand() which requires @backup
@@ -40,12 +35,13 @@ module WebTranslateIt
40
35
  @backup
41
36
  end
42
37
 
38
+ protected
39
+
43
40
  def self.human_name
44
41
  name.split('::').last.downcase
45
42
  end
46
43
 
47
44
  end
48
-
49
45
  end
50
-
51
46
  end
47
+
@@ -1,22 +1,17 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
3
  class Stream
6
4
 
7
5
  attr_accessor :config, :backup
8
-
9
6
  def initialize(config, backup)
10
- @config = config
11
- @backup = backup
7
+ @config, @backup = config, backup
12
8
  end
13
-
14
9
  # FIXME: move to Backup
15
10
  def expand(path)
16
- path
17
- .gsub(/:kind\b/, @backup.kind.to_s)
18
- .gsub(/:id\b/, @backup.id.to_s)
19
- .gsub(/:timestamp\b/, @backup.timestamp)
11
+ path .
12
+ gsub(/:kind\b/, @backup.kind.to_s) .
13
+ gsub(/:id\b/, @backup.id.to_s) .
14
+ gsub(/:timestamp\b/, @backup.timestamp)
20
15
  end
21
16
 
22
17
  private
@@ -32,9 +27,6 @@ module WebTranslateIt
32
27
  def dry_run?
33
28
  config[:dry_run]
34
29
  end
35
-
36
30
  end
37
-
38
31
  end
39
-
40
- end
32
+ end
@@ -1,17 +1,13 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
3
  class Svndump < Source
6
4
 
7
5
  def command
8
6
  "svnadmin dump #{config[:options]} #{config[:repo_path]}"
9
7
  end
10
8
 
11
- def extension = '.svn'
9
+ def extension; '.svn'; end
12
10
 
13
11
  end
14
-
15
12
  end
16
-
17
13
  end
@@ -1,10 +1,7 @@
1
1
  require 'tmpdir'
2
2
  module WebTranslateIt
3
-
4
3
  module Safe
5
-
6
4
  module TmpFile
7
-
8
5
  @keep_files = []
9
6
 
10
7
  def self.tmproot
@@ -15,21 +12,22 @@ module WebTranslateIt
15
12
  begin
16
13
  FileUtils.remove_entry_secure tmproot
17
14
  rescue ArgumentError => e
18
- raise unless e.message =~ /parent directory is world writable/
19
-
20
- puts <<~ERR
15
+ if e.message =~ /parent directory is world writable/
16
+ puts <<-ERR
21
17
 
22
18
 
23
- ********************************************************************************
24
- It looks like you have wrong permissions on your TEMP directory. The usual
25
- case is when you have world writable TEMP directory withOUT the sticky bit.
19
+ ********************************************************************************
20
+ It looks like you have wrong permissions on your TEMP directory. The usual
21
+ case is when you have world writable TEMP directory withOUT the sticky bit.
26
22
 
27
- Try "chmod +t" on it.
23
+ Try "chmod +t" on it.
28
24
 
29
- ********************************************************************************
25
+ ********************************************************************************
30
26
 
31
- ERR
32
- raise
27
+ ERR
28
+ else
29
+ raise
30
+ end
33
31
  end
34
32
  @tmproot = nil
35
33
  end
@@ -45,9 +43,6 @@ module WebTranslateIt
45
43
  @keep_files << file # so that it will not get gcollected and removed from filesystem until the end
46
44
  file.path
47
45
  end
48
-
49
46
  end
50
-
51
47
  end
52
-
53
48
  end
@@ -1,9 +1,5 @@
1
1
  module WebTranslateIt
2
-
3
2
  module Safe
4
-
5
- VERSION = '0.4.0'
6
-
3
+ VERSION = '0.4.1'
7
4
  end
8
-
9
5
  end
@@ -38,25 +38,25 @@ require 'webtranslateit/safe/sftp'
38
38
  require 'webtranslateit/safe/ftp'
39
39
 
40
40
  module WebTranslateIt
41
-
42
41
  module Safe
43
-
44
42
  ROOT = File.join(File.dirname(__FILE__), '..', '..')
45
43
 
46
- def safe(&)
47
- Config::Node.new(&)
44
+ def safe(&block)
45
+ Config::Node.new(&block)
48
46
  end
49
47
 
50
48
  def process(config)
49
+
51
50
  [[Mysqldump, [:mysqldump, :databases]],
52
51
  [Pgdump, [:pgdump, :databases]],
53
52
  [Mongodump, [:mongodump, :databases]],
54
53
  [Archive, [:tar, :archives]],
55
- [Svndump, [:svndump, :repos]]].each do |klass, path|
56
- next unless (collection = config[*path])
57
-
58
- collection.each do |name, c|
59
- klass.new(name, c).backup.run(c, :gpg, :gzip, :local, :s3, :cloudfiles, :sftp, :ftp)
54
+ [Svndump, [:svndump, :repos]]
55
+ ].each do |klass, path|
56
+ if collection = config[*path]
57
+ collection.each do |name, c|
58
+ klass.new(name, c).backup.run(c, :gpg, :gzip, :local, :s3, :cloudfiles, :sftp, :ftp)
59
+ end
60
60
  end
61
61
  end
62
62
 
@@ -64,7 +64,5 @@ module WebTranslateIt
64
64
  end
65
65
  module_function :safe
66
66
  module_function :process
67
-
68
67
  end
69
-
70
68
  end
@@ -4,9 +4,9 @@ describe WebTranslateIt::Safe::Archive do
4
4
 
5
5
  def def_config
6
6
  {
7
- options: 'OPTS',
8
- files: 'apples',
9
- exclude: 'oranges'
7
+ :options => 'OPTS',
8
+ :files => 'apples',
9
+ :exclude => 'oranges'
10
10
  }
11
11
  end
12
12
 
@@ -19,49 +19,49 @@ describe WebTranslateIt::Safe::Archive do
19
19
  describe :backup do
20
20
  before(:each) do
21
21
  @archive = archive
22
- stub(@archive).timestamp { 'NOW' }
22
+ stub(@archive).timestamp {'NOW'}
23
23
  end
24
24
 
25
25
  {
26
- id: 'foo',
27
- kind: 'archive',
28
- extension: '.tar',
29
- filename: 'archive-foo.NOW',
30
- command: 'tar -cf - OPTS --exclude=oranges apples'
26
+ :id => 'foo',
27
+ :kind => 'archive',
28
+ :extension => '.tar',
29
+ :filename => 'archive-foo.NOW',
30
+ :command => 'tar -cf - OPTS --exclude=oranges apples',
31
31
  }.each do |k, v|
32
- it "sets #{k} to #{v}" do
32
+ it "should set #{k} to #{v}" do
33
33
  @archive.backup.send(k).should == v
34
34
  end
35
35
  end
36
36
  end
37
37
 
38
38
  describe :tar_exclude_files do
39
- it "returns '' when no excludes" do
39
+ it "should return '' when no excludes" do
40
40
  archive(:foo, {}).send(:tar_exclude_files).should == ''
41
41
  end
42
42
 
43
- it 'accepts single exclude as string' do
44
- archive(:foo, {exclude: 'bar'}).send(:tar_exclude_files).should == '--exclude=bar'
43
+ it 'should accept single exclude as string' do
44
+ archive(:foo, {:exclude => 'bar'}).send(:tar_exclude_files).should == '--exclude=bar'
45
45
  end
46
46
 
47
- it 'accepts multiple exclude as array' do
48
- archive(:foo, {exclude: ['foo', 'bar']}).send(:tar_exclude_files).should == '--exclude=foo --exclude=bar'
47
+ it 'should accept multiple exclude as array' do
48
+ archive(:foo, {:exclude => ['foo', 'bar']}).send(:tar_exclude_files).should == '--exclude=foo --exclude=bar'
49
49
  end
50
50
  end
51
51
 
52
52
  describe :tar_files do
53
- it 'raises RuntimeError when no files' do
53
+ it 'should raise RuntimeError when no files' do
54
54
  lambda {
55
55
  archive(:foo, {}).send(:tar_files)
56
56
  }.should raise_error(RuntimeError, 'missing files for tar')
57
57
  end
58
58
 
59
- it 'accepts single file as string' do
60
- archive(:foo, {files: 'foo'}).send(:tar_files).should == 'foo'
59
+ it 'should accept single file as string' do
60
+ archive(:foo, {:files => 'foo'}).send(:tar_files).should == 'foo'
61
61
  end
62
62
 
63
- it 'accepts multiple files as array' do
64
- archive(:foo, {files: ['foo', 'bar']}).send(:tar_files).should == 'foo bar'
63
+ it 'should accept multiple files as array' do
64
+ archive(:foo, {:files => ['foo', 'bar']}).send(:tar_files).should == 'foo bar'
65
65
  end
66
66
  end
67
67
  end
@@ -172,4 +172,4 @@ describe WebTranslateIt::Safe::Cloudfiles do
172
172
  @cloudfiles.send(:save)
173
173
  end
174
174
  end
175
- end
175
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe WebTranslateIt::Safe::Config do
4
- it 'parses example config' do
4
+ it 'should parse example config' do
5
5
  config = WebTranslateIt::Safe::Config::Node.new do
6
6
 
7
7
  dry_run false
@@ -47,7 +47,7 @@ describe WebTranslateIt::Safe::Config do
47
47
  database :blog
48
48
 
49
49
  database :production do
50
- keep local: 3
50
+ keep :local => 3
51
51
 
52
52
  gpg do
53
53
  password 'custom-production-pass'
@@ -69,7 +69,7 @@ describe WebTranslateIt::Safe::Config do
69
69
  database :blog
70
70
 
71
71
  database :production do
72
- keep local: 3
72
+ keep :local => 3
73
73
 
74
74
  skip_tables [:logger_exceptions, :request_logs]
75
75
  end
@@ -102,7 +102,7 @@ describe WebTranslateIt::Safe::Config do
102
102
  end
103
103
 
104
104
  archive :misc do
105
- files ['/backup/*.rb']
105
+ files [ '/backup/*.rb' ]
106
106
  end
107
107
  end
108
108
 
@@ -125,13 +125,13 @@ describe WebTranslateIt::Safe::Config do
125
125
  'key' => 's3 key',
126
126
  'secret' => 'secret',
127
127
  'bucket' => 'bucket',
128
- 'path' => 'path1'
128
+ 'path' => 'path1',
129
129
  },
130
130
 
131
131
  'sftp' => {
132
132
  'user' => 'sftp user',
133
133
  'password' => 'sftp password',
134
- 'host' => 'sftp host'
134
+ 'host' => 'sftp host',
135
135
  },
136
136
 
137
137
  'gpg' => {'password' => 'astrails', 'key' => 'gpg-key'},
@@ -149,11 +149,11 @@ describe WebTranslateIt::Safe::Config do
149
149
  'databases' => {
150
150
  'blog' => {},
151
151
  'production' => {
152
- 'keep' => {'local' => 3},
153
- 'gpg' => {'password' => 'custom-production-pass'},
154
- 'skip_tables' => ['logger_exceptions', 'request_logs']
155
- }
156
- }
152
+ 'keep' => {'local' => 3},
153
+ 'gpg' => {'password' => 'custom-production-pass'},
154
+ 'skip_tables' => ['logger_exceptions', 'request_logs'],
155
+ },
156
+ },
157
157
  },
158
158
 
159
159
  'pgdump' => {
@@ -166,15 +166,15 @@ describe WebTranslateIt::Safe::Config do
166
166
  'databases' => {
167
167
  'blog' => {},
168
168
  'production' => {
169
- 'keep' => {'local' => 3},
170
- 'skip_tables' => ['logger_exceptions', 'request_logs']
171
- }
172
- }
169
+ 'keep' => {'local' => 3},
170
+ 'skip_tables' => ['logger_exceptions', 'request_logs'],
171
+ },
172
+ },
173
173
  },
174
174
 
175
175
  'svndump' => {
176
176
  'repos' => {
177
- 'my_repo' => {
177
+ 'my_repo'=> {
178
178
  'repo_path' => '/home/svn/my_repo'
179
179
  }
180
180
  }
@@ -187,10 +187,10 @@ describe WebTranslateIt::Safe::Config do
187
187
  'dot-configs' => {'files' => ['/home/*/.[^.]*']},
188
188
  'blog' => {
189
189
  'files' => ['/var/www/blog.astrails.com/'],
190
- 'exclude' => ['/var/www/blog.astrails.com/log', '/var/www/blog.astrails.com/tmp']
190
+ 'exclude' => ['/var/www/blog.astrails.com/log', '/var/www/blog.astrails.com/tmp'],
191
191
  },
192
- 'misc' => {'files' => ['/backup/*.rb']}
193
- }
192
+ 'misc' => { 'files' => ['/backup/*.rb'] },
193
+ },
194
194
  },
195
195
 
196
196
  'mongodump' => {
@@ -206,7 +206,7 @@ describe WebTranslateIt::Safe::Config do
206
206
  config.to_hash.should == expected
207
207
  end
208
208
 
209
- it 'makes an array from multivalues' do
209
+ it 'should make an array from multivalues' do
210
210
  config = WebTranslateIt::Safe::Config::Node.new do
211
211
  skip_tables 'a'
212
212
  skip_tables 'b'
@@ -219,13 +219,13 @@ describe WebTranslateIt::Safe::Config do
219
219
  expected = {
220
220
  'skip_tables' => ['a', 'b'],
221
221
  'files' => ['/foo', '/bar'],
222
- 'exclude' => ['/foo/bar', '/foo/bar/baz']
222
+ 'exclude' => ['/foo/bar', '/foo/bar/baz'],
223
223
  }
224
224
 
225
225
  config.to_hash.should == expected
226
226
  end
227
227
 
228
- it 'raises error on key duplication' do
228
+ it 'should raise error on key duplication' do
229
229
  proc do
230
230
  WebTranslateIt::Safe::Config::Node.new do
231
231
  path 'foo'
@@ -234,7 +234,7 @@ describe WebTranslateIt::Safe::Config do
234
234
  end.should raise_error(ArgumentError, "duplicate value for 'path'")
235
235
  end
236
236
 
237
- it 'accepts hash as data' do
237
+ it 'should accept hash as data' do
238
238
  WebTranslateIt::Safe::Config::Node.new do
239
239
  tar do
240
240
  archive 'blog', files: 'foo', exclude: ['aaa', 'bbb']
@@ -251,7 +251,7 @@ describe WebTranslateIt::Safe::Config do
251
251
  }
252
252
  end
253
253
 
254
- it 'accepts hash as data and a block' do
254
+ it 'should accept hash as data and a block' do
255
255
  WebTranslateIt::Safe::Config::Node.new do
256
256
  tar do
257
257
  archive 'blog', files: 'foo' do
@@ -270,21 +270,21 @@ describe WebTranslateIt::Safe::Config do
270
270
  }
271
271
  end
272
272
 
273
- it 'accepts multiple levels of data hash' do
273
+ it 'should accept multiple levels of data hash' do
274
274
  config = WebTranslateIt::Safe::Config::Node.new nil, tar: {
275
- s3: {bucket: '_bucket', key: '_key', secret: '_secret'},
276
- keep: {s3: 2}
275
+ s3: { bucket: '_bucket', key: '_key', secret: '_secret', },
276
+ keep: { s3: 2 }
277
277
  }
278
278
 
279
279
  config.to_hash.should == {
280
280
  'tar' => {
281
- 's3' => {'bucket' => '_bucket', 'key' => '_key', 'secret' => '_secret'},
282
- 'keep' => {'s3' => 2}
281
+ 's3' => { 'bucket' => '_bucket', 'key' => '_key', 'secret' => '_secret', },
282
+ 'keep' => { 's3' => 2 }
283
283
  }
284
284
  }
285
285
  end
286
-
287
- it 'sets multi value as array' do
286
+
287
+ it 'should set multi value as array' do
288
288
  config = WebTranslateIt::Safe::Config::Node.new do
289
289
  tar do
290
290
  archive 'foo' do