source: trunk/src/allmydata/check_results.py

Last change on this file was dfdb6c60, checked in by Itamar Turner-Trauring <itamar@…>, at 2024-03-01T17:17:11Z

Fix lints.

  • Property mode set to 100644
File size: 11.6 KB
Line 
1"""Ported to Python 3.
2"""
3
4from zope.interface import implementer
5from allmydata.interfaces import ICheckResults, ICheckAndRepairResults, \
6     IDeepCheckResults, IDeepCheckAndRepairResults, IURI, IDisplayableServer
7from allmydata.util import base32
8
9@implementer(ICheckResults)
10class CheckResults(object):
11
12    def __init__(self, uri, storage_index,
13                 healthy, recoverable, count_happiness,
14                 count_shares_needed, count_shares_expected,
15                 count_shares_good, count_good_share_hosts,
16                 count_recoverable_versions, count_unrecoverable_versions,
17                 servers_responding, sharemap,
18                 count_wrong_shares, list_corrupt_shares, count_corrupt_shares,
19                 list_incompatible_shares, count_incompatible_shares,
20                 summary, report, share_problems, servermap):
21        assert IURI.providedBy(uri), uri
22        self._uri = uri
23        self._storage_index = storage_index
24        self._summary = ""
25        self._healthy = bool(healthy)
26        if self._healthy:
27            assert recoverable
28            if not summary:
29                summary = "healthy"
30        else:
31            if not summary:
32                summary = "not healthy"
33        self._recoverable = recoverable
34        if not self._recoverable:
35            assert not self._healthy
36
37        self._count_happiness = count_happiness
38        self._count_shares_needed = count_shares_needed
39        self._count_shares_expected = count_shares_expected
40        self._count_shares_good = count_shares_good
41        self._count_good_share_hosts = count_good_share_hosts
42        self._count_recoverable_versions = count_recoverable_versions
43        self._count_unrecoverable_versions = count_unrecoverable_versions
44        for server in servers_responding:
45            assert IDisplayableServer.providedBy(server), server
46        self._servers_responding = servers_responding
47        for shnum, servers in sharemap.items():
48            for server in servers:
49                assert IDisplayableServer.providedBy(server), server
50        self._sharemap = sharemap
51        self._count_wrong_shares = count_wrong_shares
52        for (server, SI, shnum) in list_corrupt_shares:
53            assert IDisplayableServer.providedBy(server), server
54        self._list_corrupt_shares = list_corrupt_shares
55        self._count_corrupt_shares = count_corrupt_shares
56        for (server, SI, shnum) in list_incompatible_shares:
57            assert IDisplayableServer.providedBy(server), server
58        self._list_incompatible_shares = list_incompatible_shares
59        self._count_incompatible_shares = count_incompatible_shares
60
61        # On Python 2, we can mix bytes and Unicode. On Python 3, we want
62        # unicode.
63        if isinstance(summary, bytes):
64            summary = str(summary, "utf-8")
65        assert isinstance(summary, str)  # should be a single string
66        self._summary = summary
67        assert not isinstance(report, str) # should be list of strings
68        self._report = report
69        if servermap:
70            from allmydata.mutable.servermap import ServerMap
71            assert isinstance(servermap, ServerMap), servermap
72        self._servermap = servermap # mutable only
73        self._share_problems = share_problems
74
75    def get_storage_index(self):
76        return self._storage_index
77    def get_storage_index_string(self):
78        return base32.b2a(self._storage_index)
79    def get_uri(self):
80        return self._uri
81
82    def is_healthy(self):
83        return self._healthy
84    def is_recoverable(self):
85        return self._recoverable
86
87    def get_happiness(self):
88        return self._count_happiness
89
90    def get_encoding_needed(self):
91        return self._count_shares_needed
92    def get_encoding_expected(self):
93        return self._count_shares_expected
94
95    def get_share_counter_good(self):
96        return self._count_shares_good
97    def get_share_counter_wrong(self):
98        return self._count_wrong_shares
99
100    def get_corrupt_shares(self):
101        return self._list_corrupt_shares
102
103    def get_incompatible_shares(self):
104        return self._list_incompatible_shares
105
106    def get_servers_responding(self):
107        return self._servers_responding
108
109    def get_host_counter_good_shares(self):
110        return self._count_good_share_hosts
111
112    def get_version_counter_recoverable(self):
113        return self._count_recoverable_versions
114    def get_version_counter_unrecoverable(self):
115        return self._count_unrecoverable_versions
116
117    def get_sharemap(self):
118        return self._sharemap
119
120    def as_dict(self):
121        sharemap = {}
122        for shnum, servers in self._sharemap.items():
123            sharemap[shnum] = sorted([s.get_serverid() for s in servers])
124        responding = [s.get_serverid() for s in self._servers_responding]
125        corrupt = [(s.get_serverid(), SI, shnum)
126                   for (s, SI, shnum) in self._list_corrupt_shares]
127        incompatible = [(s.get_serverid(), SI, shnum)
128                        for (s, SI, shnum) in self._list_incompatible_shares]
129        d = {"count-happiness": self._count_happiness,
130             "count-shares-needed": self._count_shares_needed,
131             "count-shares-expected": self._count_shares_expected,
132             "count-shares-good": self._count_shares_good,
133             "count-good-share-hosts": self._count_good_share_hosts,
134             "count-recoverable-versions": self._count_recoverable_versions,
135             "count-unrecoverable-versions": self._count_unrecoverable_versions,
136             "servers-responding": responding,
137             "sharemap": sharemap,
138             "count-wrong-shares": self._count_wrong_shares,
139             "list-corrupt-shares": corrupt,
140             "count-corrupt-shares": self._count_corrupt_shares,
141             "list-incompatible-shares": incompatible,
142             "count-incompatible-shares": self._count_incompatible_shares,
143             }
144        return d
145
146    def get_summary(self):
147        return self._summary
148    def get_report(self):
149        return self._report
150    def get_share_problems(self):
151        return self._share_problems
152    def get_servermap(self):
153        return self._servermap
154
155@implementer(ICheckAndRepairResults)
156class CheckAndRepairResults(object):
157
158    def __init__(self, storage_index):
159        self.storage_index = storage_index
160        self.repair_attempted = False
161
162    def get_storage_index(self):
163        return self.storage_index
164    def get_storage_index_string(self):
165        return base32.b2a(self.storage_index)
166    def get_repair_attempted(self):
167        return self.repair_attempted
168    def get_repair_successful(self):
169        if not self.repair_attempted:
170            return False
171        return self.repair_successful
172    def get_pre_repair_results(self):
173        return self.pre_repair_results
174    def get_post_repair_results(self):
175        return self.post_repair_results
176
177
178class DeepResultsBase(object):
179
180    def __init__(self, root_storage_index):
181        self.root_storage_index = root_storage_index
182        if root_storage_index is None:
183            self.root_storage_index_s = "<none>"  # is this correct?
184        else:
185            self.root_storage_index_s = base32.b2a(root_storage_index)
186
187        self.objects_checked = 0
188        self.objects_healthy = 0
189        self.objects_unhealthy = 0
190        self.objects_unrecoverable = 0
191        self.corrupt_shares = []
192        self.all_results = {}
193        self.all_results_by_storage_index = {}
194        self.stats = {}
195
196    def update_stats(self, new_stats):
197        self.stats.update(new_stats)
198
199    def get_root_storage_index_string(self):
200        return self.root_storage_index_s
201
202    def get_corrupt_shares(self):
203        return self.corrupt_shares
204
205    def get_all_results(self):
206        return self.all_results
207
208    def get_results_for_storage_index(self, storage_index):
209        return self.all_results_by_storage_index[storage_index]
210
211    def get_stats(self):
212        return self.stats
213
214
215@implementer(IDeepCheckResults)
216class DeepCheckResults(DeepResultsBase):
217
218    def add_check(self, r, path):
219        if not r:
220            return # non-distributed object, i.e. LIT file
221        r = ICheckResults(r)
222        assert isinstance(path, (list, tuple))
223        self.objects_checked += 1
224        if r.is_healthy():
225            self.objects_healthy += 1
226        else:
227            self.objects_unhealthy += 1
228        if not r.is_recoverable():
229            self.objects_unrecoverable += 1
230        self.all_results[tuple(path)] = r
231        self.all_results_by_storage_index[r.get_storage_index()] = r
232        self.corrupt_shares.extend(r.get_corrupt_shares())
233
234    def get_counters(self):
235        return {"count-objects-checked": self.objects_checked,
236                "count-objects-healthy": self.objects_healthy,
237                "count-objects-unhealthy": self.objects_unhealthy,
238                "count-objects-unrecoverable": self.objects_unrecoverable,
239                "count-corrupt-shares": len(self.corrupt_shares),
240                }
241
242
243@implementer(IDeepCheckAndRepairResults)
244class DeepCheckAndRepairResults(DeepResultsBase):
245
246    def __init__(self, root_storage_index):
247        DeepResultsBase.__init__(self, root_storage_index)
248        self.objects_healthy_post_repair = 0
249        self.objects_unhealthy_post_repair = 0
250        self.objects_unrecoverable_post_repair = 0
251        self.repairs_attempted = 0
252        self.repairs_successful = 0
253        self.repairs_unsuccessful = 0
254        self.corrupt_shares_post_repair = []
255
256    def add_check_and_repair(self, r, path):
257        if not r:
258            return # non-distributed object, i.e. LIT file
259        r = ICheckAndRepairResults(r)
260        assert isinstance(path, (list, tuple))
261        pre_repair = r.get_pre_repair_results()
262        post_repair = r.get_post_repair_results()
263        self.objects_checked += 1
264        if pre_repair.is_healthy():
265            self.objects_healthy += 1
266        else:
267            self.objects_unhealthy += 1
268        if not pre_repair.is_recoverable():
269            self.objects_unrecoverable += 1
270        self.corrupt_shares.extend(pre_repair.get_corrupt_shares())
271        if r.get_repair_attempted():
272            self.repairs_attempted += 1
273            if r.get_repair_successful():
274                self.repairs_successful += 1
275            else:
276                self.repairs_unsuccessful += 1
277        if post_repair.is_healthy():
278            self.objects_healthy_post_repair += 1
279        else:
280            self.objects_unhealthy_post_repair += 1
281        if not post_repair.is_recoverable():
282            self.objects_unrecoverable_post_repair += 1
283        self.all_results[tuple(path)] = r
284        self.all_results_by_storage_index[r.get_storage_index()] = r
285        self.corrupt_shares_post_repair.extend(post_repair.get_corrupt_shares())
286
287    def get_counters(self):
288        return {"count-objects-checked": self.objects_checked,
289                "count-objects-healthy-pre-repair": self.objects_healthy,
290                "count-objects-unhealthy-pre-repair": self.objects_unhealthy,
291                "count-objects-unrecoverable-pre-repair": self.objects_unrecoverable,
292                "count-objects-healthy-post-repair": self.objects_healthy_post_repair,
293                "count-objects-unhealthy-post-repair": self.objects_unhealthy_post_repair,
294                "count-objects-unrecoverable-post-repair": self.objects_unrecoverable_post_repair,
295                "count-repairs-attempted": self.repairs_attempted,
296                "count-repairs-successful": self.repairs_successful,
297                "count-repairs-unsuccessful": self.repairs_unsuccessful,
298                "count-corrupt-shares-pre-repair": len(self.corrupt_shares),
299                "count-corrupt-shares-post-repair": len(self.corrupt_shares_post_repair),
300                }
301
302    def get_remaining_corrupt_shares(self):
303        return self.corrupt_shares_post_repair
Note: See TracBrowser for help on using the repository browser.