summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazul <azul@leap.se>2014-06-26 11:38:26 +0200
committerazul <azul@leap.se>2014-06-26 11:38:26 +0200
commit3c431ed42419dd55fc4064133b899cb494278051 (patch)
treed61a3b68eadb94cbd9cdaf8284f84fccba8d2f46
parent02cd662255e52896445e0ba03455b858776a2b52 (diff)
parenta5ce2d2563ccd56a37b281e549f44bf6f056f1d8 (diff)
Merge pull request #15 from azul/feature/replication
initial take on replication
-rwxr-xr-xbin/tapicero9
-rw-r--r--lib/tapicero/replication.rb70
-rw-r--r--lib/tapicero/user_database.rb10
-rw-r--r--lib/tapicero/user_event_handler.rb1
4 files changed, 85 insertions, 5 deletions
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..1a2db22
--- /dev/null
+++ b/lib/tapicero/replication.rb
@@ -0,0 +1,70 @@
+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://#{username}@#{domain}:#{port}/#{name}"; end
+ def domain; remote[:internal_domain]; end
+ def port; remote[:couch_port]; end
+ def name; remote[:name]; end
+ def creds; username + ':' + credentials[:password]; end
+ def username; credentials[:username]; 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