lockss-debugpanel 0.9.0.dev7__py3-none-any.whl → 0.10.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lockss/debugpanel/__init__.py +3 -295
- lockss/debugpanel/__main__.py +1 -1
- lockss/debugpanel/_core.py +396 -0
- lockss/debugpanel/cli.py +230 -169
- {lockss_debugpanel-0.9.0.dev7.dist-info → lockss_debugpanel-0.10.0.dev1.dist-info}/METADATA +11 -11
- lockss_debugpanel-0.10.0.dev1.dist-info/RECORD +9 -0
- {lockss_debugpanel-0.9.0.dev7.dist-info → lockss_debugpanel-0.10.0.dev1.dist-info}/WHEEL +1 -1
- {lockss_debugpanel-0.9.0.dev7.dist-info → lockss_debugpanel-0.10.0.dev1.dist-info}/licenses/LICENSE +1 -1
- lockss_debugpanel-0.9.0.dev7.dist-info/RECORD +0 -8
- {lockss_debugpanel-0.9.0.dev7.dist-info → lockss_debugpanel-0.10.0.dev1.dist-info}/entry_points.txt +0 -0
lockss/debugpanel/__init__.py
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
Library and command line tool to interact with the LOCKSS 1.x DebugPanel servlet.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
__version__ = '0.
|
|
7
|
+
__version__ = '0.10.0-dev1'
|
|
8
8
|
|
|
9
9
|
__copyright__ = '''
|
|
10
|
-
Copyright (c) 2000-
|
|
10
|
+
Copyright (c) 2000-2026, Board of Trustees of Leland Stanford Jr. University
|
|
11
11
|
'''.strip()
|
|
12
12
|
|
|
13
13
|
__license__ = __copyright__ + '\n\n' + '''
|
|
@@ -38,296 +38,4 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
38
38
|
POSSIBILITY OF SUCH DAMAGE.
|
|
39
39
|
'''.strip()
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
from base64 import b64encode
|
|
43
|
-
from urllib.request import Request, urlopen
|
|
44
|
-
from typing import Any
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
type RequestUrlOpenT = Any
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
DEFAULT_DEPTH = 123
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class Node(object):
|
|
54
|
-
"""
|
|
55
|
-
Connector to a LOCKSS 1.x node.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
DEFAULT_PROTOCOL = 'http'
|
|
59
|
-
|
|
60
|
-
def __init__(self, node_reference: str, u: str, p: str) -> None:
|
|
61
|
-
"""
|
|
62
|
-
Constructs a new ``Node`` instance.
|
|
63
|
-
|
|
64
|
-
:param node_reference: A LOCKSS 1.x node reference, typically of the
|
|
65
|
-
form ``http://lockss.university.edu:8081``. If
|
|
66
|
-
no protocol is specified,
|
|
67
|
-
``Node.DEFAULT_PROTOCOL`` is assumed. If a final
|
|
68
|
-
slash is included, it is ignored.
|
|
69
|
-
:type node_reference: str
|
|
70
|
-
:param u: The username for the given node's Web user interface.
|
|
71
|
-
:type u: str
|
|
72
|
-
:param p: The password for the given node's Web user interface.
|
|
73
|
-
:type p: str
|
|
74
|
-
"""
|
|
75
|
-
super().__init__()
|
|
76
|
-
if '://' not in node_reference:
|
|
77
|
-
node_reference = f'{Node.DEFAULT_PROTOCOL}://{node_reference}'
|
|
78
|
-
if node_reference.endswith('/'):
|
|
79
|
-
node_reference = node_reference[:-1]
|
|
80
|
-
self._url: str = node_reference
|
|
81
|
-
self._basic: str = b64encode(f'{u}:{p}'.encode('utf-8')).decode('utf-8')
|
|
82
|
-
|
|
83
|
-
def authenticate(self, req: Request) -> None:
|
|
84
|
-
"""
|
|
85
|
-
Does what is necessary to authenticate with the given ``Request``
|
|
86
|
-
object.
|
|
87
|
-
|
|
88
|
-
:param req: A ``Request`` instance.
|
|
89
|
-
:type req: Request
|
|
90
|
-
"""
|
|
91
|
-
req.add_header('Authorization', f'Basic {self._basic}')
|
|
92
|
-
|
|
93
|
-
def get_url(self) -> str:
|
|
94
|
-
"""
|
|
95
|
-
Returns the full URL corresponding to this node (with protocol but no
|
|
96
|
-
final slash).
|
|
97
|
-
|
|
98
|
-
:return: The full URL corresponding to this node.
|
|
99
|
-
:rtype: str
|
|
100
|
-
"""
|
|
101
|
-
return self._url
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def check_substance(node: Node, auid: str) -> RequestUrlOpenT:
|
|
105
|
-
"""
|
|
106
|
-
Performs the DebugPanel servlet "Check Substance" operation on the given
|
|
107
|
-
node for the given AUID.
|
|
108
|
-
|
|
109
|
-
:param node: A ``Node`` instance.
|
|
110
|
-
:type node: Node
|
|
111
|
-
:param auid: An AUID.
|
|
112
|
-
:type auid: str
|
|
113
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
114
|
-
:rtype: RequestUrlOpenT
|
|
115
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
116
|
-
"""
|
|
117
|
-
return _auid_action(node, auid, 'Check Substance')
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def crawl(node: Node, auid: str) -> RequestUrlOpenT:
|
|
121
|
-
"""
|
|
122
|
-
Performs the DebugPanel servlet "Force Start Crawl" operation on the given
|
|
123
|
-
node for the given AUID.
|
|
124
|
-
|
|
125
|
-
:param node: A ``Node`` instance.
|
|
126
|
-
:type node: Node
|
|
127
|
-
:param auid: An AUID.
|
|
128
|
-
:type auid: str
|
|
129
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
130
|
-
:rtype: RequestUrlOpenT
|
|
131
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
132
|
-
"""
|
|
133
|
-
return _auid_action(node, auid, 'Force Start Crawl')
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def crawl_plugins(node: Node) -> RequestUrlOpenT:
|
|
137
|
-
"""
|
|
138
|
-
Performs the DebugPanel servlet "Crawl Plugins" operation on the given
|
|
139
|
-
node.
|
|
140
|
-
|
|
141
|
-
:param node: A ``Node`` instance.
|
|
142
|
-
:type node: Node
|
|
143
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
144
|
-
:rtype: RequestUrlOpenT
|
|
145
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
146
|
-
"""
|
|
147
|
-
return _node_action(node, 'Crawl Plugins')
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def deep_crawl(node: Node, auid: str, depth: int=DEFAULT_DEPTH) -> RequestUrlOpenT:
|
|
151
|
-
"""
|
|
152
|
-
Performs the DebugPanel servlet "Force Deep Crawl" operation on the given
|
|
153
|
-
node for the given AUID, with the given depth (default ``DEFAULT_DEPTH``).
|
|
154
|
-
|
|
155
|
-
:param node: A ``Node`` instance.
|
|
156
|
-
:type node: Node
|
|
157
|
-
:param auid: An AUID.
|
|
158
|
-
:type auid: str
|
|
159
|
-
:param depth: A strictly positive refetch depth.
|
|
160
|
-
:type auid: int
|
|
161
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
162
|
-
:rtype: RequestUrlOpenT
|
|
163
|
-
:raises ValueError: If depth is negative or zero.
|
|
164
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
165
|
-
"""
|
|
166
|
-
if depth < 1:
|
|
167
|
-
raise ValueError(f'depth must be a strictly positive integer, got {depth}')
|
|
168
|
-
return _auid_action(node, auid, 'Force Deep Crawl', depth=depth)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def disable_indexing(node: Node, auid: str) -> RequestUrlOpenT:
|
|
172
|
-
"""
|
|
173
|
-
Performs the DebugPanel servlet "Disable Indexing" operation on the given
|
|
174
|
-
node for the given AUID.
|
|
175
|
-
|
|
176
|
-
:param node: A ``Node`` instance.
|
|
177
|
-
:type node: Node
|
|
178
|
-
:param auid: An AUID.
|
|
179
|
-
:type auid: str
|
|
180
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
181
|
-
:rtype: RequestUrlOpenT
|
|
182
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
183
|
-
"""
|
|
184
|
-
return _auid_action(node, auid, 'Disable Indexing')
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def node(node_reference: str, u: str, p: str) -> Node:
|
|
188
|
-
"""
|
|
189
|
-
DEPRECATED: Constructs a new ``Node`` instance (see the ``Node``
|
|
190
|
-
constructor); THIS FUNCTION WILL BE REMOVED IN VERSION 0.9.0.
|
|
191
|
-
|
|
192
|
-
:param node_reference: See the ``Node`` constructor.
|
|
193
|
-
:type node_reference: str
|
|
194
|
-
:param u: See the ``Node`` constructor.
|
|
195
|
-
:type node_reference: str
|
|
196
|
-
:param p: See the ``Node`` constructor.
|
|
197
|
-
:type node_reference: str
|
|
198
|
-
:return: See the ``Node`` constructor.
|
|
199
|
-
:rtype: Node
|
|
200
|
-
"""
|
|
201
|
-
return Node(node_reference, u, p)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def poll(node: Node, auid: str) -> RequestUrlOpenT:
|
|
205
|
-
"""
|
|
206
|
-
Performs the DebugPanel servlet "Start V3 Poll" operation on the given
|
|
207
|
-
node for the given AUID.
|
|
208
|
-
|
|
209
|
-
:param node: A ``Node`` instance.
|
|
210
|
-
:type node: Node
|
|
211
|
-
:param auid: An AUID.
|
|
212
|
-
:type auid: str
|
|
213
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
214
|
-
:rtype: RequestUrlOpenT
|
|
215
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
216
|
-
"""
|
|
217
|
-
return _auid_action(node, auid, 'Start V3 Poll')
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
def reindex_metadata(node: Node, auid: str) -> RequestUrlOpenT:
|
|
221
|
-
"""
|
|
222
|
-
Performs the DebugPanel servlet "Force Reindex Metadata" operation on the
|
|
223
|
-
given node for the given AUID.
|
|
224
|
-
|
|
225
|
-
:param node: A ``Node`` instance.
|
|
226
|
-
:type node: Node
|
|
227
|
-
:param auid: An AUID.
|
|
228
|
-
:type auid: str
|
|
229
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
230
|
-
:rtype: RequestUrlOpenT
|
|
231
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
232
|
-
"""
|
|
233
|
-
return _auid_action(node, auid, 'Force Reindex Metadata')
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def reload_config(node: Node) -> RequestUrlOpenT:
|
|
237
|
-
"""
|
|
238
|
-
Performs the DebugPanel servlet "Reload Config" operation on the given
|
|
239
|
-
node.
|
|
240
|
-
|
|
241
|
-
:param node: A ``Node`` instance.
|
|
242
|
-
:type node: Node
|
|
243
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
244
|
-
:rtype: RequestUrlOpenT
|
|
245
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
246
|
-
"""
|
|
247
|
-
return _node_action(node, 'Reload Config')
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
def validate_files(node: Node, auid: str) -> RequestUrlOpenT:
|
|
251
|
-
"""
|
|
252
|
-
Performs the DebugPanel servlet "Validate Files" operation on the given
|
|
253
|
-
node for the given AUID.
|
|
254
|
-
|
|
255
|
-
:param node: A ``Node`` instance.
|
|
256
|
-
:type node: Node
|
|
257
|
-
:param auid: An AUID.
|
|
258
|
-
:type auid: str
|
|
259
|
-
:return: The result of ``urllib.request.urlopen``.
|
|
260
|
-
:rtype: RequestUrlOpenT
|
|
261
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
262
|
-
"""
|
|
263
|
-
return _auid_action(node, auid, 'Validate Files')
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
def _auid_action(node: Node, auid: str, action: str, **kwargs) -> RequestUrlOpenT:
|
|
267
|
-
"""
|
|
268
|
-
Performs one AUID-centric action.
|
|
269
|
-
|
|
270
|
-
:param node: A ``Node`` instance.
|
|
271
|
-
:type node: Node
|
|
272
|
-
:param auid: An AUID.
|
|
273
|
-
:type auid: str
|
|
274
|
-
:param action: An AUID-oriented DebugPanel servlet action string, e.g.
|
|
275
|
-
``Force Deep Crawl``.
|
|
276
|
-
:type action: str
|
|
277
|
-
:param kwargs: Key-value pairs of additional query string arguments.
|
|
278
|
-
:type kwargs: dict[str, Any]
|
|
279
|
-
:return: The result of calling `urllib.request.urlopen`` on an appropriate
|
|
280
|
-
URL.
|
|
281
|
-
:rtype: RequestUrlOpenT
|
|
282
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
283
|
-
"""
|
|
284
|
-
action_encoded = action.replace(" ", "%20")
|
|
285
|
-
auid_encoded = auid.replace('%', '%25').replace('|', '%7C').replace('&', '%26').replace('~', '%7E')
|
|
286
|
-
req = _make_request(node, f'action={action_encoded}&auid={auid_encoded}', **kwargs)
|
|
287
|
-
return urlopen(req)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
def _make_request(node: Node, query: str, **kwargs) -> Request:
|
|
291
|
-
"""
|
|
292
|
-
Constructs and authenticates an HTTP request.
|
|
293
|
-
|
|
294
|
-
:param node: A ``Node`` instance.
|
|
295
|
-
:type node: Node
|
|
296
|
-
:param query: A primary ampersand-separated query string, e.g.
|
|
297
|
-
``"action=MyAction&auid=MyAuid"``.
|
|
298
|
-
:type query: str
|
|
299
|
-
:param kwargs: Key-value pairs of additional query string arguments, e.g.
|
|
300
|
-
``(..., depth=99)`` to add ``"&depth=99"``.
|
|
301
|
-
:type kwargs: dict[str, Any]
|
|
302
|
-
:return: An authenticated ``Request`` instance (before
|
|
303
|
-
``urllib.request.urlopen`` is called).
|
|
304
|
-
:rtype: Request
|
|
305
|
-
"""
|
|
306
|
-
for key, val in kwargs.items():
|
|
307
|
-
query = f'{query}&{key}={val}'
|
|
308
|
-
url = f'{node.get_url()}/DebugPanel?{query}'
|
|
309
|
-
req: Request = Request(url)
|
|
310
|
-
node.authenticate(req)
|
|
311
|
-
return req
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
def _node_action(node: Node, action: str, **kwargs) -> RequestUrlOpenT:
|
|
315
|
-
"""
|
|
316
|
-
Performs one node-centric action.
|
|
317
|
-
|
|
318
|
-
:param node: A ``Node`` instance.
|
|
319
|
-
:type node: Node
|
|
320
|
-
:param action: A node-oriented DebugPanel servlet action string, e.g.
|
|
321
|
-
``Reload Config``.
|
|
322
|
-
:type action: str
|
|
323
|
-
:param kwargs: Key-value pairs of additional query string arguments, e.g.
|
|
324
|
-
``(..., depth=99)`` to add ``"&depth=99"``.
|
|
325
|
-
:type kwargs: dict[str, Any]
|
|
326
|
-
:return: The result of calling `urllib.request.urlopen`` on an appropriate
|
|
327
|
-
URL.
|
|
328
|
-
:rtype: RequestUrlOpenT
|
|
329
|
-
:raises Exception: Whatever ``urllib.request.urlopen`` might raise.
|
|
330
|
-
"""
|
|
331
|
-
action_encoded = action.replace(" ", "%20")
|
|
332
|
-
req = _make_request(node, f'action={action_encoded}', **kwargs)
|
|
333
|
-
return urlopen(req)
|
|
41
|
+
from ._core import *
|
lockss/debugpanel/__main__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2000-
|
|
3
|
+
# Copyright (c) 2000-2026, Board of Trustees of Leland Stanford Jr. University
|
|
4
4
|
#
|
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
|
6
6
|
# modification, are permitted provided that the following conditions are met:
|