Merge lp://qastaging/~tcole/desktopcouch/no-lsof into lp://qastaging/desktopcouch

Proposed by Tim Cole
Status: Merged
Approved by: Elliot Murphy
Approved revision: 9
Merged at revision: not available
Proposed branch: lp://qastaging/~tcole/desktopcouch/no-lsof
Merge into: lp://qastaging/desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~tcole/desktopcouch/no-lsof
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Needs Fixing
Elliot Murphy (community) Approve
Review via email: mp+8725@code.qastaging.launchpad.net
To post a comment you must log in.
Revision history for this message
Tim Cole (tcole) wrote :

Replace the ugly losf shell recipe that doesn't work on Karmic with ugly python code that does.

Revision history for this message
Elliot Murphy (statik) wrote :

WJW. ugly that works is better than ugly that doesn't - it's pretty crazy that you managed to reimplement lsof here and make it all make sense.

marking as disapprove only because i think this needs to be a branch of the desktopcouch project, not of ubunet since this code comes in from sourcedeps now.

review: Disapprove
7. By Tim Cole

nicer syntax from jamesh

Revision history for this message
Elliot Murphy (statik) wrote :

this is interesting, how did my disapprove vote on an ubunet branch get transferred over to a merge proposal on desktopcouch?

review: Approve
Revision history for this message
Eric Casteleijn (thisfred) wrote :

It's not working for me:

1. created a fresh branch of trunk and merged your branch in
2. made a fresh branch of ubuntuone and made link-sourcedeps
3. replaced sourcecode/desktopcouch with a symlink to 1.

when running make start (which invokes make start-desktopcouch) I get an error, which seems to apply the advertiseport no longer works. This may not have been broken on your branch, but we do need to fix it:

Traceback (most recent call last):
  File "utilities/load_sample_data.py", line 235, in <module>
    main()
  File "utilities/load_sample_data.py", line 227, in main
    if master_server.database_exists(user.u1_account_id):
  File "./lib/ubuntuone/cloud_server/server.py", line 347, in database_exists
    return dbname in self._server
  File "./lib/couchdb/client.py", line 122, in __contains__
    self.resource.head(validate_dbname(name))
  File "./lib/couchdb/client.py", line 859, in head
    return self._request('HEAD', path, headers=headers, **params)
  File "./lib/couchdb/client.py", line 893, in _request
    resp, data = _make_request()
  File "./lib/couchdb/client.py", line 888, in _make_request
    body=body, headers=headers)
  File "/var/lib/python-support/python2.6/httplib2/__init__.py", line 1068, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/var/lib/python-support/python2.6/httplib2/__init__.py", line 872, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/var/lib/python-support/python2.6/httplib2/__init__.py", line 841, in _conn_request
    conn.request(method, request_uri, body, headers)
  File "/usr/lib/python2.6/httplib.py", line 874, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.6/httplib.py", line 911, in _send_request
    self.endheaders()
  File "/usr/lib/python2.6/httplib.py", line 868, in endheaders
    self._send_output()
  File "/usr/lib/python2.6/httplib.py", line 740, in _send_output
    self.send(msg)
  File "/usr/lib/python2.6/httplib.py", line 699, in send
    self.connect()
  File "/var/lib/python-support/python2.6/httplib2/__init__.py", line 733, in connect
    raise socket.error, msg
socket.error: [Errno 111] Connection refused
make: *** [load-sample-data] Error 1
eric@thelog:~/canonical/ubuntuone/r-lsof$ Traceback (most recent call last):
  File "utilities/advertisePort.py", line 95, in <module>
    for fd in os.listdir(fd_dir)]
OSError: [Errno 2] No such file or directory: '/proc/21261/fd'

review: Needs Fixing
Revision history for this message
Tim Cole (tcole) wrote :

Ah, right. Need to deal with the stale pidfile case.

Revision history for this message
Tim Cole (tcole) wrote :

But it would appear that for you desktop couch is failing to start for reasons unrelated to my branch.

8. By Tim Cole

more informative errors

9. By Tim Cole

merge from trunk

Revision history for this message
Tim Cole (tcole) wrote :

So now it should report more useful errors when the PID file is stale or missing.

Revision history for this message
Elliot Murphy (statik) wrote :

> So now it should report more useful errors when the PID file is stale or
> missing.

