def migrate_sonic_packages(bootloader, binary_image_version):
    ' Migrate SONiC packages to new SONiC image. '
    SONIC_PACKAGE_MANAGER = 'sonic-package-manager'
    PACKAGE_MANAGER_DIR = '/var/lib/sonic-package-manager/'
    DOCKER_CTL_SCRIPT = '/usr/lib/docker/docker.sh'
    DOCKERD_SOCK = 'docker.sock'
    VAR_RUN_PATH = '/var/run/'
    tmp_dir = 'tmp'
    packages_file = 'packages.json'
    packages_path = os.path.join(PACKAGE_MANAGER_DIR, packages_file)
    sonic_version = re.sub(IMAGE_PREFIX, '', binary_image_version)
    new_image_dir = bootloader.get_image_path(binary_image_version)
    new_image_upper_dir = os.path.join(new_image_dir, UPPERDIR_NAME)
    new_image_work_dir = os.path.join(new_image_dir, WORKDIR_NAME)
    new_image_docker_dir = os.path.join(new_image_dir, DOCKERDIR_NAME)
    new_image_mount = os.path.join('/', tmp_dir, 'image-{0}-fs'.format(sonic_version))
    new_image_docker_mount = os.path.join(new_image_mount, 'var', 'lib', 'docker')
    if (not os.path.isdir(new_image_docker_dir)):
        echo_and_log('Error: SONiC package migration cannot proceed due to missing docker folder', LOG_ERR, fg='red')
        return
    docker_started = False
    with bootloader.get_rootfs_path(new_image_dir) as new_image_squashfs_path:
        try:
            mount_squash_fs(new_image_squashfs_path, new_image_mount)
            run_command_or_raise(['mkdir', '-p', new_image_upper_dir])
            run_command_or_raise(['mkdir', '-p', new_image_work_dir])
            mount_overlay_fs(new_image_mount, new_image_upper_dir, new_image_work_dir, new_image_mount)
            mount_bind(new_image_docker_dir, new_image_docker_mount)
            mount_procfs_chroot(new_image_mount)
            mount_sysfs_chroot(new_image_mount)
            if (not os.path.exists(os.path.join(new_image_mount, os.path.relpath(DOCKER_CTL_SCRIPT, os.path.abspath(os.sep))))):
                echo_and_log('Warning: SONiC Application Extension is not supported in this image', LOG_WARN, fg='yellow')
                return
            run_command_or_raise(['chroot', new_image_mount, DOCKER_CTL_SCRIPT, 'start'])
            docker_started = True
            run_command_or_raise(['cp', packages_path, os.path.join(new_image_mount, tmp_dir, packages_file)])
            run_command_or_raise(['touch', os.path.join(new_image_mount, 'tmp', DOCKERD_SOCK)])
            run_command_or_raise(['mount', '--bind', os.path.join(VAR_RUN_PATH, DOCKERD_SOCK), os.path.join(new_image_mount, 'tmp', DOCKERD_SOCK)])
            run_command_or_raise(['chroot', new_image_mount, 'sh', '-c', 'command -v {}'.format(SONIC_PACKAGE_MANAGER)])
            run_command_or_raise(['chroot', new_image_mount, SONIC_PACKAGE_MANAGER, 'migrate', os.path.join('/', tmp_dir, packages_file), '--dockerd-socket', os.path.join('/', tmp_dir, DOCKERD_SOCK), '-y'])
        finally:
            if docker_started:
                run_command_or_raise(['chroot', new_image_mount, DOCKER_CTL_SCRIPT, 'stop'], raise_exception=False)
            umount(new_image_mount, recursive=True, read_only=False, remove_dir=False, raise_exception=False)
            umount(new_image_mount, raise_exception=False)
Migrate SONiC packages to new SONiC image.
def migrate_sonic_packages(bootloader, binary_image_version):
    '  '
    SONIC_PACKAGE_MANAGER = 'sonic-package-manager'
    PACKAGE_MANAGER_DIR = '/var/lib/sonic-package-manager/'
    DOCKER_CTL_SCRIPT = '/usr/lib/docker/docker.sh'
    DOCKERD_SOCK = 'docker.sock'
    VAR_RUN_PATH = '/var/run/'
    tmp_dir = 'tmp'
    packages_file = 'packages.json'
    packages_path = os.path.join(PACKAGE_MANAGER_DIR, packages_file)
    sonic_version = re.sub(IMAGE_PREFIX, , binary_image_version)
    new_image_dir = bootloader.get_image_path(binary_image_version)
    new_image_upper_dir = os.path.join(new_image_dir, UPPERDIR_NAME)
    new_image_work_dir = os.path.join(new_image_dir, WORKDIR_NAME)
    new_image_docker_dir = os.path.join(new_image_dir, DOCKERDIR_NAME)
    new_image_mount = os.path.join('/', tmp_dir, 'image-{0}-fs'.format(sonic_version))
    new_image_docker_mount = os.path.join(new_image_mount, 'var', 'lib', 'docker')
    if (not os.path.isdir(new_image_docker_dir)):
        echo_and_log('Error: SONiC package migration cannot proceed due to missing docker folder', LOG_ERR, fg='red')
        return
    docker_started = False
    with bootloader.get_rootfs_path(new_image_dir) as new_image_squashfs_path:
        try:
            mount_squash_fs(new_image_squashfs_path, new_image_mount)
            run_command_or_raise(['mkdir', '-p', new_image_upper_dir])
            run_command_or_raise(['mkdir', '-p', new_image_work_dir])
            mount_overlay_fs(new_image_mount, new_image_upper_dir, new_image_work_dir, new_image_mount)
            mount_bind(new_image_docker_dir, new_image_docker_mount)
            mount_procfs_chroot(new_image_mount)
            mount_sysfs_chroot(new_image_mount)
            if (not os.path.exists(os.path.join(new_image_mount, os.path.relpath(DOCKER_CTL_SCRIPT, os.path.abspath(os.sep))))):
                echo_and_log('Warning: SONiC Application Extension is not supported in this image', LOG_WARN, fg='yellow')
                return
            run_command_or_raise(['chroot', new_image_mount, DOCKER_CTL_SCRIPT, 'start'])
            docker_started = True
            run_command_or_raise(['cp', packages_path, os.path.join(new_image_mount, tmp_dir, packages_file)])
            run_command_or_raise(['touch', os.path.join(new_image_mount, 'tmp', DOCKERD_SOCK)])
            run_command_or_raise(['mount', '--bind', os.path.join(VAR_RUN_PATH, DOCKERD_SOCK), os.path.join(new_image_mount, 'tmp', DOCKERD_SOCK)])
            run_command_or_raise(['chroot', new_image_mount, 'sh', '-c', 'command -v {}'.format(SONIC_PACKAGE_MANAGER)])
            run_command_or_raise(['chroot', new_image_mount, SONIC_PACKAGE_MANAGER, 'migrate', os.path.join('/', tmp_dir, packages_file), '--dockerd-socket', os.path.join('/', tmp_dir, DOCKERD_SOCK), '-y'])
        finally:
            if docker_started:
                run_command_or_raise(['chroot', new_image_mount, DOCKER_CTL_SCRIPT, 'stop'], raise_exception=False)
            umount(new_image_mount, recursive=True, read_only=False, remove_dir=False, raise_exception=False)
            umount(new_image_mount, raise_exception=False)