From bff92a492465e5948ca192b50ca3da34e0d08a8e Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Feb 26 2024 10:16:34 +0000 Subject: create-filelist: add Checksum sections for other hash algorithms This change adds a Checksum section for the same files with the following hashing algorithms: - MD5 - SHA256 - SHA512 The SHA1 section is untouched, the hashed files are the same. This is needed for MirrorManager to scan a primary mirror without actually downloading and checksumming all the files. Signed-off-by: Aurélien Bompard --- diff --git a/README.rst b/README.rst index 8235533..2d6eb97 100644 --- a/README.rst +++ b/README.rst @@ -162,7 +162,7 @@ up to date and will create the hardlinks directory (assuming, of course, that it is called with ``-H``). But this works *only* if all of the file lists are updated at once. -The output also includes a section with checksums of selected files. By +The output also includes sections with checksums of selected files. By default, this includes only the repomd.xml files, because they are important, their names never change and neither does their size. So if they ever get missed by the mirror process somehow, it's still possible to detect this diff --git a/create-filelist b/create-filelist index 44968aa..4a0c28f 100755 --- a/create-filelist +++ b/create-filelist @@ -26,6 +26,9 @@ except ImportError: SUPPORTED_IMAGE_FORMATS = [] +CHECKSUM_ALGORITHMS = ("sha1", "md5", "sha256", "sha512") + + class SEntry(object): """A simpler DirEntry-like object.""" @@ -61,16 +64,16 @@ class SEntry(object): self.ftype = ftype + perm -def sha1(fname): - """Return the SHA1 checksum of a file in hex.""" +def get_checksum(algo, fname): + """Return the checksum of a file in hex.""" fh = open(fname, 'rb') - sha1 = hashlib.sha1() + hasher = getattr(hashlib, algo)() block = fh.read(2 ** 16) while len(block) > 0: - sha1.update(block) + hasher.update(block) block = fh.read(2 ** 16) - return sha1.hexdigest() + return hasher.hexdigest() def recursedir(path='.', skip=[], alwaysskip=['.~tmp~'], in_restricted=False): @@ -117,6 +120,15 @@ def recursedir(path='.', skip=[], alwaysskip=['.~tmp~'], in_restricted=False): yield se +def write_checksum_section(algo, files, output): + print('\n[Checksums {}]'.format(algo.upper()), file=output) + + # It's OK if the checksum section is empty, but we should include it anyway + # as the client expects it. + for f in sorted(files): + print('{0}\t{1}'.format(get_checksum(algo, f), f), file=output) + + def parseopts(): null = open(os.devnull, 'w') p = argparse.ArgumentParser( @@ -194,12 +206,8 @@ def main(): entry.size, entry.path[2:]), file=opts.timelist) - print('\n[Checksums SHA1]', file=opts.timelist) - - # It's OK if the checksum section is empty, but we should include it anyway - # as the client expects it. - for f in sorted(checksums): - print('{0}\t{1}'.format(sha1(f), f), file=opts.timelist) + for algo in CHECKSUM_ALGORITHMS: + write_checksum_section(algo, checksums, opts.timelist) print('\n[End]', file=opts.timelist)