Skip to content

Commit ff74ed5

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 <[email protected]>
1 parent eecb6cb commit ff74ed5

File tree

1 file changed

+41
-35
lines changed

1 file changed

+41
-35
lines changed

openstack_image_manager/update.py

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
import shutil
88
import sys
99
import time
10+
import hashlib
11+
import math
1012
from urllib.parse import urlparse
11-
from urllib.request import urlopen
1213

1314
from loguru import logger
1415
from minio import Minio
@@ -72,6 +73,11 @@ def mirror_image(
7273
client.fput_object(minio_bucket, os.path.join(dirname, new_filename), filename)
7374
os.remove(filename)
7475

76+
def size_clean(size):
77+
size_name = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB")
78+
i = int(math.floor(math.log(size, 1024)))
79+
s = size / 1024 ** i
80+
return f"{s:.2f} {size_name[i]}"
7581

7682
def update_image(image, minio_server, minio_bucket, minio_access_key, minio_secret_key):
7783
name = image["name"]
@@ -87,54 +93,54 @@ def update_image(image, minio_server, minio_bucket, minio_access_key, minio_secr
8793
logger.info(f"Getting checksums from {latest_checksum_url}")
8894

8995
result = requests.get(latest_checksum_url)
90-
checksums = {}
9196

92-
checksum_type = "sha256"
97+
hash_obj = hashlib.new("sha512")
98+
file_headers = None
99+
with requests.get(url=latest_url, stream=True, timeout=30) as response:
100+
if response.status_code != 200:
101+
logger.error(f"Downloading image '{name}' failed with error code {response.status_code}")
102+
return None
103+
104+
file_headers = response.headers
105+
file_size = int(file_headers["Content-Length"])
106+
logger.info(f"Image size {size_clean(file_size)}")
107+
108+
downloadedBytes = 0
109+
lastProgress = 0
110+
for chunk in response.iter_content(chunk_size=8192):
111+
downloadedBytes += 8192
112+
progressPercent = (downloadedBytes / file_size) * 100
113+
progress = round(min(max(progressPercent, 0), 100))
114+
if progress - lastProgress >= 5:
115+
logger.info(f"Downloading image: {progress}%")
116+
lastProgress = progress
117+
118+
hash_obj.update(chunk)
119+
120+
sha512_value = hash_obj.hexdigest()
121+
93122
filename_pattern = None
94123

95124
if image["shortname"] in ["centos-stream-8", "centos-stream-9", "centos-7"]:
96125
filename_pattern = latest_filename.replace("HEREBE", "")
97126
filename_pattern = filename_pattern.replace("DRAGONS", "")
98-
elif image["shortname"] in ["debian-10", "debian-11", "debian-12"]:
99-
checksum_type = "sha512"
127+
new_latest_filename_list = []
100128

101129
for line in result.text.split("\n"):
102-
if image["shortname"] in ["rocky-8", "rocky-9"]:
103-
splitted_line = re.split("\s+", line) # noqa W605
104-
if splitted_line[0] == "SHA256":
105-
checksums[latest_filename] = splitted_line[3]
106-
elif image["shortname"] in [
107-
"ubuntu-14.04",
108-
"ubuntu-16.04",
109-
"ubuntu-16.04-minimal",
110-
"ubuntu-18.04",
111-
"ubuntu-18.04-minimal",
112-
"ubuntu-20.04",
113-
"ubuntu-20.04-minimal",
114-
"ubuntu-22.04",
115-
"ubuntu-22.04-minimal",
116-
]:
117-
splitted_line = re.split("\s+", line) # noqa W605
118-
if len(splitted_line) == 2:
119-
checksums[splitted_line[1][1:]] = splitted_line[0]
120-
elif image["shortname"] in ["centos-7"]:
130+
if image["shortname"] in ["centos-7"]:
121131
splitted_line = re.split("\s+", line) # noqa W605
122132
if len(splitted_line) == 2:
123133
if re.search(filename_pattern, splitted_line[1]):
124-
checksums[splitted_line[1]] = splitted_line[0]
134+
new_latest_filename_list.append(splitted_line[1])
125135
elif image["shortname"] in ["centos-stream-8", "centos-stream-9"]:
126136
splitted_line = re.split("\s+", line) # noqa W605
127137
if splitted_line[0] == "SHA256" and re.search(
128138
filename_pattern, splitted_line[1][1:-1]
129139
):
130-
checksums[splitted_line[1][1:-1]] = splitted_line[3]
131-
else:
132-
splitted_line = re.split("\s+", line) # noqa W605
133-
if len(splitted_line) == 2:
134-
checksums[splitted_line[1]] = splitted_line[0]
140+
new_latest_filename_list.append(splitted_line[1][1:-1])
135141

136142
if filename_pattern:
137-
new_latest_filename = natsorted(checksums.keys())[-1]
143+
new_latest_filename = natsorted(new_latest_filename_list)[-1]
138144
new_latest_url = latest_url.replace(latest_filename, new_latest_filename)
139145

140146
logger.info(f"Latest URL is now {new_latest_url}")
@@ -143,7 +149,7 @@ def update_image(image, minio_server, minio_bucket, minio_access_key, minio_secr
143149
latest_filename = new_latest_filename
144150
latest_url = new_latest_url
145151

146-
current_checksum = f"{checksum_type}:{checksums[latest_filename]}"
152+
current_checksum = f"sha512:{sha512_value}"
147153
logger.info(f"Checksum of current {latest_filename} is {current_checksum}")
148154

149155
try:
@@ -165,9 +171,8 @@ def update_image(image, minio_server, minio_bucket, minio_access_key, minio_secr
165171
if latest_checksum != current_checksum:
166172
logger.info(f"Checking {latest_url}")
167173

168-
conn = urlopen(latest_url, timeout=30)
169174
struct = time.strptime(
170-
conn.headers["last-modified"], "%a, %d %b %Y %H:%M:%S %Z"
175+
file_headers["last-modified"], "%a, %d %b %Y %H:%M:%S %Z"
171176
)
172177
dt = datetime.fromtimestamp(time.mktime(struct))
173178

@@ -250,7 +255,8 @@ def main(
250255
minio_access_key,
251256
minio_secret_key,
252257
)
253-
data["images"][index] = updated_image
258+
if updated_image:
259+
data["images"][index] = updated_image
254260

255261
with open(p, "w+") as fp:
256262
ryaml = ruamel.yaml.YAML()

0 commit comments

Comments
 (0)