2011-11-22 15 views
5

Używam usługi meskyanichi: backup gem. W zasadzie robi to, czego potrzebuję, ale muszę mieć wiele kopii zapasowych (np. Co godzinę, codziennie, co tydzień). Konfiguracje są w większości takie same, ale mają kilka różnic, więc muszę mieć wiele plików konfiguracyjnych. Mam problem ze znalezieniem rozsądnego sposobu zarządzania wspólnymi bitami konfiguracji (tzn. Nie powtarzania części wspólnych).Klejnot kopii zapasowej Ruby - udostępniane konfiguracje?

Pliki konfiguracyjne używają wielu struktur bloków iz tego co wiem, każda kopia zapasowa musi mieć osobny plik konfiguracyjny (np. Config/backup/hourly.rb, config/backup/daily.rb, etc) . Typowy plik config wygląda następująco:

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 

Następnie kopia zapasowa jest wykonywana la bundle exec backup perform -t my_backup -c path/to/config.rb.

Mój pierwszy łup umożliwienie wspólnego config było zdefiniowanie metod, że mogę połączyć się z bloków:

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 

Ale to się nie powiedzie z undefined method 'my_db_config' for #<Backup::Database::MySQL:0x10155adf0>.

Moim zamiarem było, aby to zadziałało, a następnie podzielono wspólne funkcje konfiguracyjne na inny plik, który mogłem require w każdym z moich plików konfiguracyjnych. Próbowałem również utworzenie pliku z kodem konfiguracyjnym i require ing go do bloku definicji modelu

# 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 

To również nie działa, a od późniejszych badań odkryłem, że to nie jest po prostu tak, że require Prace. Coś bardziej zgodnego ze sposobem działania C/C++ na #include (tzn. Ślepo wklejając zawartość do dowolnego zakresu, z którego jest wywoływana) może działać.

Wszelkie pomysły?

Odpowiedz

2

Klej wydaje się modyfikować zakres wykonywania bloków konfiguracji. Aby obejść ten problem, można owinąć swoje funkcje w klasie:

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 

Można dostać nieco bardziej wyszukane i abstrakcyjne domyślny 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 
+0

Świetny pomysł! Dzięki! – dantswain

1

W najnowszych wersjach gem zapasowej możesz prosta obsługa główny plik konfiguracyjny tak:

genrate główny plik konfiguracyjny:

[email protected]:~# backup generate:config 

Modyfikowanie pliku /root/Backup/config.rb tak:

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 

Tworzenie modelu plik:

[email protected]:~# backup generate:model --trigger daily_backup \ 
--databases="postgresql" --storages="s3" 

następnie zmodyfikować /root/Backup/models/daily_backup.rb tak:

# 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 

Umożliwia to tworzenie archiwów dziennych, miesięcznych lub rocznych.

Powiązane problemy