Skip to content

Commit d409987

Browse files
authored
[sonic_installer] Improve error handling (sonic-net#460)
1 parent 5b62831 commit d409987

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

sonic_installer/main.py

+39-3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,26 @@ def get_docker_tag_name(image):
189189
return "unknown"
190190
return tag
191191

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+
192212
# Callback for confirmation prompt. Aborts if user enters "n"
193213
def abort_if_false(ctx, param, value):
194214
if not value:
@@ -218,11 +238,22 @@ def install(url):
218238

219239
if url.startswith('http://') or url.startswith('https://'):
220240
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()
222247
image_path = DEFAULT_IMAGE_PATH
223248
else:
224249
image_path = os.path.join("./", url)
225250

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+
226257
if get_image_type() == IMAGE_TYPE_ABOOT:
227258
run_command("/usr/bin/unzip -od /tmp %s boot0" % image_path)
228259
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):
389420
DEFAULT_IMAGE_PATH = os.path.join("/tmp/", image_name)
390421
if url.startswith('http://') or url.startswith('https://'):
391422
click.echo('Downloading image...')
423+
validate_url_or_abort(url)
392424
try:
393425
urllib.urlretrieve(url, DEFAULT_IMAGE_PATH, reporthook)
394426
except Exception, e:
395427
click.echo("Download error", e)
396-
return
428+
raise click.Abort()
397429
image_path = DEFAULT_IMAGE_PATH
398430
else:
399431
image_path = os.path.join("./", url)
400432

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()
402438

403439
warm = False
404440
# warm restart enable/disable config is put in stateDB, not persistent across cold reboot, not saved to config_DB.json file

0 commit comments

Comments
 (0)