19
19
* Metadata must be loaded/updated in order:
20
20
root -> timestamp -> snapshot -> targets -> (other delegated targets)
21
21
22
+
22
23
Exceptions are raised if metadata fails to load in any way.
23
24
24
25
Example of loading root, timestamp and snapshot:
@@ -121,12 +122,23 @@ def verify_with_threshold(
121
122
class MetadataBundle (abc .Mapping ):
122
123
"""Internal class to keep track of valid metadata in Updater
123
124
124
- MetadataBundle ensures that metadata is valid. It provides easy ways to
125
- update the metadata with the caller making decisions on what is updated.
125
+ MetadataBundle ensures that the collection of metadata in the bundle valid.
126
+ It provides easy ways to update the metadata with the caller making
127
+ decisions on what is updated.
126
128
"""
127
129
128
130
def __init__ (self , data : bytes ):
129
- """Initialize by loading trusted root metadata"""
131
+ """Initialize bundle by loading trusted root metadata
132
+
133
+ Args:
134
+ data: Trusted root metadata as bytes. Note that this metadata will
135
+ will only be verified by itself: it is the source of trust for
136
+ all metadata in the bundle.
137
+
138
+ Raises:
139
+ RepositoryError: Metadata failed to load or verify. The actual
140
+ error type and content will contain more details.
141
+ """
130
142
self ._bundle = {} # type: Dict[str: Metadata]
131
143
self .reference_time = datetime .utcnow ()
132
144
self ._root_update_finished = False
@@ -136,39 +148,53 @@ def __init__(self, data: bytes):
136
148
logger .debug ("Updating initial trusted root" )
137
149
self .update_root (data )
138
150
139
- # Implement Mapping
140
- def __getitem__ ( self , key : str ) -> Metadata :
141
- return self ._bundle [key ]
151
+ def __getitem__ ( self , role : str ) -> Metadata :
152
+ """Returns current Metadata for 'role'"""
153
+ return self ._bundle [role ]
142
154
143
155
def __len__ (self ) -> int :
156
+ """Returns number of Metadata objects in bundle"""
144
157
return len (self ._bundle )
145
158
146
159
def __iter__ (self ) -> Iterator [Metadata ]:
160
+ """Returns iterator over all Metadata objects in bundle"""
147
161
return iter (self ._bundle )
148
162
149
163
# Helper properties for top level metadata
150
164
@property
151
165
def root (self ) -> Optional [Metadata ]:
166
+ """Current root Metadata or None"""
152
167
return self ._bundle .get ("root" )
153
168
154
169
@property
155
170
def timestamp (self ) -> Optional [Metadata ]:
171
+ """Current timestamp Metadata or None"""
156
172
return self ._bundle .get ("timestamp" )
157
173
158
174
@property
159
175
def snapshot (self ) -> Optional [Metadata ]:
176
+ """Current snapshot Metadata or None"""
160
177
return self ._bundle .get ("snapshot" )
161
178
162
179
@property
163
180
def targets (self ) -> Optional [Metadata ]:
181
+ """Current targets Metadata or None"""
164
182
return self ._bundle .get ("targets" )
165
183
166
184
# Methods for updating metadata
167
185
def update_root (self , data : bytes ):
168
186
"""Verifies and loads 'data' as new root metadata.
169
187
170
188
Note that an expired intermediate root is considered valid: expiry is
171
- only checked for the final root in root_update_finished()."""
189
+ only checked for the final root in root_update_finished().
190
+
191
+ Args:
192
+ data: unverified new root metadata as bytes
193
+
194
+ Raises:
195
+ RepositoryError: Metadata failed to load or verify. The actual
196
+ error type and content will contain more details.
197
+ """
172
198
if self ._root_update_finished :
173
199
raise RuntimeError (
174
200
"Cannot update root after root update is finished"
@@ -206,7 +232,11 @@ def update_root(self, data: bytes):
206
232
logger .debug ("Updated root" )
207
233
208
234
def root_update_finished (self ):
209
- """Mark root metadata as final."""
235
+ """Marks root metadata as final and verifies it is not expired
236
+
237
+ Raises:
238
+ ExpiredMetadataError: The final root metadata is expired.
239
+ """
210
240
if self ._root_update_finished :
211
241
raise RuntimeError ("Root update is already finished" )
212
242
@@ -220,7 +250,15 @@ def root_update_finished(self):
220
250
logger .debug ("Verified final root.json" )
221
251
222
252
def update_timestamp (self , data : bytes ):
223
- """Verifies and loads 'data' as new timestamp metadata."""
253
+ """Verifies and loads 'data' as new timestamp metadata.
254
+
255
+ Args:
256
+ data: unverified new timestamp metadata as bytes
257
+
258
+ Raises:
259
+ RepositoryError: Metadata failed to load or verify. The actual
260
+ error type and content will contain more details.
261
+ """
224
262
if not self ._root_update_finished :
225
263
# root_update_finished() not called
226
264
raise RuntimeError ("Cannot update timestamp before root" )
@@ -270,7 +308,15 @@ def update_timestamp(self, data: bytes):
270
308
271
309
# TODO: remove pylint disable once the hash verification is in metadata.py
272
310
def update_snapshot (self , data : bytes ): # pylint: disable=too-many-branches
273
- """Verifies and loads 'data' as new snapshot metadata."""
311
+ """Verifies and loads 'data' as new snapshot metadata.
312
+
313
+ Args:
314
+ data: unverified new snapshot metadata as bytes
315
+
316
+ Raises:
317
+ RepositoryError: Metadata failed to load or verify. The actual
318
+ error type and content will contain more details.
319
+ """
274
320
275
321
if self .timestamp is None :
276
322
raise RuntimeError ("Cannot update snapshot before timestamp" )
@@ -339,15 +385,30 @@ def update_snapshot(self, data: bytes): # pylint: disable=too-many-branches
339
385
logger .debug ("Updated snapshot" )
340
386
341
387
def update_targets (self , data : bytes ):
342
- """Verifies and loads 'data' as new top-level targets metadata."""
388
+ """Verifies and loads 'data' as new top-level targets metadata.
389
+
390
+ Args:
391
+ data: unverified new targets metadata as bytes
392
+
393
+ Raises:
394
+ RepositoryError: Metadata failed to load or verify. The actual
395
+ error type and content will contain more details.
396
+ """
343
397
self .update_delegated_targets (data , "targets" , "root" )
344
398
345
399
def update_delegated_targets (
346
400
self , data : bytes , role_name : str , delegator_name : str
347
401
):
348
402
"""Verifies and loads 'data' as new metadata for target 'role_name'.
349
403
350
- Raises if verification fails
404
+ Args:
405
+ data: unverified new metadata as bytes
406
+ role_name: The role name of the new metadata
407
+ delegator_name: The name of the role delegating the new metadata
408
+
409
+ Raises:
410
+ RepositoryError: Metadata failed to load or verify. The actual
411
+ error type and content will contain more details.
351
412
"""
352
413
if self .snapshot is None :
353
414
raise RuntimeError ("Cannot load targets before snapshot" )
0 commit comments