lib/backup/config/dsl.rb
module Backup
module Config
# Context for loading user config.rb and model files.
class DSL
class Error < Backup::Error; end
Model = Backup::Model
class << self
private
# List the available database, storage, syncer, compressor, encryptor
# and notifier constants. These are used to define constant names within
# Backup::Config::DSL so that users may 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(
DSL,
[ # Databases
["MySQL", "PostgreSQL", "MongoDB", "Redis", "Riak", "OpenLDAP", "SQLite"],
# Storages
["S3", "CloudFiles", "Dropbox", "FTP",
"SFTP", "SCP", "RSync", "Local", "Qiniu"],
# Compressors
["Gzip", "Bzip2", "Custom"],
# Encryptors
["OpenSSL", "GPG"],
# Syncers
[
{ "Cloud" => ["CloudFiles", "S3"] },
{ "RSync" => ["Push", "Pull", "Local"] }
],
# Notifiers
["Mail", "Twitter", "Campfire", "Prowl",
"Hipchat", "PagerDuty", "Pushover", "HttpPost", "Nagios",
"Slack", "FlowDock", "Zabbix", "Ses", "DataDog", "Command"]
]
)
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_dsl_constants # add constants on load
attr_reader :_config_options
def initialize
@_config_options = {}
end
# Allow users to set command line path options in config.rb
[:root_path, :data_path, :tmp_path].each do |name|
define_method name do |path|
_config_options[name] = path
end
end
# Allows users to create preconfigured models.
def preconfigure(name, &block)
unless name.is_a?(String) && name =~ /^[A-Z]/
raise Error, "Preconfigured model names must be given as a string " \
"and start with a capital letter."
end
if DSL.const_defined?(name)
raise Error, "'#{name}' is already in use " \
"and can not be used for a preconfigured model."
end
DSL.const_set(name, Class.new(Model))
DSL.const_get(name).preconfigure(&block)
end
end
end
end