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
@@ -73,6 +74,11 @@ def mirror_image(image, latest_url, CONF):
7374 )
7475 os .remove (filename )
7576
77+ def size_clean (size ):
78+ size_name = ("B" , "KiB" , "MiB" , "GiB" , "TiB" , "PiB" , "EiB" , "ZiB" , "YiB" )
79+ i = int (math .floor (math .log (size , 1024 )))
80+ s = size / 1024 ** i
81+ return f"{ s :.2f} { size_name [i ]} "
7682
7783def update_image (image , CONF ):
7884 name = image ["name" ]
@@ -88,54 +94,54 @@ def update_image(image, CONF):
8894 logger .info (f"Getting checksums from { latest_checksum_url } " )
8995
9096 result = requests .get (latest_checksum_url )
91- checksums = {}
9297
93- checksum_type = "sha256"
98+ hash_obj = hashlib .new ("sha512" )
99+ file_headers = None
100+ with requests .get (url = latest_url , stream = True , timeout = 30 ) as response :
101+ if response .status_code != 200 :
102+ logger .error (f"Downloading image '{ name } ' failed with error code { response .status_code } " )
103+ return None
104+
105+ file_headers = response .headers
106+ file_size = int (file_headers ["Content-Length" ])
107+ logger .info (f"Image size { size_clean (file_size )} " )
108+
109+ downloadedBytes = 0
110+ lastProgress = 0
111+ for chunk in response .iter_content (chunk_size = 8192 ):
112+ downloadedBytes += 8192
113+ progressPercent = (downloadedBytes / file_size ) * 100
114+ progress = round (min (max (progressPercent , 0 ), 100 ))
115+ if progress - lastProgress >= 5 :
116+ logger .info (f"Downloading image: { progress } %" )
117+ lastProgress = progress
118+
119+ hash_obj .update (chunk )
120+
121+ sha512_value = hash_obj .hexdigest ()
122+
94123 filename_pattern = None
95124
96125 if image ["shortname" ] in ["centos-stream-8" , "centos-stream-9" , "centos-7" ]:
97126 filename_pattern = latest_filename .replace ("HEREBE" , "" )
98127 filename_pattern = filename_pattern .replace ("DRAGONS" , "" )
99- elif image ["shortname" ] in ["debian-10" , "debian-11" , "debian-12" ]:
100- checksum_type = "sha512"
128+ new_latest_filename_list = []
101129
102130 for line in result .text .split ("\n " ):
103- if image ["shortname" ] in ["rocky-8" , "rocky-9" ]:
104- splitted_line = re .split ("\s+" , line ) # noqa W605
105- if splitted_line [0 ] == "SHA256" :
106- checksums [latest_filename ] = splitted_line [3 ]
107- elif image ["shortname" ] in [
108- "ubuntu-14.04" ,
109- "ubuntu-16.04" ,
110- "ubuntu-16.04-minimal" ,
111- "ubuntu-18.04" ,
112- "ubuntu-18.04-minimal" ,
113- "ubuntu-20.04" ,
114- "ubuntu-20.04-minimal" ,
115- "ubuntu-22.04" ,
116- "ubuntu-22.04-minimal" ,
117- ]:
118- splitted_line = re .split ("\s+" , line ) # noqa W605
119- if len (splitted_line ) == 2 :
120- checksums [splitted_line [1 ][1 :]] = splitted_line [0 ]
121- elif image ["shortname" ] in ["centos-7" ]:
131+ if image ["shortname" ] in ["centos-7" ]:
122132 splitted_line = re .split ("\s+" , line ) # noqa W605
123133 if len (splitted_line ) == 2 :
124134 if re .search (filename_pattern , splitted_line [1 ]):
125- checksums [ splitted_line [1 ]] = splitted_line [ 0 ]
135+ new_latest_filename_list . append ( splitted_line [1 ])
126136 elif image ["shortname" ] in ["centos-stream-8" , "centos-stream-9" ]:
127137 splitted_line = re .split ("\s+" , line ) # noqa W605
128138 if splitted_line [0 ] == "SHA256" and re .search (
129139 filename_pattern , splitted_line [1 ][1 :- 1 ]
130140 ):
131- checksums [splitted_line [1 ][1 :- 1 ]] = splitted_line [3 ]
132- else :
133- splitted_line = re .split ("\s+" , line ) # noqa W605
134- if len (splitted_line ) == 2 :
135- checksums [splitted_line [1 ]] = splitted_line [0 ]
141+ new_latest_filename_list .append (splitted_line [1 ][1 :- 1 ])
136142
137143 if filename_pattern :
138- new_latest_filename = natsorted (checksums . keys () )[- 1 ]
144+ new_latest_filename = natsorted (new_latest_filename_list )[- 1 ]
139145 new_latest_url = latest_url .replace (latest_filename , new_latest_filename )
140146
141147 logger .info (f"Latest URL is now { new_latest_url } " )
@@ -144,7 +150,7 @@ def update_image(image, CONF):
144150 latest_filename = new_latest_filename
145151 latest_url = new_latest_url
146152
147- current_checksum = f"{ checksum_type } : { checksums [ latest_filename ] } "
153+ current_checksum = f"sha512: { sha512_value } "
148154 logger .info (f"Checksum of current { latest_filename } is { current_checksum } " )
149155
150156 try :
@@ -166,9 +172,8 @@ def update_image(image, CONF):
166172 if latest_checksum != current_checksum :
167173 logger .info (f"Checking { latest_url } " )
168174
169- conn = urlopen (latest_url , timeout = 30 )
170175 struct = time .strptime (
171- conn . headers ["last-modified" ], "%a, %d %b %Y %H:%M:%S %Z"
176+ file_headers ["last-modified" ], "%a, %d %b %Y %H:%M:%S %Z"
172177 )
173178 dt = datetime .fromtimestamp (time .mktime (struct ))
174179
@@ -240,7 +245,8 @@ def main(
240245 for index , image in enumerate (data ["images" ]):
241246 if "latest_url" in image :
242247 updated_image = update_image (image , CONF )
243- data ["images" ][index ] = updated_image
248+ if updated_image :
249+ data ["images" ][index ] = updated_image
244250
245251 with open (p , "w+" ) as fp :
246252 ryaml = ruamel .yaml .YAML ()
0 commit comments