Ruby备份gem - 共享配置?

时间:2011-11-22 15:18:43

标签: ruby configuration backup dry

我正在使用meskyanichi的backup gem。总的来说,它可以满足我的需求,但我需要有多个备份(例如,每小时,每天,每周)。配置大致相同,但有一些差异,所以我需要有多个配置文件。我无法找到一种理智的方法来管理配置的常见位(即,不重复公共部分)。

配置文件使用了很多块结构,据我所知,每个备份都需要一个单独的配置文件(例如config / backup / hourly.rb,config / backup / daily.rb等)。典型的配置文件如下所示:

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

然后执行备份la bundle exec backup perform -t my_backup -c path/to/config.rb

我在启用公共配置时的第一个想法是定义我可以从块调用的方法:

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

但是undefined method 'my_db_config' for #<Backup::Database::MySQL:0x10155adf0>失败了。

我的目的是让它工作,然后将公共配置功能拆分成另一个文件,我可以在每个配置文件中require。我还尝试使用配置代码创建一个文件,并require将其放入模型定义块:

# 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

这也行不通,从后来的研究中我发现这不是require的工作方式。更符合C / C ++的#include工作方式(即盲目地将内容粘贴到调用的任何范围)的方法可能会有效。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

gem似乎修改了配置块的执行范围。要解决这个问题,您可以将函数包装在一个类中:

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

你可能会更加花哨和抽象你的默认配置合并:

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

答案 1 :(得分:1)

在最新版本的备份gem中,您可以简单地使用主配置文件,如下所示:

Genrate主配置文件:

root@youhost:~# backup generate:config

修改文件/root/Backup/config.rb,如下所示:

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

创建模型文件:

root@youhost:~# backup generate:model --trigger daily_backup \
--databases="postgresql" --storages="s3"

然后像这样修改/root/Backup/models/daily_backup.rb:

# 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

通过此功能,您只需创建每日,每月或每年的档案。