webtranslateit-safe 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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