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
@@ -1,29 +0,0 @@
|
|
1
|
-
module SimpleBackup
|
2
|
-
module Engine
|
3
|
-
module AppStrategy
|
4
|
-
class Bare < Abstract
|
5
|
-
def backup(name, path, attr)
|
6
|
-
app_elements = get_path_entries(path).map do |p|
|
7
|
-
if p.match(/^\.\.?$/)
|
8
|
-
nil
|
9
|
-
else
|
10
|
-
File.join(path, p)
|
11
|
-
end
|
12
|
-
end.compact
|
13
|
-
|
14
|
-
@storage.backup do |dir|
|
15
|
-
FileUtils.cp_r app_elements, dir
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
def get_path_entries(path)
|
21
|
-
Dir.entries(path)
|
22
|
-
rescue Errno::ENOENT
|
23
|
-
Logger::warning "App path does not exists"
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module SimpleBackup
|
2
|
-
module Engine
|
3
|
-
module AppStrategy
|
4
|
-
class Capistrano < Abstract
|
5
|
-
def backup(name, path, attr)
|
6
|
-
shared = get_shared_path(path, attr)
|
7
|
-
current = get_current_path(path, attr)
|
8
|
-
|
9
|
-
paths = [current, shared].compact
|
10
|
-
|
11
|
-
if paths.empty?
|
12
|
-
Logger::warning "No capistrano paths for application"
|
13
|
-
return false
|
14
|
-
end
|
15
|
-
|
16
|
-
@storage.backup do |dir|
|
17
|
-
FileUtils.cp_r paths, dir
|
18
|
-
end
|
19
|
-
|
20
|
-
true
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def get_current_path(path, attr)
|
25
|
-
current = Dir.new(File.join(path, attr[:current] || 'current') + '/')
|
26
|
-
Logger::debug "Capistrano current path: #{current.path}"
|
27
|
-
current
|
28
|
-
rescue Errno::ENOENT
|
29
|
-
Logger::warning "No capistrano current path for application"
|
30
|
-
nil
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_shared_path(path, attr)
|
34
|
-
shared = Dir.new(File.join(path, attr[:shared] || 'shared'))
|
35
|
-
Logger::debug "Capistrano shared path: #{shared.path}"
|
36
|
-
shared
|
37
|
-
rescue Errno::ENOENT
|
38
|
-
Logger::warning "No capistrano shared path for application"
|
39
|
-
nil
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'simple_backup/engine/app_strategy/abstract'
|
2
|
-
|
3
|
-
module SimpleBackup
|
4
|
-
module Engine
|
5
|
-
module AppStrategy
|
6
|
-
class Factory
|
7
|
-
@@types = [:bare, :capistrano]
|
8
|
-
|
9
|
-
def self.create(type)
|
10
|
-
raise Exception::TypeDoesNotExists.new "Strategy type '#{type}' does not exists" unless @@types.include?(type)
|
11
|
-
file = "simple_backup/engine/app_strategy/#{type.to_s}"
|
12
|
-
|
13
|
-
require file
|
14
|
-
strategy = Object.const_get("SimpleBackup::Engine::AppStrategy::#{type.to_s.capitalize}")
|
15
|
-
strategy.new
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'simple_backup/engine/app_strategy/factory'
|
2
|
-
|
3
|
-
module SimpleBackup
|
4
|
-
module Engine
|
5
|
-
class Apps < Abstract
|
6
|
-
def initialize
|
7
|
-
@apps = {}
|
8
|
-
@strategies = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
def app(path, attr = {})
|
12
|
-
Logger::debug "Adding application #{path} #{attr}"
|
13
|
-
raise Exception::AppAlreadyDefined.new "Application '#{path}' is already defined" if @apps.has_key?(path)
|
14
|
-
|
15
|
-
@apps[path] = attr
|
16
|
-
end
|
17
|
-
|
18
|
-
def backup
|
19
|
-
@apps.each do |path, attr|
|
20
|
-
next unless app_exists(path)
|
21
|
-
backup_app(path, attr)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def sources
|
26
|
-
sources = []
|
27
|
-
@apps.each do |path, attr|
|
28
|
-
sources << path
|
29
|
-
end
|
30
|
-
|
31
|
-
sources
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
def backup_app(path, attr)
|
36
|
-
name = path.split('/').last
|
37
|
-
Logger::scope_start :info, "Backup of application #{name} started"
|
38
|
-
Logger::debug "name: #{name}, attr: #{attr}"
|
39
|
-
|
40
|
-
strategy = get_strategy(attr[:type])
|
41
|
-
strategy.storage = @storage.space(name)
|
42
|
-
is_backuped = strategy.backup(name, path, attr)
|
43
|
-
|
44
|
-
Logger::scope_end :info, "Backup of application #{name} finished" if is_backuped
|
45
|
-
Logger::scope_end :info, "Backup of application #{name} skipped" unless is_backuped
|
46
|
-
end
|
47
|
-
|
48
|
-
def app_exists(path)
|
49
|
-
Dir.new(path)
|
50
|
-
true
|
51
|
-
rescue Errno::ENOENT
|
52
|
-
Logger::warning "App path '#{path}' does not exists"
|
53
|
-
false
|
54
|
-
end
|
55
|
-
|
56
|
-
def get_strategy(type)
|
57
|
-
return @strategies[type] if @strategies.has_key?(type)
|
58
|
-
|
59
|
-
AppStrategy::Factory.create(type)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
require 'mysql2'
|
2
|
-
|
3
|
-
module SimpleBackup
|
4
|
-
module Engine
|
5
|
-
class MySQL < Abstract
|
6
|
-
def initialize
|
7
|
-
@host = 'localhost'
|
8
|
-
@port = 3306
|
9
|
-
@user = nil
|
10
|
-
@pass = nil
|
11
|
-
@dbs = {}
|
12
|
-
end
|
13
|
-
|
14
|
-
def host(host)
|
15
|
-
@host = host
|
16
|
-
end
|
17
|
-
|
18
|
-
def port(port)
|
19
|
-
@port = port
|
20
|
-
end
|
21
|
-
|
22
|
-
def user(user)
|
23
|
-
@user = user
|
24
|
-
end
|
25
|
-
|
26
|
-
def pass(pass)
|
27
|
-
@pass = pass
|
28
|
-
end
|
29
|
-
|
30
|
-
def db(name, attr = {})
|
31
|
-
Logger::debug "Adding database #{name} #{attr}"
|
32
|
-
raise Exception::AppAlreadyDefined.new "Database '#{name}' is already defined" if @dbs.has_key?(name)
|
33
|
-
|
34
|
-
@dbs[name] = attr
|
35
|
-
end
|
36
|
-
|
37
|
-
def backup
|
38
|
-
@conn = Mysql2::Client.new(host: @host, username: @user, password: @pass, port: @port)
|
39
|
-
|
40
|
-
prepare_tables
|
41
|
-
return if @dbs.empty?
|
42
|
-
|
43
|
-
@storage.backup do |dir|
|
44
|
-
@dbs.each do |db, attr|
|
45
|
-
dump_db(dir, db, attr)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
ensure
|
49
|
-
@conn.close unless @conn.nil?
|
50
|
-
end
|
51
|
-
|
52
|
-
def sources
|
53
|
-
sources = []
|
54
|
-
@dbs.each do |db, attr|
|
55
|
-
sources << db
|
56
|
-
end
|
57
|
-
|
58
|
-
sources
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
def prepare_tables
|
63
|
-
@existing_dbs = []
|
64
|
-
@conn.query("SHOW DATABASES").each do |row|
|
65
|
-
@existing_dbs << row['Database']
|
66
|
-
end
|
67
|
-
|
68
|
-
dbs = {}
|
69
|
-
@dbs.each do |db, attr|
|
70
|
-
dbs[db] = attr if check_database_exists?(db)
|
71
|
-
end
|
72
|
-
|
73
|
-
@dbs = dbs
|
74
|
-
@dbs.each do |db, attr|
|
75
|
-
tables = []
|
76
|
-
@conn.query("SHOW TABLES FROM `#{db}`").each do |row|
|
77
|
-
tables << row["Tables_in_#{db}"]
|
78
|
-
end
|
79
|
-
tables = tables - attr[:exclude_tables] if attr[:exclude_tables]
|
80
|
-
|
81
|
-
@dbs[db][:tables] ||= tables
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def check_database_exists?(db)
|
86
|
-
if @existing_dbs.include?(db)
|
87
|
-
return true
|
88
|
-
end
|
89
|
-
Logger::warning "Database '#{db}' does not exists"
|
90
|
-
end
|
91
|
-
|
92
|
-
def dump_db(dir, db, attr)
|
93
|
-
Logger::scope_start :info, "Backup of mysql database #{db} started"
|
94
|
-
|
95
|
-
file = File.join(dir, db) + '.sql'
|
96
|
-
cmd = "mysqldump --flush-logs --flush-privileges --order-by-primary --complete-insert -C -h #{@host} -u #{@user} -p#{@pass} #{db} #{attr[:tables].join(' ')} > #{file}"
|
97
|
-
Logger::debug "Running command: #{cmd}"
|
98
|
-
`#{cmd}`
|
99
|
-
|
100
|
-
Logger::scope_end :info, "Backup of mysql database #{db} finished"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
data/lib/simple_backup/logger.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'colorize'
|
2
|
-
|
3
|
-
module SimpleBackup
|
4
|
-
class Logger
|
5
|
-
TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
|
6
|
-
|
7
|
-
@@buffer = []
|
8
|
-
@@scope = 0
|
9
|
-
@@level = :info
|
10
|
-
@@levels = {
|
11
|
-
debug: {weight: 3, color: :light_cyan},
|
12
|
-
info: {weight: 2, color: :green},
|
13
|
-
warning: {weight: 1, color: :light_yellow},
|
14
|
-
error: {weight: 0, color: :red}
|
15
|
-
}
|
16
|
-
|
17
|
-
banner = "LOG STARTED #{Time.new.strftime('%Y-%m-%dT%H:%M:%S')}"
|
18
|
-
banner2 = "SimpleBackup v#{SimpleBackup::Version::get}"
|
19
|
-
|
20
|
-
banner_length = 0
|
21
|
-
banner_length = banner.length if banner.length > banner_length
|
22
|
-
banner_length = banner2.length if banner2.length > banner_length
|
23
|
-
banner_length = 80 if 80 > banner_length
|
24
|
-
|
25
|
-
border = '=' * ((banner_length - banner.length) / 2).ceil.to_i
|
26
|
-
@@buffer << "#{border}==[ #{banner} ]==#{border}"
|
27
|
-
border = '=' * ((banner_length - banner2.length) / 2).ceil.to_i
|
28
|
-
@@buffer << "#{border}==[ #{banner2} ]==#{border}"
|
29
|
-
puts @@buffer[0].green
|
30
|
-
puts @@buffer[1].green
|
31
|
-
|
32
|
-
def self.level=(level)
|
33
|
-
self.check_level(level)
|
34
|
-
@@level = level
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.scope_start(level = nil, message = nil)
|
38
|
-
self.log level, message unless level.nil? and message.nil?
|
39
|
-
@@scope += 1
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.scope_end(level = nil, message = nil)
|
43
|
-
self.log level, message unless level.nil? and message.nil?
|
44
|
-
@@scope -= 1
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.debug(message)
|
48
|
-
self.log(:debug, message)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.info(message)
|
52
|
-
self.log(:info, message)
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.warning(message)
|
56
|
-
self.log(:warning, message)
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.error(message)
|
60
|
-
self.log(:error, message)
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.log(level, message)
|
64
|
-
self.check_level(level)
|
65
|
-
|
66
|
-
color = @@levels[level][:color]
|
67
|
-
should_write = @@levels[level][:weight] <= @@levels[@@level][:weight]
|
68
|
-
|
69
|
-
scope_prefix = '..' * @@scope
|
70
|
-
message = "%s %7s: %s%s" % [Time.new.strftime(TIME_FORMAT), level.to_s.upcase, scope_prefix, message]
|
71
|
-
@@buffer << message
|
72
|
-
|
73
|
-
puts message.colorize(color: color) if should_write
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.check_level(level)
|
77
|
-
raise "Unknown logging level #{level}" unless @@levels.has_key?(level)
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.buffer
|
81
|
-
@@buffer
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
data/lib/simple_backup/mailer.rb
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
require 'mail'
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
module SimpleBackup
|
5
|
-
class Mailer
|
6
|
-
def initialize(dsl, storage)
|
7
|
-
@dsl = dsl
|
8
|
-
@storage = storage
|
9
|
-
|
10
|
-
@to = []
|
11
|
-
@cc = []
|
12
|
-
@bcc = []
|
13
|
-
@hostname = Socket.gethostbyname(Socket.gethostname).first
|
14
|
-
end
|
15
|
-
|
16
|
-
def subject_prefix(prefix)
|
17
|
-
@subject_prefix = prefix
|
18
|
-
end
|
19
|
-
|
20
|
-
def from(from)
|
21
|
-
@from = from
|
22
|
-
end
|
23
|
-
|
24
|
-
def to(to)
|
25
|
-
@to << to
|
26
|
-
end
|
27
|
-
|
28
|
-
def cc(cc)
|
29
|
-
@cc << cc
|
30
|
-
end
|
31
|
-
|
32
|
-
def bcc(bcc)
|
33
|
-
@bcc << bcc
|
34
|
-
end
|
35
|
-
|
36
|
-
def send
|
37
|
-
Logger::scope_start :info, "Sending e-mail notification"
|
38
|
-
|
39
|
-
Logger::info "Setting sender to: #{@from}"
|
40
|
-
from = @from
|
41
|
-
Logger::scope_start :info, "Adding recipients:"
|
42
|
-
to = @to
|
43
|
-
to.each do |mail|
|
44
|
-
Logger::info "to: #{mail}"
|
45
|
-
end
|
46
|
-
cc = @cc
|
47
|
-
cc.each do |mail|
|
48
|
-
Logger::info "cc: #{mail}"
|
49
|
-
end
|
50
|
-
bcc = @bcc
|
51
|
-
bcc.each do |mail|
|
52
|
-
Logger::info "bcc: #{mail}"
|
53
|
-
end
|
54
|
-
Logger::scope_end
|
55
|
-
|
56
|
-
@subject_prefix += '[FAILED]' if SimpleBackup.status == :failed
|
57
|
-
|
58
|
-
subject = "%s Backup %s for %s" % [@subject_prefix, TIMESTAMP, @hostname]
|
59
|
-
Logger::debug "Subject: #{subject}"
|
60
|
-
|
61
|
-
body = get_body
|
62
|
-
|
63
|
-
mail = Mail.new do
|
64
|
-
from from
|
65
|
-
to to
|
66
|
-
cc cc
|
67
|
-
bcc bcc
|
68
|
-
subject subject.strip
|
69
|
-
body body
|
70
|
-
end
|
71
|
-
|
72
|
-
mail.delivery_method :sendmail
|
73
|
-
Logger::debug "Setting delivery method to sendmail"
|
74
|
-
|
75
|
-
mail.deliver
|
76
|
-
Logger::info "Notification sent"
|
77
|
-
|
78
|
-
Logger::scope_end
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
def get_body
|
83
|
-
sources = ''
|
84
|
-
@dsl.sources.each do |type, srcs|
|
85
|
-
sources += "+ %s:\n" % type.to_s
|
86
|
-
srcs.each do |src|
|
87
|
-
sources += " - %s\n" % src
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
backup_files = ''
|
92
|
-
@storage.created_files.each do |file|
|
93
|
-
backup_files += "- %s\n" % file
|
94
|
-
end
|
95
|
-
|
96
|
-
body = <<MAIL
|
97
|
-
Hi,
|
98
|
-
|
99
|
-
Backup #{TIMESTAMP} was created!
|
100
|
-
|
101
|
-
Backup contains:
|
102
|
-
#{sources}
|
103
|
-
Created backup files:
|
104
|
-
#{backup_files}
|
105
|
-
Disk usage after backup:
|
106
|
-
#{disk_usage}
|
107
|
-
Backup log:
|
108
|
-
------------
|
109
|
-
#{Logger::buffer.join("\n")}
|
110
|
-
------------
|
111
|
-
|
112
|
-
Have a nice day,
|
113
|
-
Backuper
|
114
|
-
|
115
|
-
--
|
116
|
-
Mail was send automatically
|
117
|
-
Do not respond!
|
118
|
-
MAIL
|
119
|
-
|
120
|
-
body
|
121
|
-
end
|
122
|
-
|
123
|
-
def disk_usage
|
124
|
-
content = "%16s %25s %12s %12s %12s %12s\n" % ['Mount', 'Filesystem', 'Size', 'Used', 'Available', 'Percent used']
|
125
|
-
|
126
|
-
usage = Utils::Disk::usage
|
127
|
-
usage[:mounts].each do |m|
|
128
|
-
percent_usage = (m[:percent] * 100).to_s
|
129
|
-
percent_usage = '(!!) ' + percent_usage if m[:high_usage_exceeded]
|
130
|
-
content += "%16s %25s %8s MiB %8s MiB %8s MiB %11s%%\n" % [m[:mount], m[:fs], m[:size], m[:used], m[:available], percent_usage]
|
131
|
-
end
|
132
|
-
|
133
|
-
content += "\nHigh usage treshold exceeded!\nMax usage is #{usage[:high_usage]} where treshold is set to #{Utils::Disk::high_usage_treshold}\n" if usage[:high_usage_exceeded]
|
134
|
-
|
135
|
-
content
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'rubygems/package'
|
2
|
-
require 'zlib'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
module SimpleBackup
|
6
|
-
class Storage
|
7
|
-
attr_accessor :dir
|
8
|
-
|
9
|
-
@@created_files = []
|
10
|
-
|
11
|
-
def dir=(dir)
|
12
|
-
@dir = get_dir(dir)
|
13
|
-
|
14
|
-
Logger::info "Backup dir set to '#{dir}'"
|
15
|
-
end
|
16
|
-
|
17
|
-
def space(space)
|
18
|
-
Logger::debug "Setting backup_dir for space '#{space}'"
|
19
|
-
storage = Storage.new
|
20
|
-
storage.dir = File.join(@dir.path, format_for_path(space))
|
21
|
-
storage
|
22
|
-
end
|
23
|
-
|
24
|
-
def backup
|
25
|
-
dir = get_dir(File.join(@dir, TIMESTAMP))
|
26
|
-
yield(dir)
|
27
|
-
|
28
|
-
targz = targz(dir)
|
29
|
-
backup_file = File.join(@dir, TIMESTAMP) + '.tar.gz'
|
30
|
-
|
31
|
-
File.open(backup_file, 'w') do |f|
|
32
|
-
f.write targz.string
|
33
|
-
end
|
34
|
-
|
35
|
-
FileUtils.rm_r dir.path
|
36
|
-
|
37
|
-
@@created_files.push backup_file
|
38
|
-
backup_file
|
39
|
-
end
|
40
|
-
|
41
|
-
def created_files
|
42
|
-
@@created_files
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
def get_dir(dir)
|
47
|
-
tries ||= 2
|
48
|
-
Dir.new(dir)
|
49
|
-
rescue Errno::ENOENT
|
50
|
-
recreate_dir(dir)
|
51
|
-
retry unless (tries -= 1).zero?
|
52
|
-
end
|
53
|
-
|
54
|
-
def recreate_dir(dir)
|
55
|
-
Dir.mkdir(dir, 0755)
|
56
|
-
|
57
|
-
Logger::warning "Recreated non-existing directory '#{dir}'"
|
58
|
-
rescue Errno::EACCES => e
|
59
|
-
raise Exception::CantCreateDir.new(e.message)
|
60
|
-
end
|
61
|
-
|
62
|
-
def format_for_path(value)
|
63
|
-
value.downcase.gsub(/[^a-zA-Z0-9\-\_\.]*/, '').gsub(/\s+/, '_')
|
64
|
-
end
|
65
|
-
|
66
|
-
def targz(dir)
|
67
|
-
path = dir.path
|
68
|
-
content = StringIO.new('');
|
69
|
-
Gem::Package::TarWriter.new(content) do |tar|
|
70
|
-
Dir[File.join(path, '**/*')].each do |file|
|
71
|
-
mode = File.stat(file).mode
|
72
|
-
relative_file = file.sub(/^#{Regexp::escape path}\/?/, '')
|
73
|
-
|
74
|
-
if File.directory?(file)
|
75
|
-
tar.mkdir(relative_file, mode)
|
76
|
-
else
|
77
|
-
tar.add_file relative_file, mode do |tf|
|
78
|
-
File.open(file, 'rb') do |f|
|
79
|
-
tf.write f.read
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
content.rewind
|
87
|
-
|
88
|
-
gz = StringIO.new('')
|
89
|
-
zip = Zlib::GzipWriter.new(gz)
|
90
|
-
zip.write content.string
|
91
|
-
zip.close
|
92
|
-
|
93
|
-
gz
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|