@sonic_installer.command('upgrade-docker')
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false, expose_value=False, prompt='New docker image will be installed, continue?')
@click.option('--cleanup_image', is_flag=True, help='Clean up old docker image')
@click.option('--skip_check', is_flag=True, help='Skip task check for docker upgrade')
@click.option('--tag', type=str, help='Tag for the new docker image')
@click.option('--warm', is_flag=True, help='Perform warm upgrade')
@click.argument('container_name', metavar='<container_name>', required=True, type=click.Choice(DOCKER_CONTAINER_LIST))
@click.argument('url')
def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
    ' Upgrade docker image from local binary or URL'
    if ('upgrade_docker' in sys.argv):
        print_deprecation_warning('upgrade_docker', 'upgrade-docker')
    image_name = get_container_image_name(container_name)
    image_latest = (image_name + ':latest')
    image_id_previous = get_container_image_id(image_latest)
    DEFAULT_IMAGE_PATH = os.path.join('/tmp/', image_name)
    if (url.startswith('http://') or url.startswith('https://')):
        echo_and_log('Downloading image...')
        validate_url_or_abort(url)
        try:
            urlretrieve(url, DEFAULT_IMAGE_PATH, reporthook)
        except Exception as e:
            echo_and_log('Download error: {}'.format(e), LOG_ERR)
            raise click.Abort()
        image_path = DEFAULT_IMAGE_PATH
    else:
        image_path = os.path.join('./', url)
    if (not os.path.isfile(image_path)):
        echo_and_log("Image file '{}' does not exist or is not a regular file. Aborting...".format(image_path), LOG_ERR)
        raise click.Abort()
    warm_configured = False
    state_db = SonicV2Connector(host='127.0.0.1')
    state_db.connect(state_db.STATE_DB, False)
    TABLE_NAME_SEPARATOR = '|'
    prefix = ('WARM_RESTART_ENABLE_TABLE' + TABLE_NAME_SEPARATOR)
    _hash = '{}{}'.format(prefix, container_name)
    if (state_db.get(state_db.STATE_DB, _hash, 'enable') == 'true'):
        warm_configured = True
    state_db.close(state_db.STATE_DB)
    if ((container_name == 'swss') or (container_name == 'bgp') or (container_name == 'teamd')):
        if ((warm_configured is False) and warm):
            run_command(('config warm_restart enable %s' % container_name))
    tag_previous = get_docker_tag_name(image_latest)
    run_command(('docker load < %s' % image_path))
    warm_app_names = []
    if ((warm_configured is True) or warm):
        if (container_name == 'swss'):
            skipPendingTaskCheck = ''
            if skip_check:
                skipPendingTaskCheck = ' -s'
            cmd = ('docker exec -i swss orchagent_restart_check -w 2000 -r 5 ' + skipPendingTaskCheck)
            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, text=True)
            (out, err) = proc.communicate()
            if (proc.returncode != 0):
                if (not skip_check):
                    echo_and_log('Orchagent is not in clean state, RESTARTCHECK failed', LOG_ERR)
                    if ((warm_configured is False) and warm):
                        run_command(('config warm_restart disable %s' % container_name))
                    image_id_latest = get_container_image_id(image_latest)
                    run_command(('docker rmi -f %s' % image_id_latest))
                    run_command(('docker tag %s:%s %s' % (image_name, tag_previous, image_latest)))
                    sys.exit(proc.returncode)
                else:
                    echo_and_log('Orchagent is not in clean state, upgrading it anyway')
            else:
                echo_and_log('Orchagent is in clean state and frozen for warm upgrade')
            warm_app_names = ['orchagent', 'neighsyncd']
        elif (container_name == 'bgp'):
            echo_and_log('Stopping bgp ...')
            run_command('docker exec -i bgp pkill -9 zebra')
            run_command('docker exec -i bgp pkill -9 bgpd')
            warm_app_names = ['bgp']
            echo_and_log('Stopped  bgp ...')
        elif (container_name == 'teamd'):
            echo_and_log('Stopping teamd ...')
            run_command('docker exec -i teamd pkill -USR1 teamd > /dev/null')
            warm_app_names = ['teamsyncd']
            echo_and_log('Stopped  teamd ...')
        for warm_app_name in warm_app_names:
            hdel_warm_restart_table('STATE_DB', 'WARM_RESTART_TABLE', warm_app_name, 'state')
    run_command(('docker kill %s > /dev/null' % container_name))
    run_command(('docker rm %s ' % container_name))
    if (tag is None):
        tag = get_docker_tag_name(image_latest)
    run_command(('docker tag %s:latest %s:%s' % (image_name, image_name, tag)))
    run_command(('systemctl restart %s' % container_name))
    image_id_all = get_container_image_id_all(image_name)
    image_id_latest = get_container_image_id(image_latest)
    for id in image_id_all:
        if (id != image_id_latest):
            if ((not cleanup_image) and (id == image_id_previous)):
                continue
            run_command(('docker rmi -f %s' % id))
    exp_state = 'reconciled'
    state = ''
    if ((warm_configured is True) or warm):
        count = 0
        for warm_app_name in warm_app_names:
            state = ''
            while ((state != exp_state) and (count < 90)):
                sys.stdout.write('\r  {}: '.format(warm_app_name))
                sys.stdout.write(('[%-s' % ('=' * count)))
                sys.stdout.flush()
                count += 1
                time.sleep(2)
                state = hget_warm_restart_table('STATE_DB', 'WARM_RESTART_TABLE', warm_app_name, 'state')
                log.log_notice(('%s reached %s state' % (warm_app_name, state)))
            sys.stdout.write(']\n\r')
            if (state != exp_state):
                echo_and_log(('%s failed to reach %s state' % (warm_app_name, exp_state)), LOG_ERR)
    else:
        exp_state = ''
    if ((warm_configured is False) and warm):
        if ((container_name == 'swss') or (container_name == 'bgp') or (container_name == 'teamd')):
            run_command(('config warm_restart disable %s' % container_name))
    if (state == exp_state):
        echo_and_log('Done')
    else:
        echo_and_log('Failed', LOG_ERR)
        sys.exit(1)
