Merge lp:~verterok/ubuntuone-client/kill-the-zombie-share into lp:ubuntuone-client

Proposed by Guillermo Gonzalez
Status: Merged
Approved by: Joshua Blount
Approved revision: 47
Merged at revision: not available
Proposed branch: lp:~verterok/ubuntuone-client/kill-the-zombie-share
Merge into: lp:ubuntuone-client
Diff against target: None lines
To merge this branch: bzr merge lp:~verterok/ubuntuone-client/kill-the-zombie-share
Reviewer Review Type Date Requested Status
Joshua Blount (community) Approve
Elliot Murphy (community) Approve
Review via email: mp+7649@code.launchpad.net

Commit message

[r=jblount, r=statik] delete share/d metadata if the share was deleted/canceled (this is done when a new share list is received)

To post a comment you must log in.
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

This branch adds some housekeeping code to the SHARE_LIST handler in VolumeManager, in order to delete dead/orphaned shares.

Revision history for this message
Guillermo Gonzalez (verterok) wrote :

This is the first branch of two in order to fix Bug #383760

Revision history for this message
Elliot Murphy (statik) :
review: Approve
Revision history for this message
Joshua Blount (jblount) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'canonical/ubuntuone/storage/syncdaemon/filesystem_manager.py'
2--- canonical/ubuntuone/storage/syncdaemon/filesystem_manager.py 2009-05-19 14:11:44 +0000
3+++ canonical/ubuntuone/storage/syncdaemon/filesystem_manager.py 2009-06-18 01:31:04 +0000
4@@ -544,7 +544,7 @@
5 # it that, :(. We handle this here because it's possible
6 # and correct that the path is not there anymore
7 m = "Error %s when trying to remove the watch on %r"
8- log_warning(m, path)
9+ log_warning(m, e, path)
10
11 self.delete_metadata(p)
12 mdobj["info"]["last_conflicted"] = time.time()
13
14=== modified file 'canonical/ubuntuone/storage/syncdaemon/volume_manager.py'
15--- canonical/ubuntuone/storage/syncdaemon/volume_manager.py 2009-05-12 13:36:05 +0000
16+++ canonical/ubuntuone/storage/syncdaemon/volume_manager.py 2009-06-18 14:47:31 +0000
17@@ -23,6 +23,7 @@
18 import shutil
19 import stat
20 from contextlib import contextmanager
21+from itertools import ifilter
22
23 from canonical.ubuntuone.storage.syncdaemon.marker import MDMarker
24 from canonical.ubuntuone.storage.syncdaemon import file_shelf
25@@ -175,18 +176,21 @@
26
27 def handle_AQ_SHARES_LIST(self, shares_list):
28 """ handle AQ_SHARES_LIST event """
29- for share in shares_list.shares:
30- share_id = getattr(share, 'id', getattr(share, 'share_id', None))
31- self.log.debug('new share %r: id=%s, name=%r',
32- share.direction, share_id, share.name)
33-
34+ self.log.debug('handling shares list: ')
35 self.list_shares_retries = 0
36+ shares = []
37+ shared = []
38 for a_share in shares_list.shares:
39+ share_id = getattr(a_share, 'id',
40+ getattr(a_share, 'share_id', None))
41+ self.log.debug('share %r: id=%s, name=%r', a_share.direction,
42+ share_id, a_share.name)
43 if a_share.direction == "to_me":
44 dir_name = self._build_dirname(a_share.name,
45 a_share.other_visible_name)
46 path = os.path.join(self.m.shares_dir, dir_name)
47 share = Share.from_response(a_share, path)
48+ shares.append(share.id)
49 self.add_share(share)
50 elif a_share.direction == "from_me":
51 try:
52@@ -199,8 +203,21 @@
53 " but don't have the node_id in the metadata yet")
54 path = None
55 share = Share.from_response(a_share, path)
56+ shared.append(share.id)
57 self.add_shared(share)
58
59+ # housekeeping of the shares and shared shelf's each time we get the
60+ # list of shares
61+ self.log.debug('deleting dead shares')
62+ for share in ifilter(lambda item: item and item not in shares,
63+ self.shares):
64+ self.log.debug('deleting share: id=%s', share)
65+ self.share_deleted(share)
66+ for share in ifilter(lambda item: item and item not in shared,
67+ self.shared):
68+ self.log.debug('deleting shared: id=%s', share)
69+ del self.shared[share]
70+
71 def _build_dirname(self, share_name, visible_name):
72 '''Builds the root path using the share information.'''
73 dir_name = share_name + u' from ' + visible_name
74@@ -210,7 +227,6 @@
75 dir_name = dir_name.encode("utf8")
76 return dir_name
77
78-
79 def handle_AQ_LIST_SHARES_ERROR(self, error):
80 """ handle AQ_LIST_SHARES_ERROR event """
81 # just call list_shares again, until we reach the retry limit
82@@ -268,6 +284,8 @@
83 """ Add a share to the share list, and creates the fs mdobj. """
84 self.log.info('Adding new share with id: %s - path: %r',
85 share.id, share.path)
86+ if share.id in self.shares:
87+ del self.shares[share.id]
88 self.shares[share.id] = share
89 if share.accepted:
90 self._create_fsm_object(share)
91@@ -294,8 +312,6 @@
92
93 def share_deleted(self, share_id):
94 """ process the share deleted event. """
95- # XXX: verterok: shares deletion is not fully implemented,
96- # the files aren't deleted from disk
97 self.log.debug("Share (id: %s) deleted. ", share_id)
98 share = self.shares.get(share_id, None)
99 if share is None:
100@@ -343,9 +359,21 @@
101 server_hash=None,))
102
103 def _delete_fsm_object(self, share):
104- """ Deletes the share from fsm. """
105- #XXX: not implemented yet, this ;ll delegate most of the work in fsm
106- pass
107+ """ Deletes the share and it files/folders metadata from fsm. """
108+ #XXX: partially implemented, this should be moved into fsm?.
109+ # should delete all the files in the share?
110+ if share.can_write():
111+ try:
112+ self.m.event_q.inotify_rm_watch(share.path)
113+ except (ValueError, RuntimeError, TypeError), e:
114+ # pyinotify has an ugly error management, if we can call
115+ # it that, :(. We handle this here because it's possible
116+ # and correct that the path is not there anymore
117+ self.log.warning("Error %s when trying to remove the watch"
118+ " on %r", e, share.path)
119+ # delete all the metadata but dont touch the files/folders
120+ for path, is_dir in self.m.fs.get_paths_starting_with(share.path):
121+ self.m.fs.delete_metadata(path)
122
123 def create_share(self, path, username, name, access_level):
124 """ create a share for the specified path, username, name """
125
126=== modified file 'tests/syncdaemon/test_vm.py'
127--- tests/syncdaemon/test_vm.py 2009-05-12 17:34:36 +0000
128+++ tests/syncdaemon/test_vm.py 2009-06-18 01:31:04 +0000
129@@ -322,6 +322,45 @@
130 self.vm.handle_SV_SHARE_ANSWERED('share_id', 'Yes')
131 self.assertNotIn('share_id', self.vm.shared)
132
133+ def test_delete_share(self):
134+ share_response = ShareResponse.from_params('share_id', 'to_me',
135+ 'fake_share_uuid',
136+ 'fake_share', 'username',
137+ 'visible_username', 'yes',
138+ 'View')
139+ share_response_1 = ShareResponse.from_params('share_id_1', 'to_me',
140+ 'fake_share_uuid_1',
141+ 'fake_share_1', 'username',
142+ 'visible_username', 'yes',
143+ 'View')
144+ # initialize the the root
145+ self.vm.on_server_root('root_uuid')
146+ response = ListShares(None)
147+ response.shares = [share_response, share_response_1]
148+ self.vm.handle_AQ_SHARES_LIST(response)
149+ self.assertEquals(3, len(self.vm.shares)) # the new shares and root
150+ # check that the share is in the shares dict
151+ self.assertTrue('share_id' in self.vm.shares)
152+ self.assertTrue('share_id_1' in self.vm.shares)
153+ share = self.vm.shares['share_id']
154+ self.assertEquals('fake_share', share.name)
155+ self.assertEquals('fake_share_uuid', share.subtree)
156+ share = self.vm.shares['share_id_1']
157+ self.assertEquals('fake_share_1', share.name)
158+ self.assertEquals('fake_share_uuid_1', share.subtree)
159+ # inject a new ListShares response
160+ new_response = ListShares(None)
161+ new_response.shares = [share_response]
162+ self.vm.handle_AQ_SHARES_LIST(new_response)
163+ # check that the missing share was removed
164+ self.assertTrue('share_id' in self.vm.shares)
165+ self.assertFalse('share_id_1' in self.vm.shares)
166+ share = self.vm.shares['share_id']
167+ self.assertEquals('fake_share', share.name)
168+ self.assertEquals('fake_share_uuid', share.subtree)
169+ self.assertEquals(None, self.vm.shares.get('share_id_1'))
170+
171+
172 class VolumeManagerUnicodeTests(BaseVolumeManagerTests):
173 """Tests for Volume Manager unicode capabilities."""
174

Subscribers

People subscribed via source and target branches