Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,14 +674,16 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
src_fn = os.path.basename(src_path)

# report both MD5 and SHA256 checksums, since both are valid default checksum types
src_checksums = {}
for checksum_type in (CHECKSUM_TYPE_MD5, CHECKSUM_TYPE_SHA256):
src_checksum = compute_checksum(src_path, checksum_type=checksum_type)
src_checksums[checksum_type] = src_checksum
self.log.info("%s checksum for %s: %s", checksum_type, src_path, src_checksum)

# verify checksum (if provided)
self.log.debug('Verifying checksums for extension source...')
fn_checksum = self.get_checksum_for(checksums, filename=src_fn, index=0)
if verify_checksum(src_path, fn_checksum):
if verify_checksum(src_path, fn_checksum, src_checksums):
self.log.info('Checksum for extension source %s verified', src_fn)
elif build_option('ignore_checksums'):
print_warning("Ignoring failing checksum verification for %s" % src_fn)
Expand All @@ -700,12 +702,15 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
ext_src.update({'patches': ext_patches})

if verify_checksums:
computed_checksums = {}
for patch in ext_patches:
patch = patch['path']
computed_checksums[patch] = {}
# report both MD5 and SHA256 checksums,
# since both are valid default checksum types
for checksum_type in (CHECKSUM_TYPE_MD5, CHECKSUM_TYPE_SHA256):
checksum = compute_checksum(patch, checksum_type=checksum_type)
computed_checksums[patch][checksum_type] = checksum
self.log.info("%s checksum for %s: %s", checksum_type, patch, checksum)

# verify checksum (if provided)
Expand All @@ -715,7 +720,7 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
patch_fn = os.path.basename(patch)

checksum = self.get_checksum_for(checksums, filename=patch_fn, index=idx+1)
if verify_checksum(patch, checksum):
if verify_checksum(patch, checksum, computed_checksums[patch]):
self.log.info('Checksum for extension patch %s verified', patch_fn)
elif build_option('ignore_checksums'):
print_warning("Ignoring failing checksum verification for %s" % patch_fn)
Expand Down
12 changes: 9 additions & 3 deletions easybuild/tools/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ def calc_block_checksum(path, algorithm):
return algorithm.hexdigest()


def verify_checksum(path, checksums):
def verify_checksum(path, checksums, computed_checksums=None):
"""
Verify checksum of specified file.

Expand Down Expand Up @@ -1303,8 +1303,14 @@ def verify_checksum(path, checksums):
"2-tuple (type, value), or tuple of alternative checksum specs.",
checksum)

actual_checksum = compute_checksum(path, typ)
_log.debug("Computed %s checksum for %s: %s (correct checksum: %s)" % (typ, path, actual_checksum, checksum))
if computed_checksums is not None and typ in computed_checksums:
actual_checksum = computed_checksums[typ]
computed_str = 'Precomputed'
else:
actual_checksum = compute_checksum(path, typ)
computed_str = 'Computed'
_log.debug("%s %s checksum for %s: %s (correct checksum: %s)" %
(computed_str, typ, path, actual_checksum, checksum))

if actual_checksum != checksum:
return False
Expand Down
19 changes: 18 additions & 1 deletion test/framework/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"""
import datetime
import glob
import logging
import os
import re
import shutil
Expand Down Expand Up @@ -297,10 +298,26 @@ def test_checksums(self):
'b7297da8b547d5e74b851d7c4e475900cec4744df0f887ae5c05bf1757c224b4',
}

old_log_level = ft._log.getEffectiveLevel()
ft._log.setLevel(logging.DEBUG)
# make sure checksums computation/verification is correct
for checksum_type, checksum in known_checksums.items():
self.assertEqual(ft.compute_checksum(fp, checksum_type=checksum_type), checksum)
self.assertTrue(ft.verify_checksum(fp, (checksum_type, checksum)))
with self.log_to_testlogfile():
self.assertTrue(ft.verify_checksum(fp, (checksum_type, checksum)))
self.assertIn('Computed ' + checksum_type, ft.read_file(self.logfile))
# Passing precomputed checksums reuses it
with self.log_to_testlogfile():
computed_checksums = {checksum_type: checksum}
self.assertTrue(ft.verify_checksum(fp, (checksum_type, checksum), computed_checksums))
self.assertIn('Precomputed ' + checksum_type, ft.read_file(self.logfile))
# If the type isn't contained the checksum will be computed
with self.log_to_testlogfile():
computed_checksums = {'doesnt exist': 'checksum'}
self.assertTrue(ft.verify_checksum(fp, (checksum_type, checksum), computed_checksums))
self.assertIn('Computed ' + checksum_type, ft.read_file(self.logfile))

ft._log.setLevel(old_log_level)

# default checksum type is MD5
self.assertEqual(ft.compute_checksum(fp), known_checksums['md5'])
Expand Down