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,77 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba::Destination
|
4
|
+
module Dir
|
5
|
+
class DestDir
|
6
|
+
include Siba::FilePlug
|
7
|
+
include Siba::LoggerPlug
|
8
|
+
attr_accessor :dir
|
9
|
+
|
10
|
+
def initialize(dir)
|
11
|
+
@dir = siba_file.file_expand_path dir
|
12
|
+
test_dir_access
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_backup_to_dest(path_to_backup)
|
16
|
+
siba_file.run_this "copy backup to dest" do
|
17
|
+
logger.info "Copying backup to destination directory: #{dir}"
|
18
|
+
unless siba_file.file_file? path_to_backup
|
19
|
+
raise Siba::Error, "Backup file '#{path_to_backup}' does not exist"
|
20
|
+
end
|
21
|
+
unless siba_file.file_directory? dir
|
22
|
+
raise Siba::Error, "Destination directory '#{dir}' does not exist"
|
23
|
+
end
|
24
|
+
siba_file.file_utils_cp(path_to_backup, dir)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def restore_backup_to_dir(backup_name, to_dir)
|
29
|
+
siba_file.run_this do
|
30
|
+
logger.info "Copying backup from destination directory: #{dir}"
|
31
|
+
path_to_backup = File.join dir, backup_name
|
32
|
+
unless siba_file.file_file? path_to_backup
|
33
|
+
raise Siba::Error, "Can not find backup #{path_to_backup}"
|
34
|
+
end
|
35
|
+
|
36
|
+
siba_file.file_utils_cp path_to_backup, to_dir
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_dir_access
|
41
|
+
siba_file.run_this "test dir access" do
|
42
|
+
# create dest dir
|
43
|
+
begin
|
44
|
+
siba_file.file_utils_mkpath dir unless siba_file.file_directory? dir
|
45
|
+
rescue Exception
|
46
|
+
logger.error "Failed to create destination dir '#{dir}'."
|
47
|
+
raise
|
48
|
+
end
|
49
|
+
|
50
|
+
# copy a test file to dest dir
|
51
|
+
begin
|
52
|
+
test_file = Siba::TestFiles.prepare_test_file "destination_dir", dir
|
53
|
+
raise "Can not find the test file." unless siba_file.file_file? test_file
|
54
|
+
siba_file.file_utils_remove_entry_secure test_file
|
55
|
+
rescue Exception
|
56
|
+
logger.error "Could not write to destination dir '#{dir}'"
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
|
60
|
+
logger.debug "Access to destination directory is verified"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns an array of two-element arrays: [file_name, mtime]
|
65
|
+
def get_backups_list(backup_name)
|
66
|
+
siba_file.run_this do
|
67
|
+
Siba::FileHelper.entries(dir).select do |f|
|
68
|
+
f =~ /^#{backup_name}/
|
69
|
+
end.map do |f|
|
70
|
+
mtime = siba_file.file_mtime File.join dir, f
|
71
|
+
[f, mtime]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'siba/plugins/destination/dir/dest_dir'
|
4
|
+
|
5
|
+
module Siba::Destination
|
6
|
+
module Dir
|
7
|
+
class Init
|
8
|
+
attr_accessor :dest_dir
|
9
|
+
|
10
|
+
def initialize(options)
|
11
|
+
dir = Siba::SibaCheck.options_string options, "dir"
|
12
|
+
@dest_dir = Siba::Destination::Dir::DestDir.new dir
|
13
|
+
end
|
14
|
+
|
15
|
+
def backup(path_to_backup_file)
|
16
|
+
@dest_dir.copy_backup_to_dest path_to_backup_file
|
17
|
+
end
|
18
|
+
|
19
|
+
# Put backup file into dir
|
20
|
+
def restore(backup_name, dir)
|
21
|
+
@dest_dir.restore_backup_to_dir backup_name, dir
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns an array of two-element arrays:
|
25
|
+
# [backup_file_name, modification_time]
|
26
|
+
def get_backups_list(backup_name)
|
27
|
+
@dest_dir.get_backups_list backup_name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba::Encryption
|
4
|
+
module Gpg
|
5
|
+
class Encryption
|
6
|
+
include Siba::LoggerPlug
|
7
|
+
include Siba::FilePlug
|
8
|
+
|
9
|
+
DEFAULT_CIPHER = "AES256"
|
10
|
+
|
11
|
+
attr_accessor :passphrase, :cipher
|
12
|
+
|
13
|
+
def initialize(passphrase, cipher=DEFAULT_CIPHER)
|
14
|
+
@passphrase = passphrase
|
15
|
+
@cipher = Encryption.check_cipher cipher
|
16
|
+
check_password_strength
|
17
|
+
test_encryption
|
18
|
+
end
|
19
|
+
|
20
|
+
def encrypt(path_to_archive)
|
21
|
+
path_to_encrypted_backup = "#{path_to_archive}.gpg"
|
22
|
+
siba_file.run_this("encrypt") do
|
23
|
+
if siba_file.file_file? path_to_encrypted_backup
|
24
|
+
raise Siba::Error, "Encrypted file #{path_to_encrypted_backup} already exists"
|
25
|
+
end
|
26
|
+
passphare_for_command = passphrase.gsub('"','\\"')
|
27
|
+
gpg_homedir = Siba::TestFiles.mkdir_in_tmp_dir "gpg-homedir"
|
28
|
+
command_without_password = %(gpg -c -q --batch --homedir="#{gpg_homedir}" --no-options --cipher-algo=#{cipher} --passphrase="****" --no-use-agent "#{path_to_archive}")
|
29
|
+
command = command_without_password.gsub "****", passphare_for_command
|
30
|
+
siba_file.run_shell command, "failed to encrypt: #{command_without_password}"
|
31
|
+
unless siba_file.file_file? path_to_encrypted_backup
|
32
|
+
raise siba::error, "failed to find encrypted backup file: #{command_without_password}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
path_to_encrypted_backup
|
36
|
+
end
|
37
|
+
|
38
|
+
def decrypt(path_to_encrypted_file, path_to_decrypted_file=nil)
|
39
|
+
path_to_decrypted_file = path_to_encrypted_file.gsub /\.gpg$/, "" if path_to_decrypted_file.nil?
|
40
|
+
siba_file.run_this("decrypt") do
|
41
|
+
if siba_file.file_file? path_to_decrypted_file
|
42
|
+
raise Siba::Error, "Decrypted file #{path_to_decrypted_file} already exists"
|
43
|
+
end
|
44
|
+
passphare_for_command = passphrase.gsub('"','\\"')
|
45
|
+
gpg_homedir = Siba::TestFiles.mkdir_in_tmp_dir "gpg-homedir"
|
46
|
+
command_without_password = %(gpg -d -q --batch --homedir="#{gpg_homedir}" --no-options --passphrase="****" -o "#{path_to_decrypted_file}" --no-use-agent "#{path_to_encrypted_file}")
|
47
|
+
command = command_without_password.gsub "****", passphare_for_command
|
48
|
+
siba_file.run_shell command, "failed to decrypt: #{command_without_password}"
|
49
|
+
unless siba_file.file_file? path_to_decrypted_file
|
50
|
+
raise siba::error, "failed to find decrypted backup file: #{command_without_password}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
path_to_decrypted_file
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_encryption
|
57
|
+
begin
|
58
|
+
siba_file.run_this("test_encryption") do
|
59
|
+
# encrypt
|
60
|
+
path_to_source_file = Siba::TestFiles.prepare_test_file "encryption-gpg"
|
61
|
+
path_to_encrypted_file = encrypt path_to_source_file
|
62
|
+
raise unless path_to_encrypted_file == "#{path_to_source_file}.gpg"
|
63
|
+
raise unless siba_file.file_file? path_to_encrypted_file
|
64
|
+
raise if siba_file.file_utils_compare_file path_to_source_file, path_to_encrypted_file
|
65
|
+
|
66
|
+
# decrypt
|
67
|
+
path_to_output_file = "#{path_to_source_file}.decrypted"
|
68
|
+
path_to_decrypted_file = decrypt path_to_encrypted_file, path_to_output_file
|
69
|
+
raise unless path_to_decrypted_file == path_to_output_file
|
70
|
+
raise unless siba_file.file_utils_compare_file path_to_source_file, path_to_decrypted_file
|
71
|
+
|
72
|
+
logger.debug "GPG encryption is verified"
|
73
|
+
end
|
74
|
+
rescue Exception
|
75
|
+
logger.error "'gpg' encryption utility does not work correctly. Try reinstalling it."
|
76
|
+
raise
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class << self
|
81
|
+
include Siba::FilePlug
|
82
|
+
include Siba::LoggerPlug
|
83
|
+
|
84
|
+
def check_cipher(cipher)
|
85
|
+
siba_file.run_this("check_cipher") do
|
86
|
+
supported_ciphers = nil
|
87
|
+
begin
|
88
|
+
supported_ciphers = Encryption.get_cipher_names
|
89
|
+
rescue Exception
|
90
|
+
logger.error "'gpg' encryption utility is not found. Please install it."
|
91
|
+
raise
|
92
|
+
end
|
93
|
+
|
94
|
+
supported_ciphers_msg = "Please use one of the following: #{supported_ciphers.join(', ')}."
|
95
|
+
if cipher.nil?
|
96
|
+
cipher = Encryption::DEFAULT_CIPHER
|
97
|
+
raise Siba::CheckError, "Default cipher '#{cipher}' is not supported.
|
98
|
+
#{supported_ciphers_msg}" unless supported_ciphers.include?(cipher)
|
99
|
+
else
|
100
|
+
cipher.upcase!
|
101
|
+
end
|
102
|
+
|
103
|
+
raise Siba::CheckError, "'#{cipher}' cipher is not supported.
|
104
|
+
#{supported_ciphers_msg}" unless supported_ciphers.include?(cipher)
|
105
|
+
end
|
106
|
+
cipher
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_cipher_names
|
110
|
+
output = siba_file.run_shell "gpg --version"
|
111
|
+
cipher_names = parse_cipher_names output
|
112
|
+
raise Siba::Error, "Failed to get the list of supported ciphers" if cipher_names.empty?
|
113
|
+
cipher_names
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse_cipher_names(version)
|
117
|
+
scan = version.scan /Cipher:(.*?)\n\w+:/m
|
118
|
+
scan = version.scan /Cipher:(.*)/m if scan.size == 0
|
119
|
+
if scan.size == 0 || !scan[0].is_a?(Array) || scan[0].size == 0 || !scan[0][0].is_a?(String)
|
120
|
+
raise "Failed to parse gpg version information"
|
121
|
+
end
|
122
|
+
scan = scan[0][0]
|
123
|
+
scan.gsub!(/ |\n/, "")
|
124
|
+
scan.split(",").each {|a| a.upcase!}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def check_password_strength
|
131
|
+
seconds_to_crack = Siba::PasswordStrength.seconds_to_crack(@passphrase)
|
132
|
+
if Siba::PasswordStrength.is_weak? seconds_to_crack
|
133
|
+
timespan_to_guess = Siba::PasswordStrength.seconds_to_timespan seconds_to_crack
|
134
|
+
guess_estimation_message = "It will take #{timespan_to_guess} to guess it."
|
135
|
+
logger.warn "Your encryption password is weak. #{guess_estimation_message}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'siba/helpers/password_strength'
|
4
|
+
require 'siba/plugins/encryption/gpg/encryption'
|
5
|
+
|
6
|
+
module Siba::Encryption
|
7
|
+
module Gpg
|
8
|
+
class Init
|
9
|
+
include Siba::LoggerPlug
|
10
|
+
include Siba::FilePlug
|
11
|
+
attr_accessor :encryption
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
passphrase = Siba::SibaCheck.options_string(options, "passphrase")
|
15
|
+
cipher = Siba::SibaCheck.options_string(options, "cipher", true)
|
16
|
+
@encryption = Siba::Encryption::Gpg::Encryption.new passphrase, cipher
|
17
|
+
end
|
18
|
+
|
19
|
+
# Encrypt backup archive file (path_to_archive) and put it to dest_dir.
|
20
|
+
# Return the name of encrypted file. It must begin with archive name
|
21
|
+
# and its ending must always be the same.
|
22
|
+
def backup(path_to_archive, dest_dir)
|
23
|
+
logger.info "Encrypting backup with 'gpg', cipher: '#{encryption.cipher}'"
|
24
|
+
path_to_encrypted_file = encryption.encrypt path_to_archive
|
25
|
+
|
26
|
+
# move encrypted file to dest_dir
|
27
|
+
file_name = File.basename path_to_encrypted_file
|
28
|
+
dest_file_path = File.join dest_dir, file_name
|
29
|
+
siba_file.file_utils_mv path_to_encrypted_file, dest_file_path
|
30
|
+
file_name
|
31
|
+
end
|
32
|
+
|
33
|
+
# Decrypt backup file (path_to_backup) to_dir.
|
34
|
+
# Return the name of decrypted file.
|
35
|
+
def restore(path_to_backup, to_dir)
|
36
|
+
logger.info "Decrypting backup with 'gpg', cipher: '#{encryption.cipher}'"
|
37
|
+
decrypted_file_name = File.basename path_to_backup
|
38
|
+
decrypted_file_name.gsub! /\.gpg$/, ""
|
39
|
+
path_to_decrypted_file = File.join to_dir, decrypted_file_name
|
40
|
+
encryption.decrypt path_to_backup, path_to_decrypted_file
|
41
|
+
decrypted_file_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class InstalledPlugins
|
5
|
+
GEM_PREFIX = "siba-"
|
6
|
+
|
7
|
+
class << self
|
8
|
+
include Siba::FilePlug
|
9
|
+
|
10
|
+
def installed?(category, type)
|
11
|
+
types = all_installed[category]
|
12
|
+
return false if types.nil?
|
13
|
+
types.include? type
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_installed
|
17
|
+
@installed ||= find_installed
|
18
|
+
end
|
19
|
+
|
20
|
+
def plugin_path(category, type)
|
21
|
+
unless installed? category, type
|
22
|
+
raise Siba::Error, "Plugin #{plugin_category_and_type(category, type)} is not installed"
|
23
|
+
end
|
24
|
+
siba_file.run_this do
|
25
|
+
path = type_dir category, type
|
26
|
+
unless siba_file.file_directory? path
|
27
|
+
path = Siba::GemHelper.gem_path gem_name(category, type)
|
28
|
+
path = File.join path, "lib", gem_name(category, type)
|
29
|
+
end
|
30
|
+
unless siba_file.file_directory? path
|
31
|
+
raise Siba::Error, "Failed to get path to plugin #{plugin_category_and_type(category, type)}"
|
32
|
+
end
|
33
|
+
path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def category_dir(category)
|
38
|
+
File.expand_path "../#{category}/", __FILE__
|
39
|
+
end
|
40
|
+
|
41
|
+
def type_dir(category, type)
|
42
|
+
File.join category_dir(category), type
|
43
|
+
end
|
44
|
+
|
45
|
+
def gem_name(category, type)
|
46
|
+
"#{GEM_PREFIX}#{category}-#{type}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def plugin_category_and_type(category, type)
|
50
|
+
"#{category}#{type.nil? ? "" : '-' + type}"
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def find_installed
|
56
|
+
installed = {}
|
57
|
+
Siba::GemHelper.all_local_gems.map{|a| a.name}.each do |item|
|
58
|
+
Siba::Plugins::CATEGORIES.each do |category|
|
59
|
+
installed[category] ||= []
|
60
|
+
gem_prefix_full = /^#{GEM_PREFIX}#{category}-/
|
61
|
+
installed[category] << item.gsub(gem_prefix_full, '') if item =~ /#{gem_prefix_full}.*$/
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Siba::Plugins::CATEGORIES.each do |category|
|
66
|
+
installed[category] += Dir.glob(File.join(category_dir(category),"*")).select { |entry|
|
67
|
+
File.directory? entry
|
68
|
+
}.select{|dir| File.file?(File.join(dir,"init.rb")) }
|
69
|
+
.map{|directory| File.basename(directory)}
|
70
|
+
end
|
71
|
+
|
72
|
+
installed
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class PluginLoader
|
5
|
+
include Siba::LoggerPlug
|
6
|
+
include Siba::FilePlug
|
7
|
+
|
8
|
+
InitClassName = "Init"
|
9
|
+
|
10
|
+
def self.loader
|
11
|
+
@loader ||= PluginLoader.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def load(category, type, options)
|
15
|
+
unless Siba::Plugins.valid_category? category
|
16
|
+
raise PluginLoadError, "Incorrect plugin category '#{category}'. Available plugin categories are: #{Siba::Plugins.categories_str}"
|
17
|
+
end
|
18
|
+
|
19
|
+
raise PluginLoadError, "Options data is incorrect for #{plugin_category_and_type} plugin." unless options.is_a? Hash
|
20
|
+
|
21
|
+
@category=category
|
22
|
+
@type=type
|
23
|
+
@options = options
|
24
|
+
logger.debug "Loading #{plugin_category_and_type} plugin"
|
25
|
+
|
26
|
+
require_plugin
|
27
|
+
plugin_module = get_plugin_module
|
28
|
+
plugin_type_module = get_plugin_type_module plugin_module
|
29
|
+
init_class = get_plugin_init_class plugin_type_module
|
30
|
+
init_plugin(init_class)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
attr_accessor :category, :type, :options
|
35
|
+
|
36
|
+
def require_plugin
|
37
|
+
path_to_init_file = File.join(plugin_dir, "init.rb")
|
38
|
+
if File.exists?(path_to_init_file)
|
39
|
+
require path_to_init_file
|
40
|
+
else
|
41
|
+
gem_name = Siba::InstalledPlugins.gem_name category, type
|
42
|
+
begin
|
43
|
+
Gem::Specification.find_by_name(gem_name)
|
44
|
+
rescue Gem::LoadError
|
45
|
+
raise PluginLoadError, "Unknown type '#{type}' for '#{category}' plugin. #{available_types_msg}"
|
46
|
+
end
|
47
|
+
require gem_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_plugin_module
|
52
|
+
plugin_module_name = "#{category.capitalize}"
|
53
|
+
Siba.const_get(plugin_module_name)
|
54
|
+
rescue Exception
|
55
|
+
raise PluginLoadError, "Failed to load #{plugin_category_and_type} plugin: module 'Siba::#{plugin_module_name}' is undefined."
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_plugin_type_module(plugin_module)
|
59
|
+
plugin_type_module_name = StringHelper.camelize type
|
60
|
+
plugin_module.const_get(plugin_type_module_name)
|
61
|
+
rescue
|
62
|
+
raise PluginLoadError, "Failed to load #{plugin_category_and_type} plugin: module 'Siba::#{category.capitalize}::#{plugin_type_module_name}' is undefined."
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_plugin_init_class(plugin_type_module)
|
66
|
+
plugin_type_module.const_get InitClassName
|
67
|
+
rescue Exception => e
|
68
|
+
raise PluginLoadError, "#{InitClassName} class is undefined for #{plugin_category_and_type} plugin."
|
69
|
+
end
|
70
|
+
|
71
|
+
def init_plugin(plugin_init_class)
|
72
|
+
plugin_init_class.new options
|
73
|
+
rescue ArgumentError
|
74
|
+
logger.error "Failed to load #{plugin_category_and_type} plugin: 'initialize' method is not defined or has wrong agruments."
|
75
|
+
raise
|
76
|
+
end
|
77
|
+
|
78
|
+
def plugin_category_and_type
|
79
|
+
Siba::InstalledPlugins.plugin_category_and_type category, type
|
80
|
+
end
|
81
|
+
|
82
|
+
def plugins_root_dir
|
83
|
+
Siba::InstalledPlugins.category_dir category
|
84
|
+
end
|
85
|
+
|
86
|
+
def plugin_dir
|
87
|
+
Siba::InstalledPlugins.type_dir category, type
|
88
|
+
end
|
89
|
+
|
90
|
+
def available_types_msg
|
91
|
+
return "No #{category} plugins are installed." if find_all_installed.empty?
|
92
|
+
return "Available types are: #{find_all_installed.join(", ")}." if find_all_installed.size > 1
|
93
|
+
"Available type is '#{find_all_installed.join(", ")}'."
|
94
|
+
end
|
95
|
+
|
96
|
+
def find_all_installed
|
97
|
+
Siba::InstalledPlugins.all_installed[category]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|