77import shutil
88import sys
99import time
10+ import hashlib
11+ import math
1012from urllib .parse import urlparse
11- from urllib .request import urlopen
1213
1314from loguru import logger
1415from 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
7682def 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