7
7
import shutil
8
8
import sys
9
9
import time
10
+ import hashlib
11
+ import math
10
12
from urllib .parse import urlparse
11
- from urllib .request import urlopen
12
13
13
14
from loguru import logger
14
15
from minio import Minio
@@ -73,6 +74,11 @@ def mirror_image(image, latest_url, CONF):
73
74
)
74
75
os .remove (filename )
75
76
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 ]} "
76
82
77
83
def update_image (image , CONF ):
78
84
name = image ["name" ]
@@ -88,54 +94,54 @@ def update_image(image, CONF):
88
94
logger .info (f"Getting checksums from { latest_checksum_url } " )
89
95
90
96
result = requests .get (latest_checksum_url )
91
- checksums = {}
92
97
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
+
94
123
filename_pattern = None
95
124
96
125
if image ["shortname" ] in ["centos-stream-8" , "centos-stream-9" , "centos-7" ]:
97
126
filename_pattern = latest_filename .replace ("HEREBE" , "" )
98
127
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 = []
101
129
102
130
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" ]:
122
132
splitted_line = re .split ("\s+" , line ) # noqa W605
123
133
if len (splitted_line ) == 2 :
124
134
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 ])
126
136
elif image ["shortname" ] in ["centos-stream-8" , "centos-stream-9" ]:
127
137
splitted_line = re .split ("\s+" , line ) # noqa W605
128
138
if splitted_line [0 ] == "SHA256" and re .search (
129
139
filename_pattern , splitted_line [1 ][1 :- 1 ]
130
140
):
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 ])
136
142
137
143
if filename_pattern :
138
- new_latest_filename = natsorted (checksums . keys () )[- 1 ]
144
+ new_latest_filename = natsorted (new_latest_filename_list )[- 1 ]
139
145
new_latest_url = latest_url .replace (latest_filename , new_latest_filename )
140
146
141
147
logger .info (f"Latest URL is now { new_latest_url } " )
@@ -144,7 +150,7 @@ def update_image(image, CONF):
144
150
latest_filename = new_latest_filename
145
151
latest_url = new_latest_url
146
152
147
- current_checksum = f"{ checksum_type } : { checksums [ latest_filename ] } "
153
+ current_checksum = f"sha512: { sha512_value } "
148
154
logger .info (f"Checksum of current { latest_filename } is { current_checksum } " )
149
155
150
156
try :
@@ -166,9 +172,8 @@ def update_image(image, CONF):
166
172
if latest_checksum != current_checksum :
167
173
logger .info (f"Checking { latest_url } " )
168
174
169
- conn = urlopen (latest_url , timeout = 30 )
170
175
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"
172
177
)
173
178
dt = datetime .fromtimestamp (time .mktime (struct ))
174
179
@@ -240,7 +245,8 @@ def main(
240
245
for index , image in enumerate (data ["images" ]):
241
246
if "latest_url" in image :
242
247
updated_image = update_image (image , CONF )
243
- data ["images" ][index ] = updated_image
248
+ if updated_image :
249
+ data ["images" ][index ] = updated_image
244
250
245
251
with open (p , "w+" ) as fp :
246
252
ryaml = ruamel .yaml .YAML ()
0 commit comments