@@ -189,6 +189,26 @@ def get_docker_tag_name(image):
189
189
return "unknown"
190
190
return tag
191
191
192
+ # Function which validates whether a given URL specifies an existent file
193
+ # on a reachable remote machine. Will abort the current operation if not
194
+ def validate_url_or_abort (url ):
195
+ # Attempt to retrieve HTTP response code
196
+ try :
197
+ urlfile = urllib .urlopen (url )
198
+ response_code = urlfile .getcode ()
199
+ urlfile .close ()
200
+ except IOError , err :
201
+ response_code = None
202
+
203
+ if not response_code :
204
+ click .echo ("Did not receive a response from remote machine. Aborting..." )
205
+ raise click .Abort ()
206
+ else :
207
+ # Check for a 4xx response code which indicates a nonexistent URL
208
+ if response_code / 100 == 4 :
209
+ click .echo ("Image file not found on remote machine. Aborting..." )
210
+ raise click .Abort ()
211
+
192
212
# Callback for confirmation prompt. Aborts if user enters "n"
193
213
def abort_if_false (ctx , param , value ):
194
214
if not value :
@@ -218,11 +238,22 @@ def install(url):
218
238
219
239
if url .startswith ('http://' ) or url .startswith ('https://' ):
220
240
click .echo ('Downloading image...' )
221
- urllib .urlretrieve (url , DEFAULT_IMAGE_PATH , reporthook )
241
+ validate_url_or_abort (url )
242
+ try :
243
+ urllib .urlretrieve (url , DEFAULT_IMAGE_PATH , reporthook )
244
+ except Exception , e :
245
+ click .echo ("Download error" , e )
246
+ raise click .Abort ()
222
247
image_path = DEFAULT_IMAGE_PATH
223
248
else :
224
249
image_path = os .path .join ("./" , url )
225
250
251
+ # Verify that the local file exists and is a regular file
252
+ # TODO: Verify the file is a *proper SONiC image file*
253
+ if not os .path .isfile (image_path ):
254
+ click .echo ("Image file '{}' does not exist or is not a regular file. Aborting..." .format (image_path ))
255
+ raise click .Abort ()
256
+
226
257
if get_image_type () == IMAGE_TYPE_ABOOT :
227
258
run_command ("/usr/bin/unzip -od /tmp %s boot0" % image_path )
228
259
run_command ("swipath=%s target_path=/host sonic_upgrade=1 . /tmp/boot0" % image_path )
@@ -389,16 +420,21 @@ def upgrade_docker(container_name, url, cleanup_image, enforce_check, tag):
389
420
DEFAULT_IMAGE_PATH = os .path .join ("/tmp/" , image_name )
390
421
if url .startswith ('http://' ) or url .startswith ('https://' ):
391
422
click .echo ('Downloading image...' )
423
+ validate_url_or_abort (url )
392
424
try :
393
425
urllib .urlretrieve (url , DEFAULT_IMAGE_PATH , reporthook )
394
426
except Exception , e :
395
427
click .echo ("Download error" , e )
396
- return
428
+ raise click . Abort ()
397
429
image_path = DEFAULT_IMAGE_PATH
398
430
else :
399
431
image_path = os .path .join ("./" , url )
400
432
401
- # TODO: Validate the new docker image before disrupting existsing images.
433
+ # Verify that the local file exists and is a regular file
434
+ # TODO: Verify the file is a *proper Docker image file*
435
+ if not os .path .isfile (image_path ):
436
+ click .echo ("Image file '{}' does not exist or is not a regular file. Aborting..." .format (image_path ))
437
+ raise click .Abort ()
402
438
403
439
warm = False
404
440
# warm restart enable/disable config is put in stateDB, not persistent across cold reboot, not saved to config_DB.json file
0 commit comments