blob: 7c621ae853ad5548d472d755c664580d4fd47873 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
require 'couchrest'
require 'json'
require 'tapicero/replication'
module Tapicero
class UserDatabase
def initialize(user_id)
@db = couch.database(config.options[:db_prefix] + user_id)
end
def create
retry_request_once "Creating database" do
create_db
end
end
def secure(security = nil)
security ||= config.options[:security]
# let's not overwrite if we have a security doc already
return if secured? && !Tapicero::FLAGS.include?('--overwrite-security')
retry_request_once "Writing security to" do
Tapicero.logger.debug security.to_json
CouchRest.put security_url, security
end
end
def replicate()
return unless config.options[:mode] == 'mirror'
replication = config.options[:replication]
replication["masters"].each do |key, node|
node["name"] = name
retry_request_once "Replicating" do
Tapicero::Replication.new(node, 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}"
Pathname.glob(pattern).each do |file|
retry_request_once "Uploading design doc to" do
upload_design_doc(file)
end
end
end
def upload_design_doc(file)
old = CouchRest.get design_url(file.basename('.json'))
rescue RestClient::ResourceNotFound
begin
CouchRest.put design_url(file.basename('.json')), JSON.parse(file.read)
rescue RestClient::Conflict
end
end
def destroy
retry_request_once "Deleting database" do
delete_db
end
end
def name
db.name
end
protected
#
# Sometimes attempting to create the db will fail with PreconditionFailed.
# This error is supposed to be returned only when the db already exists.
# However, sometimes the db will be created and PreconditionFailed will
# be returned.
#
# Might throw one of the following exceptions:
# * RestClient::BadRequest
# * RestClient::Unauthorized
#
def create_db
db.info # test if db exists
rescue RestClient::ResourceNotFound
begin
couch.create_db(db.name)
rescue RestClient::PreconditionFailed
end
end
def delete_db
db.delete! if db
rescue RestClient::ResourceNotFound # no database found
end
def retry_request_once(action)
second_try ||= false
Tapicero.logger.debug "#{action} #{db.name}"
yield
rescue RestClient::Exception => exc
raise exc if Tapicero::RERAISE
if second_try
log_error "#{action} #{db.name} failed twice due to: ", exc
else
log_info "#{action} #{db.name} failed (trying again soon): ", exc
sleep 5
second_try = true
retry
end
end
def log_error(message, exc)
# warn message is a one liner so nagios can parse it
Tapicero.logger.warn message.to_s + exc.class.name + ': ' + exc.to_s
Tapicero.logger.debug exc.backtrace.join("\n")
end
def log_info(message, exc)
Tapicero.logger.info message.to_s + exc.class.name + ': ' + exc.to_s
end
def secured?
retry_request_once "Checking security of" do
CouchRest.get(security_url).keys.any?
end
end
def security_url
db.root + "/_security"
end
def design_url(doc_name)
db.root + "/_design/#{doc_name}"
end
attr_reader :db
def couch
@couch ||= CouchRest.new(config.couch_host)
end
def config
Tapicero.config
end
end
end
|