From 17e6a95390ce5f5b62d4fc5cbe3a7fde87656bcc Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 23 Jun 2014 15:32:13 +0200 Subject: initial take on replication --- bin/tapicero | 9 +++-- lib/tapicero/replication.rb | 69 ++++++++++++++++++++++++++++++++++++++ lib/tapicero/user_database.rb | 10 ++++++ lib/tapicero/user_event_handler.rb | 1 + 4 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 lib/tapicero/replication.rb diff --git a/bin/tapicero b/bin/tapicero index 72f974b..49e73c2 100755 --- a/bin/tapicero +++ b/bin/tapicero @@ -61,11 +61,10 @@ end # Start the daemon # require 'daemons' -if ENV["USER"] == "root" - options = {:app_name => 'tapicero', :dir_mode => :system} # this will put the pid file in /var/run -else - options = {:app_name => 'tapicero', :dir_mode => :normal, :dir => '/tmp'} # this will put the pid file in /tmp -end + +# this will put the pid file in /var/run +options = {:app_name => 'tapicero', :dir_mode => :system} + begin Daemons.run("#{BASE_DIR}/lib/tapicero_daemon.rb", options) rescue SystemExit diff --git a/lib/tapicero/replication.rb b/lib/tapicero/replication.rb new file mode 100644 index 0000000..c8253a1 --- /dev/null +++ b/lib/tapicero/replication.rb @@ -0,0 +1,69 @@ +require 'couchrest' +require 'json' + +module Tapicero + class Replication + + LocalEndpoint = Struct.new(:name) do + def key; name; end + def url; name; end + def save_url; name; end + end + + RemoteEndpoint = Struct.new(:remote, :credentials) do + def key; domain; end + def url; "http://#{creds}@#{domain}:#{port}/#{name}"; end + def save_url; "http://...@#{domain}:#{port}/#{name}"; end + def domain; remote[:internal_domain]; end + def port; remote[:couch_port]; end + def name; remote[:name]; end + def creds; credentials[:username] + ':' + credentials[:password]; end + end + + def initialize(source, target) + @source = endpoint_for(source) + @target = endpoint_for(target) + end + + def run(options) + Tapicero.logger.debug "Replicating from #{source.save_url} to #{target.save_url}." + replication_db.save_doc replication_doc.merge(options) + end + + def replication_doc + { + _id: "#{source.key}_to_#{target.key}" + source: source.url, + target: target.url, + user_ctx: { + name: replication_credentials[:username], + roles: [replication_credentials[:role]] + } + } + end + + protected + + def endpoint_for(hash_or_string) + hash_or_string.respond_to? :[] ? + RemoteEndpoint.new(hash_or_string, replication_credentials) : + LocalEndpoint.new(hash_or_string) + end + + def replication_credentials + config.options[:replication].slice(:username, :password, :role) + end + + def replication_db + @replication_db ||= couch.database('_replicator') + end + + def couch + @couch ||= CouchRest.new(config.couch_host) + end + + def config + Tapicero.config + end + +end diff --git a/lib/tapicero/user_database.rb b/lib/tapicero/user_database.rb index f04e3e7..4061292 100644 --- a/lib/tapicero/user_database.rb +++ b/lib/tapicero/user_database.rb @@ -24,6 +24,16 @@ module Tapicero end end + def replicate() + return unless config.options[:mode] == 'mirror' + replication = config.options[:replication] + replication[:masters].each do |key, node| + retry_request_once "Replicating" do + Replication.new(source, name).run continuous: true + end + end + end + def add_design_docs pattern = BASE_DIR + 'designs' + '*.json' Tapicero.logger.debug "Looking for design docs in #{pattern}" diff --git a/lib/tapicero/user_event_handler.rb b/lib/tapicero/user_event_handler.rb index 38cf8f8..e49416b 100644 --- a/lib/tapicero/user_event_handler.rb +++ b/lib/tapicero/user_event_handler.rb @@ -26,6 +26,7 @@ module Tapicero db.create db.secure db.add_design_docs + db.replicate logger.info "Prepared storage " + db.name end -- cgit v1.2.3 From a5ce2d2563ccd56a37b281e549f44bf6f056f1d8 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 26 Jun 2014 11:37:20 +0200 Subject: minor: include username in save_url --- lib/tapicero/replication.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/tapicero/replication.rb b/lib/tapicero/replication.rb index c8253a1..1a2db22 100644 --- a/lib/tapicero/replication.rb +++ b/lib/tapicero/replication.rb @@ -13,11 +13,12 @@ module Tapicero RemoteEndpoint = Struct.new(:remote, :credentials) do def key; domain; end def url; "http://#{creds}@#{domain}:#{port}/#{name}"; end - def save_url; "http://...@#{domain}:#{port}/#{name}"; end + def save_url; "http://#{username}@#{domain}:#{port}/#{name}"; end def domain; remote[:internal_domain]; end def port; remote[:couch_port]; end def name; remote[:name]; end - def creds; credentials[:username] + ':' + credentials[:password]; end + def creds; username + ':' + credentials[:password]; end + def username; credentials[:username]; end end def initialize(source, target) -- cgit v1.2.3