depends: Use FALLBACK_DOWNLOAD_PATH if the primary's hash doesn't match

The previous behaviour was to use FALLBACK_DOWNLOAD_PATH to download
dependencies if the primary did not resolve. This was not resilient
against primaries that either mis-report HTTP status codes (e.g.
SourceForge returning 200 OK alongside a 404 webpage), or did not
guarantee artifacts to be bit-stable (e.g. GitHub regenerating commit
archive caches in a non-reproducible manner); in either case, the
incorrect file would be fetched and then the build would fail due to
hash mismatch.

The new behaviour is to download dependencies and check their hashes as
an atomic operation, and use FALLBACK_DOWNLOAD_PATH if any part of the
operation fails.
This commit is contained in:
Jack Grigg 2020-08-07 09:47:10 +01:00
parent 25ef1940b0
commit 9cdc6f2a85
1 changed files with 6 additions and 4 deletions

View File

@ -19,13 +19,15 @@ define int_get_all_dependencies
$(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies))))
endef
define download_and_check_file
($(build_DOWNLOAD) "$(1)/$(2).temp" $(3) && echo "$(4) $(1)/$(2).temp" > $(1)/.$(2).hash && $(build_SHA256SUM) -c $(1)/.$(2).hash)
endef
define fetch_file
(test -f $$($(1)_source_dir)/$(4) || \
( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \
( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \
$(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(4)" ) && \
echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
$(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
( $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(2)/$(3)",$(5)) || \
$(call download_and_check_file,$$($(1)_download_dir),$(4),"$(FALLBACK_DOWNLOAD_PATH)/$(4)",$(5)) ) && \
mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
rm -rf $$($(1)_download_dir) ))
endef