1515from .exception import SonicRuntimeException
1616
1717SYSLOG_IDENTIFIER = "sonic-installer"
18+ LOG_ERR = logger .Logger .LOG_PRIORITY_ERROR
19+ LOG_NOTICE = logger .Logger .LOG_PRIORITY_NOTICE
1820
1921# Global Config object
2022_config = None
@@ -123,6 +125,15 @@ def get_docker_tag_name(image):
123125 return tag
124126
125127
128+ def echo_and_log (msg , priority = LOG_NOTICE , fg = None ):
129+ if priority >= LOG_ERR :
130+ # Print to stderr if priority is error
131+ click .secho (msg , fg = fg , err = True )
132+ else :
133+ click .secho (msg , fg = fg )
134+ log .log (priority , msg , False )
135+
136+
126137# Function which validates whether a given URL specifies an existent file
127138# on a reachable remote machine. Will abort the current operation if not
128139def validate_url_or_abort (url ):
@@ -135,12 +146,12 @@ def validate_url_or_abort(url):
135146 response_code = None
136147
137148 if not response_code :
138- click . echo ("Did not receive a response from remote machine. Aborting..." )
149+ echo_and_log ("Did not receive a response from remote machine. Aborting..." , LOG_ERR )
139150 raise click .Abort ()
140151 else :
141152 # Check for a 4xx response code which indicates a nonexistent URL
142153 if response_code / 100 == 4 :
143- click . echo ("Image file not found on remote machine. Aborting..." )
154+ echo_and_log ("Image file not found on remote machine. Aborting..." , LOG_ERR )
144155 raise click .Abort ()
145156
146157
@@ -207,6 +218,7 @@ def print_deprecation_warning(deprecated_cmd_or_subcmd, new_cmd_or_subcmd):
207218 fg = "red" , err = True )
208219 click .secho ("Please use '{}' instead" .format (new_cmd_or_subcmd ), fg = "red" , err = True )
209220
221+
210222def update_sonic_environment (click , binary_image_version ):
211223 """Prepare sonic environment variable using incoming image template file. If incoming image template does not exist
212224 use current image template file.
@@ -248,8 +260,7 @@ def umount_next_image_fs(mount_point):
248260 print (sonic_env , file = ef )
249261 os .chmod (env_file , 0o644 )
250262 except SonicRuntimeException as ex :
251- click .secho ("Warning: SONiC environment variables are not supported for this image: {0}" .format (str (ex )),
252- fg = "red" , err = True )
263+ echo_and_log ("Warning: SONiC environment variables are not supported for this image: {0}" .format (str (ex )), LOG_ERR , fg = "red" )
253264 if os .path .exists (env_file ):
254265 os .remove (env_file )
255266 os .rmdir (env_dir )
@@ -282,42 +293,42 @@ def install(url, force, skip_migration=False):
282293 bootloader = get_bootloader ()
283294
284295 if url .startswith ('http://' ) or url .startswith ('https://' ):
285- click . echo ('Downloading image...' )
296+ echo_and_log ('Downloading image...' )
286297 validate_url_or_abort (url )
287298 try :
288299 urlretrieve (url , bootloader .DEFAULT_IMAGE_PATH , reporthook )
289300 click .echo ('' )
290301 except Exception as e :
291- click . echo ("Download error" , e )
302+ echo_and_log ("Download error" , e )
292303 raise click .Abort ()
293304 image_path = bootloader .DEFAULT_IMAGE_PATH
294305 else :
295306 image_path = os .path .join ("./" , url )
296307
297308 binary_image_version = bootloader .get_binary_image_version (image_path )
298309 if not binary_image_version :
299- click . echo ("Image file does not exist or is not a valid SONiC image file" )
310+ echo_and_log ("Image file does not exist or is not a valid SONiC image file" , LOG_ERR )
300311 raise click .Abort ()
301312
302313 # Is this version already installed?
303314 if binary_image_version in bootloader .get_installed_images ():
304- click . echo ("Image {} is already installed. Setting it as default..." .format (binary_image_version ))
315+ echo_and_log ("Image {} is already installed. Setting it as default..." .format (binary_image_version ))
305316 if not bootloader .set_default_image (binary_image_version ):
306- click . echo ('Error: Failed to set image as default' )
317+ echo_and_log ('Error: Failed to set image as default' , LOG_ERR )
307318 raise click .Abort ()
308319 else :
309320 # Verify that the binary image is of the same type as the running image
310321 if not bootloader .verify_binary_image (image_path ) and not force :
311- click . echo ("Image file '{}' is of a different type than running image.\n " .format (url ) +
322+ echo_and_log ("Image file '{}' is of a different type than running image.\n " .format (url ) +
312323 "If you are sure you want to install this image, use -f|--force.\n " +
313- "Aborting..." )
324+ "Aborting..." , LOG_ERR )
314325 raise click .Abort ()
315326
316- click . echo ("Installing image {} and setting it as default..." .format (binary_image_version ))
327+ echo_and_log ("Installing image {} and setting it as default..." .format (binary_image_version ))
317328 bootloader .install_image (image_path )
318329 # Take a backup of current configuration
319330 if skip_migration :
320- click . echo ("Skipping configuration migration as requested in the command option." )
331+ echo_and_log ("Skipping configuration migration as requested in the command option." )
321332 else :
322333 run_command ('config-setup backup' )
323334
@@ -326,7 +337,7 @@ def install(url, force, skip_migration=False):
326337 # Finally, sync filesystem
327338 run_command ("sync;sync;sync" )
328339 run_command ("sleep 3" ) # wait 3 seconds after sync
329- click . echo ('Done' )
340+ echo_and_log ('Done' )
330341
331342
332343# List installed images
@@ -355,7 +366,7 @@ def set_default(image):
355366
356367 bootloader = get_bootloader ()
357368 if image not in bootloader .get_installed_images ():
358- click . echo ('Error: Image does not exist' )
369+ echo_and_log ('Error: Image does not exist' , LOG_ERR )
359370 raise click .Abort ()
360371 bootloader .set_default_image (image )
361372
@@ -371,7 +382,7 @@ def set_next_boot(image):
371382
372383 bootloader = get_bootloader ()
373384 if image not in bootloader .get_installed_images ():
374- click . echo ('Error: Image does not exist' )
385+ echo_and_log ('Error: Image does not exist' , LOG_ERR )
375386 sys .exit (1 )
376387 bootloader .set_next_image (image )
377388
@@ -387,10 +398,10 @@ def remove(image):
387398 images = bootloader .get_installed_images ()
388399 current = bootloader .get_current_image ()
389400 if image not in images :
390- click . echo ('Image does not exist' )
401+ echo_and_log ('Image does not exist' , LOG_ERR )
391402 sys .exit (1 )
392403 if image == current :
393- click . echo ('Cannot remove current image' )
404+ echo_and_log ('Cannot remove current image' , LOG_ERR )
394405 sys .exit (1 )
395406 # TODO: check if image is next boot or default boot and fix these
396407 bootloader .remove_image (image )
@@ -427,12 +438,12 @@ def cleanup():
427438 image_removed = 0
428439 for image in images :
429440 if image != curimage and image != nextimage :
430- click . echo ("Removing image %s" % image )
441+ echo_and_log ("Removing image %s" % image )
431442 bootloader .remove_image (image )
432443 image_removed += 1
433444
434445 if image_removed == 0 :
435- click . echo ("No image(s) to remove" )
446+ echo_and_log ("No image(s) to remove" )
436447
437448
438449DOCKER_CONTAINER_LIST = [
@@ -474,12 +485,12 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
474485
475486 DEFAULT_IMAGE_PATH = os .path .join ("/tmp/" , image_name )
476487 if url .startswith ('http://' ) or url .startswith ('https://' ):
477- click . echo ('Downloading image...' )
488+ echo_and_log ('Downloading image...' )
478489 validate_url_or_abort (url )
479490 try :
480491 urlretrieve (url , DEFAULT_IMAGE_PATH , reporthook )
481492 except Exception as e :
482- click . echo ("Download error" , e )
493+ echo_and_log ("Download error: {}" . format ( e ), LOG_ERR )
483494 raise click .Abort ()
484495 image_path = DEFAULT_IMAGE_PATH
485496 else :
@@ -488,7 +499,7 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
488499 # Verify that the local file exists and is a regular file
489500 # TODO: Verify the file is a *proper Docker image file*
490501 if not os .path .isfile (image_path ):
491- click . echo ("Image file '{}' does not exist or is not a regular file. Aborting..." .format (image_path ))
502+ echo_and_log ("Image file '{}' does not exist or is not a regular file. Aborting..." .format (image_path ), LOG_ERR )
492503 raise click .Abort ()
493504
494505 warm_configured = False
@@ -525,7 +536,7 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
525536 (out , err ) = proc .communicate ()
526537 if proc .returncode != 0 :
527538 if not skip_check :
528- click . echo ("Orchagent is not in clean state, RESTARTCHECK failed" )
539+ echo_and_log ("Orchagent is not in clean state, RESTARTCHECK failed" , LOG_ERR )
529540 # Restore orignal config before exit
530541 if warm_configured is False and warm :
531542 run_command ("config warm_restart disable %s" % container_name )
@@ -537,27 +548,27 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
537548
538549 sys .exit (proc .returncode )
539550 else :
540- click . echo ("Orchagent is not in clean state, upgrading it anyway" )
551+ echo_and_log ("Orchagent is not in clean state, upgrading it anyway" )
541552 else :
542- click . echo ("Orchagent is in clean state and frozen for warm upgrade" )
553+ echo_and_log ("Orchagent is in clean state and frozen for warm upgrade" )
543554
544555 warm_app_names = ["orchagent" , "neighsyncd" ]
545556
546557 elif container_name == "bgp" :
547558 # Kill bgpd to restart the bgp graceful restart procedure
548- click . echo ("Stopping bgp ..." )
559+ echo_and_log ("Stopping bgp ..." )
549560 run_command ("docker exec -i bgp pkill -9 zebra" )
550561 run_command ("docker exec -i bgp pkill -9 bgpd" )
551562 warm_app_names = ["bgp" ]
552- click . echo ("Stopped bgp ..." )
563+ echo_and_log ("Stopped bgp ..." )
553564
554565 elif container_name == "teamd" :
555- click . echo ("Stopping teamd ..." )
566+ echo_and_log ("Stopping teamd ..." )
556567 # Send USR1 signal to all teamd instances to stop them
557568 # It will prepare teamd for warm-reboot
558569 run_command ("docker exec -i teamd pkill -USR1 teamd > /dev/null" )
559570 warm_app_names = ["teamsyncd" ]
560- click . echo ("Stopped teamd ..." )
571+ echo_and_log ("Stopped teamd ..." )
561572
562573 # clean app reconcilation state from last warm start if exists
563574 for warm_app_name in warm_app_names :
@@ -602,8 +613,7 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
602613 log .log_notice ("%s reached %s state" % (warm_app_name , state ))
603614 sys .stdout .write ("]\n \r " )
604615 if state != exp_state :
605- click .echo ("%s failed to reach %s state" % (warm_app_name , exp_state ))
606- log .log_error ("%s failed to reach %s state" % (warm_app_name , exp_state ))
616+ echo_and_log ("%s failed to reach %s state" % (warm_app_name , exp_state ), LOG_ERR )
607617 else :
608618 exp_state = "" # this is cold upgrade
609619
@@ -613,9 +623,9 @@ def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
613623 run_command ("config warm_restart disable %s" % container_name )
614624
615625 if state == exp_state :
616- click . echo ('Done' )
626+ echo_and_log ('Done' )
617627 else :
618- click . echo ('Failed' )
628+ echo_and_log ('Failed' , LOG_ERR )
619629 sys .exit (1 )
620630
621631
@@ -635,7 +645,7 @@ def rollback_docker(container_name):
635645 # All images id under the image name
636646 image_id_all = get_container_image_id_all (image_name )
637647 if len (image_id_all ) != 2 :
638- click . echo ("Two images required, but there are '{}' images for '{}'. Aborting..." .format (len (image_id_all ), image_name ))
648+ echo_and_log ("Two images required, but there are '{}' images for '{}'. Aborting..." .format (len (image_id_all ), image_name ), LOG_ERR )
639649 raise click .Abort ()
640650
641651 image_latest = image_name + ":latest"
@@ -649,19 +659,19 @@ def rollback_docker(container_name):
649659 # make previous image as latest
650660 run_command ("docker tag %s:%s %s:latest" % (image_name , version_tag , image_name ))
651661 if container_name == "swss" or container_name == "bgp" or container_name == "teamd" :
652- click . echo ("Cold reboot is required to restore system state after '{}' rollback !!" .format (container_name ))
662+ echo_and_log ("Cold reboot is required to restore system state after '{}' rollback !!" .format (container_name ), LOG_ERR )
653663 else :
654664 run_command ("systemctl restart %s" % container_name )
655665
656- click . echo ('Done' )
666+ echo_and_log ('Done' )
657667
658668# verify the next image
659669@sonic_installer .command ('verify-next-image' )
660670def verify_next_image ():
661671 """ Verify the next image for reboot"""
662672 bootloader = get_bootloader ()
663673 if not bootloader .verify_next_image ():
664- click . echo ('Image verification failed' )
674+ echo_and_log ('Image verification failed' , LOG_ERR )
665675 sys .exit (1 )
666676 click .echo ('Image successfully verified' )
667677
0 commit comments