Upgrade docker image from local binary or URL
@sonic_installer.command('upgrade-docker')
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false, expose_value=False, prompt='New docker image will be installed, continue?')
@click.option('--cleanup_image', is_flag=True, help='Clean up old docker image')
@click.option('--skip_check', is_flag=True, help='Skip task check for docker upgrade')
@click.option('--tag', type=str, help='Tag for the new docker image')
@click.option('--warm', is_flag=True, help='Perform warm upgrade')
@click.argument('container_name', metavar='<container_name>', required=True, type=click.Choice(DOCKER_CONTAINER_LIST))
@click.argument('url')
def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
    ' '
    if ('upgrade_docker' in sys.argv):
        print_deprecation_warning('upgrade_docker', 'upgrade-docker')
    image_name = get_container_image_name(container_name)
    image_latest = (image_name + ':latest')
    image_id_previous = get_container_image_id(image_latest)
    DEFAULT_IMAGE_PATH = os.path.join('/tmp/', image_name)
    if (url.startswith('http://') or url.startswith('https://')):
        echo_and_log('Downloading image...')
        validate_url_or_abort(url)
        try:
            urlretrieve(url, DEFAULT_IMAGE_PATH, reporthook)
        except Exception as e:
            echo_and_log('Download error: {}'.format(e), LOG_ERR)
            raise click.Abort()
        image_path = DEFAULT_IMAGE_PATH
    else:
        image_path = os.path.join('./', url)
    if (not os.path.isfile(image_path)):
        echo_and_log("Image file '{}' does not exist or is not a regular file. Aborting...".format(image_path), LOG_ERR)
        raise click.Abort()
    warm_configured = False
    state_db = SonicV2Connector(host='127.0.0.1')
    state_db.connect(state_db.STATE_DB, False)
    TABLE_NAME_SEPARATOR = '|'
    prefix = ('WARM_RESTART_ENABLE_TABLE' + TABLE_NAME_SEPARATOR)
    _hash = '{}{}'.format(prefix, container_name)
    if (state_db.get(state_db.STATE_DB, _hash, 'enable') == 'true'):
        warm_configured = True
    state_db.close(state_db.STATE_DB)
    if ((container_name == 'swss') or (container_name == 'bgp') or (container_name == 'teamd')):
        if ((warm_configured is False) and warm):
            run_command(('config warm_restart enable %s' % container_name))
    tag_previous = get_docker_tag_name(image_latest)
    run_command(('docker load < %s' % image_path))
    warm_app_names = []
    if ((warm_configured is True) or warm):
        if (container_name == 'swss'):
            skipPendingTaskCheck = 
            if skip_check:
                skipPendingTaskCheck = ' -s'
            cmd = ('docker exec -i swss orchagent_restart_check -w 2000 -r 5 ' + skipPendingTaskCheck)
            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, text=True)
            (out, err) = proc.communicate()
            if (proc.returncode != 0):
                if (not skip_check):
                    echo_and_log('Orchagent is not in clean state, RESTARTCHECK failed', LOG_ERR)
                    if ((warm_configured is False) and warm):
                        run_command(('config warm_restart disable %s' % container_name))
                    image_id_latest = get_container_image_id(image_latest)
                    run_command(('docker rmi -f %s' % image_id_latest))
                    run_command(('docker tag %s:%s %s' % (image_name, tag_previous, image_latest)))
                    sys.exit(proc.returncode)
                else:
                    echo_and_log('Orchagent is not in clean state, upgrading it anyway')
            else:
                echo_and_log('Orchagent is in clean state and frozen for warm upgrade')
            warm_app_names = ['orchagent', 'neighsyncd']
        elif (container_name == 'bgp'):
            echo_and_log('Stopping bgp ...')
            run_command('docker exec -i bgp pkill -9 zebra')
            run_command('docker exec -i bgp pkill -9 bgpd')
            warm_app_names = ['bgp']
            echo_and_log('Stopped  bgp ...')
        elif (container_name == 'teamd'):
            echo_and_log('Stopping teamd ...')
            run_command('docker exec -i teamd pkill -USR1 teamd > /dev/null')
            warm_app_names = ['teamsyncd']
            echo_and_log('Stopped  teamd ...')
        for warm_app_name in warm_app_names:
            hdel_warm_restart_table('STATE_DB', 'WARM_RESTART_TABLE', warm_app_name, 'state')
    run_command(('docker kill %s > /dev/null' % container_name))
    run_command(('docker rm %s ' % container_name))
    if (tag is None):
        tag = get_docker_tag_name(image_latest)
    run_command(('docker tag %s:latest %s:%s' % (image_name, image_name, tag)))
    run_command(('systemctl restart %s' % container_name))
    image_id_all = get_container_image_id_all(image_name)
    image_id_latest = get_container_image_id(image_latest)
    for id in image_id_all:
        if (id != image_id_latest):
            if ((not cleanup_image) and (id == image_id_previous)):
                continue
            run_command(('docker rmi -f %s' % id))
    exp_state = 'reconciled'
    state = 
    if ((warm_configured is True) or warm):
        count = 0
        for warm_app_name in warm_app_names:
            state = 
            while ((state != exp_state) and (count < 90)):
                sys.stdout.write('\r  {}: '.format(warm_app_name))
                sys.stdout.write(('[%-s' % ('=' * count)))
                sys.stdout.flush()
                count += 1
                time.sleep(2)
                state = hget_warm_restart_table('STATE_DB', 'WARM_RESTART_TABLE', warm_app_name, 'state')
                log.log_notice(('%s reached %s state' % (warm_app_name, state)))
            sys.stdout.write(']\n\r')
            if (state != exp_state):
                echo_and_log(('%s failed to reach %s state' % (warm_app_name, exp_state)), LOG_ERR)
    else:
        exp_state = 
    if ((warm_configured is False) and warm):
        if ((container_name == 'swss') or (container_name == 'bgp') or (container_name == 'teamd')):
            run_command(('config warm_restart disable %s' % container_name))
    if (state == exp_state):
        echo_and_log('Done')
    else:
        echo_and_log('Failed', LOG_ERR)
        sys.exit(1)