Merge lp:~cmiller/desktopcouch/replication-to-u1 into lp:desktopcouch

Proposed by Chad Miller
Status: Merged
Approved by: Chad Miller
Approved revision: 79
Merged at revision: not available
Proposed branch: lp:~cmiller/desktopcouch/replication-to-u1
Merge into: lp:desktopcouch
Diff against target: 253 lines
8 files modified
bin/desktopcouch-service (+1/-1)
desktopcouch/pair/couchdb_pairing/couchdb_io.py (+23/-14)
desktopcouch/records/server.py (+5/-4)
desktopcouch/records/server_base.py (+5/-2)
desktopcouch/replication.py (+1/-4)
desktopcouch/replication_services/example.py (+1/-7)
desktopcouch/replication_services/ubuntuone.py (+8/-11)
setup.py (+1/-1)
To merge this branch: bzr merge lp:~cmiller/desktopcouch/replication-to-u1
Reviewer Review Type Date Requested Status
Ubuntu One hackers Pending
Review via email: mp+12527@code.launchpad.net

Commit message

Use U1 credentials when connecting to U1 for creating databases to replicate into. Remove extraneous function for couchdb service locations.

To post a comment you must log in.
75. By Chad Miller

Switch back to HMAC, from debugging PLAINTEXT, for OAuth.

76. By Chad Miller

Log to correct place.

77. By Chad Miller

Always try to replicate. Destroy the semantic of not having a self-identity
record meaning no replication; now, always create a self-identity record in
the service.

78. By Chad Miller

Restructure replicate function so we try replicate even if we can't verify that
the database exists.

Remove bogus put of test record!

79. By Chad Miller

Use OAuthCapableServer to connect to local, for replication action unsupported
in python couchdb module.

Revision history for this message
Chad Miller (cmiller) wrote :

Reviewed by Stuart and me on phone.

80. By Chad Miller

