def test__delete_obsolete_metadata(self): repository_name = 'test_repository' temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) repository_directory = os.path.join(temporary_directory, 'repository') metadata_directory = os.path.join(repository_directory, repo_lib.METADATA_STAGED_DIRECTORY_NAME) os.makedirs(metadata_directory) snapshot_filepath = os.path.join('repository_data', 'repository', 'metadata', 'snapshot.json') snapshot_signable = securesystemslib.util.load_json_file(snapshot_filepath) storage_backend = securesystemslib.storage.FilesystemBackend() # Create role metadata that should not exist in snapshot.json. role1_filepath = os.path.join('repository_data', 'repository', 'metadata', 'role1.json') shutil.copyfile(role1_filepath, os.path.join(metadata_directory, 'role2.json')) repo_lib._delete_obsolete_metadata(metadata_directory, snapshot_signable['signed'], True, repository_name, storage_backend) # _delete_obsolete_metadata should never delete root.json. root_filepath = os.path.join('repository_data', 'repository', 'metadata', 'root.json') shutil.copyfile(root_filepath, os.path.join(metadata_directory, 'root.json')) repo_lib._delete_obsolete_metadata(metadata_directory, snapshot_signable['signed'], True, repository_name, storage_backend) self.assertTrue(os.path.exists(os.path.join(metadata_directory, 'root.json'))) # Verify what happens for a non-existent metadata directory (a debug # message is logged). self.assertRaises(securesystemslib.exceptions.StorageError, repo_lib._delete_obsolete_metadata, 'non-existent', snapshot_signable['signed'], True, repository_name, storage_backend)
def write(self, write_partial=False): """ <Purpose> Write all the JSON Metadata objects to their corresponding files. write() raises an exception if any of the role metadata to be written to disk is invalid, such as an insufficient threshold of signatures, missing private keys, etc. <Arguments> write_partial: A boolean indicating whether partial metadata should be written to disk. Partial metadata may be written to allow multiple maintainters to independently sign and update role metadata. write() raises an exception if a metadata role cannot be written due to not having enough signatures. <Exceptions> tuf.Error, if any of the project roles do not have a minimum threshold of signatures. <Side Effects> Creates metadata files in the project's metadata directory. <Returns> None. """ # Does 'write_partial' have the correct format? # Ensure the arguments have the appropriate number of objects and object # types, and that all dict keys are properly named. # Raise 'tuf.FormatError' if any are improperly formatted. tuf.formats.BOOLEAN_SCHEMA.check_match(write_partial) # At this point the tuf.keydb and tuf.roledb stores must be fully # populated, otherwise write() throwns a 'tuf.Repository' exception if # any of the project roles are missing signatures, keys, etc. # Write the metadata files of all the delegated roles of the project. delegated_rolenames = \ tuf.roledb.get_delegated_rolenames(self._project_name) for delegated_rolename in delegated_rolenames: roleinfo = tuf.roledb.get_roleinfo(delegated_rolename) delegated_filename = os.path.join(self._metadata_directory, delegated_rolename + METADATA_EXTENSION) # Ensure the parent directories of 'metadata_filepath' exist, otherwise an # IO exception is raised if 'metadata_filepath' is written to a # sub-directory. tuf.util.ensure_parent_dir(delegated_filename) _generate_and_write_metadata(delegated_rolename, delegated_filename, write_partial, self._targets_directory, self._metadata_directory, prefix=self._prefix) # Generate the 'project_name' metadata file. targets_filename = self._project_name + METADATA_EXTENSION targets_filename = os.path.join(self._metadata_directory, targets_filename) project_signable, targets_filename = \ _generate_and_write_metadata(self._project_name, targets_filename, write_partial, self._targets_directory, self._metadata_directory, prefix=self._prefix) # Save configuration information that is not stored in the project's # metadata _save_project_configuration(self._metadata_directory, self._targets_directory, self.keys, self._prefix, self.threshold, self.layout_type, self._project_name) # Delete the metadata of roles no longer in 'tuf.roledb'. Obsolete roles # may have been revoked. _delete_obsolete_metadata(self._metadata_directory, project_signable['signed'], False)