Skip to content

Commit 2b561dd

Browse files
committed
Force update script to download the image and calculate SHA512
Previously the precomputed SHA256 was used for most images. Since we want to check the hash against the openstack backend, we need to have the SHA512. Sadly, most images creators do not provide us with that hash pre-computed. The only solution is to download the images and computing the hash at runtime. Signed-off-by: Gondermann <gondermann@b1-systems.de>
1 parent fdae6af commit 2b561dd

1 file changed

Lines changed: 42 additions & 2 deletions

File tree

openstack_image_manager/update.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# source of latest URLs: https://gitlab.com/libosinfo/osinfo-db
33

44
from datetime import datetime
5+
import hashlib
6+
import math
57
import os
68
import re
79
import shutil
@@ -157,6 +159,39 @@ def mirror_image(
157159
client.fput_object(minio_bucket, os.path.join(dirname, new_filename), filename)
158160
os.remove(filename)
159161

162+
def size_clean(size):
163+
size_name = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB")
164+
i = int(math.floor(math.log(size, 1024)))
165+
s = size / 1024 ** i
166+
return f"{s:.2f} {size_name[i]}"
167+
168+
def headers_and_sha512(download_url: str):
169+
hash_obj = hashlib.new("sha512")
170+
171+
file_headers = None
172+
with requests.get(url=download_url, stream=True, timeout=30) as response:
173+
if response.status_code != 200:
174+
logger.error(f"Downloading image '{download_url}' failed with error code {response.status_code}")
175+
return None, None
176+
177+
file_headers = response.headers
178+
file_size = int(file_headers["Content-Length"])
179+
logger.info(f"Image size {size_clean(file_size)}")
180+
181+
downloadedBytes = 0
182+
lastProgress = 0
183+
for chunk in response.iter_content(chunk_size=8192):
184+
downloadedBytes += 8192
185+
progressPercent = (downloadedBytes / file_size) * 100
186+
progress = round(min(max(progressPercent, 0), 100))
187+
if progress - lastProgress >= 5:
188+
logger.info(f"Downloading image: {progress}%")
189+
lastProgress = progress
190+
191+
hash_obj.update(chunk)
192+
193+
sha512 = hash_obj.hexdigest()
194+
return file_headers, f"sha512:{sha512}"
160195

161196
def update_image(image, getter, minio_server, minio_bucket, minio_access_key, minio_secret_key):
162197
name = image["name"]
@@ -181,6 +216,7 @@ def update_image(image, getter, minio_server, minio_bucket, minio_access_key, mi
181216
"checksum": None,
182217
"url": None,
183218
"version": None,
219+
"verify_checksum": None
184220
}
185221
)
186222

@@ -191,12 +227,15 @@ def update_image(image, getter, minio_server, minio_bucket, minio_access_key, mi
191227
logger.info(f"Image {name} is up-to-date, nothing to do")
192228
return 0
193229

230+
headers, verify_checksum = headers_and_sha512(current_url)
231+
if verify_checksum == None:
232+
return 0
233+
194234
if current_version is None:
195235
logger.info(f"Checking {current_url}")
196236

197-
conn = urlopen(current_url, timeout=30)
198237
dt = datetime.strptime(
199-
conn.headers["last-modified"], "%a, %d %b %Y %H:%M:%S %Z"
238+
headers["last-modified"], "%a, %d %b %Y %H:%M:%S %Z"
200239
)
201240
current_version = dt.strftime("%Y%m%d")
202241

@@ -205,6 +244,7 @@ def update_image(image, getter, minio_server, minio_bucket, minio_access_key, mi
205244
"build_date": datetime.strptime(current_version, "%Y%m%d").date(),
206245
"checksum": current_checksum,
207246
"url": current_url,
247+
"verify_checksum": verify_checksum,
208248
}
209249
logger.info(f"New values are {new_values}")
210250
image["versions"][0].update(new_values)

0 commit comments

Comments
 (0)