/
config.rb
174 lines (158 loc) · 5.63 KB
/
config.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# encoding: utf-8
module Backup
module Config
DEFAULTS = {
:config_file => 'config.rb',
:data_path => 'data',
:log_path => 'log',
:cache_path => '.cache',
:tmp_path => '.tmp'
}
class << self
attr_reader :user, :root_path, :config_file,
:data_path, :log_path, :cache_path, :tmp_path
##
# Setup required paths based on the given options
def update(options = {})
root_path = options[:root_path].to_s.strip
new_root = root_path.empty? ? false : set_root_path(root_path)
DEFAULTS.each do |name, ending|
set_path_variable(name, options[name], ending, new_root)
end
end
##
# Tries to find and load the configuration file
def load_config!
unless File.exist?(@config_file)
raise Errors::Config::NotFoundError,
"Could not find configuration file: '#{@config_file}'."
end
module_eval(File.read(@config_file), @config_file)
end
private
##
# Sets the @root_path to the given +path+ and returns it.
# Raises an error if the given +path+ does not exist.
def set_root_path(path)
# allows #reset! to set the default @root_path,
# then use #update to set all other paths,
# without requiring that @root_path exist.
return @root_path if path == @root_path
path = File.expand_path(path)
unless File.directory?(path)
raise Errors::Config::NotFoundError, <<-EOS
Root Path Not Found
When specifying a --root-path, the path must exist.
Path was: #{ path }
EOS
end
@root_path = path
end
def set_path_variable(name, path, ending, root_path)
# strip any trailing '/' in case the user supplied this as part of
# an absolute path, so we can match it against File.expand_path()
path = path.to_s.sub(/\/\s*$/, '').lstrip
new_path = false
if path.empty?
new_path = File.join(root_path, ending) if root_path
else
new_path = File.expand_path(path)
unless path == new_path
new_path = File.join(root_path, path) if root_path
end
end
instance_variable_set(:"@#{name}", new_path) if new_path
end
##
# Set default values for accessors
def reset!
@user = ENV['USER'] || Etc.getpwuid.name
@root_path = File.join(File.expand_path(ENV['HOME'] || ''), 'Backup')
update(:root_path => @root_path)
end
##
# List the available database, storage, syncer, compressor, encryptor
# and notifier constants. These are used to dynamically define these
# constant names inside Backup::Config to provide a nicer configuration
# file DSL syntax to the users. Adding existing constants to the arrays
# below will enable the user to use a constant instead of a string.
# Nested namespaces are represented using Hashs. Deep nesting supported.
#
# Example, instead of:
# database "MySQL" do |mysql|
# sync_with "RSync::Local" do |rsync|
#
# You can do:
# database MySQL do |mysql|
# sync_with RSync::Local do |rsync|
#
def add_dsl_constants!
create_modules(
self,
[ # Databases
['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Riak'],
# Storages
['S3', 'CloudFiles', 'Ninefold', 'Dropbox', 'FTP',
'SFTP', 'SCP', 'RSync', 'Local'],
# Compressors
['Gzip', 'Bzip2', 'Custom', 'Pbzip2', 'Lzma'],
# Encryptors
['OpenSSL', 'GPG'],
# Syncers
[
{ 'Cloud' => ['CloudFiles', 'S3'] },
{ 'RSync' => ['Push', 'Pull', 'Local'] }
],
# Notifiers
['Mail', 'Twitter', 'Campfire', 'Presently', 'Prowl', 'Hipchat']
]
)
end
def create_modules(scope, names)
names.flatten.each do |name|
if name.is_a?(Hash)
name.each do |key, val|
create_modules(get_or_create_empty_module(scope, key), [val])
end
else
get_or_create_empty_module(scope, name)
end
end
end
def get_or_create_empty_module(scope, const)
if scope.const_defined?(const)
scope.const_get(const)
else
scope.const_set(const, Module.new)
end
end
end
##
# Add the DSL constants and set default values for accessors when loaded.
add_dsl_constants!
reset!
end
##
# Warn user of deprecated Backup::CONFIG_FILE constant reference
# in older config.rb files and return the proper Config.config_file value.
class << self
def const_missing(const)
if const.to_s == 'CONFIG_FILE'
Logger.warn Errors::ConfigError.new(<<-EOS)
Configuration File Upgrade Needed
Your configuration file, located at #{ Config.config_file }
needs to be upgraded for this version of Backup.
The reference to 'Backup::CONFIG_FILE' in your current config.rb file
has been deprecated and needs to be replaced with 'Config.config_file'.
You may update this reference in your config.rb manually,
or generate a new config.rb using 'backup generate:config'.
* Note: if you have global configuration defaults set in config.rb,
be sure to transfer them to your new config.rb, should you choose
to generate a new config.rb file.
EOS
return Config.config_file
end
super
end
end
end