Bumped version number for release.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/desktopcouch-pair'
2=== modified file 'bin/desktopcouch-service'
3--- bin/desktopcouch-service 2009-09-11 03:18:00 +0000
4+++ bin/desktopcouch-service 2009-09-28 18:39:12 +0000
5@@ -72,7 +72,7 @@
6 import xdg.BaseDirectory
7
8 log_directory = os.path.join(xdg.BaseDirectory.xdg_cache_home,
9- "ubuntuone/log")
10+ "desktop-couch/log")
11 try:
12 os.makedirs(log_directory)
13 except:
14
15=== modified file 'desktopcouch/pair/couchdb_pairing/couchdb_io.py'
16--- desktopcouch/pair/couchdb_pairing/couchdb_io.py 2009-09-26 11:49:49 +0000
17+++ desktopcouch/pair/couchdb_pairing/couchdb_io.py 2009-09-28 18:39:12 +0000
18@@ -180,10 +180,12 @@
19 logging.debug("found %d %s records", len(values), key)
20 return values
21
22-def create_database(dst_host, dst_port, dst_name):
23+def create_database(dst_host, dst_port, dst_name, use_ssl=False,
24+ oauth_tokens=None):
25 """Given parts, create a database."""
26- dst_url = mkuri(dst_host, dst_port)
27- return server.CouchDatabase(dst_name, dst_url, create=True)
28+ dst_url = mkuri(dst_host, dst_port, use_ssl)
29+ return server.CouchDatabase(dst_name, dst_url, create=True,
30+ oauth_tokens=oauth_tokens)
31
32 def replicate(source_database, target_database, target_host=None,
33 target_port=None, source_host=None, source_port=None,
34@@ -211,27 +213,34 @@
35
36 record = dict(source=source, target=target)
37 try:
38- # regardless of source and target, we talk to our local couchdb :(
39- url = None # so logging works in exception handler
40- port = int(desktopcouch_find_port())
41- # TODO: Get admin username and password from keyring. Populate URL.
42- url = mkuri("localhost", port,)
43
44 if target_host:
45 # Target databases must exist before replicating to them.
46 logging.debug("creating %r %s:%d", target_database, target_host,
47 target_port)
48- create_database(target_host, target_port, target_database)
49+ create_database(target_host, target_port, target_database,
50+ target_ssl, target_oauth)
51+ except:
52+ logging.exception("can't talk to couchdb. %r %s:%d oauth=%s",
53+ target_database, target_host, target_port, target_oauth)
54+
55+ logging.debug("db exists, and we're ready to replicate")
56+ try:
57+ # regardless of source and target, we talk to our local couchdb :(
58+ port = int(desktopcouch_find_port())
59+ url = mkuri("localhost", port,)
60+
61+ logging.debug("asking %r to send %s to %s", url, source, target)
62
63 ### All until python-couchdb gets a Server.replicate() function
64- import couchdb
65- logging.debug("asking %r to send %s to %s", url, source, target)
66- server = couchdb.client.Server(url)
67- resp, data = server.resource.post(path='/_replicate', content=record)
68+ local_server = server.OAuthCapableServer(url)
69+ resp, data = local_server.resource.post(path='/_replicate', content=record)
70+
71 logging.debug("replicate result: %r %r", resp, data)
72 ###
73 except:
74- logging.exception("can't talk to couchdb. %r <== %r", url, record)
75+ logging.error("can't talk to couchdb. %r <== %r", url, record)
76+ raise
77
78 def get_pairings(uri=None):
79 """Get a list of paired servers."""
80
81=== modified file 'desktopcouch/records/server.py'
82--- desktopcouch/records/server.py 2009-09-14 20:18:53 +0000
83+++ desktopcouch/records/server.py 2009-09-28 18:39:12 +0000
84@@ -26,12 +26,13 @@
85 from desktopcouch.records import server_base
86
87 class OAuthCapableServer(Server):
88- def __init__(self, uri):
89+ def __init__(self, uri, oauth_tokens=None):
90 """Subclass of couchdb.client.Server which creates a custom
91 httplib2.Http subclass which understands OAuth"""
92 http = server_base.OAuthCapableHttp()
93 http.force_exception_to_status_code = False
94- oauth_tokens = desktopcouch.local_files.get_oauth_tokens()
95+ if oauth_tokens is None:
96+ oauth_tokens = desktopcouch.local_files.get_oauth_tokens()
97 (consumer_key, consumer_secret, token, token_secret) = (
98 oauth_tokens["consumer_key"], oauth_tokens["consumer_secret"],
99 oauth_tokens["token"], oauth_tokens["token_secret"])
100@@ -42,11 +43,11 @@
101 """An small records specific abstraction over a couch db database."""
102
103 def __init__(self, database, uri=None, record_factory=None, create=False,
104- server_class=OAuthCapableServer):
105+ server_class=OAuthCapableServer, oauth_tokens=None):
106 if not uri:
107 desktopcouch.find_pid()
108 port = desktopcouch.find_port()
109 uri = "http://localhost:%s" % port
110 super(CouchDatabase, self).__init__(
111 database, uri, record_factory=record_factory, create=create,
112- server_class=server_class)
113+ server_class=server_class, oauth_tokens=oauth_tokens)
114
115=== modified file 'desktopcouch/records/server_base.py'
116--- desktopcouch/records/server_base.py 2009-09-14 20:22:03 +0000
117+++ desktopcouch/records/server_base.py 2009-09-28 18:39:12 +0000
118@@ -29,6 +29,7 @@
119 from oauth import oauth
120 import urlparse
121 import cgi
122+import logging
123
124 #DEFAULT_DESIGN_DOCUMENT = "design"
125 DEFAULT_DESIGN_DOCUMENT = None # each view in its own eponymous design doc.
126@@ -72,6 +73,8 @@
127 )
128 req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, access_token)
129 headers.update(httplib2._normalize_headers(req.to_header()))
130+ for header in headers.iteritems():
131+ logging.debug("header %s", header)
132
133 class OAuthCapableHttp(httplib2.Http):
134 """Subclass of httplib2.Http which specifically uses our OAuth
135@@ -107,9 +110,9 @@
136 """An small records specific abstraction over a couch db database."""
137
138 def __init__(self, database, uri, record_factory=None, create=False,
139- server_class=Server):
140+ server_class=Server, **server_class_extras):
141 self.server_uri = uri
142- self._server = server_class(self.server_uri)
143+ self._server = server_class(self.server_uri, **server_class_extras)
144 if database not in self._server:
145 if create:
146 self._server.create(database)
147
148=== modified file 'desktopcouch/replication.py'
149--- desktopcouch/replication.py 2009-09-16 17:03:02 +0000
150+++ desktopcouch/replication.py 2009-09-28 18:39:12 +0000
151@@ -205,10 +205,7 @@
152 def set_up(port_getter):
153 port = port_getter()
154 unique_identifiers = couchdb_io.get_my_host_unique_id(
155- couchdb_io.mkuri("localhost", int(port)), create=False)
156- if unique_identifiers is None:
157- log.warn("No unique hostaccount id is set, so pairing not enabled.")
158- return None
159+ couchdb_io.mkuri("localhost", int(port)), create=True)
160
161 beacons = [dbus_io.LocationAdvertisement(port, "desktopcouch " + i)
162 for i in unique_identifiers]
163
164=== modified file 'desktopcouch/replication_services/example.py'
165--- desktopcouch/replication_services/example.py 2009-09-04 22:25:44 +0000
166+++ desktopcouch/replication_services/example.py 2009-09-28 18:39:12 +0000
167@@ -19,14 +19,8 @@
168 # or to symbolize failure
169 return None
170
171-# Required
172-def couchdb_location():
173- """Give a tuple of hostname and port number."""
174-
175- return "couchdb.example.com", 5984
176-
177 # Access to this as a string fires off functions.
178 # Required
179-db_name_prefix = "foo"
180+db_name_prefix = "http://host.required.example.com/a_prefix_if_necessary"
181 # You can be sure that access to this will always, always be through its
182 # __str__ method.
183
184=== modified file 'desktopcouch/replication_services/ubuntuone.py'
185--- desktopcouch/replication_services/ubuntuone.py 2009-09-17 09:58:35 +0000
186+++ desktopcouch/replication_services/ubuntuone.py 2009-09-28 18:39:12 +0000
187@@ -8,6 +8,9 @@
188 name = "Ubuntu One"
189 description = "The Ubuntu One cloud service"
190
191+oauth_consumer_key = "ubuntuone"
192+oauth_consumer_secret = "hammertime"
193+
194 def is_active():
195 """Can we deliver information?"""
196 return get_oauth_data() is not None
197@@ -24,7 +27,7 @@
198 matches = gnomekeyring.find_items_sync(
199 gnomekeyring.ITEM_GENERIC_SECRET,
200 {'ubuntuone-realm': "https://ubuntuone.com",
201- 'oauth-consumer-key': "ubuntuone"})
202+ 'oauth-consumer-key': oauth_consumer_key})
203 if matches:
204 # parse "a=b&c=d" to {"a":"b","c":"d"}
205 kv_list = [x.split("=", 1) for x in matches[0].secret.split("&")]
206@@ -32,8 +35,8 @@
207 keys = [k.replace("oauth_", "") for k in keys]
208 oauth_data = dict(zip(keys, values))
209 oauth_data.update({
210- "consumer_key": "ubuntuone",
211- "consumer_secret": "",
212+ "consumer_key": oauth_consumer_key,
213+ "consumer_secret": oauth_consumer_secret,
214 })
215 return oauth_data
216 except ImportError, e:
217@@ -47,13 +50,6 @@
218 logging.error("No keyring daemon found in this session, so we have "
219 "no access to Ubuntu One data.")
220
221-def couchdb_location():
222- """This can vary more often than the OAuth information. Support SRV
223- records and whatnot."""
224-
225- # ...eventually. For now, hard-coded. Maybe YAGNI.
226- return "couchdb.one.ubuntu.com", 5984
227-
228 def get_oauth_token(consumer):
229 """Get the token from the keyring"""
230 import gobject
231@@ -96,7 +92,8 @@
232
233 url = "https://one.ubuntu.com/api/account/"
234 if self.oauth_header is None:
235- consumer = oauth.OAuthConsumer("ubuntuone", "hammertime")
236+ consumer = oauth.OAuthConsumer(oauth_consumer_key,
237+ oauth_consumer_secret)
238 try:
239 access_token = get_oauth_token(consumer)
240 except gnomekeyring.NoKeyringDaemonError:
241
242=== modified file 'setup.py'
243--- setup.py 2009-09-14 21:48:36 +0000
244+++ setup.py 2009-09-28 18:39:12 +0000
245@@ -22,7 +22,7 @@
246
247 setup(
248 name='desktopcouch',
249- version='0.4',
250+ version='0.4.2',
251 description='A Desktop CouchDB instance.',
252 url='https://launchpad.net/desktopcouch',
253 license='LGPL-3',

Subscribers

People subscribed via source and target branches