simple_backup 0.2.1 → 0.3.0
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -1
- data/backup_example.rb +23 -13
- data/lib/simple_backup/backend/abstract.rb +35 -0
- data/lib/simple_backup/backend/local.rb +45 -0
- data/lib/simple_backup/backends.rb +60 -0
- data/lib/simple_backup/dsl.rb +26 -93
- data/lib/simple_backup/engine.rb +41 -3
- data/lib/simple_backup/source/abstract.rb +130 -0
- data/lib/simple_backup/source/dir.rb +39 -0
- data/lib/simple_backup/source/dir_strategy/bare.rb +17 -0
- data/lib/simple_backup/source/dir_strategy/capistrano.rb +41 -0
- data/lib/simple_backup/source/file.rb +20 -0
- data/lib/simple_backup/source/mysql.rb +28 -0
- data/lib/simple_backup/sources.rb +74 -0
- data/lib/simple_backup/utils/disk_usage.rb +53 -0
- data/lib/simple_backup/utils/logger.rb +92 -0
- data/lib/simple_backup/utils/mailer.rb +126 -0
- data/lib/simple_backup/utils/mysql.rb +65 -0
- data/lib/simple_backup/utils.rb +4 -53
- data/lib/simple_backup/version.rb +2 -2
- data/lib/simple_backup.rb +40 -5
- metadata +17 -19
- data/lib/simple_backup/engine/abstract.rb +0 -42
- data/lib/simple_backup/engine/app_strategy/abstract.rb +0 -13
- data/lib/simple_backup/engine/app_strategy/bare.rb +0 -29
- data/lib/simple_backup/engine/app_strategy/capistrano.rb +0 -44
- data/lib/simple_backup/engine/app_strategy/factory.rb +0 -20
- data/lib/simple_backup/engine/apps.rb +0 -63
- data/lib/simple_backup/engine/mysql.rb +0 -104
- data/lib/simple_backup/exception/app_already_defined.rb +0 -6
- data/lib/simple_backup/exception/apps_dir_does_not_exists.rb +0 -6
- data/lib/simple_backup/exception/base.rb +0 -6
- data/lib/simple_backup/exception/cant_create_dir.rb +0 -6
- data/lib/simple_backup/exception/type_does_not_exists.rb +0 -6
- data/lib/simple_backup/exception.rb +0 -5
- data/lib/simple_backup/logger.rb +0 -84
- data/lib/simple_backup/mailer.rb +0 -138
- data/lib/simple_backup/storage.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db18d1aeca0f0b1e397e8599de6ed70474fd49e1
|
4
|
+
data.tar.gz: 9e70279a4648074f77da59a0f070a869ce8c555d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d94e122a1bfab65a376e29087564568917c939149cec9d52c37d5905dd683687b033b1132fb28bcf6cf373da9f0fc3cb6492fd8cc30fe1c09bb2d38ef3412421
|
7
|
+
data.tar.gz: 00bb1b44ad48000765a9aa84817cc451772886beb03dc41e07a7503cbcf3d2e4d1293844de049caa6987d5d11a0221f57534453cafa9904ff4356d38eae1c54b
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,8 @@ development and its API should be treat as unstable.
|
|
9
9
|
## TODO
|
10
10
|
|
11
11
|
- [ ] Refactorization
|
12
|
-
- [ ] Few
|
12
|
+
- [ ] Few backends for backup store (file, s3, ftp)
|
13
|
+
- [ ] Filters mechanism (e.g. PGP encryption)
|
13
14
|
- [ ] Tests
|
14
15
|
- [ ] Docummentation and examples
|
15
16
|
|
data/backup_example.rb
CHANGED
@@ -1,31 +1,41 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
3
6
|
require 'simple_backup'
|
4
7
|
|
5
8
|
SimpleBackup.run do
|
6
|
-
|
7
|
-
|
9
|
+
log_level :debug
|
10
|
+
|
8
11
|
high_usage_treshold 0.9
|
9
12
|
check_disk_path '/'
|
10
13
|
check_disk_path '/backup'
|
11
14
|
check_disk_path '/home/app'
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
default_keep_last 9
|
17
|
+
|
18
|
+
sources do
|
19
|
+
dir 'app-1', '/home/app/app-1', type: :capistrano, backends: 'backup'
|
20
|
+
dir 'app-2', '/home/app/app-2', backends: :none
|
21
|
+
dir 'none', '/none'
|
22
|
+
|
23
|
+
file 'hosts', '/etc/hosts'
|
15
24
|
|
16
|
-
|
17
|
-
|
25
|
+
mysql 'test1', 'test1'
|
26
|
+
mysql 'test2', 'test2'
|
27
|
+
mysql 'test3', 'test3', exclude_tables: ['t_test1']
|
18
28
|
end
|
19
29
|
|
20
|
-
|
21
|
-
|
30
|
+
backends do
|
31
|
+
local 'backup', path: '/srv/backup'
|
32
|
+
end
|
22
33
|
|
34
|
+
mysql do
|
23
35
|
host 'localhost'
|
24
36
|
port 3306
|
25
|
-
user '
|
26
|
-
pass '
|
27
|
-
db 'test1'
|
28
|
-
db 'test2', exclude_tables: ['t_test1']
|
37
|
+
user 'root'
|
38
|
+
pass 'root'
|
29
39
|
end
|
30
40
|
|
31
41
|
mailer do
|
@@ -33,7 +43,7 @@ SimpleBackup.run do
|
|
33
43
|
|
34
44
|
from 'backup@localhost'
|
35
45
|
to 'root@localhost'
|
36
|
-
cc '
|
46
|
+
cc 'rb@localhost'
|
37
47
|
bcc 'root@localhost'
|
38
48
|
end
|
39
49
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SimpleBackup
|
2
|
+
module Backend
|
3
|
+
class Abstract
|
4
|
+
@@logger = Utils::Logger.instance
|
5
|
+
|
6
|
+
def configure(*args)
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def name=(value)
|
11
|
+
@name = value.gsub(/[^a-zA-Z0-9\-\_\. ]*/, '').gsub(/\s+/, '_').downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
@name
|
16
|
+
end
|
17
|
+
|
18
|
+
def type
|
19
|
+
self.class.name.split('::').last.gsub(/[^a-zA-Z0-9\-\_\. ]*/, '').gsub(/\s+/, '_').downcase
|
20
|
+
end
|
21
|
+
|
22
|
+
def desc
|
23
|
+
'%5s :: %s' % [type, @name]
|
24
|
+
end
|
25
|
+
|
26
|
+
def store(source)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def cleanup(source)
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SimpleBackup
|
2
|
+
module Backend
|
3
|
+
class Local < Abstract
|
4
|
+
def configure(options = {})
|
5
|
+
raise "Must provide :path option" unless options[:path]
|
6
|
+
|
7
|
+
@path = options[:path]
|
8
|
+
|
9
|
+
raise "#{@path} does not exists" unless ::File.exist?(@path)
|
10
|
+
raise "#{@path} is not a directory" unless ::File.directory?(@path)
|
11
|
+
raise "#{@path} is not writable" unless ::File.writable?(@path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def store(source)
|
15
|
+
storage_path = get_storage_path(source)
|
16
|
+
FileUtils.cp source.backup_file, storage_path
|
17
|
+
end
|
18
|
+
|
19
|
+
def cleanup(source)
|
20
|
+
storage_path = get_storage_path(source)
|
21
|
+
|
22
|
+
files = ::Dir.glob(::File.join(storage_path, '*.tar.gz')).sort
|
23
|
+
|
24
|
+
to_persist = files
|
25
|
+
to_persist = files.slice(source.keep_last * -1, source.keep_last) if files.length > source.keep_last
|
26
|
+
to_remove = files - to_persist
|
27
|
+
|
28
|
+
@@logger.scope_start
|
29
|
+
to_remove.each do |file|
|
30
|
+
FileUtils.rm(file)
|
31
|
+
@@logger.debug "Old backup '#{file}' for source '#{source.desc.strip}' cleaned up from '#{desc.strip}'"
|
32
|
+
end
|
33
|
+
@@logger.scope_end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def get_storage_path(source)
|
38
|
+
path = ::File.join(@path, source.type, source.name)
|
39
|
+
FileUtils.mkpath path unless ::File.exist?(path)
|
40
|
+
|
41
|
+
path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'simple_backup/backend/abstract'
|
3
|
+
|
4
|
+
module SimpleBackup
|
5
|
+
class Backends
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
@@logger = Utils::Logger.instance
|
9
|
+
@@sources = Sources.instance
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@backends = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
@backends.each(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def save_and_cleanup
|
20
|
+
each do |name, backend|
|
21
|
+
@@sources.each do |name, source|
|
22
|
+
next unless source.backup_file and source.supports(backend)
|
23
|
+
|
24
|
+
backend.store(source)
|
25
|
+
@@logger.info "Source '#{source.desc.strip}' stored in backend '#{backend.desc.strip}'"
|
26
|
+
|
27
|
+
backend.cleanup(source)
|
28
|
+
@@logger.info "Source '#{source.desc.strip}' cleaned up in backend '#{backend.desc.strip}'"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(method, *args)
|
34
|
+
backend = create_backend(method)
|
35
|
+
|
36
|
+
return nil if backend.nil?
|
37
|
+
|
38
|
+
name = args.shift
|
39
|
+
options = args.shift
|
40
|
+
options ||= {}
|
41
|
+
|
42
|
+
raise "Name '#{name}' for backend already used" if @backends.has_key?(name.to_sym)
|
43
|
+
|
44
|
+
backend.name = name
|
45
|
+
backend.configure(options)
|
46
|
+
|
47
|
+
@@logger.info "Created backend for: #{backend.desc}"
|
48
|
+
@backends[name.to_sym] = backend
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def create_backend(name)
|
53
|
+
file = "simple_backup/backend/#{name}"
|
54
|
+
|
55
|
+
require file
|
56
|
+
backend_name = Object.const_get("SimpleBackup::Backend::#{name.capitalize}")
|
57
|
+
backend_name.new
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/simple_backup/dsl.rb
CHANGED
@@ -1,120 +1,53 @@
|
|
1
1
|
module SimpleBackup
|
2
|
-
TIMESTAMP = Time.new.strftime('%Y%m%d%H%M%S')
|
3
|
-
@@status = :failed
|
4
|
-
|
5
|
-
def self.status
|
6
|
-
@@status
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.run(&block)
|
10
|
-
Logger::info "Backup #{TIMESTAMP} started"
|
11
|
-
|
12
|
-
dsl = DSL.new
|
13
|
-
|
14
|
-
Logger::scope_start :info, "Configuration"
|
15
|
-
dsl.instance_eval(&block)
|
16
|
-
dsl.prepare
|
17
|
-
Logger::scope_end
|
18
|
-
|
19
|
-
dsl.run
|
20
|
-
dsl.cleanup
|
21
|
-
@@status = :succeed
|
22
|
-
|
23
|
-
Logger::info "Backup #{TIMESTAMP} finished"
|
24
|
-
rescue StandardError => e
|
25
|
-
self.handle_exception(e)
|
26
|
-
ensure
|
27
|
-
dsl.notify
|
28
|
-
Logger::info "Notifications for backup #{TIMESTAMP} finished"
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.handle_exception(e)
|
32
|
-
Logger::error "#{e.class} => #{e.message}"
|
33
|
-
Logger::error "Backup #{TIMESTAMP} failed"
|
34
|
-
STDERR.puts "Error @ #{Time.new.strftime('%Y-%m-%dT%H:%M:%S')}"
|
35
|
-
STDERR.puts "#{e.inspect}"
|
36
|
-
STDERR.puts e.backtrace
|
37
|
-
end
|
38
|
-
|
39
2
|
class DSL
|
40
|
-
|
41
|
-
@storage = Storage.new
|
42
|
-
end
|
43
|
-
|
44
|
-
def prepare
|
45
|
-
if @apps_block
|
46
|
-
@apps = Engine::Apps.new
|
47
|
-
@apps.storage = @storage
|
48
|
-
@apps.instance_eval(&@apps_block)
|
49
|
-
end
|
50
|
-
|
51
|
-
if @mysql_block
|
52
|
-
@mysql = Engine::MySQL.new
|
53
|
-
@mysql.storage = @storage
|
54
|
-
@mysql.instance_eval(&@mysql_block)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def run
|
59
|
-
usage = Utils::Disk::usage
|
60
|
-
Logger::error "Disk high usage treshold exceeded #{usage[:high_usage]}" if usage[:high_usage_exceeded]
|
3
|
+
@@logger = Utils::Logger.instance
|
61
4
|
|
62
|
-
|
63
|
-
@
|
64
|
-
@mysql.backup if @mysql
|
65
|
-
Logger::scope_end
|
5
|
+
def initialize(engine)
|
6
|
+
@engine = engine
|
66
7
|
end
|
67
8
|
|
68
|
-
def
|
69
|
-
|
70
|
-
@apps.cleanup if @apps
|
71
|
-
@mysql.cleanup if @mysql
|
72
|
-
Logger::scope_end
|
73
|
-
end
|
74
|
-
|
75
|
-
def notify
|
76
|
-
@mailer.send if @mailer
|
77
|
-
rescue StandardError => e
|
78
|
-
SimpleBackup.handle_exception(e)
|
9
|
+
def log_level(level)
|
10
|
+
@@logger.level = level
|
79
11
|
end
|
80
12
|
|
81
|
-
def
|
82
|
-
|
83
|
-
sources[:apps] = @apps.sources if @apps
|
84
|
-
sources[:mysql] = @mysql.sources if @mysql
|
13
|
+
def high_usage_treshold(value)
|
14
|
+
@@logger.info "Setting high_usage_treshold to #{value}"
|
85
15
|
|
86
|
-
|
16
|
+
Utils::Disk.high_usage_treshold = value
|
87
17
|
end
|
88
18
|
|
89
|
-
def
|
90
|
-
|
91
|
-
end
|
19
|
+
def check_disk_path(path)
|
20
|
+
@@logger.info "Adding disk path '#{path}' to usage check"
|
92
21
|
|
93
|
-
|
94
|
-
@storage.dir = dir
|
22
|
+
Utils::Disk.add_path(path)
|
95
23
|
end
|
96
24
|
|
97
|
-
def
|
98
|
-
|
99
|
-
Utils::Disk.high_usage_treshold = value
|
25
|
+
def default_keep_last(value)
|
26
|
+
Sources.instance.default_keep_last = value
|
100
27
|
end
|
101
28
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
29
|
+
def sources(&block)
|
30
|
+
sources = Sources.instance
|
31
|
+
sources.instance_eval(&block)
|
105
32
|
end
|
106
33
|
|
107
|
-
def
|
108
|
-
|
34
|
+
def backends(&block)
|
35
|
+
backends = Backends.instance
|
36
|
+
backends.instance_eval(&block)
|
109
37
|
end
|
110
38
|
|
111
39
|
def mysql(&block)
|
112
|
-
|
40
|
+
@@logger.info "Configuring MySQL Util"
|
41
|
+
|
42
|
+
Utils::MySQL.instance.instance_eval(&block)
|
113
43
|
end
|
114
44
|
|
115
45
|
def mailer(&block)
|
116
|
-
|
46
|
+
@@logger.info "Configuring Mailer Util"
|
47
|
+
|
48
|
+
@mailer = Utils::Mailer.new
|
117
49
|
@mailer.instance_eval(&block)
|
50
|
+
@engine.mailer = @mailer
|
118
51
|
end
|
119
52
|
end
|
120
53
|
end
|
data/lib/simple_backup/engine.rb
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module SimpleBackup
|
2
|
+
module Engine
|
3
|
+
class Engine
|
4
|
+
|
5
|
+
@@backends = Backends.instance
|
6
|
+
@@sources = Sources.instance
|
7
|
+
@@logger = Utils::Logger.instance
|
8
|
+
@@mysql = Utils::MySQL.instance
|
9
|
+
|
10
|
+
def mailer=(mailer)
|
11
|
+
@mailer = mailer
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
usage = Utils::Disk::usage
|
16
|
+
|
17
|
+
@@logger.error "Disk high usage treshold exceeded #{usage[:high_usage]}" if usage[:high_usage_exceeded]
|
18
|
+
@@logger.scope_start :info, "Backup"
|
19
|
+
|
20
|
+
@@sources.backup
|
21
|
+
@@backends.save_and_cleanup
|
22
|
+
@@sources.cleanup
|
23
|
+
|
24
|
+
@@logger.scope_end
|
25
|
+
ensure
|
26
|
+
@@mysql.close
|
27
|
+
end
|
28
|
+
|
29
|
+
def notify
|
30
|
+
return unless @mailer
|
31
|
+
@@logger.scope_start :info, "Sending e-mail notification"
|
32
|
+
|
33
|
+
@mailer.send
|
34
|
+
|
35
|
+
@@logger.scope_end :info, "Notifications for backup #{TIMESTAMP} finished"
|
36
|
+
rescue StandardError => e
|
37
|
+
SimpleBackup.handle_exception(e)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'rubygems/package'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'zlib'
|
4
|
+
|
5
|
+
module SimpleBackup
|
6
|
+
module Source
|
7
|
+
class Abstract
|
8
|
+
@@logger = Utils::Logger.instance
|
9
|
+
|
10
|
+
def configure(*args)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def keep_last=(value)
|
15
|
+
@keep_last = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def keep_last
|
19
|
+
@keep_last
|
20
|
+
end
|
21
|
+
|
22
|
+
def name=(value)
|
23
|
+
@name = value.gsub(/[^a-zA-Z0-9\-\_\. ]*/, '').gsub(/\s+/, '_').downcase
|
24
|
+
end
|
25
|
+
|
26
|
+
def name
|
27
|
+
@name
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
self.class.name.split('::').last.gsub(/[^a-zA-Z0-9\-\_\. ]*/, '').gsub(/\s+/, '_').downcase
|
32
|
+
end
|
33
|
+
|
34
|
+
def desc
|
35
|
+
'%5s :: %s' % [type, @name]
|
36
|
+
end
|
37
|
+
|
38
|
+
def get
|
39
|
+
return @backup_file if @backup_file
|
40
|
+
|
41
|
+
@@logger.scope_start :info, "Getting archive for: #{desc}"
|
42
|
+
|
43
|
+
@tmp_dir = ::Dir.mktmpdir('simple_backup-')
|
44
|
+
@@logger.debug "Created tmp directory #{@tmp_dir}"
|
45
|
+
|
46
|
+
data_exists = prepare_data
|
47
|
+
|
48
|
+
@@logger.warning "No data for: #{desc}" unless data_exists
|
49
|
+
archive_data if data_exists
|
50
|
+
|
51
|
+
FileUtils.rm_rf(@tmp_dir)
|
52
|
+
@@logger.debug "Removed tmp directory #{@tmp_dir}"
|
53
|
+
|
54
|
+
@backup_file
|
55
|
+
ensure
|
56
|
+
@@logger.scope_end
|
57
|
+
end
|
58
|
+
|
59
|
+
def cleanup
|
60
|
+
return nil unless @backup_file
|
61
|
+
|
62
|
+
FileUtils.rm (@backup_file)
|
63
|
+
@@logger.debug "Temporary backup file #{@backup_file} was removed"
|
64
|
+
end
|
65
|
+
|
66
|
+
def backup_file
|
67
|
+
@backup_file
|
68
|
+
end
|
69
|
+
|
70
|
+
def backends=(value)
|
71
|
+
@backends = []
|
72
|
+
@backends = @backends + value if value.kind_of?(Array)
|
73
|
+
@backends << value unless value.kind_of?(Array)
|
74
|
+
end
|
75
|
+
|
76
|
+
def supports(backend)
|
77
|
+
return TRUE unless @backends
|
78
|
+
return FALSE unless @backends.include?(backend.name)
|
79
|
+
|
80
|
+
TRUE
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def prepare_data
|
85
|
+
raise NotImplementedError
|
86
|
+
end
|
87
|
+
|
88
|
+
def archive_data
|
89
|
+
filename = "#{type}-#{name}.#{SimpleBackup::TIMESTAMP}.tar.gz"
|
90
|
+
@backup_file = ::File.join(::Dir.tmpdir, filename)
|
91
|
+
|
92
|
+
::File.open(backup_file, 'w') do |f|
|
93
|
+
f.write targz.string
|
94
|
+
end
|
95
|
+
|
96
|
+
@@logger.debug "Backup saved to temporary file #{backup_file}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def targz
|
100
|
+
path = @tmp_dir
|
101
|
+
|
102
|
+
content = StringIO.new('');
|
103
|
+
Gem::Package::TarWriter.new(content) do |tar|
|
104
|
+
::Dir[::File.join(path, '**/*')].each do |file|
|
105
|
+
mode = ::File.stat(file).mode
|
106
|
+
relative_file = file.sub(/^#{Regexp::escape path}\/?/, '')
|
107
|
+
|
108
|
+
if ::File.directory?(file)
|
109
|
+
tar.mkdir(relative_file, mode)
|
110
|
+
else
|
111
|
+
tar.add_file relative_file, mode do |tf|
|
112
|
+
::File.open(file, 'rb') do |f|
|
113
|
+
tf.write f.read
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
content.rewind
|
120
|
+
|
121
|
+
gz = StringIO.new('')
|
122
|
+
zip = Zlib::GzipWriter.new(gz)
|
123
|
+
zip.write content.string
|
124
|
+
zip.close
|
125
|
+
|
126
|
+
gz
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SimpleBackup
|
2
|
+
module Source
|
3
|
+
class Dir < Abstract
|
4
|
+
def initialize
|
5
|
+
@strategy = :bare
|
6
|
+
end
|
7
|
+
|
8
|
+
def configure(path, options = {})
|
9
|
+
@path = path
|
10
|
+
|
11
|
+
raise "#{path} is a file - use File source instead of Dir" unless !::File.exist?(path) or ::File.directory?(path)
|
12
|
+
@strategy = options[:strategy] if options[:strategy]
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def prepare_data
|
17
|
+
return false unless ::File.exist?(@path)
|
18
|
+
|
19
|
+
path_entries = get_path_entries
|
20
|
+
FileUtils.cp_r path_entries, @tmp_dir if path_entries
|
21
|
+
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_path_entries
|
26
|
+
file = "simple_backup/source/dir_strategy/#{@strategy.to_s}"
|
27
|
+
|
28
|
+
require file
|
29
|
+
strategy_name = Object.const_get("SimpleBackup::Source::DirStrategy::#{@strategy.to_s.capitalize}")
|
30
|
+
strategy = strategy_name.new
|
31
|
+
|
32
|
+
strategy.get_entries(@path)
|
33
|
+
rescue Errno::ENOENT
|
34
|
+
@@logger.warning "Path '#{@path}' does not exists"
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SimpleBackup
|
2
|
+
module Source
|
3
|
+
module DirStrategy
|
4
|
+
class Capistrano
|
5
|
+
@@logger = Utils::Logger.instance
|
6
|
+
|
7
|
+
def get_entries(path)
|
8
|
+
shared = shared_path(path)
|
9
|
+
current = current_path(path)
|
10
|
+
paths = [current, shared].compact
|
11
|
+
|
12
|
+
if paths.empty?
|
13
|
+
@@logger.warning "No capistrano paths for application"
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
paths
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def current_path(path)
|
22
|
+
current = ::Dir.new(::File.join(path, 'current') + '/')
|
23
|
+
@@logger.debug "Capistrano current path: #{current.path}"
|
24
|
+
current.path
|
25
|
+
rescue Errno::ENOENT
|
26
|
+
@@logger.warning "No capistrano current path for application"
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def shared_path(path)
|
31
|
+
shared = ::Dir.new(::File.join(path, 'shared'))
|
32
|
+
@@logger.debug "Capistrano shared path: #{shared.path}"
|
33
|
+
shared.path
|
34
|
+
rescue Errno::ENOENT
|
35
|
+
@@logger.warning "No capistrano shared path for application"
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SimpleBackup
|
2
|
+
module Source
|
3
|
+
class File < Abstract
|
4
|
+
def configure(path, options = {})
|
5
|
+
@path = path
|
6
|
+
|
7
|
+
raise "#{path} is a directory - use Dir source instead of File" unless !::File.exist?(path) or ::File.file?(path)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def prepare_data
|
12
|
+
return false unless ::File.exist?(@path)
|
13
|
+
|
14
|
+
FileUtils.cp @path, @tmp_dir
|
15
|
+
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|