Reputation: 5467
I'm using meskyanichi's backup gem. By and large it does what I need it to, but I need to have multiple backups (e.g., hourly, daily, weekly). The configurations are mostly the same but have a few differences, so I need to have multiple configuration files. I'm having trouble finding a sane way to manage the common bits of configurations (i.e., not repeat the common parts).
The configuration files use a lot of block structures, and from what I can tell, each backup needs to have a separate config file (e.g. config/backup/hourly.rb, config/backup/daily.rb, etc). A typical config file looks like this:
Backup::Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
db.name = "my_database"
db.username = "foo"
db.password = "bar"
# etc
end
# similar for other config options
end
Then the backup is executed a la bundle exec backup perform -t my_backup -c path/to/config.rb
.
My first swag at enabling a common config was to define methods that I could call from the blocks:
def my_db_config db
db.name = "my_database"
# etc
end
Backup::Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
my_db_config db
end
#etc
end
But this fails with an undefined method 'my_db_config' for #<Backup::Database::MySQL:0x10155adf0>
.
My intention was to get this to work and then split the common config functions into another file that I could require
in each of my config files. I also tried creating a file with the config code and require
ing it into the model definition block:
# common.rb
database MySQL do |db|
db.name = "my_database"
#etc
end
# config.rb
Backup::Model.new(:my_backup, 'My Backup') do
require "common.rb" # with the right path, etc
end
This also doesn't work, and from subsequent research I've discovered that that's just not the way that require
works. Something more in line with the way that C/C++'s #include
works (i.e., blindly pasting the contents into whatever scope it is called from) might work.
Any ideas?
Upvotes: 5
Views: 1315
Reputation: 3651
In newest versions of backup gem you can simple use main config file like this:
Genrate main config file:
root@youhost:~# backup generate:config
Modify file /root/Backup/config.rb like this:
Backup::Storage::S3.defaults do |s3|
s3.access_key_id = "youkey"
s3.secret_access_key = "yousecret"
s3.region = "us-east-1"
s3.bucket = "youbacket"
s3.path = "youpath"
end
Backup::Database::PostgreSQL.defaults do |db|
db.name = "youname"
db.username = "youusername"
db.password = "youpassword"
db.host = "localhost"
db.port = 5432
db.additional_options = ["-xc", "-E=utf8"]
end
Dir[File.join(File.dirname(Config.config_file), "models", "*.rb")].each do |model|
instance_eval(File.read(model))
end
Create model file:
root@youhost:~# backup generate:model --trigger daily_backup \
--databases="postgresql" --storages="s3"
Then modify /root/Backup/models/daily_backup.rb like this:
# encoding: utf-8
Backup::Model.new(:daily_backup, 'Description for daily_backup') do
split_into_chunks_of 250
database PostgreSQL do |db|
db.keep = 20
end
store_with S3 do |s3|
s3.keep = 20
end
end
With this you can simply create daily, monthly or yearly archives.
Upvotes: 1
Reputation: 13675
The gem seems to modify the execution scope of the config blocks. To work around this, you could wrap your functions in a class:
class MyConfig
def self.prepare_db(db)
db.name = "my_database"
# etc
db
end
end
Backup::Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
db = MyConfig.prepare_db(db)
end
#etc
end
You could get a bit more fancy and abstract your default config merge:
class BaseConfig
@@default_sets =
:db => {
:name => "my_database"
},
:s3 => {
:access_key => "my_s3_key"
}
}
def self.merge_defaults(initial_set, set_name)
@@default_sets[set_name].each do |k, v|
initial_set.send("#{k}=".to_sym, v)
end
initial_set
end
end
Backup::Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
db = BaseConfig.merge_defaults(db, :db)
end
store_with S3 do |s3|
s3 = BaseConfig.merge_defaults(s3, :s3)
end
end
Upvotes: 2