siba 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/Guardfile +18 -0
- data/LICENSE +22 -0
- data/README.md +47 -0
- data/Rakefile +27 -0
- data/bin/siba +5 -0
- data/lib/siba.rb +27 -0
- data/lib/siba/backup.rb +31 -0
- data/lib/siba/console.rb +196 -0
- data/lib/siba/errors.rb +8 -0
- data/lib/siba/generator.rb +115 -0
- data/lib/siba/globals.rb +19 -0
- data/lib/siba/helpers/encoding_helper.rb +38 -0
- data/lib/siba/helpers/file_helper.rb +89 -0
- data/lib/siba/helpers/gem_helper.rb +22 -0
- data/lib/siba/helpers/password_strength.rb +94 -0
- data/lib/siba/helpers/security_helper.rb +30 -0
- data/lib/siba/helpers/string_helper.rb +32 -0
- data/lib/siba/helpers/test/extend_test.rb +114 -0
- data/lib/siba/helpers/test/file_mock.rb +38 -0
- data/lib/siba/helpers/test/helper.rb +55 -0
- data/lib/siba/helpers/test/kernel_mock.rb +44 -0
- data/lib/siba/helpers/test/removable_constants.rb +18 -0
- data/lib/siba/helpers/test/require.rb +12 -0
- data/lib/siba/logger_plug.rb +36 -0
- data/lib/siba/options_backup.rb +37 -0
- data/lib/siba/options_loader.rb +38 -0
- data/lib/siba/plugins/archive/tar/archive.rb +117 -0
- data/lib/siba/plugins/archive/tar/init.rb +38 -0
- data/lib/siba/plugins/archive/tar/options.yml +1 -0
- data/lib/siba/plugins/destination/dir/dest_dir.rb +77 -0
- data/lib/siba/plugins/destination/dir/init.rb +31 -0
- data/lib/siba/plugins/destination/dir/options.yml +2 -0
- data/lib/siba/plugins/encryption/gpg/encryption.rb +140 -0
- data/lib/siba/plugins/encryption/gpg/init.rb +45 -0
- data/lib/siba/plugins/encryption/gpg/options.yml +2 -0
- data/lib/siba/plugins/installed_plugins.rb +77 -0
- data/lib/siba/plugins/plugin_loader.rb +100 -0
- data/lib/siba/plugins/plugins.rb +57 -0
- data/lib/siba/plugins/plugins.yml +9 -0
- data/lib/siba/plugins/source/files/files.rb +166 -0
- data/lib/siba/plugins/source/files/init.rb +33 -0
- data/lib/siba/plugins/source/files/options.yml +11 -0
- data/lib/siba/restore.rb +113 -0
- data/lib/siba/scaffold.rb +166 -0
- data/lib/siba/siba_check.rb +75 -0
- data/lib/siba/siba_file.rb +89 -0
- data/lib/siba/siba_kernel.rb +37 -0
- data/lib/siba/siba_logger.rb +172 -0
- data/lib/siba/tasks/siba_task.rb +42 -0
- data/lib/siba/tasks/siba_tasks.rb +120 -0
- data/lib/siba/test_files.rb +76 -0
- data/lib/siba/test_files/a_file +1 -0
- data/lib/siba/test_files/files_and_dirs/.hidden +1 -0
- data/lib/siba/test_files/files_and_dirs/.hidden_dir/file10 +1 -0
- data/lib/siba/test_files/files_and_dirs/File With Spaces +1 -0
- data/lib/siba/test_files/files_and_dirs/dir1/file10 +1 -0
- data/lib/siba/test_files/files_and_dirs/dir1/sub-dir/file111.txt +1 -0
- data/lib/siba/test_files/files_and_dirs/file1 +1 -0
- data/lib/siba/test_files/files_and_dirs/file2.txt +1 -0
- data/lib/siba/tmp_dir.rb +94 -0
- data/lib/siba/version.rb +5 -0
- data/scaffolds/archive.rb +26 -0
- data/scaffolds/destination.rb +20 -0
- data/scaffolds/encryption.rb +26 -0
- data/scaffolds/project/.gitignore +5 -0
- data/scaffolds/project/Gemfile +4 -0
- data/scaffolds/project/Guardfile +9 -0
- data/scaffolds/project/LICENSE +22 -0
- data/scaffolds/project/README.md +33 -0
- data/scaffolds/project/Rakefile +28 -0
- data/scaffolds/project/lib/siba-c6y-demo.rb +11 -0
- data/scaffolds/project/lib/siba-c6y-demo/options.yml +2 -0
- data/scaffolds/project/lib/siba-c6y-demo/version.rb +9 -0
- data/scaffolds/project/siba-c6y-demo.gemspec +26 -0
- data/scaffolds/project/test/helper/require_integration.rb +5 -0
- data/scaffolds/project/test/helper/require_unit.rb +4 -0
- data/scaffolds/project/test/integration/i9n_init.rb +35 -0
- data/scaffolds/project/test/unit/test_init.rb +43 -0
- data/scaffolds/project/test/unit/yml/valid.yml +8 -0
- data/scaffolds/shared/examples.rb +47 -0
- data/scaffolds/shared/init_example.rb +13 -0
- data/scaffolds/source.rb +25 -0
- data/siba.gemspec +30 -0
- data/test/helper/require_integration.rb +4 -0
- data/test/helper/require_unit.rb +4 -0
- data/test/integration/helpers/i9n_file_helper.rb +50 -0
- data/test/integration/i9n_backup.rb +53 -0
- data/test/integration/i9n_console.rb +16 -0
- data/test/integration/i9n_generator.rb +29 -0
- data/test/integration/i9n_options_backup.rb +22 -0
- data/test/integration/i9n_scaffold.rb +27 -0
- data/test/integration/i9n_siba_file.rb +30 -0
- data/test/integration/i9n_test_unicode_files.rb +40 -0
- data/test/integration/i9n_tmp_dir.rb +44 -0
- data/test/integration/plugins/archive/tar/i9n_archive.rb +18 -0
- data/test/integration/plugins/destination/dir/i9n_dest_dir.rb +52 -0
- data/test/integration/plugins/encryption/gpg/i9n_encryption.rb +87 -0
- data/test/integration/plugins/i9n_installed_plugins.rb +13 -0
- data/test/integration/plugins/source/files/i9n_files.rb +146 -0
- data/test/integration/tasks/i9n_siba_tasks.rb +30 -0
- data/test/integration/yml/valid.yml +16 -0
- data/test/unit/helpers/test_encoding_helper.rb +17 -0
- data/test/unit/helpers/test_gem_helper.rb +17 -0
- data/test/unit/helpers/test_security_helper.rb +21 -0
- data/test/unit/helpers/test_string_helper.rb +35 -0
- data/test/unit/plugins/archive/tar/test_archive.rb +41 -0
- data/test/unit/plugins/archive/tar/test_init.rb +36 -0
- data/test/unit/plugins/archive/tar/yml/archive/check_installed.yml +2 -0
- data/test/unit/plugins/archive/tar/yml/init/default_compression.yml +1 -0
- data/test/unit/plugins/archive/tar/yml/init/invalid_compression.yml +2 -0
- data/test/unit/plugins/archive/tar/yml/init/valid.yml +2 -0
- data/test/unit/plugins/destination/dir/test_dest_dir.rb +41 -0
- data/test/unit/plugins/destination/dir/test_init.rb +36 -0
- data/test/unit/plugins/destination/dir/yml/init/valid.yml +2 -0
- data/test/unit/plugins/encryption/gpg/test_encryption.rb +70 -0
- data/test/unit/plugins/encryption/gpg/test_init.rb +47 -0
- data/test/unit/plugins/source/files/test_files.rb +44 -0
- data/test/unit/plugins/source/files/test_init.rb +48 -0
- data/test/unit/plugins/source/files/test_path_match.rb +140 -0
- data/test/unit/plugins/source/files/yml/ignore_list.yml +8 -0
- data/test/unit/plugins/source/files/yml/ignore_not_array.yml +5 -0
- data/test/unit/plugins/source/files/yml/include_not_array.yml +3 -0
- data/test/unit/plugins/source/files/yml/include_subdirs_false.yml +6 -0
- data/test/unit/plugins/source/files/yml/include_subdirs_missing.yml +5 -0
- data/test/unit/plugins/source/files/yml/no_ignore.yml +4 -0
- data/test/unit/plugins/source/files/yml/no_include.yml +1 -0
- data/test/unit/plugins/source/files/yml/valid.yml +9 -0
- data/test/unit/plugins/test_installed_plugins.rb +32 -0
- data/test/unit/plugins/test_plugin_loader.rb +27 -0
- data/test/unit/plugins/test_plugins.rb +44 -0
- data/test/unit/tasks/test_siba_task.rb +30 -0
- data/test/unit/tasks/test_siba_tasks.rb +84 -0
- data/test/unit/tasks/yml/task/invalid.yml +4 -0
- data/test/unit/tasks/yml/task/valid.yml +7 -0
- data/test/unit/test_backup.rb +18 -0
- data/test/unit/test_console.rb +166 -0
- data/test/unit/test_generator.rb +21 -0
- data/test/unit/test_globals.rb +34 -0
- data/test/unit/test_log_message.rb +26 -0
- data/test/unit/test_logger_plug.rb +49 -0
- data/test/unit/test_options_backup.rb +21 -0
- data/test/unit/test_options_loader.rb +72 -0
- data/test/unit/test_password_strength.rb +76 -0
- data/test/unit/test_restore.rb +18 -0
- data/test/unit/test_scaffold.rb +26 -0
- data/test/unit/test_siba_check.rb +118 -0
- data/test/unit/test_siba_logger.rb +174 -0
- data/test/unit/test_tmp_dir.rb +21 -0
- data/test/unit/yml/options_loader/array.yml +2 -0
- data/test/unit/yml/options_loader/empty.yml +0 -0
- data/test/unit/yml/options_loader/invalid.yml +4 -0
- data/test/unit/yml/options_loader/string.yml +1 -0
- data/test/unit/yml/options_loader/utf8_with_bom.yml +2 -0
- data/test/unit/yml/options_loader/valid.yml +12 -0
- data/test/unit/yml/siba_options_backup.yml +20 -0
- data/test/unit/yml/valid.yml +18 -0
- metadata +240 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class SibaCheck
|
5
|
+
class << self
|
6
|
+
def options_bool(options, key_name, is_optional = false, default_value=false)
|
7
|
+
check_options options, key_name, [TrueClass, FalseClass], is_optional, default_value
|
8
|
+
end
|
9
|
+
|
10
|
+
def options_hash(options, key_name, is_optional = false, default_value=nil)
|
11
|
+
check_options options, key_name, Hash, is_optional, default_value
|
12
|
+
end
|
13
|
+
|
14
|
+
def options_string(options, key_name, is_optional = false, default_value=nil)
|
15
|
+
check_options(options, key_name, String, is_optional, default_value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def options_string_array(options, key_name, is_optional = false, default_value=nil)
|
19
|
+
value = options[key_name]
|
20
|
+
if value.nil?
|
21
|
+
return default_value if is_optional
|
22
|
+
raise Siba::CheckError, "'#{key_name}' option is not defined"
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
if value.is_a? Array
|
27
|
+
value.each_index do |i|
|
28
|
+
value[i] = try_to_s value[i], key_name
|
29
|
+
end
|
30
|
+
else
|
31
|
+
value = [ try_to_s(value, key_name) ]
|
32
|
+
end
|
33
|
+
rescue Exception
|
34
|
+
raise Siba::CheckError, "'#{key_name}' option should be string or an array of strings"
|
35
|
+
end
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
def hash(obj, name, is_optional=false)
|
40
|
+
if obj.nil?
|
41
|
+
return nil if is_optional
|
42
|
+
raise Siba::CheckError, "'#{name}' option is not defined"
|
43
|
+
end
|
44
|
+
raise Siba::CheckError, "'#{name}' option should be of [Hash] type" unless obj.is_a? Hash
|
45
|
+
obj
|
46
|
+
end
|
47
|
+
|
48
|
+
# Tries to conver value to string
|
49
|
+
def try_to_s(value, key_name)
|
50
|
+
raise Siba::CheckError, "'#{key_name}' option should be string" if [Array, Hash].any?{|a| value.is_a?(a)}
|
51
|
+
value = value.to_s.strip
|
52
|
+
raise Siba::CheckError, "'#{key_name}' option should not be empty" if value.empty?
|
53
|
+
value
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def check_options(options, key_name, item_type, is_optional = false, default_value = nil)
|
59
|
+
value = options[key_name]
|
60
|
+
if value.nil?
|
61
|
+
raise Siba::CheckError, "'#{key_name}' option is not defined" unless is_optional
|
62
|
+
return default_value
|
63
|
+
end
|
64
|
+
|
65
|
+
if item_type == String
|
66
|
+
value = try_to_s value, key_name
|
67
|
+
else
|
68
|
+
item_type = [item_type] unless item_type.is_a?(Array)
|
69
|
+
raise Siba::CheckError, "'#{key_name}' option should be of #{item_type.to_s} type" if item_type.none? {|i| value.is_a? i }
|
70
|
+
end
|
71
|
+
value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'open3'
|
6
|
+
|
7
|
+
module Siba
|
8
|
+
class SibaFile
|
9
|
+
def run_this(name="noname")
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
|
13
|
+
DIR_REGEXP = /^dir_/
|
14
|
+
FILE_REGEXP = /^file_/
|
15
|
+
FILE_UTILS_REGEXP = /^file_utils_/
|
16
|
+
|
17
|
+
def self.get_file_class(meth)
|
18
|
+
case meth
|
19
|
+
when FILE_UTILS_REGEXP
|
20
|
+
return FileUtils, meth.to_s.gsub(FILE_UTILS_REGEXP, "")
|
21
|
+
when DIR_REGEXP
|
22
|
+
return Dir, meth.to_s.gsub(DIR_REGEXP, "")
|
23
|
+
when FILE_REGEXP
|
24
|
+
return File, meth.to_s.gsub(FILE_REGEXP, "")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(meth, *args, &block)
|
29
|
+
file_class, class_meth = SibaFile.get_file_class meth
|
30
|
+
if file_class
|
31
|
+
file_class.send(class_meth, *args, &block)
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def respond_to?(meth)
|
38
|
+
if SibaFile.get_file_class meth
|
39
|
+
true
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def file_expand_path(file_name, dir_string=nil)
|
46
|
+
file_utils_cd Siba.current_dir unless Siba.current_dir.nil?
|
47
|
+
File.expand_path file_name, dir_string
|
48
|
+
end
|
49
|
+
|
50
|
+
# Runs shell command and raises error if it fails
|
51
|
+
# returns output (both stdout and stderr)
|
52
|
+
def run_shell(command, fail_message=nil)
|
53
|
+
strout, status = Open3.capture2e command
|
54
|
+
raise strout if status.to_i != 0
|
55
|
+
return strout
|
56
|
+
rescue Exception => ex
|
57
|
+
fail_message ||= "Failed to run the command: #{command}"
|
58
|
+
raise Siba::Error, "#{fail_message}
|
59
|
+
#{ex.message}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Runs the shell command.
|
63
|
+
# Works the same way as Kernel.system method but without showing the output.
|
64
|
+
# Returns true if it was successfull.
|
65
|
+
def shell_ok?(command)
|
66
|
+
# Using Open3 instead of `` or system("cmd") in order to hide stderr output
|
67
|
+
sout, status = Open3.capture2e command
|
68
|
+
return status.to_i == 0
|
69
|
+
rescue
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Used to inject "siba_file" to classes that include this module
|
75
|
+
module FilePlug
|
76
|
+
def siba_file
|
77
|
+
FilePlug.siba_file
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.siba_file
|
81
|
+
@siba_file ||= SibaFile.new
|
82
|
+
end
|
83
|
+
|
84
|
+
# It is used in test to insert mock SibaFile object
|
85
|
+
def self.siba_file=(val)
|
86
|
+
@siba_file = val
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class SibaKernel
|
5
|
+
undef_method :puts
|
6
|
+
def method_missing(meth, *args, &block)
|
7
|
+
if Kernel.respond_to? meth
|
8
|
+
Kernel.send meth, *args, &block
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def respond_to?(meth)
|
15
|
+
if Kernel.respond_to? meth
|
16
|
+
true
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module KernelPlug
|
24
|
+
def siba_kernel
|
25
|
+
KernelPlug.siba_kernel
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.siba_kernel
|
29
|
+
@siba_kernel ||= Siba::SibaKernel.new
|
30
|
+
end
|
31
|
+
|
32
|
+
# It is used in test to insert mock SibaKernel object
|
33
|
+
def self.siba_kernel=(val)
|
34
|
+
@siba_kernel = val
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Siba
|
5
|
+
class SibaLogger
|
6
|
+
LogLevels = %w(debug info warn error fatal unknown)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :quiet, :verbose, :no_log, :messages
|
10
|
+
|
11
|
+
def log_level?(level)
|
12
|
+
SibaLogger::LogLevels.include? level
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_log_level(level)
|
16
|
+
raise "Unsupported log level '#{level}'" unless SibaLogger::log_level? level
|
17
|
+
end
|
18
|
+
|
19
|
+
def level_to_i(level)
|
20
|
+
check_log_level level
|
21
|
+
SibaLogger::LogLevels.index level
|
22
|
+
end
|
23
|
+
|
24
|
+
def count(severity=nil, exact_level=true)
|
25
|
+
return 0 if SibaLogger.messages.nil?
|
26
|
+
return SibaLogger.messages.size if severity.nil?
|
27
|
+
severity_i = SibaLogger.level_to_i severity
|
28
|
+
SibaLogger.messages.count do |i|
|
29
|
+
if exact_level
|
30
|
+
i.level == severity_i
|
31
|
+
else
|
32
|
+
i.level >= severity_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :show_finish_message
|
39
|
+
|
40
|
+
def initialize(name, path_to_log_file, show_start_message = true)
|
41
|
+
@show_finish_message = true
|
42
|
+
@name = name
|
43
|
+
SibaLogger.messages = []
|
44
|
+
@loggers = []
|
45
|
+
|
46
|
+
@strlog = StringIO.new
|
47
|
+
@loggers << Logger.new(@strlog)
|
48
|
+
|
49
|
+
unless SibaLogger.quiet
|
50
|
+
@stdout_log = Logger.new(STDOUT)
|
51
|
+
@loggers << stdout_log
|
52
|
+
end
|
53
|
+
|
54
|
+
unless path_to_log_file.nil? || SibaLogger.no_log
|
55
|
+
@file = File.open(path_to_log_file, "a:utf-8")
|
56
|
+
@file_log = Logger.new(file)
|
57
|
+
@loggers << file_log
|
58
|
+
end
|
59
|
+
|
60
|
+
@loggers.each do |logger|
|
61
|
+
logger.formatter = method(:formatter)
|
62
|
+
end
|
63
|
+
|
64
|
+
file_log.info "
|
65
|
+
||----------NEW LOG----------||
|
66
|
+
|| #{Time.now} ||
|
67
|
+
||---------------------------||
|
68
|
+
" unless file_log.nil?
|
69
|
+
|
70
|
+
info "#{name} started" if show_start_message
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
strlog.string
|
75
|
+
end
|
76
|
+
|
77
|
+
def close
|
78
|
+
if show_finish_message
|
79
|
+
if SibaLogger.count('fatal') > 0
|
80
|
+
info "#{name} failed"
|
81
|
+
elsif SibaLogger.count('warn', false) == 0
|
82
|
+
info "#{name} finished successfully"
|
83
|
+
else
|
84
|
+
info "#{name} completed with some issues"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
unless file.nil?
|
89
|
+
file.close
|
90
|
+
end
|
91
|
+
|
92
|
+
unless file_log.nil?
|
93
|
+
file_log.close
|
94
|
+
end
|
95
|
+
@loggers = []
|
96
|
+
@strlog = nil
|
97
|
+
@file_log = nil
|
98
|
+
@file = nil
|
99
|
+
@stdout_log = nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def warn(*args, &block)
|
103
|
+
log('warn', *args, &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
def log_exception(exception, log_only_backtrace=false)
|
107
|
+
log('debug',exception.message) unless log_only_backtrace
|
108
|
+
unless exception.backtrace.nil?
|
109
|
+
log('debug',"\n--- stack trace ---\n#{exception.backtrace.join("\n")}\n--- stack trace ---")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def method_missing(meth, *args, &block)
|
114
|
+
if SibaLogger::log_level? meth.to_s
|
115
|
+
log(meth.to_s, *args, &block)
|
116
|
+
else
|
117
|
+
super
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def respond_to?(meth)
|
122
|
+
if SibaLogger::log_level? meth.to_s
|
123
|
+
true
|
124
|
+
else
|
125
|
+
super
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
attr_accessor :loggers, :name, :strlog, :file_log, :stdout_log, :file
|
131
|
+
|
132
|
+
def log(level, *args, &block)
|
133
|
+
raise Siba::Error, "Log is closed" if loggers.empty?
|
134
|
+
level_i = SibaLogger::level_to_i level
|
135
|
+
unless block.nil?
|
136
|
+
msg = block.call.to_s
|
137
|
+
else
|
138
|
+
assert "Wrong number of arguments" if args.size != 1
|
139
|
+
msg = args[0].to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
log_message = LogMessage.new
|
143
|
+
log_message.level = level_i
|
144
|
+
log_message.time = Time.now
|
145
|
+
log_message.msg = msg
|
146
|
+
SibaLogger.messages << log_message
|
147
|
+
|
148
|
+
loggers.each do |l|
|
149
|
+
l.send(level, msg) unless l == stdout_log
|
150
|
+
end
|
151
|
+
|
152
|
+
unless stdout_log.nil?
|
153
|
+
stdout_log.send(level, EncodingHelper.encode_to_external(msg)) unless level == 'debug' && !SibaLogger.verbose
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def formatter(severity, datetime, progname, msg)
|
158
|
+
if ["INFO", "DEBUG"].include? severity
|
159
|
+
severity = ""
|
160
|
+
else
|
161
|
+
severity = "WARNING" if severity == "WARN"
|
162
|
+
severity += " - "
|
163
|
+
end
|
164
|
+
|
165
|
+
"#{severity}#{msg}\n"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class LogMessage
|
170
|
+
attr_accessor :level, :time, :msg
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class SibaTask
|
5
|
+
include Siba::LoggerPlug
|
6
|
+
|
7
|
+
attr_accessor :category, :type, :options, :plugin
|
8
|
+
|
9
|
+
def initialize(options, category)
|
10
|
+
@category = category
|
11
|
+
load Siba::SibaCheck.options_hash(options, category)
|
12
|
+
rescue
|
13
|
+
logger.error "Failed to load #{category} plugin"
|
14
|
+
raise
|
15
|
+
end
|
16
|
+
|
17
|
+
def backup(*args)
|
18
|
+
logger.debug "Running #{category}/#{type}"
|
19
|
+
@plugin.backup *args
|
20
|
+
rescue Exception
|
21
|
+
logger.error "Failed to backup #{category}/#{type}"
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore(*args)
|
26
|
+
logger.debug "Restoring #{category}/#{type}"
|
27
|
+
@plugin.restore *args
|
28
|
+
rescue Exception
|
29
|
+
logger.error "Failed to restore #{category}/#{type}"
|
30
|
+
raise
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def load(options)
|
36
|
+
@options = options
|
37
|
+
@type = Siba::SibaCheck.options_string(@options, "type")
|
38
|
+
@type.downcase!
|
39
|
+
@plugin = Siba::PluginLoader.loader.load(category, type, options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'siba/tasks/siba_task'
|
4
|
+
|
5
|
+
module Siba
|
6
|
+
class SibaTasks
|
7
|
+
include Siba::FilePlug
|
8
|
+
attr_accessor :tasks
|
9
|
+
|
10
|
+
def initialize(options, path_to_options_yml, skip_source_task)
|
11
|
+
@path_to_options_yml = path_to_options_yml
|
12
|
+
raise 'Options are not loaded' if options.nil?
|
13
|
+
|
14
|
+
@tasks = {}
|
15
|
+
Siba::Plugins::CATEGORIES.each do |category|
|
16
|
+
next if category == "source" && skip_source_task
|
17
|
+
@tasks[category] = SibaTask.new options, category
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def backup
|
22
|
+
siba_file.run_this "backup" do
|
23
|
+
@tasks["source"].backup source_dir
|
24
|
+
raise Siba::Error, "There are no files to backup" if Siba::FileHelper.dir_empty? source_dir
|
25
|
+
OptionsBackup.save_options_backup path_to_options_yml, source_dir
|
26
|
+
|
27
|
+
archive_file_name = @tasks["archive"].backup source_dir, archive_dir, SibaTasks.backup_name
|
28
|
+
unless archive_file_name =~ /^#{SibaTasks.backup_name}/
|
29
|
+
raise Siba::Error, "Archive file name must begin with: #{SibaTasks.backup_name}"
|
30
|
+
end
|
31
|
+
path_to_archive = File.join archive_dir, archive_file_name
|
32
|
+
unless siba_file.file_file? path_to_archive
|
33
|
+
raise Siba::Error, "Failed to create archive file: #{path_to_archive}"
|
34
|
+
end
|
35
|
+
|
36
|
+
name_of_encrypted_file = @tasks["encryption"].backup path_to_archive, encryption_dir
|
37
|
+
unless name_of_encrypted_file =~ /^#{archive_file_name}/
|
38
|
+
raise Siba::Error, "File name of encrypted file must begin with: #{archive_file_name}"
|
39
|
+
end
|
40
|
+
path_to_backup = File.join encryption_dir, name_of_encrypted_file
|
41
|
+
unless siba_file.file_file? path_to_backup
|
42
|
+
raise Siba::Error, "Failed to encrypt backup: #{path_to_backup}"
|
43
|
+
end
|
44
|
+
|
45
|
+
@tasks["destination"].backup path_to_backup
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def restore(backup_file_name)
|
50
|
+
siba_file.run_this do
|
51
|
+
@tasks["destination"].restore backup_file_name, destination_dir
|
52
|
+
path_to_backup = File.join destination_dir, backup_file_name
|
53
|
+
unless siba_file.file_file? path_to_backup
|
54
|
+
raise Siba::Error, "Failed to get backup from destination: #{backup_file_name}"
|
55
|
+
end
|
56
|
+
|
57
|
+
archive_file_name = @tasks["encryption"].restore path_to_backup, encryption_dir
|
58
|
+
path_to_archive = File.join encryption_dir, archive_file_name
|
59
|
+
unless siba_file.file_file? path_to_archive
|
60
|
+
raise Siba::Error, "Failed to get archive file: #{path_to_archive}"
|
61
|
+
end
|
62
|
+
|
63
|
+
@tasks["archive"].restore path_to_archive, source_dir
|
64
|
+
if Siba::FileHelper.dir_empty? source_dir
|
65
|
+
raise Siba::Error, "Failed to extract archive: #{path_to_archive}"
|
66
|
+
end
|
67
|
+
|
68
|
+
@tasks["source"] = OptionsBackup.load_source_from_backup source_dir
|
69
|
+
@tasks["source"].restore source_dir
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_backups_list
|
74
|
+
@tasks["destination"].plugin.get_backups_list Siba.backup_name
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.backup_name(now=nil)
|
78
|
+
if Siba::StringHelper.nil_or_empty Siba.backup_name
|
79
|
+
raise Siba::Error, "Backup task name is not specified"
|
80
|
+
end
|
81
|
+
"#{Siba.backup_name}-#{SibaTasks.backup_name_suffix(now)}"
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
private
|
86
|
+
attr_accessor :path_to_options_yml
|
87
|
+
|
88
|
+
def source_dir
|
89
|
+
@source_dir ||= TestFiles::mkdir_in_tmp_dir("src").freeze
|
90
|
+
end
|
91
|
+
|
92
|
+
def archive_dir
|
93
|
+
@archive_dir ||= TestFiles::mkdir_in_tmp_dir("arc").freeze
|
94
|
+
end
|
95
|
+
|
96
|
+
def encryption_dir
|
97
|
+
@encryption_dir ||= TestFiles::mkdir_in_tmp_dir("enc").freeze
|
98
|
+
end
|
99
|
+
|
100
|
+
def destination_dir
|
101
|
+
@destination_dir ||= TestFiles::mkdir_in_tmp_dir("dest").freeze
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.backup_name_suffix(now=nil)
|
105
|
+
now ||= Time.now
|
106
|
+
|
107
|
+
# Monthly backup on the 1st day of each month
|
108
|
+
# "month-01" through "month-12"
|
109
|
+
return "month-#{"%02d" % now.month}" if now.day == 1
|
110
|
+
|
111
|
+
# Weekly backup on Sunday
|
112
|
+
# "week-1-sun" through "week-5-sun"
|
113
|
+
return "week-#{(now.day-1) / 7 + 1}-sun" if now.wday == 0
|
114
|
+
|
115
|
+
# Daily backup
|
116
|
+
# "day-2-mon" through "day-7-sat"
|
117
|
+
"day-#{now.wday+1}-#{now.strftime("%a").downcase}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|