i'm gonna go ahead and merge this since we're busted on karmic otherwise.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'utilities/advertisePort.py'
2--- utilities/advertisePort.py 2009-07-09 19:44:43 +0000
3+++ utilities/advertisePort.py 2009-07-14 03:14:43 +0000
4@@ -15,7 +15,8 @@
5 # You should have received a copy of the GNU Lesser General Public License
6 # along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
7 #
8-# Author: Stuart Langridge <stuart.langridge@canonical.com>
9+# Authors: Stuart Langridge <stuart.langridge@canonical.com>
10+# Tim Cole <tim.cole@canonical.com>
11
12 """CouchDB port advertiser.
13
14@@ -35,6 +36,7 @@
15
16 import local_files
17
18+import re
19 from dbus.mainloop.glib import DBusGMainLoop
20 import dbus.service, gobject, os, errno, time
21 DBusGMainLoop(set_as_default=True)
22@@ -77,16 +79,53 @@
23 start_local_couchdb.start_couchdb()
24 time.sleep(2) # give the process a chance to start
25
26- # Look in the CouchDB log to find the port number
27- # FIXME: currently do this by running the world's most complex lsof command
28- import subprocess
29- lsofcmd = 'lsof -i4TCP@localhost | grep $(couchdb -C %s -p %s -s | ' + \
30- 'cut -d" " -f7 | cut -d "," -f1) | grep "TCP " | ' + \
31- 'grep LISTEN | awk \'{print $8}\' | cut -d":" -f2'
32- actual_lsof_cmd = lsofcmd % (local_files.FILE_INI, local_files.FILE_PID)
33- stdout, stderr = subprocess.Popen(actual_lsof_cmd, shell=True,
34- stdout=subprocess.PIPE).communicate()
35- port = stdout.strip()
36+ # Look in the CouchDB log to find the port number, someday.
37+ # Currently, we have to grovel around in /proc instead.
38+ # Oh, the huge manatee... (this replaced an lsof shell recipe
39+ # which was shorter but less reliable)
40+
41+ # get the pid
42+ with open(local_files.FILE_PID) as pid_file:
43+ pid = int(pid_file.read().strip())
44+ proc_dir = "/proc/%s" % (pid,)
45+
46+ # enumerate the process' file descriptors
47+ fd_dir = os.path.join(proc_dir, 'fd')
48+ fd_paths = [os.readlink(os.path.join(fd_dir, fd))
49+ for fd in os.listdir(fd_dir)]
50+
51+ # identify socket fds
52+ socket_matches = [re.match('socket:\\[([0-9]+)\\]', p) for p in fd_paths]
53+ # extract their inode numbers
54+ socket_inodes = [m.group(1) for m in socket_matches if m is not None]
55+
56+ # construct a subexpression which matches any one of these inodes
57+ inode_subexp = "|".join(socket_inodes)
58+ # construct regexp to match /proc/net/tcp entries which are listening
59+ # sockets having one of the given inode numbers
60+ listening_regexp = re.compile('\\s*\\d+:\s*' # sl
61+ '0100007F:([0-9A-F]{4})\\s+' # local_address
62+ '00000000:0000\\s+' # rem_address
63+ '0A\\s+' # st (0A = listening)
64+ '[0-9A-F]{8}:' # tx_queue
65+ '[0-9A-F]{8}\\s+' # rx_queue
66+ '[0-9A-F]{2}:' # tr
67+ '[0-9A-F]{8}\\s+' # tm->when
68+ '[0-9A-F]{8}\\s*' # retrnsmt
69+ '\\d+\\s+\\d+\\s+' # uid, timeout
70+ '(?:%s)\\s+' % # inode
71+ (inode_subexp,))
72+
73+ # extract the TCP port from the first matching line in /proc/$pid/net/tcp
74+ port = None
75+ with open(os.path.join(proc_dir, 'net', 'tcp')) as tcp_file:
76+ for line in tcp_file:
77+ match = listening_regexp.match(line)
78+ if match is not None:
79+ port = int(match.group(1), 16)
80+ break
81+ if port is None:
82+ raise RuntimeError("Unable to find listening port")
83
84 # Advertise the port
85 mainloop = gobject.MainLoop()

Subscribers

People subscribed via source and target branches