Wainer dos Santos Moschetta <waine...@redhat.com> writes:
> The current implementation of basevm does not check if the image > file to be downloaded has changed on server side before honouring > the cache. So any change on server-side file can go unnoticed, > keeping the cached image. > > This change implements a simple mechanism to detect the image > file changed by using the sha256sum file stored on server. It > compares with the expected checksum and then abort the execution > on mismatch. > > Signed-off-by: Wainer dos Santos Moschetta <waine...@redhat.com> > --- > tests/vm/basevm.py | 31 ++++++++++++++++++++++++++++++- > 1 file changed, 30 insertions(+), 1 deletion(-) > > diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py > index 083befce9f..4dfad2dc9b 100755 > --- a/tests/vm/basevm.py > +++ b/tests/vm/basevm.py > @@ -27,6 +27,7 @@ import tempfile > import shutil > import multiprocessing > import traceback > +import urllib.request > > SSH_KEY = open(os.path.join(os.path.dirname(__file__), > "..", "keys", "id_rsa")).read() > @@ -81,6 +82,18 @@ class BaseVM(object): > self._data_args = [] > > def _download_with_cache(self, url, sha256sum=None): > + > + def fetch_image_hash(url): > + fetch_url = "%s.sha256sum" % url OK this fails with the FreeBSD code as they use the form: https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.0/CHECKSUM.SHA256-FreeBSD-12.0-RELEASE-amd64 I guess we need to have a method that can be overridden for this. > + try: > + with urllib.request.urlopen(fetch_url) as response: > + content = response.read() > + except urllib.error.URLError as error: > + logging.error("Failed to fetch image checksum file: %s", > + fetch_url) > + raise error > + return content.decode().strip() > + > def check_sha256sum(fname): > if not sha256sum: > return True > @@ -91,8 +104,24 @@ class BaseVM(object): > if not os.path.exists(cache_dir): > os.makedirs(cache_dir) > fname = os.path.join(cache_dir, > hashlib.sha1(url.encode()).hexdigest()) > - if os.path.exists(fname) and check_sha256sum(fname): > + > + if os.path.exists(fname) and sha256sum is None: > return fname > + > + if sha256sum: > + image_checksum = fetch_image_hash(url) > + # Check the url points to a known image file. > + if image_checksum != sha256sum: > + logging.error("Image %s checksum (%s) does not match " + > + "expected (%s).", url, image_checksum, sha256sum) > + raise Exception("Image checksum failed.") > + # Check the cached image is up to date. > + if os.path.exists(fname): > + if check_sha256sum(fname): > + return fname > + logging.warning("Invalid cached image. Attempt to download " > + > + "the updated one.") > + > logging.debug("Downloading %s to %s...", url, fname) > subprocess.check_call(["wget", "-c", url, "-O", fname + ".download"], > stdout=self._stdout, stderr=self._stderr) -- Alex Bennée