pkg-download: check hashes before the download (branch yem/download-hash)
v3 cover pkg-download: check hashes before the download (branch yem/download-hash)
Hello All!
This series introduces a way to check hashes prior to doing a download.
This is required for when upstream silently update their release tarballs without renaming them, and the user is left with a stray locally cached tarball that no longer match the hashes with have for that package.
In so doing, this series:
- moves the check for a cached file into the wrapper;
- moves the post-download check for hashes into the wrapper;
- adds a pre-download check for hashes in the wrapper.
Doing the pre-download checks in the Makefile, like the post-download checks were done, made the Makefile a bit harder to read. On the other hand, we have a download wrapper shell script, so it is easier to do trickey stuff in there (shell syntax) than in the Makefile (make syntax can become unreadable pretty fast).
This has a side effect of cleaning up the pkg-download.mk Makefile, too, but that was not the goal.
The check for host packages was not working; this series also fixes that.
Changes v2 -> v3:
- fix checking hashes for host packages
- fix left-over line continuations
Changes v1 -> v2:
- add options parsing to the wrapper (Thomas)
- typoes (Thomas)
- rename the wrapper to dl-wrapper so it looks better in the traces, and it is not confused with another wrapper
Regards,
Yann E. MORIN.
The following changes since commit 0fb5dee3e6a78afba125e613e943db16d82046e3:
package/gcc: set e5500 and e6500 version mask (2014-12-07 23:47:22 +0100)
are available in the git repository at:
git://git.busybox.net/~ymorin/git/buildroot yem/download-hash
for you to fetch changes up to ac4eef89b5bac135b130b833de5712c3cca0e9b7:
pkg-download: check hashes for locally cached files (2014-12-08 00:50:10 +0100)
----------------------------------------------------------------
Yann E. MORIN (5):
suppot/download: add option parsing to the download wrapper
pkg-download: check for already downloaded file in the download wrapper
pkg-download: verify the hashes from the download wrapper
pkg-download: fix checking hash for host packages
pkg-download: check hashes for locally cached files
package/pkg-download.mk | 78 +++++++++--------- support/download/check-hash | 14 ++-- support/download/dl-wrapper | 191 ++++++++++++++++++++++++++++++++++++++++++++ support/download/wrapper | 99 ----------------------- 4 files changed, 236 insertions(+), 146 deletions(-) create mode 100755 support/download/dl-wrapper delete mode 100755 support/download/wrapper
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH v3 1/5 suppot/download: add option parsing to the download wrapper
Instead of relying on argument ordering, use actual options in the download wrapper.
Download backends (bzr, cp, hg...) are left as-is, because it does not make sense to complexifies them, since they are almost very trivial shell scripts, and adding option parsing would be really overkill.
--- package/pkg-download.mk | 42 ++++++----- support/download/dl-wrapper | 166 ++++++++++++++++++++++++++++++++++++++++++++ support/download/wrapper | 99 -------------------------- 3 files changed, 192 insertions(+), 115 deletions(-) create mode 100755 support/download/dl-wrapper delete mode 100755 support/download/wrapper
package/pkg-download.mk +26 -16
@@ -18,6 +18,8 @@ export SCP := $(call qstrip,$(BR2_SCP)) $(QUIET) SSH := $(call qstrip,$(BR2_SSH)) $(QUIET) export LOCALFILES := $(call qstrip,$(BR2_LOCALFILES)) +DL_WRAPPER = support/download/dl-wrapper + # Default spider mode is 'DOWNLOAD'. Other possible values are 'SOURCE_CHECK' # used by the _source-check target and 'SHOW_EXTERNAL_DEPS', used by the # external-deps target.
@@ -95,8 +97,9 @@ endef # problems define DOWNLOAD_GIT test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ - $(EXTRA_ENV) support/download/wrapper git \ - $(DL_DIR)/$($(PKG)_SOURCE) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b git \ + -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \ $($(PKG)_BASE_NAME)
@@ -115,8 +118,9 @@ endef define DOWNLOAD_BZR test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ - $(EXTRA_ENV) support/download/wrapper bzr \ - $(DL_DIR)/$($(PKG)_SOURCE) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b bzr \ + -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \ $($(PKG)_BASE_NAME)
@@ -132,8 +136,9 @@ endef define DOWNLOAD_CVS test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ - $(EXTRA_ENV) support/download/wrapper cvs \ - $(DL_DIR)/$($(PKG)_SOURCE) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b cvs \ + -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -- \ $(call stripurischeme,$(call qstrip,$($(PKG)_SITE))) \ $($(PKG)_DL_VERSION) \ $($(PKG)_RAWNAME) \
@@ -151,8 +156,9 @@ endef define DOWNLOAD_SVN test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ - $(EXTRA_ENV) support/download/wrapper svn \ - $(DL_DIR)/$($(PKG)_SOURCE) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b svn \ + -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \ $($(PKG)_BASE_NAME)
@@ -171,8 +177,9 @@ endef # to prepend the path with a slash: scp://[user@]host:/absolutepath define DOWNLOAD_SCP test -e $(DL_DIR)/$(2) || \ - $(EXTRA_ENV) support/download/wrapper scp \ - $(DL_DIR)/$(2) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b scp \ + -o $(DL_DIR)/$(2) \ + -- \ '$(call stripurischeme,$(call qstrip,$(1)))' && \ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) endef
@@ -188,8 +195,9 @@ endef define DOWNLOAD_HG test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ - $(EXTRA_ENV) support/download/wrapper hg \ - $(DL_DIR)/$($(PKG)_SOURCE) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b hg \ + -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \ $($(PKG)_BASE_NAME)
@@ -208,8 +216,9 @@ endef define DOWNLOAD_WGET test -e $(DL_DIR)/$(2) || \ - $(EXTRA_ENV) support/download/wrapper wget \ - $(DL_DIR)/$(2) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b wget \ + -o $(DL_DIR)/$(2) \ + -- \ '$(call qstrip,$(1))' && \ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) endef
@@ -224,8 +233,9 @@ endef define DOWNLOAD_LOCALFILES test -e $(DL_DIR)/$(2) || \ - $(EXTRA_ENV) support/download/wrapper cp \ - $(DL_DIR)/$(2) \ + $(EXTRA_ENV) $(DL_WRAPPER) -b cp \ + -o $(DL_DIR)/$(2) \ + -- \ $(call stripurischeme,$(call qstrip,$(1))) && \ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) endef
support/download/dl-wrapper new file +166 -0
166 lines not on this page · raw message
support/download/wrapper deleted +0 -99
99 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 2/5 pkg-download: check for already downloaded file in the download wrapper
In reply to Yann E. MORINInstead of repeating the same test again and again in all our download rules, just delegate the check for an already downloaded file to the download wrapper.
This clears up the path for doing the hash checks on a cached file before the download.
--- package/pkg-download.mk | 8 -------- support/download/dl-wrapper | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-)
package/pkg-download.mk +0 -8
@@ -96,7 +96,6 @@ endef # Messages for the type of clone used are provided to ease debugging in case of # problems define DOWNLOAD_GIT - test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b git \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ -- \
@@ -117,7 +116,6 @@ endef define DOWNLOAD_BZR - test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b bzr \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ -- \
@@ -135,7 +133,6 @@ define SHOW_EXTERNAL_DEPS_BZR endef define DOWNLOAD_CVS - test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b cvs \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ -- \
@@ -155,7 +152,6 @@ define SHOW_EXTERNAL_DEPS_CVS endef define DOWNLOAD_SVN - test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b svn \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ -- \
@@ -176,7 +172,6 @@ endef # Note that filepath is relative to the user's home directory, so you may want # to prepend the path with a slash: scp://[user@]host:/absolutepath define DOWNLOAD_SCP - test -e $(DL_DIR)/$(2) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b scp \ -o $(DL_DIR)/$(2) \ -- \
@@ -194,7 +189,6 @@ endef define DOWNLOAD_HG - test -e $(DL_DIR)/$($(PKG)_SOURCE) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b hg \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ -- \
@@ -215,7 +209,6 @@ endef define DOWNLOAD_WGET - test -e $(DL_DIR)/$(2) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b wget \ -o $(DL_DIR)/$(2) \ -- \
@@ -232,7 +225,6 @@ define SHOW_EXTERNAL_DEPS_WGET endef define DOWNLOAD_LOCALFILES - test -e $(DL_DIR)/$(2) || \ $(EXTRA_ENV) $(DL_WRAPPER) -b cp \ -o $(DL_DIR)/$(2) \ -- \
support/download/dl-wrapper +5 -0
@@ -49,6 +49,11 @@ main() { error "no output specified, use -o\n" fi + # If the output file already exists, do not download it again + if [ -e "${output}" ]; then + exit 0 + fi + # tmpd is a temporary directory in which backends may store intermediate # by-products of the download. # tmpf is the file in which the backends should put the downloaded content.
Signature · 1 line
1.9.1
PATCH v3 3/5 pkg-download: verify the hashes from the download wrapper
In reply to Yann E. MORINInstead of repeating the check in our download rules, delegate the check of the hashes to the download wrapper.
This needs three different changes:
- add a new argument to the download wrapper, that is the full path to the hash file; if the hash file does not exist, that does not change the current behaviour, as the existence of the hash file is checked for in the check-hash script;
- add a third argument to the check-hash script, to be the basename of the file to check; this is required because we no longer check the final file with the final filename, but an intermediate file with a temporary filename;
- do the actual call to the check-hash script from within the download wrapper.
This further paves the way to doing pre-download checks of the hashes for the locally cached files.
Note: this patch removes the check for hashes for already downloaded files, since the wrapper script exits early. The behaviour to check localy cached files will be restored and enhanced in the following patch.
--- package/pkg-download.mk | 28 +++++++++++----------------- support/download/check-hash | 14 ++++++++------ support/download/dl-wrapper | 22 +++++++++++++++++++--- 3 files changed, 38 insertions(+), 26 deletions(-)
package/pkg-download.mk +11 -17
@@ -60,17 +60,6 @@ domainseparator = $(if $(1),$(1),/) # github(user,package,version): returns site of GitHub repository github = https://github.com/$(1)/$(2)/archive/$(3) -# Helper for checking a tarball's checksum -# If the hash does not match, remove the incorrect file -# $(1): the path to the file with the hashes -# $(2): the full path to the file to check -define VERIFY_HASH - if ! support/download/check-hash $(1) $(2) $(if $(QUIET),>/dev/null); then \ - rm -f $(2); \ - exit 1; \ - fi -endef - ################################################################################ # The DOWNLOAD_* helpers are in charge of getting a working copy # of the source repository for their corresponding SCM,
@@ -98,6 +87,7 @@ endef define DOWNLOAD_GIT $(EXTRA_ENV) $(DL_WRAPPER) -b git \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -118,6 +108,7 @@ endef define DOWNLOAD_BZR $(EXTRA_ENV) $(DL_WRAPPER) -b bzr \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -135,6 +126,7 @@ endef define DOWNLOAD_CVS $(EXTRA_ENV) $(DL_WRAPPER) -b cvs \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ $(call stripurischeme,$(call qstrip,$($(PKG)_SITE))) \ $($(PKG)_DL_VERSION) \
@@ -154,6 +146,7 @@ endef define DOWNLOAD_SVN $(EXTRA_ENV) $(DL_WRAPPER) -b svn \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -174,9 +167,9 @@ endef define DOWNLOAD_SCP $(EXTRA_ENV) $(DL_WRAPPER) -b scp \ -o $(DL_DIR)/$(2) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ - '$(call stripurischeme,$(call qstrip,$(1)))' && \ - $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) + '$(call stripurischeme,$(call qstrip,$(1)))' endef define SOURCE_CHECK_SCP
@@ -191,6 +184,7 @@ endef define DOWNLOAD_HG $(EXTRA_ENV) $(DL_WRAPPER) -b hg \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -211,9 +205,9 @@ endef define DOWNLOAD_WGET $(EXTRA_ENV) $(DL_WRAPPER) -b wget \ -o $(DL_DIR)/$(2) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ - '$(call qstrip,$(1))' && \ - $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) + '$(call qstrip,$(1))' endef define SOURCE_CHECK_WGET
@@ -227,9 +221,9 @@ endef define DOWNLOAD_LOCALFILES $(EXTRA_ENV) $(DL_WRAPPER) -b cp \ -o $(DL_DIR)/$(2) \ + -H $(PKGDIR)/$($(PKG)_NAME).hash \ -- \ - $(call stripurischeme,$(call qstrip,$(1))) && \ - $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2)) + $(call stripurischeme,$(call qstrip,$(1))) endef define SOURCE_CHECK_LOCALFILES
support/download/check-hash +8 -6
@@ -5,9 +5,11 @@ set -e # Call it with: # $1: the path of the file containing all the the expected hashes # $2: the full path to the file to check +# $3: the basename of the file to check h_file="${1}" file="${2}" +base="${3}" # Does the hash-file exist? if [ ! -f "${h_file}" ]; then
@@ -30,7 +32,7 @@ check_one_hash() { sha224|sha256|sha384|sha512) ;; *) # Unknown hash, exit with error printf "ERROR: unknown hash '%s' for '%s'\n" \ - "${_h}" "${_file##*/}" >&2 + "${_h}" "${base}" >&2 exit 1 ;; esac
@@ -38,11 +40,11 @@ check_one_hash() { # Do the hashes match? _hash=$( ${_h}sum "${_file}" |cut -d ' ' -f 1 ) if [ "${_hash}" = "${_known}" ]; then - printf "%s: OK (%s: %s)\n" "${_file##*/}" "${_h}" "${_hash}" + printf "%s: OK (%s: %s)\n" "${base}" "${_h}" "${_hash}" return 0 fi - printf "ERROR: %s has wrong %s hash:\n" "${_file##*/}" "${_h}" >&2 + printf "ERROR: %s has wrong %s hash:\n" "${base}" "${_h}" >&2 printf "ERROR: expected: %s\n" "${_known}" >&2 printf "ERROR: got : %s\n" "${_hash}" >&2 printf "ERROR: Incomplete download, or man-in-the-middle (MITM) attack\n" >&2
@@ -59,7 +61,7 @@ while read t h f; do continue ;; *) - if [ "${f}" = "${file##*/}" ]; then + if [ "${f}" = "${base}" ]; then check_one_hash "${t}" "${h}" "${file}" : $((nb_checks++)) fi
@@ -69,9 +71,9 @@ done <"${h_file}" if [ ${nb_checks} -eq 0 ]; then if [ -n "${BR2_ENFORCE_CHECK_HASH}" ]; then - printf "ERROR: No hash found for %s\n" "${file}" >&2 + printf "ERROR: No hash found for %s\n" "${base}" >&2 exit 1 else - printf "WARNING: No hash found for %s\n" "${file}" >&2 + printf "WARNING: No hash found for %s\n" "${base}" >&2 fi fi
support/download/dl-wrapper +19 -3
@@ -8,6 +8,7 @@ # Call it with: # -b BACKEND name of the backend (eg. cvs, git, cp...) # -o FILE full path to the file in which to save the download +# -H FILE full path to the hash file # -- everything after '--' are options for the backend # Environment: # BUILD_DIR: the path to Buildroot's build dir
@@ -26,15 +27,16 @@ set -e main() { local OPT OPTARG - local backend output + local backend output hfile # Parse our options; anythong after '--' is for the backend # Sop we only care to -b (backend) and -o (output file) - while getopts :hb:o: OPT; do + while getopts :hb:o:H: OPT; do case "${OPT}" in h) help; exit 0;; b) backend="${OPTARG}";; o) output="${OPTARG}";; + H) hfile="${OPTARG}";; :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";; \?) error "unknown option '%s'\n" "${OPTARG}";; esac
@@ -48,6 +50,9 @@ main() { if [ -z "${output}" ]; then error "no output specified, use -o\n" fi + if [ -z "${hfile}" ]; then + error "no hash-file specified, use -H\n" + fi # If the output file already exists, do not download it again if [ -e "${output}" ]; then
@@ -81,6 +86,13 @@ main() { # cd back to free the temp-dir, so we can remove it later cd "${OLDPWD}" + # Check if the downloaded file is sane, and matches the stored hashes + # for that file + if ! support/download/check-hash "${hfile}" "${tmpf}" "${output##*/}"; then + rm -rf "${tmpd}" + exit 1 + fi + # tmp_output is in the same directory as the final output, so we can # later move it atomically. tmp_output="$( mktemp "${output}.XXXXXX" )"
@@ -147,7 +159,7 @@ DESCRIPTION bzr Bazaar cp local files via simple copy cvs Concurrent Versions System - git git + git Git hg Mercurial scp remote files via Secure copy svn Subversion
@@ -156,6 +168,10 @@ DESCRIPTION -o FILE Store the downloaded archive in FILE. + -H FILE + Use FILE to read hashes from, and check them against the downloaded + archive. + Exit status: 0 if OK !0 in case of error
Signature · 1 line
1.9.1
PATCH v3 4/5 pkg-download: fix checking hash for host packages
In reply to Yann E. MORINCurrently, we use $($(PKG)_NAME) to find the hash file.
but for host package, $(PKG) is host-foo, which would have us look for host-foo.hash, while the hash file is really foo.hash.
Fix that by using the raw name of the package, $($(PKG)_RAWNAME).
--- package/pkg-download.mk | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
package/pkg-download.mk +8 -8
@@ -87,7 +87,7 @@ github = https://github.com/$(1)/$(2)/archive/$(3) define DOWNLOAD_GIT $(EXTRA_ENV) $(DL_WRAPPER) -b git \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -108,7 +108,7 @@ endef define DOWNLOAD_BZR $(EXTRA_ENV) $(DL_WRAPPER) -b bzr \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -126,7 +126,7 @@ endef define DOWNLOAD_CVS $(EXTRA_ENV) $(DL_WRAPPER) -b cvs \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $(call stripurischeme,$(call qstrip,$($(PKG)_SITE))) \ $($(PKG)_DL_VERSION) \
@@ -146,7 +146,7 @@ endef define DOWNLOAD_SVN $(EXTRA_ENV) $(DL_WRAPPER) -b svn \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -167,7 +167,7 @@ endef define DOWNLOAD_SCP $(EXTRA_ENV) $(DL_WRAPPER) -b scp \ -o $(DL_DIR)/$(2) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ '$(call stripurischeme,$(call qstrip,$(1)))' endef
@@ -184,7 +184,7 @@ endef define DOWNLOAD_HG $(EXTRA_ENV) $(DL_WRAPPER) -b hg \ -o $(DL_DIR)/$($(PKG)_SOURCE) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $($(PKG)_SITE) \ $($(PKG)_DL_VERSION) \
@@ -205,7 +205,7 @@ endef define DOWNLOAD_WGET $(EXTRA_ENV) $(DL_WRAPPER) -b wget \ -o $(DL_DIR)/$(2) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ '$(call qstrip,$(1))' endef
@@ -221,7 +221,7 @@ endef define DOWNLOAD_LOCALFILES $(EXTRA_ENV) $(DL_WRAPPER) -b cp \ -o $(DL_DIR)/$(2) \ - -H $(PKGDIR)/$($(PKG)_NAME).hash \ + -H $(PKGDIR)/$($(PKG)_RAWNAME).hash \ -- \ $(call stripurischeme,$(call qstrip,$(1))) endef
Signature · 1 line
1.9.1
PATCH v3 5/5 pkg-download: check hashes for locally cached files
In reply to Yann E. MORINIn some cases, upstream just update their releases in-place, without renaming them. When that package is updated in Buildroot, a new hash to match the new upstream release is included in the corresponding .hash file.
As a consequence, users who previously downloaded that package's tarball with an older version of Buildroot, will get stuck with an old archive for that package, and after updating their Buildroot copy, will be greeted with a failed download, due to the local file not matching the new hashes.
So, to avoid this situation, check the hashes prior to doing the download. If the hashes match, consider the locally cached file genuine, and do not download it. However, if the locally cached file does not match the known hashes we have for it, it is promptly removed, and a download is re-attempted.
Note: this does not add any overhead compared to the previous situation, because we were already checking hashes of localy cached files. It just changes the order in which we do the checks. For the records, here is the overhead of hashing a 231MiB file (qt-everywhere-opensource-src-4.8.6.tar.gz) on a core-i5 @2.5GHz:
cache-cold cache-hot
sha1 1.914s 0.762s
sha256 2.109s 1.270sBut again, this overhead already existed before this patch.
--- support/download/dl-wrapper | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
support/download/dl-wrapper +5 -1
@@ -56,7 +56,11 @@ main() { # If the output file already exists, do not download it again if [ -e "${output}" ]; then - exit 0 + if support/download/check-hash "${hfile}" "${output}" "${output##*/}"; then + exit 0 + fi + rm -f "${output}" + printf "Re-downloading '%s'...\n" "${output##*/}" fi # tmpd is a temporary directory in which backends may store intermediate
Signature · 1 line
1.9.1